[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250716152515.20699c64@batman.local.home>
Date: Wed, 16 Jul 2025 15:25:15 -0400
From: Steven Rostedt <rostedt@...dmis.org>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Steven Rostedt <rostedt@...nel.org>, linux-kernel@...r.kernel.org,
linux-trace-kernel@...r.kernel.org, bpf@...r.kernel.org, x86@...nel.org,
Masami Hiramatsu <mhiramat@...nel.org>, Mathieu Desnoyers
<mathieu.desnoyers@...icios.com>, Josh Poimboeuf <jpoimboe@...nel.org>,
Ingo Molnar <mingo@...nel.org>, Jiri Olsa <jolsa@...nel.org>, Namhyung Kim
<namhyung@...nel.org>, Thomas Gleixner <tglx@...utronix.de>, Andrii
Nakryiko <andrii@...nel.org>, Indu Bhagat <indu.bhagat@...cle.com>, "Jose
E. Marchesi" <jemarch@....org>, Beau Belgrave <beaub@...ux.microsoft.com>,
Jens Remus <jremus@...ux.ibm.com>, Linus Torvalds
<torvalds@...ux-foundation.org>, Andrew Morton <akpm@...ux-foundation.org>,
Jens Axboe <axboe@...nel.dk>, Florian Weimer <fweimer@...hat.com>, Sam
James <sam@...too.org>
Subject: Re: [PATCH v13 10/14] unwind: Clear unwind_mask on exit back to
user space
On Wed, 16 Jul 2025 14:33:52 -0400
Steven Rostedt <rostedt@...dmis.org> wrote:
> [Task enters kernel]
> request -> add cookie
> request -> add cookie
> [..]
> callback -> add trace + cookie
> [ftrace clears bits]
> callback -> add trace + cookie
> [Task exits back to user space]
Another solution could be to add another unwind mask of completed
callbacks. Then we could use the fetch_or(). I guess that could look
like this:
diff --git a/include/linux/unwind_deferred.h b/include/linux/unwind_deferred.h
index 15045999c5e2..0124865aaab4 100644
--- a/include/linux/unwind_deferred.h
+++ b/include/linux/unwind_deferred.h
@@ -61,8 +61,10 @@ static __always_inline void unwind_reset_info(void)
} while (!try_cmpxchg(&info->unwind_mask, &bits, 0UL));
current->unwind_info.id.id = 0;
- if (unlikely(info->cache))
+ if (unlikely(info->cache)) {
info->cache->nr_entries = 0;
+ info->cache->unwind_completed = 0;
+ }
}
}
diff --git a/include/linux/unwind_deferred_types.h b/include/linux/unwind_deferred_types.h
index 5dc9cda141ff..33b62ac25c86 100644
--- a/include/linux/unwind_deferred_types.h
+++ b/include/linux/unwind_deferred_types.h
@@ -3,6 +3,7 @@
#define _LINUX_UNWIND_USER_DEFERRED_TYPES_H
struct unwind_cache {
+ unsigned long unwind_completed;
unsigned int nr_entries;
unsigned long entries[];
};
diff --git a/kernel/unwind/deferred.c b/kernel/unwind/deferred.c
index 60cc71062f86..9a3e06ee9d63 100644
--- a/kernel/unwind/deferred.c
+++ b/kernel/unwind/deferred.c
@@ -170,13 +170,19 @@ static void process_unwind_deferred(struct task_struct *task)
unwind_user_faultable(&trace);
+ if (info->cache)
+ bits &= ~(info->cache->unwind_completed);
+
cookie = info->id.id;
guard(srcu_lite)(&unwind_srcu);
list_for_each_entry_srcu(work, &callbacks, list,
srcu_read_lock_held(&unwind_srcu)) {
- if (test_bit(work->bit, &bits))
+ if (test_bit(work->bit, &bits)) {
work->func(work, &trace, cookie);
+ if (info->cache)
+ info->cache->unwind_completed |= BIT(work->bit);
+ }
}
}
Instead of adding another long word in the tasks struct, I just use the
unwind_cache that gets allocated on the first use.
I think this can work. I'll switch it over to this and then I can use
the fetch_or() and there should be no extra callbacks, even if an
already called callback is requested again after another callback was
requested which would trigger another task work.
I'll update this patch (and fold it into the bitmask patch) with the
fetch_or() and create this patch as a separate patch that just gets rid
of spurious callbacks.
-- Steve
Powered by blists - more mailing lists