mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Martin KaFai Lau <martin.lau@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	martin.lau@linux.dev, daniel@iogearbox.net, andrii@kernel.org,
	bpf@vger.kernel.org
Subject: [PATCH AUTOSEL 6.13 18/22] bpf: Only fails the busy counter check in bpf_cgrp_storage_get if it creates storage
Date: Thu,  3 Apr 2025 20:04:47 -0400	[thread overview]
Message-ID: <20250404000453.2688371-18-sashal@kernel.org> (raw)
In-Reply-To: <20250404000453.2688371-1-sashal@kernel.org>

From: Martin KaFai Lau <martin.lau@kernel.org>

[ Upstream commit f4edc66e48a694b3e6d164cc71f059de542dfaec ]

The current cgrp storage has a percpu counter, bpf_cgrp_storage_busy,
to detect potential deadlock at a spin_lock that the local storage
acquires during new storage creation.

There are false positives. It turns out to be too noisy in
production. For example, a bpf prog may be doing a
bpf_cgrp_storage_get on map_a. An IRQ comes in and triggers
another bpf_cgrp_storage_get on a different map_b. It will then
trigger the false positive deadlock check in the percpu counter.
On top of that, both are doing lookup only and no need to create
new storage, so practically it does not need to acquire
the spin_lock.

The bpf_task_storage_get already has a strategy to minimize this
false positive by only failing if the bpf_task_storage_get needs
to create a new storage and the percpu counter is busy. Creating
a new storage is the only time it must acquire the spin_lock.

This patch borrows the same idea. Unlike task storage that
has a separate variant for tracing (_recur) and non-tracing, this
patch stays with one bpf_cgrp_storage_get helper to keep it simple
for now in light of the upcoming res_spin_lock.

The variable could potentially use a better name noTbusy instead
of nobusy. This patch follows the same naming in
bpf_task_storage_get for now.

I have tested it by temporarily adding noinline to
the cgroup_storage_lookup(), traced it by fentry, and the fentry
program succeeded in calling bpf_cgrp_storage_get().

Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20250318182759.3676094-1-martin.lau@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/bpf_cgrp_storage.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c
index 7996fcea3755e..c535e8f46d2cd 100644
--- a/kernel/bpf/bpf_cgrp_storage.c
+++ b/kernel/bpf/bpf_cgrp_storage.c
@@ -162,6 +162,7 @@ BPF_CALL_5(bpf_cgrp_storage_get, struct bpf_map *, map, struct cgroup *, cgroup,
 	   void *, value, u64, flags, gfp_t, gfp_flags)
 {
 	struct bpf_local_storage_data *sdata;
+	bool nobusy;
 
 	WARN_ON_ONCE(!bpf_rcu_lock_held());
 	if (flags & ~(BPF_LOCAL_STORAGE_GET_F_CREATE))
@@ -170,21 +171,21 @@ BPF_CALL_5(bpf_cgrp_storage_get, struct bpf_map *, map, struct cgroup *, cgroup,
 	if (!cgroup)
 		return (unsigned long)NULL;
 
-	if (!bpf_cgrp_storage_trylock())
-		return (unsigned long)NULL;
+	nobusy = bpf_cgrp_storage_trylock();
 
-	sdata = cgroup_storage_lookup(cgroup, map, true);
+	sdata = cgroup_storage_lookup(cgroup, map, nobusy);
 	if (sdata)
 		goto unlock;
 
 	/* only allocate new storage, when the cgroup is refcounted */
 	if (!percpu_ref_is_dying(&cgroup->self.refcnt) &&
-	    (flags & BPF_LOCAL_STORAGE_GET_F_CREATE))
+	    (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) && nobusy)
 		sdata = bpf_local_storage_update(cgroup, (struct bpf_local_storage_map *)map,
 						 value, BPF_NOEXIST, false, gfp_flags);
 
 unlock:
-	bpf_cgrp_storage_unlock();
+	if (nobusy)
+		bpf_cgrp_storage_unlock();
 	return IS_ERR_OR_NULL(sdata) ? (unsigned long)NULL : (unsigned long)sdata->data;
 }
 
-- 
2.39.5


  parent reply	other threads:[~2025-04-04  0:05 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-04  0:04 [PATCH AUTOSEL 6.13 01/22] crypto: ecdsa - Harden against integer overflows in DIV_ROUND_UP() Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 02/22] selftests/bpf: Fix stdout race condition in traffic monitor Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 03/22] pinctrl: renesas: rza2: Fix potential NULL pointer dereference Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 04/22] pinctrl: mcp23s08: Get rid of spurious level interrupts Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 05/22] MIPS: cm: Detect CM quirks from device tree Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 06/22] crypto: ccp - Add support for PCI device 0x1134 Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 07/22] crypto: lib/Kconfig - Fix lib built-in failure when arch is modular Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 08/22] crypto: null - Use spin lock instead of mutex Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 09/22] bpf: Fix kmemleak warning for percpu hashmap Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 10/22] HSI: ssi_protocol: Fix use after free vulnerability in ssi_protocol Driver Due to Race Condition Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 11/22] bpf: Fix deadlock between rcu_tasks_trace and event_mutex Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 12/22] clk: check for disabled clock-provider in of_clk_get_hw_from_clkspec() Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 13/22] parisc: PDT: Fix missing prototype warning Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 14/22] s390/sclp: Add check for get_zeroed_page() Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 15/22] s390/tty: Fix a potential memory leak bug Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 16/22] selftests/bpf: Fix cap_enable_effective() return code Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 17/22] bpf: bpftool: Setting error code in do_loader() Sasha Levin
2025-04-04  0:04 ` Sasha Levin [this message]
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 19/22] bpf: Reject attaching fexit/fmod_ret to __noreturn functions Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 20/22] x86/Kconfig: Make CONFIG_PCI_CNB20LE_QUIRK depend on X86_32 Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 21/22] mailbox: pcc: Fix the possible race in updation of chan_in_use flag Sasha Levin
2025-04-04  0:04 ` [PATCH AUTOSEL 6.13 22/22] mailbox: pcc: Always clear the platform ack interrupt first Sasha Levin

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=20250404000453.2688371-18-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=stable@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®