@@ -940,8 +940,12 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
__pcpu_freelist_push(&htab->freelist, &l->fnode);
} else {
dec_elem_count(htab);
- l->htab = htab;
- call_rcu(&l->rcu, htab_elem_free_rcu);
+ if (htab->map.map_type == BPF_MAP_TYPE_PERCPU_HASH) {
+ l->htab = htab;
+ call_rcu(&l->rcu, htab_elem_free_rcu);
+ } else {
+ htab_elem_free(htab, l);
+ }
}
}
@@ -277,7 +277,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size)
return -ENOMEM;
size += LLIST_NODE_SZ; /* room for llist_node */
snprintf(buf, sizeof(buf), "bpf-%u", size);
- kmem_cache = kmem_cache_create(buf, size, 8, 0, NULL);
+ kmem_cache = kmem_cache_create(buf, size, 8, SLAB_TYPESAFE_BY_RCU, NULL);
if (!kmem_cache) {
free_percpu(pc);
return -ENOMEM;
@@ -208,17 +208,6 @@ static int timer_cb2(void *map, int *key, struct hmap_elem *val)
*/
bpf_map_delete_elem(map, key);
- /* in non-preallocated hashmap both 'key' and 'val' are RCU
- * protected and still valid though this element was deleted
- * from the map. Arm this timer for ~35 seconds. When callback
- * finishes the call_rcu will invoke:
- * htab_elem_free_rcu
- * check_and_free_timer
- * bpf_timer_cancel_and_free
- * to cancel this 35 second sleep and delete the timer for real.
- */
- if (bpf_timer_start(&val->timer, 1ull << 35, 0) != 0)
- err |= 256;
ok |= 4;
}
return 0;