All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Mykyta Yatsenko" <mykyta.yatsenko5@gmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH RFC bpf-next 1/3] bpf: Fix NMI/tracepoint re-entry deadlock on lru locks
Date: Thu, 28 May 2026 18:57:11 +0000	[thread overview]
Message-ID: <20260528185711.EEDC31F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260528-lru_map_spin-v1-1-4f52223170cf@meta.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] A race condition between `__local_list_flush` and an NMI calling `bpf_common_lru_push_free` can cause a deleted LRU node to be permanently leaked, because `__bpf_lru_node_move_in` unconditionally clears the `pending_free` flag.
--

commit c004ee038ff11ff6f1bdd2bb613d6dc9eddf7165
Author: Mykyta Yatsenko <yatsenko@meta.com>
bpf: Fix NMI/tracepoint re-entry deadlock on lru locks

This commit converts LRU lock sites to rqspinlock_t to prevent AA-deadlocks
when NMI and tracepoint BPF programs re-enter the per-CPU or global LRU
lock. It also adds a recovery path for each failure window to ensure nodes
are not leaked on contention or deadlock.

Link: https://lore.kernel.org/bpf/CAPPBnEYO4R+m+SpVc2gNj_x31R6fo1uJvj2bK2YS1P09GWT6kQ@mail.gmail.com/
Link: https://lore.kernel.org/bpf/CAPPBnEZmFA3ab8Uc=PEm0bdojZy=7T_F5_+eyZSHyZR3MBG4Vw@mail.gmail.com/
Link: https://lore.kernel.org/bpf/20251030030010.95352-1-dongml2@chinatelecom.cn/
Link: https://lore.kernel.org/bpf/20260119142120.28170-1-leon.hwang@linux.dev/

> diff --git a/kernel/bpf/bpf_lru_list.c b/kernel/bpf/bpf_lru_list.c
> index e7a2fc60523f6..a5faf4464d889 100644
> --- a/kernel/bpf/bpf_lru_list.c
> +++ b/kernel/bpf/bpf_lru_list.c

[ ... ]

> @@ -87,6 +73,7 @@ static void __bpf_lru_node_move_in(struct bpf_lru_list *l,
>  	bpf_lru_list_count_inc(l, tgt_type);
>  	node->type = tgt_type;
>  	bpf_lru_node_clear_ref(node);
> +	WRITE_ONCE(node->pending_free, 0);

[Severity: High]
Can a race condition here cause an LRU node to be leaked if an NMI
interrupts __local_list_flush()?

If an NMI occurs exactly after __local_list_flush() reads
node->pending_free as 0:

__local_list_flush()
    if (READ_ONCE(node->pending_free))
        // skipped
    else
        // interrupted here by NMI

And the NMI's BPF program deletes this element from the hash table, calling
bpf_common_lru_push_free(). It fails to acquire the lock because
__local_list_flush()'s caller already holds it:

NMI: bpf_common_lru_push_free()
    if (raw_res_spin_lock_irqsave(&loc_l->lock, flags)) {
        WRITE_ONCE(node->pending_free, 1);
        return;
    }

When the NMI completes and __local_list_flush() resumes, it will call
__bpf_lru_node_move_in() which unconditionally clears the flag:

__bpf_lru_node_move_in()
    WRITE_ONCE(node->pending_free, 0);

Will this wipe the pending_free state set by the NMI? Since the node
is already deleted from the hash table, future shrink scans would see
del_from_htab() return false and skip the node, potentially permanently
leaking it and degrading the LRU map over time.

>  	list_move(&node->list, &l->lists[tgt_type]);
>  }

[ ... ]

> @@ -290,8 +280,10 @@ static void __local_list_flush(struct bpf_lru_list *l,
>  	struct bpf_lru_node *node, *tmp_node;
>  
>  	list_for_each_entry_safe_reverse(node, tmp_node,
> -					 local_pending_list(loc_l), list) {
> -		if (bpf_lru_node_is_ref(node))
> +					 &loc_l->pending_list, list) {
> +		if (READ_ONCE(node->pending_free))
> +			__bpf_lru_node_move_in(l, node, BPF_LRU_LIST_T_FREE);
> +		else if (bpf_lru_node_is_ref(node))
>  			__bpf_lru_node_move_in(l, node, BPF_LRU_LIST_T_ACTIVE);
>  		else
>  			__bpf_lru_node_move_in(l, node,

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260528-lru_map_spin-v1-0-4f52223170cf@meta.com?part=1

  reply	other threads:[~2026-05-28 18:57 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-28 18:13 [PATCH RFC bpf-next 0/3] bpf: Fix LRU NMI/tracepoint re-entry deadlock Mykyta Yatsenko
2026-05-28 18:13 ` [PATCH RFC bpf-next 1/3] bpf: Fix NMI/tracepoint re-entry deadlock on lru locks Mykyta Yatsenko
2026-05-28 18:57   ` sashiko-bot [this message]
2026-05-28 18:59   ` bot+bpf-ci
2026-05-28 18:13 ` [PATCH RFC bpf-next 2/3] Documentation/bpf: Refresh map_lru_hash_update.dot for rqspinlock Mykyta Yatsenko
2026-05-28 18:13 ` [PATCH RFC bpf-next 3/3] selftests/bpf: Stress LRU rqspinlock recovery paths Mykyta Yatsenko
2026-05-28 19:32   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260528185711.EEDC31F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=mykyta.yatsenko5@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.