> When rte_hash_add_key_data() is called with an existing key, the old
> data pointer is silently overwritten. With RCU-protected readers still
> potentially accessing the old data, the application cannot safely free
> it since the old pointer is never returned.
> 
> This series fixes the issue in two places:
> 
> * When RCU is configured with a free_key_data_func callback,
>   rte_hash_add_key_data() now automatically defers freeing the old data
>   on overwrite. No caller changes are needed.
> 
> * If rte_hash_del_key() fails to enqueue the deleted entry in
>   RTE_HASH_QSBR_MODE_DQ, it falls back on RTE_HASH_QSBR_MODE_SYNC to
>   avoid leaking slots and data pointers.
> 
> v3:
> 
> * Use rte_atomic_exchange_explicit() to swap the new data pointer with
>   the old one in search_and_update().
> 
> * Removed the rte_hash_replace_key_data() API 

That's a pity - I think it is a useful one.

> which required to bubble
>   a potential old_data pointer from search_and_update() to all
>   intermediate callers down to __rte_hash_add_key_with_hash(). It made
>   an already complex code even more obscure.
> 
> v2:
> 
> * New patch to fallback to SYNC mode when DQ fails on delete.
> * Check key_idx == EMPTY_SLOT in DQ mode to differentiate when old_data
>   is NULL.
> * Also fallback to SYNC mode when DQ fails on replace.
> 
> Robin Jarry (2):
>   hash: avoid leaking entries on RCU defer queue failure
>   hash: free replaced data on overwrite when RCU is configured
> 
>  app/test/test_hash.c                   | 134 +++++++++++++++++++++++++
>  doc/guides/rel_notes/release_26_03.rst |   7 ++
>  lib/hash/rte_cuckoo_hash.c             |  47 +++++++--
>  lib/hash/rte_hash.h                    |   8 +-
>  4 files changed, 187 insertions(+), 9 deletions(-)
> 
> --
> 2.53.0
> 

Reply via email to