> diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
> index d40cb5dd446ca..aaedda3730f37 100644
> --- a/kernel/bpf/hashtab.c
> +++ b/kernel/bpf/hashtab.c

[ ... ]

> @@ -3022,10 +3013,12 @@ static long rhtab_map_update_existing(struct bpf_map 
> *map, struct rhtab_elem *el
>        * BPF_F_LOCK, matching arraymap semantics.
>        *
>        * copy_map_value() skips special-field offsets, so old timers/
> -      * kptrs/etc. still sit in the slot. Cancel them after the copy
> -      * to match arraymap's update semantics.
> +      * kptrs/etc. still sit in the slot. Cancel the NMI-safe ones after
> +      * the copy to match arraymap's update semantics; referenced kptrs
> +      * stay attached and are destroyed by rhtab_mem_dtor().
>        */
> -     rhtab_check_and_free_fields(rhtab, elem);
> +     bpf_obj_cancel_fields(&rhtab->map,
> +                           rhtab_elem_value(elem, rhtab->map.key_size));

This isn't a bug, but could the second argument use old_val here? It
already holds rhtab_elem_value(elem, map->key_size) from the top of the
function and is used by copy_map_value_locked() two lines above.

> @@ -3066,7 +3059,14 @@ static long rhtab_map_update_elem(struct bpf_map *map, 
> void *key, void *value, u
>
>       memcpy(elem->data, key, map->key_size);
>       copy_map_value(map, rhtab_elem_value(elem, map->key_size), value);
> -     check_and_init_map_value(map, rhtab_elem_value(elem, map->key_size));
> +     /*
> +      * No explicit special-field initialization, matching the hash map's
> +      * non-prealloc path: fresh elements come zeroed from the bpf mem
> +      * allocator, and recycled elements had their timer/workqueue/task_work
> +      * slots reset by bpf_obj_cancel_fields() on delete. kptr slots are
> +      * left untouched so a recycled element keeps owning its reference
> +      * until rhtab_mem_dtor() releases it.
> +      */

A subsystem pattern flags this as potentially concerning: the
copy_map_value() call on a field-capable map type is no longer followed
by check_and_init_map_value().

Looking at the non-prealloc hash map path in alloc_htab_elem(), it
appears this pattern has never called check_and_init_map_value() for
fresh elements, and the bpf mem allocator does return zeroed memory. For
recycled elements, the kptr slot staying intact is the intended behavior
since rhtab_mem_dtor() handles final cleanup.

Could you confirm this removal is safe for all special field types that
BPF_MAP_TYPE_RHASH supports?

This isn't a bug, but does the seven-line comment block add clarity over
the briefer explanations already present in rhtab_delete_elem() and
rhtab_map_update_existing()? The same rationale appears three times
within about 110 lines.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/33478386254

Reply via email to