* [PATCH v2 tip/perf] uprobes: avoid false lockdep splat in uprobe timer callback
@ 2025-04-04 19:48 Andrii Nakryiko
2025-04-04 20:03 ` Oleg Nesterov
2025-04-07 18:19 ` [tip: perf/urgent] uprobes: Avoid false-positive lockdep splat on CONFIG_PREEMPT_RT=y in the ri_timer() uprobe timer callback, use raw_write_seqcount_*() tip-bot2 for Andrii Nakryiko
0 siblings, 2 replies; 3+ messages in thread
From: Andrii Nakryiko @ 2025-04-04 19:48 UTC (permalink / raw)
To: linux-trace-kernel, peterz, mingo
Cc: bpf, linux-kernel, kernel-team, rostedt, oleg, mhiramat, bigeasy,
ast, Andrii Nakryiko
Avoid a false-positive lockdep warning in PREEMPT_RT configuration when
using write_seqcount_begin() in uprobe timer callback by using
raw_write_* APIs. Uprobe's use of timer callback is guaranteed to not
race with itself for a given uprobe_task, and as such seqcount's
insistence on having preemption disabled on the writer side is
irrelevant. So switch to raw_ variants of seqcount API instead of
disabling preemption unnecessarily.
Also, point out in the comments more explicitly why we use seqcount
despite our reader side being rather simple and never retrying. We favor
well-maintained kernel primitive in favor of open-coding our own memory
barriers.
Link: https://lore.kernel.org/bpf/CAADnVQLLOHZmPO4X_dQ+cTaSDvzdWHzA0qUqQDhLFYL3D6xPxg@mail.gmail.com/
Reported-by: Alexei Starovoitov <ast@kernel.org>
Suggested-by: Sebastian Siewior <bigeasy@linutronix.de>
Fixes: 8622e45b5da1 ("uprobes: Reuse return_instances between multiple uretprobes within task")
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
v1->v2:
- fix comment style and s/hardirqs/preemption/ (Sebastian);
- improved added comment based on Sebastian's suggestions.
kernel/events/uprobes.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 70c84b9d7be3..0f05bae49827 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1944,6 +1944,9 @@ static void free_ret_instance(struct uprobe_task *utask,
* to-be-reused return instances for future uretprobes. If ri_timer()
* happens to be running right now, though, we fallback to safety and
* just perform RCU-delated freeing of ri.
+ * Admittedly, this is a rather simple use of seqcount, but it nicely
+ * abstracts away all the necessary memory barriers, so we use
+ * a well-supported kernel primitive here.
*/
if (raw_seqcount_try_begin(&utask->ri_seqcount, seq)) {
/* immediate reuse of ri without RCU GP is OK */
@@ -2004,12 +2007,20 @@ static void ri_timer(struct timer_list *timer)
/* RCU protects return_instance from freeing. */
guard(rcu)();
- write_seqcount_begin(&utask->ri_seqcount);
+ /*
+ * See free_ret_instance() for notes on seqcount use.
+ * We also employ raw API variants to avoid lockdep false-positive
+ * warning complaining about enabled preemption. The timer can only be
+ * invoked once for a uprobe_task. Therefore there can only be one
+ * writer. The reader does not require an even sequence count to make
+ * progress, so it is OK to remain preemptible on PREEMPT_RT.
+ */
+ raw_write_seqcount_begin(&utask->ri_seqcount);
for_each_ret_instance_rcu(ri, utask->return_instances)
hprobe_expire(&ri->hprobe, false);
- write_seqcount_end(&utask->ri_seqcount);
+ raw_write_seqcount_end(&utask->ri_seqcount);
}
static struct uprobe_task *alloc_utask(void)
--
2.47.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v2 tip/perf] uprobes: avoid false lockdep splat in uprobe timer callback
2025-04-04 19:48 [PATCH v2 tip/perf] uprobes: avoid false lockdep splat in uprobe timer callback Andrii Nakryiko
@ 2025-04-04 20:03 ` Oleg Nesterov
2025-04-07 18:19 ` [tip: perf/urgent] uprobes: Avoid false-positive lockdep splat on CONFIG_PREEMPT_RT=y in the ri_timer() uprobe timer callback, use raw_write_seqcount_*() tip-bot2 for Andrii Nakryiko
1 sibling, 0 replies; 3+ messages in thread
From: Oleg Nesterov @ 2025-04-04 20:03 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: linux-trace-kernel, peterz, mingo, bpf, linux-kernel, kernel-team,
rostedt, mhiramat, bigeasy, ast
On 04/04, Andrii Nakryiko wrote:
>
> Also, point out in the comments more explicitly why we use seqcount
> despite our reader side being rather simple and never retrying. We favor
> well-maintained kernel primitive in favor of open-coding our own memory
> barriers.
>
> Link: https://lore.kernel.org/bpf/CAADnVQLLOHZmPO4X_dQ+cTaSDvzdWHzA0qUqQDhLFYL3D6xPxg@mail.gmail.com/
> Reported-by: Alexei Starovoitov <ast@kernel.org>
> Suggested-by: Sebastian Siewior <bigeasy@linutronix.de>
> Fixes: 8622e45b5da1 ("uprobes: Reuse return_instances between multiple uretprobes within task")
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
LGTM. FWIW,
Acked-by: Oleg Nesterov <oleg@redhat.com>
^ permalink raw reply [flat|nested] 3+ messages in thread* [tip: perf/urgent] uprobes: Avoid false-positive lockdep splat on CONFIG_PREEMPT_RT=y in the ri_timer() uprobe timer callback, use raw_write_seqcount_*()
2025-04-04 19:48 [PATCH v2 tip/perf] uprobes: avoid false lockdep splat in uprobe timer callback Andrii Nakryiko
2025-04-04 20:03 ` Oleg Nesterov
@ 2025-04-07 18:19 ` tip-bot2 for Andrii Nakryiko
1 sibling, 0 replies; 3+ messages in thread
From: tip-bot2 for Andrii Nakryiko @ 2025-04-07 18:19 UTC (permalink / raw)
To: linux-tip-commits
Cc: Alexei Starovoitov, Sebastian Siewior, Andrii Nakryiko,
Ingo Molnar, Oleg Nesterov, Thomas Gleixner, Peter Zijlstra,
stable, x86, linux-kernel
The following commit has been merged into the perf/urgent branch of tip:
Commit-ID: 0cd575cab10e114e95921321f069a08d45bc412e
Gitweb: https://git.kernel.org/tip/0cd575cab10e114e95921321f069a08d45bc412e
Author: Andrii Nakryiko <andrii@kernel.org>
AuthorDate: Fri, 04 Apr 2025 12:48:48 -07:00
Committer: Ingo Molnar <mingo@kernel.org>
CommitterDate: Mon, 07 Apr 2025 20:15:16 +02:00
uprobes: Avoid false-positive lockdep splat on CONFIG_PREEMPT_RT=y in the ri_timer() uprobe timer callback, use raw_write_seqcount_*()
Avoid a false-positive lockdep warning in the CONFIG_PREEMPT_RT=y
configuration when using write_seqcount_begin() in the uprobe timer
callback by using raw_write_* APIs.
Uprobe's use of timer callback is guaranteed to not race with itself
for a given uprobe_task, and as such seqcount's insistence on having
preemption disabled on the writer side is irrelevant. So switch to
raw_ variants of seqcount API instead of disabling preemption unnecessarily.
Also, point out in the comments more explicitly why we use seqcount
despite our reader side being rather simple and never retrying. We favor
well-maintained kernel primitive in favor of open-coding our own memory
barriers.
Fixes: 8622e45b5da1 ("uprobes: Reuse return_instances between multiple uretprobes within task")
Reported-by: Alexei Starovoitov <ast@kernel.org>
Suggested-by: Sebastian Siewior <bigeasy@linutronix.de>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@kernel.org
Link: https://lore.kernel.org/r/20250404194848.2109539-1-andrii@kernel.org
---
kernel/events/uprobes.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 615b4e6..8d783b5 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1956,6 +1956,9 @@ static void free_ret_instance(struct uprobe_task *utask,
* to-be-reused return instances for future uretprobes. If ri_timer()
* happens to be running right now, though, we fallback to safety and
* just perform RCU-delated freeing of ri.
+ * Admittedly, this is a rather simple use of seqcount, but it nicely
+ * abstracts away all the necessary memory barriers, so we use
+ * a well-supported kernel primitive here.
*/
if (raw_seqcount_try_begin(&utask->ri_seqcount, seq)) {
/* immediate reuse of ri without RCU GP is OK */
@@ -2016,12 +2019,20 @@ static void ri_timer(struct timer_list *timer)
/* RCU protects return_instance from freeing. */
guard(rcu)();
- write_seqcount_begin(&utask->ri_seqcount);
+ /*
+ * See free_ret_instance() for notes on seqcount use.
+ * We also employ raw API variants to avoid lockdep false-positive
+ * warning complaining about enabled preemption. The timer can only be
+ * invoked once for a uprobe_task. Therefore there can only be one
+ * writer. The reader does not require an even sequence count to make
+ * progress, so it is OK to remain preemptible on PREEMPT_RT.
+ */
+ raw_write_seqcount_begin(&utask->ri_seqcount);
for_each_ret_instance_rcu(ri, utask->return_instances)
hprobe_expire(&ri->hprobe, false);
- write_seqcount_end(&utask->ri_seqcount);
+ raw_write_seqcount_end(&utask->ri_seqcount);
}
static struct uprobe_task *alloc_utask(void)
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-04-07 18:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-04 19:48 [PATCH v2 tip/perf] uprobes: avoid false lockdep splat in uprobe timer callback Andrii Nakryiko
2025-04-04 20:03 ` Oleg Nesterov
2025-04-07 18:19 ` [tip: perf/urgent] uprobes: Avoid false-positive lockdep splat on CONFIG_PREEMPT_RT=y in the ri_timer() uprobe timer callback, use raw_write_seqcount_*() tip-bot2 for Andrii Nakryiko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox