diff options
author | Shesha Sreenivasamurthy <shesha@cisco.com> | 2016-06-06 17:10:20 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-06-07 11:30:34 +0000 |
commit | 30097b5d2270ddf124eb0a03fcd2ad85bab78834 (patch) | |
tree | b4326d5d2c1b969eeceec6010dfc71bfdecf1ae6 | |
parent | 97d99518d727d454895f201f1990475c8a738060 (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.c | 96 |
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; |