From: Hou Tao <houtao1@xxxxxxxxxx> 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 and PREEMPT_RT is enabled, hrtimer_cancel will invoke hrtimer_cancel_wait_running() and it will try to acquire a spin-lock, however, htab_lru_map_delete_node() has already acquired a raw-spin-lock, it violates the lockdep rule and may trigger the "BUG: scheduling while atomic" warning. Fix the issue by moving the invocation of check_and_free_fields() out of bucket lock. Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx> --- kernel/bpf/hashtab.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 007571ce4343..8fecf21c132a 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -826,13 +826,14 @@ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node) hlist_nulls_for_each_entry_rcu(l, n, head, hash_node) if (l == tgt_l) { hlist_nulls_del_rcu(&l->hash_node); - check_and_free_fields(htab, l); bpf_map_dec_elem_count(&htab->map); break; } htab_unlock_bucket(htab, b, tgt_l->hash, flags); + if (l == tgt_l) + check_and_free_fields(htab, l); return l == tgt_l; } -- 2.29.2