Skip to content

Commit 58d291a

Browse files
Hou TaoKernel Patches Daemon
authored andcommitted
bpf: Free special fields after unlock in htab_lru_map_delete_node()
When bpf_timer is used in LRU hash map, calling check_and_free_fields() in htab_lru_map_delete_node() will invoke bpf_timer_cancel_and_free() to free the bpf_timer. If the timer is running on other CPUs, hrtimer_cancel() will invoke hrtimer_cancel_wait_running() to spin on current CPU to wait for the completion of the hrtimer callback. Considering that the deletion has already acquired a raw-spin-lock (bucket lock). To reduce the time holding the bucket lock, move the invocation of check_and_free_fields() out of bucket lock. However, because htab_lru_map_delete_node() is invoked with LRU raw spin lock being held, the freeing of special fields still happens in a locked scope. Signed-off-by: Hou Tao <[email protected]> Reviewed-by: Toke Høiland-Jørgensen <[email protected]>
1 parent 7190946 commit 58d291a

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

kernel/bpf/hashtab.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,13 +824,14 @@ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node)
824824
hlist_nulls_for_each_entry_rcu(l, n, head, hash_node)
825825
if (l == tgt_l) {
826826
hlist_nulls_del_rcu(&l->hash_node);
827-
check_and_free_fields(htab, l);
828827
bpf_map_dec_elem_count(&htab->map);
829828
break;
830829
}
831830

832831
htab_unlock_bucket(htab, b, tgt_l->hash, flags);
833832

833+
if (l == tgt_l)
834+
check_and_free_fields(htab, l);
834835
return l == tgt_l;
835836
}
836837

0 commit comments

Comments
 (0)