]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
00af35a5cd595b6482703b4ced1ea9791a16bd87
[thirdparty/kernel/stable-queue.git] /
1 From 0cd575cab10e114e95921321f069a08d45bc412e Mon Sep 17 00:00:00 2001
2 From: Andrii Nakryiko <andrii@kernel.org>
3 Date: Fri, 4 Apr 2025 12:48:48 -0700
4 Subject: uprobes: Avoid false-positive lockdep splat on CONFIG_PREEMPT_RT=y in the ri_timer() uprobe timer callback, use raw_write_seqcount_*()
5
6 From: Andrii Nakryiko <andrii@kernel.org>
7
8 commit 0cd575cab10e114e95921321f069a08d45bc412e upstream.
9
10 Avoid a false-positive lockdep warning in the CONFIG_PREEMPT_RT=y
11 configuration when using write_seqcount_begin() in the uprobe timer
12 callback by using raw_write_* APIs.
13
14 Uprobe's use of timer callback is guaranteed to not race with itself
15 for a given uprobe_task, and as such seqcount's insistence on having
16 preemption disabled on the writer side is irrelevant. So switch to
17 raw_ variants of seqcount API instead of disabling preemption unnecessarily.
18
19 Also, point out in the comments more explicitly why we use seqcount
20 despite our reader side being rather simple and never retrying. We favor
21 well-maintained kernel primitive in favor of open-coding our own memory
22 barriers.
23
24 Fixes: 8622e45b5da1 ("uprobes: Reuse return_instances between multiple uretprobes within task")
25 Reported-by: Alexei Starovoitov <ast@kernel.org>
26 Suggested-by: Sebastian Siewior <bigeasy@linutronix.de>
27 Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
28 Signed-off-by: Ingo Molnar <mingo@kernel.org>
29 Acked-by: Oleg Nesterov <oleg@redhat.com>
30 Cc: Thomas Gleixner <tglx@linutronix.de>
31 Cc: Peter Zijlstra <peterz@infradead.org>
32 Cc: stable@kernel.org
33 Link: https://lore.kernel.org/r/20250404194848.2109539-1-andrii@kernel.org
34 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35 ---
36 kernel/events/uprobes.c | 15 +++++++++++++--
37 1 file changed, 13 insertions(+), 2 deletions(-)
38
39 --- a/kernel/events/uprobes.c
40 +++ b/kernel/events/uprobes.c
41 @@ -1955,6 +1955,9 @@ static void free_ret_instance(struct upr
42 * to-be-reused return instances for future uretprobes. If ri_timer()
43 * happens to be running right now, though, we fallback to safety and
44 * just perform RCU-delated freeing of ri.
45 + * Admittedly, this is a rather simple use of seqcount, but it nicely
46 + * abstracts away all the necessary memory barriers, so we use
47 + * a well-supported kernel primitive here.
48 */
49 if (raw_seqcount_try_begin(&utask->ri_seqcount, seq)) {
50 /* immediate reuse of ri without RCU GP is OK */
51 @@ -2015,12 +2018,20 @@ static void ri_timer(struct timer_list *
52 /* RCU protects return_instance from freeing. */
53 guard(rcu)();
54
55 - write_seqcount_begin(&utask->ri_seqcount);
56 + /*
57 + * See free_ret_instance() for notes on seqcount use.
58 + * We also employ raw API variants to avoid lockdep false-positive
59 + * warning complaining about enabled preemption. The timer can only be
60 + * invoked once for a uprobe_task. Therefore there can only be one
61 + * writer. The reader does not require an even sequence count to make
62 + * progress, so it is OK to remain preemptible on PREEMPT_RT.
63 + */
64 + raw_write_seqcount_begin(&utask->ri_seqcount);
65
66 for_each_ret_instance_rcu(ri, utask->return_instances)
67 hprobe_expire(&ri->hprobe, false);
68
69 - write_seqcount_end(&utask->ri_seqcount);
70 + raw_write_seqcount_end(&utask->ri_seqcount);
71 }
72
73 static struct uprobe_task *alloc_utask(void)