Fix map-notify processing with multiple workers
Change-Id: Id160346ebf533ee5f55bd735803624a75ed997b9
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c
index db78678..22b5c82 100644
--- a/src/vnet/lisp-cp/control.c
+++ b/src/vnet/lisp-cp/control.c
@@ -3352,14 +3352,14 @@
static void
map_records_arg_free (map_records_arg_t * a)
{
+ lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
mapping_t *m;
vec_foreach (m, a->mappings)
{
vec_free (m->locators);
gid_address_free (&m->eid);
}
-
- clib_mem_free (a);
+ pool_put (lcm->map_records_args_pool[vlib_get_thread_index ()], a);
}
void *
@@ -3420,7 +3420,7 @@
pool_put (lcm->pending_map_requests_pool, pmr);
done:
- map_records_arg_free (a);
+ a->is_free = 1;
return 0;
}
@@ -3471,7 +3471,7 @@
return;
}
- map_records_arg_free (a);
+ a->is_free = 1;
hash_unset (lcm->map_register_messages_by_nonce, a->nonce);
}
@@ -3557,6 +3557,24 @@
}
static map_records_arg_t *
+map_record_args_get ()
+{
+ lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
+ map_records_arg_t *rec;
+
+ /* Cleanup first */
+ /* *INDENT-OFF* */
+ pool_foreach (rec, lcm->map_records_args_pool[vlib_get_thread_index()], ({
+ if (rec->is_free)
+ map_records_arg_free (rec);
+ }));
+ /* *INDENT-ON* */
+
+ pool_get (lcm->map_records_args_pool[vlib_get_thread_index ()], rec);
+ return rec;
+}
+
+static map_records_arg_t *
parse_map_notify (vlib_buffer_t * b)
{
int rc = 0;
@@ -3567,8 +3585,9 @@
gid_address_t deid;
u16 auth_data_len = 0;
u8 record_count;
- map_records_arg_t *a = clib_mem_alloc (sizeof (*a));
+ map_records_arg_t *a;
+ a = map_record_args_get ();
memset (a, 0, sizeof (*a));
mnotif_hdr = vlib_buffer_get_current (b);
vlib_buffer_pull (b, sizeof (*mnotif_hdr));
@@ -3791,8 +3810,11 @@
u32 i, len = 0;
mapping_t m;
map_reply_hdr_t *mrep_hdr;
- map_records_arg_t *a = clib_mem_alloc (sizeof (*a));
+ map_records_arg_t *a;
+
+ a = map_record_args_get ();
memset (a, 0, sizeof (*a));
+
locator_t *locators;
mrep_hdr = vlib_buffer_get_current (b);
@@ -3948,6 +3970,8 @@
{
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
clib_error_t *error = 0;
+ vlib_thread_main_t *vtm = vlib_get_thread_main ();
+ u32 num_threads;
if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
return error;
@@ -3965,6 +3989,9 @@
lcm->do_map_resolver_election = 1;
lcm->map_request_mode = MR_MODE_DST_ONLY;
+ num_threads = 1 /* main thread */ + vtm->n_threads;
+ vec_validate (lcm->map_records_args_pool, num_threads - 1);
+
/* default vrf mapped to vni 0 */
hash_set (lcm->table_id_by_vni, 0, 0);
hash_set (lcm->vni_by_table_id, 0, 0);
diff --git a/src/vnet/lisp-cp/control.h b/src/vnet/lisp-cp/control.h
index ad90b52..cf2eb6e 100644
--- a/src/vnet/lisp-cp/control.h
+++ b/src/vnet/lisp-cp/control.h
@@ -126,6 +126,14 @@
typedef struct
{
+ u64 nonce;
+ u8 is_rloc_probe;
+ mapping_t *mappings;
+ volatile u8 is_free;
+} map_records_arg_t;
+
+typedef struct
+{
u32 flags;
/* LISP feature status */
@@ -226,6 +234,9 @@
/* timing wheel for mappping timeouts */
timing_wheel_t wheel;
+ /** Per thread pool of records shared with thread0 */
+ map_records_arg_t **map_records_args_pool;
+
/* commodity */
ip4_main_t *im4;
ip6_main_t *im6;
@@ -288,13 +299,6 @@
u8 key_id;
} vnet_lisp_add_del_mapping_args_t;
-typedef struct
-{
- u64 nonce;
- u8 is_rloc_probe;
- mapping_t *mappings;
-} map_records_arg_t;
-
int
vnet_lisp_map_cache_add_del (vnet_lisp_add_del_mapping_args_t * a,
u32 * map_index);