X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fclassify%2Fvnet_classify.c;h=57d8674884c9ffc33c74f82c3f7682b5dec396a2;hb=refs%2Fchanges%2F71%2F8371%2F2;hp=418e3da8250682029118d16064f6b4ca142d732b;hpb=cada2a0ae4d1c1add4ad1b37649555ae7e9afc14;p=vpp.git diff --git a/src/vnet/classify/vnet_classify.c b/src/vnet/classify/vnet_classify.c index 418e3da8250..57d8674884c 100644 --- a/src/vnet/classify/vnet_classify.c +++ b/src/vnet/classify/vnet_classify.c @@ -362,6 +362,34 @@ split_and_rehash_linear (vnet_classify_table_t * t, return new_values; } +static void +vnet_classify_entry_claim_resource (vnet_classify_entry_t *e) +{ + switch (e->action) + { + case CLASSIFY_ACTION_SET_IP4_FIB_INDEX: + fib_table_lock (e->metadata, FIB_PROTOCOL_IP4, FIB_SOURCE_CLASSIFY); + break; + case CLASSIFY_ACTION_SET_IP6_FIB_INDEX: + fib_table_lock (e->metadata, FIB_PROTOCOL_IP6, FIB_SOURCE_CLASSIFY); + break; + } +} + +static void +vnet_classify_entry_release_resource (vnet_classify_entry_t *e) +{ + switch (e->action) + { + case CLASSIFY_ACTION_SET_IP4_FIB_INDEX: + fib_table_unlock (e->metadata, FIB_PROTOCOL_IP4, FIB_SOURCE_CLASSIFY); + break; + case CLASSIFY_ACTION_SET_IP6_FIB_INDEX: + fib_table_unlock (e->metadata, FIB_PROTOCOL_IP6, FIB_SOURCE_CLASSIFY); + break; + } +} + int vnet_classify_add_del (vnet_classify_table_t * t, vnet_classify_entry_t * add_v, int is_add) @@ -377,7 +405,7 @@ int vnet_classify_add_del (vnet_classify_table_t * t, u32 old_log2_pages, new_log2_pages; u32 thread_index = vlib_get_thread_index(); u8 * key_minus_skip; - int resplit_once; + int resplit_once = 0; int mark_bucket_linear; ASSERT ((add_v->flags & VNET_CLASSIFY_ENTRY_FREE) == 0); @@ -408,6 +436,7 @@ int vnet_classify_add_del (vnet_classify_table_t * t, clib_memcpy (v, add_v, sizeof (vnet_classify_entry_t) + t->match_n_vectors * sizeof (u32x4)); v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE); + vnet_classify_entry_claim_resource (v); tmp_b.as_u64 = 0; tmp_b.offset = vnet_classify_get_offset (t, v); @@ -445,6 +474,7 @@ int vnet_classify_add_del (vnet_classify_table_t * t, clib_memcpy (v, add_v, sizeof (vnet_classify_entry_t) + t->match_n_vectors * sizeof(u32x4)); v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE); + vnet_classify_entry_claim_resource (v); CLIB_MEMORY_BARRIER(); /* Restore the previous (k,v) pairs */ @@ -461,6 +491,8 @@ int vnet_classify_add_del (vnet_classify_table_t * t, clib_memcpy (v, add_v, sizeof (vnet_classify_entry_t) + t->match_n_vectors * sizeof(u32x4)); v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE); + vnet_classify_entry_claim_resource (v); + CLIB_MEMORY_BARRIER(); b->as_u64 = t->saved_bucket.as_u64; t->active_elements ++; @@ -477,9 +509,11 @@ int vnet_classify_add_del (vnet_classify_table_t * t, if (!memcmp (v->key, add_v->key, t->match_n_vectors * sizeof (u32x4))) { + vnet_classify_entry_release_resource (v); memset (v, 0xff, sizeof (vnet_classify_entry_t) + t->match_n_vectors * sizeof(u32x4)); v->flags |= VNET_CLASSIFY_ENTRY_FREE; + CLIB_MEMORY_BARRIER(); b->as_u64 = t->saved_bucket.as_u64; t->active_elements --; @@ -552,6 +586,8 @@ int vnet_classify_add_del (vnet_classify_table_t * t, clib_memcpy (new_v, add_v, sizeof (vnet_classify_entry_t) + t->match_n_vectors * sizeof(u32x4)); new_v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE); + vnet_classify_entry_claim_resource (new_v); + goto expand_ok; } } @@ -2060,9 +2096,13 @@ int vnet_classify_add_del_session (vnet_classify_main_t * cm, e->flags = 0; e->action = action; if (e->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX) - e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, metadata); + e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, + metadata, + FIB_SOURCE_CLASSIFY); else if (e->action == CLASSIFY_ACTION_SET_IP6_FIB_INDEX) - e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, metadata); + e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, + metadata, + FIB_SOURCE_CLASSIFY); else e->metadata = 0; @@ -2075,6 +2115,9 @@ int vnet_classify_add_del_session (vnet_classify_main_t * cm, e->key[i] &= t->mask[i]; rv = vnet_classify_add_del (t, e, is_add); + + vnet_classify_entry_release_resource(e); + if (rv) return VNET_API_ERROR_NO_SUCH_ENTRY; return 0;