bpf_percpu_lru_pop_free uses raw_spin_lock_irqsave. This function is used by htab_percpu_lru_map_update_elem() which can be called from an NMI. A deadlock can happen if a bpf program holding the lock is interrupted by the same program in NMI. Use raw_spin_trylock_irqsave if in NMI. Fixes: 961578b63474 (bpf: Add percpu LRU list) Signed-off-by: Priya Bala Govindasamy <pgovind2@xxxxxxx> Signed-off-by: Amery Hung <ameryhung@xxxxxxxxx> --- kernel/bpf/bpf_lru_list.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/bpf_lru_list.c b/kernel/bpf/bpf_lru_list.c index 3dabdd137d10..c4a9e861369b 100644 --- a/kernel/bpf/bpf_lru_list.c +++ b/kernel/bpf/bpf_lru_list.c @@ -412,7 +412,12 @@ static struct bpf_lru_node *bpf_percpu_lru_pop_free(struct bpf_lru *lru, l = per_cpu_ptr(lru->percpu_lru, cpu); - raw_spin_lock_irqsave(&l->lock, flags); + if (in_nmi()) { + if (!raw_spin_trylock_irqsave(&l->lock, flags)) + return NULL; + } else { + raw_spin_lock_irqsave(&l->lock, flags); + } __bpf_lru_list_rotate(lru, l);