aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShesha Sreenivasamurthy <shesha@cisco.com>2016-06-06 17:10:20 -0700
committerDave Barach <openvpp@barachs.net>2016-06-07 11:30:34 +0000
commit30097b5d2270ddf124eb0a03fcd2ad85bab78834 (patch)
treeb4326d5d2c1b969eeceec6010dfc71bfdecf1ae6
parent97d99518d727d454895f201f1990475c8a738060 (diff)
Multicore support for vCGN
Locks are used while populating DB, which is once once per entry. Therefore, it is not in the performance critical path. Each thread is a PMD, therefore, spin locks are used instead of mutexes. Change-Id: I4bc297f73a8f3eafebed1f00e51ec75ca24163f6 Signed-off-by: Shesha Sreenivasamurthy <shesha@cisco.com>
-rw-r--r--vnet/vnet/vcgn/cnat_db_v2.c96
1 files changed, 91 insertions, 5 deletions
diff --git a/vnet/vnet/vcgn/cnat_db_v2.c b/vnet/vnet/vcgn/cnat_db_v2.c
index 5a26fd99d6c..2b43849dca3 100644
--- a/vnet/vnet/vcgn/cnat_db_v2.c
+++ b/vnet/vnet/vcgn/cnat_db_v2.c
@@ -43,6 +43,12 @@
u8 cnat_db_init_done = 0;
typedef struct {
+ /* Locks for multi thread support */
+ CLIB_CACHE_LINE_ALIGN_MARK(cacheline0);
+ pthread_spinlock_t *main_db_lockp;
+ pthread_spinlock_t *user_db_lockp;
+ pthread_spinlock_t *session_db_lockp;
+
u32 cached_next_index;
/* $$$$ add data here */
@@ -543,6 +549,7 @@ void cnat_user_db_delete (cnat_user_db_entry_t *up)
return;
}
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
#if 1
if(PREDICT_FALSE(up->flags & CNAT_USER_DB_DSLITE_FLAG)) {
dslite_key_t dk = {
@@ -589,6 +596,7 @@ void cnat_user_db_delete (cnat_user_db_entry_t *up)
found:
pool_put(cnat_user_db, up);
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
}
cnat_user_db_entry_t*
@@ -622,6 +630,7 @@ cnat_user_db_create_entry(cnat_db_key_bucket_t *uki,
{
cnat_user_db_entry_t *udb = NULL;
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
pool_get(cnat_user_db, udb);
memset(udb, 0, sizeof(*udb));
@@ -636,6 +645,7 @@ cnat_user_db_create_entry(cnat_db_key_bucket_t *uki,
#ifndef NO_BULK_LOGGING
INIT_BULK_CACHE(udb)
#endif /* NO_BULK_LOGGING */
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
return udb;
}
@@ -773,6 +783,7 @@ void cnat_delete_main_db_entry_v2 (cnat_main_db_entry_t *ep)
return;
}
+ pthread_spin_lock(cnat_db_v2_main.main_db_lockp);
if(PREDICT_FALSE(ep->flags &
CNAT_DB_FLAG_PPTP_TUNNEL_ACTIVE)) {
pptp_clear_all_channels(ep);
@@ -815,7 +826,7 @@ void cnat_delete_main_db_entry_v2 (cnat_main_db_entry_t *ep)
#endif
spp_printf(CNAT_INV_UNUSED_USR_INDEX, 1, (u32 *) &(ep->user_index));
cnat_main_db_entry_dump(ep);
- return;
+ goto unlock;
}
up = cnat_user_db + ep->user_index;
@@ -922,7 +933,9 @@ delete_entry:
main_db_index = ep - cnat_main_db;
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
up->ntranslations--;
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
/*
* when user reaches max allowed port limit
@@ -975,6 +988,8 @@ delete_entry:
}
nat44_dslite_common_stats[instance].active_translations--;
nat44_dslite_global_stats[!!(instance - 1)].translation_delete_count ++;
+unlock:
+ pthread_spin_unlock(cnat_db_v2_main.main_db_lockp);
}
cnat_main_db_entry_t*
@@ -1098,8 +1113,8 @@ void cnat_add_dest_n_log(
* if reash per user port limit,
* set user_db_entry pointer, and error == CNAT_OUT_LIMIT
*/
-cnat_main_db_entry_t*
-cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
+static cnat_main_db_entry_t*
+_cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
port_pair_t port_pair_type,
port_type_t port_type,
cnat_gen_icmp_info *info,
@@ -1368,7 +1383,9 @@ cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
/*
* increment port in use for this user
*/
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
udb->ntranslations += 1;
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
} else {
/*
@@ -1592,7 +1609,9 @@ cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
db2->vrfmap_index = my_vrfmap - cnat_map_by_vrf;
db2->entry_expires = cnat_current_time;
db2->flags |= CNAT_DB_FLAG_ALG_ENTRY;
+ pthread_spin_lock(cnat_db_v2_main.user_db_lockp);
udb->ntranslations += 1;
+ pthread_spin_unlock(cnat_db_v2_main.user_db_lockp);
db2->dst_ipv4 = dest_info->k.ipv4;
db2->dst_port = dest_info->k.port;
db2->nsessions = 0; /* For ALG db, set sessions to 0 - CSCuf78420 */
@@ -1624,6 +1643,22 @@ cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
return db;
}
+cnat_main_db_entry_t*
+cnat_get_main_db_entry_v2(cnat_db_key_bucket_t *ki,
+ port_pair_t port_pair_type,
+ port_type_t port_type,
+ cnat_gen_icmp_info *info,
+ cnat_key_t *dest_info)
+{
+
+ cnat_main_db_entry_t *db;
+ pthread_spin_lock(cnat_db_v2_main.main_db_lockp);
+ db = _cnat_get_main_db_entry_v2(ki, port_pair_type,
+ port_type, info, dest_info);
+ pthread_spin_unlock(cnat_db_v2_main.main_db_lockp);
+ return db;
+}
+
/*
* this function is called from config handler only
* to allocate a static port based db entry
@@ -1650,6 +1685,9 @@ cnat_create_static_main_db_entry_v2 (cnat_db_key_bucket_t *ki,
int nfv9_log_req = BULK_ALLOC_NOT_ATTEMPTED;
#endif
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
/*
* need to try lookup again because
* second pkt may come here before the entry is created
@@ -1984,6 +2022,8 @@ dslite_create_static_main_db_entry_v2 (dslite_db_key_bucket_t *ki,
cnat_vrfmap_t *my_vrfmap =0;
u16 my_vrfmap_index;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
/*
* need to try lookup again because
* second pkt may come here before the entry is created
@@ -2416,6 +2456,9 @@ cnat_timeout_db_create (cnat_timeout_t t_entry)
pool_header_t *h;
u32 free;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
db_index = cnat_timeout_db_hash_lookup(t_key);
if(db_index != EMPTY) {
@@ -2457,6 +2500,9 @@ void cnat_timeout_db_delete(cnat_key_t t_key)
u32 index, bucket;
cnat_timeout_db_entry_t *this, *prev;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
key.k.ipv4 = t_key.k.ipv4;
key.k.port = t_key.k.port;
key.k.vrf = t_key.k.vrf;
@@ -2629,6 +2675,7 @@ cnat_create_session_db_entry(cnat_key_t *ko,
return NULL;
}
+ pthread_spin_lock(cnat_db_v2_main.session_db_lockp);
pool_get(cnat_session_db, db);
memset(db, 0, sizeof(*db));
@@ -2688,6 +2735,7 @@ cnat_create_session_db_entry(cnat_key_t *ko,
newly established sessions */
db->entry_expires = cnat_current_time;
nat44_dslite_common_stats[instance].sessions++;
+ pthread_spin_unlock(cnat_db_v2_main.session_db_lockp);
return db;
}
@@ -2739,7 +2787,8 @@ cnat_dest_update_session2main(cnat_main_db_entry_t *mdb,
mdb->dst_port = sdb->v4_dest_key.k.port;
}
-void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
+static void
+_cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
{
u32 session_db_index;
u32 bdb_len;
@@ -2807,7 +2856,7 @@ void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
ASSERT(sdb_last != NULL);
cnat_dest_update_session2main(be, sdb_last);
- cnat_delete_session_db_entry(sdb_last, FALSE);
+ _cnat_delete_session_db_entry(sdb_last, FALSE);
}
/* Remove from session DB hashes */
@@ -2817,6 +2866,13 @@ void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
pool_put(cnat_session_db, ep);
}
+void cnat_delete_session_db_entry (cnat_session_entry_t *ep, u8 log)
+{
+ pthread_spin_lock(cnat_db_v2_main.session_db_lockp);
+ _cnat_delete_session_db_entry (ep, log);
+ pthread_spin_unlock(cnat_db_v2_main.session_db_lockp);
+}
+
cnat_main_db_entry_t*
dslite_main_db_lookup_entry(dslite_db_key_bucket_t *ki)
{
@@ -2899,6 +2955,9 @@ dslite_user_db_create_entry(dslite_db_key_bucket_t *uki,
{
cnat_user_db_entry_t *udb = NULL;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
pool_get(cnat_user_db, udb);
memset(udb, 0, sizeof(*udb));
@@ -2943,6 +3002,9 @@ dslite_create_main_db_entry_and_hash(dslite_db_key_bucket_t *ki,
u32 db_index;
cnat_main_db_entry_t *db = NULL;
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
pool_get(cnat_main_db, db);
memset(db, 0, sizeof(*db));
@@ -3086,6 +3148,10 @@ dslite_get_main_db_entry_v2(dslite_db_key_bucket_t *ki,
#ifndef NO_BULK_LOGGING
int nfv9_log_req = BULK_ALLOC_NOT_ATTEMPTED;
#endif
+
+ /* UNUSED. Therefore not ported to be multi-thread friendly */
+ ASSERT(0);
+
/*
* need to try lookup again because
* second pkt may come here before the entry is created
@@ -3709,6 +3775,26 @@ void cnat_db_v2_init (void)
svi_params_array[i].svi_type = CGSE_SVI_TYPE_INFRA;
}
#endif
+
+ cnat_db_v2_main.main_db_lockp =
+ clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
+ CLIB_CACHE_LINE_BYTES);
+
+ cnat_db_v2_main.user_db_lockp =
+ clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
+ CLIB_CACHE_LINE_BYTES);
+
+ cnat_db_v2_main.session_db_lockp =
+ clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
+ CLIB_CACHE_LINE_BYTES);
+
+ ASSERT (pthread_spin_init(cnat_db_v2_main.main_db_lockp,
+ PTHREAD_PROCESS_PRIVATE) == 0);
+ ASSERT (pthread_spin_init(cnat_db_v2_main.user_db_lockp,
+ PTHREAD_PROCESS_PRIVATE) == 0);
+ ASSERT (pthread_spin_init(cnat_db_v2_main.session_db_lockp,
+ PTHREAD_PROCESS_PRIVATE) == 0);
+
cnat_db_init_done = 1;
printf("CNAT DB init is successful\n");
return;