diff options
author | Gabriel Oginski <gabrielx.oginski@intel.com> | 2023-02-21 08:42:06 +0000 |
---|---|---|
committer | Fan Zhang <fanzhang.oss@gmail.com> | 2023-03-02 13:21:52 +0000 |
commit | 9ad423fceb8d9877b337ada5fc1e053de21323b2 (patch) | |
tree | ed506032af861e9724fe5bb8dab50a234285cba8 /src/plugins/wireguard/wireguard_index_table.c | |
parent | 04853c67e4f06b8b33005b7c2ccaca5a2d015760 (diff) |
wireguard: add barrier to sync data
The current implmentation of the hash table is not thread-safe.
This design leads to a segfault when VPP is handling a lot of tunnels
for Wireguard, where one thread modifies the hash table and other
threads start the lookup at the same time.
This fix adds a barrier sync to the hash table access when Wireguard
adds or deletes an element.
Type: fix
Signed-off-by: Gabriel Oginski <gabrielx.oginski@intel.com>
Change-Id: Id460dfcd46ace17c7bdcd23bd9687d26cecf0a39
Diffstat (limited to 'src/plugins/wireguard/wireguard_index_table.c')
-rw-r--r-- | src/plugins/wireguard/wireguard_index_table.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/plugins/wireguard/wireguard_index_table.c b/src/plugins/wireguard/wireguard_index_table.c index 5f81204b4c0..da53bfd75f1 100644 --- a/src/plugins/wireguard/wireguard_index_table.c +++ b/src/plugins/wireguard/wireguard_index_table.c @@ -13,13 +13,15 @@ * limitations under the License. */ +#include <vlib/vlib.h> #include <vppinfra/hash.h> #include <vppinfra/pool.h> #include <vppinfra/random.h> #include <wireguard/wireguard_index_table.h> u32 -wg_index_table_add (wg_index_table_t * table, u32 peer_pool_idx, u32 rnd_seed) +wg_index_table_add (vlib_main_t *vm, wg_index_table_t *table, + u32 peer_pool_idx, u32 rnd_seed) { u32 key; @@ -29,19 +31,25 @@ wg_index_table_add (wg_index_table_t * table, u32 peer_pool_idx, u32 rnd_seed) if (hash_get (table->hash, key)) continue; + vlib_worker_thread_barrier_sync (vm); hash_set (table->hash, key, peer_pool_idx); + vlib_worker_thread_barrier_release (vm); break; } return key; } void -wg_index_table_del (wg_index_table_t * table, u32 key) +wg_index_table_del (vlib_main_t *vm, wg_index_table_t *table, u32 key) { uword *p; p = hash_get (table->hash, key); if (p) - hash_unset (table->hash, key); + { + vlib_worker_thread_barrier_sync (vm); + hash_unset (table->hash, key); + vlib_worker_thread_barrier_release (vm); + } } u32 * |