From: Steven Rostedt <rostedt@goodmis.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
bpf@vger.kernel.org, x86@kernel.org,
Masami Hiramatsu <mhiramat@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Josh Poimboeuf <jpoimboe@kernel.org>,
Ingo Molnar <mingo@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Andrii Nakryiko <andrii@kernel.org>,
Indu Bhagat <indu.bhagat@oracle.com>,
"Jose E. Marchesi" <jemarch@gnu.org>,
Beau Belgrave <beaub@linux.microsoft.com>,
Jens Remus <jremus@linux.ibm.com>,
Andrew Morton <akpm@linux-foundation.org>,
Jens Axboe <axboe@kernel.dk>, Florian Weimer <fweimer@redhat.com>
Subject: Re: [PATCH v12 06/14] unwind_user/deferred: Add deferred unwinding interface
Date: Wed, 2 Jul 2025 14:57:13 -0400 [thread overview]
Message-ID: <20250702145713.57062487@batman.local.home> (raw)
In-Reply-To: <CAHk-=wiU6aox6-QqrUY1AaBq87EsFuFa6q2w40PJkhKMEX213w@mail.gmail.com>
On Wed, 2 Jul 2025 11:21:34 -0700
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Wed, 2 Jul 2025 at 10:49, Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > To still be able to use a 32 bit cmpxchg (for racing with an NMI), we
> > could break this number up into two 32 bit words. One with the CPU that
> > it was created on, and one with the per_cpu counter:
>
> Do you actually even need a cpu number at all?
>
> If this is per-thread, maybe just a per-thread counter would be good?
> And you already *have* that per-thread thing, in
> 'current->unwind_info'.
I just hate to increase the task struct even more. I'm trying to keep
only the data I can't put elsewhere in the task struct.
>
> And the work is using task_work, so the worker callback is also per-thread.
>
> Also, is racing with NMI even a thing for the sequence number? I would
> expect that the only thing that NMI would race with is the 'pending'
> field, not the sequence number.
The sequence number is updated on the first time it's called after a
task enters the kernel. Then it should return the same number every
time after that. That's because this unique number is the identifier
for the user space stack trace which doesn't change while the task is
in the kernel, hence the id getting updated every time the task enters
the kernel and not after that.
>
> IOW, I think the logic could be
>
> - check 'pending' non-atomically, just because it's cheap
Note, later patches move the "pending" bit into a mask that is used to
figure out what callbacks to call.
>
> - do a try_cmpxchg() on pending to actually deal with nmi races
>
> Actually, there are no SMP issues, just instruction atomicity - so a
> 'local_try_cmpxchg() would be sufficient, but that's a 'long' not a
> 'u32' ;^(
Yeah, later patches do try to use more local_try_cmpxchg() at different
parts. Even for the timestamp.
>
> - now you are exclusive for that thread, you're done, no more need
> for any atomic counter or percpu things
The trick and race with NMIs is, this needs to return that cookie for
both callers, where the cookie is the same number.
>
> And then the next step is to just say "pending is the low bit of the
> id word" and having a separate 31-bit counter that gets incremented by
> "get_cookie()".
>
> So then you end up with something like
>
> // New name for 'get_timestamp()'
> get_current_cookie() { return current->unwind_info.cookie; }
> // New name for 'get_cookie()':
> // 31-bit counter by just leaving bit #0 alone
> get_new_cookie() { current->unwind_info.cookie += 2; }
>
> and then unwind_deferred_request() would do something like
>
> unwind_deferred_request()
> {
> int old, new;
>
> if (current->unwind_info.id)
> return 1;
>
> guard(irqsave)();
> // For NMI, if we race with 'get_new_cookie()'
> // we don't care if we get the old or the new one
> old = 0; new = get_current_cookie() | 1;
> if (!try_cmpxchg(¤t->unwind_info.id, &old, new))
> return 1;
> .. now schedule the thing with that cookie set.
>
> Hmm?
>
> But I didn't actually look at the users, so maybe I'm missing some
> reason why you want to have a separate per-cpu value.
Now we could just have the counter be the 32 bit cookie (old timestamp)
in the task struct, and have bit 0 be if it is valued or not.
static u32 get_cookie(struct unwind_task_info *info)
{
u32 cnt = READ_ONCE(info->id);
u32 new_cnt;
if (cnt & 1)
return cnt;
new_cnt = cnt + 3;
if (try_cmpxchg(&info->id, &cnt, new_cnt))
return new_cnt;
return cnt; // return info->id; would work too
}
Then when going back to user space:
info->id &= ~1;
Now the counter is stored in the task struct and no other info is needed.
>
> Or maybe I missed something else entirely, and the above is complete
> garbage and the ramblings of a insane mind.
>
> It happens.
>
> Off to get more coffee.
Enjoy, I just grabbed my last cup of the day.
-- Steve
next prev parent reply other threads:[~2025-07-02 18:57 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-01 0:53 [PATCH v12 00/14] unwind_user: x86: Deferred unwinding infrastructure Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 01/14] unwind_user: Add user space unwinding API Steven Rostedt
2025-07-04 17:58 ` Mathieu Desnoyers
2025-07-04 18:20 ` Mathieu Desnoyers
2025-07-07 19:42 ` Steven Rostedt
2025-07-07 21:01 ` Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 02/14] unwind_user: Add frame pointer support Steven Rostedt
2025-07-01 2:10 ` Linus Torvalds
2025-07-01 2:56 ` Steven Rostedt
2025-07-01 3:05 ` Steven Rostedt
2025-07-01 15:36 ` Jens Remus
2025-07-02 23:50 ` Steven Rostedt
2025-07-03 16:21 ` Jens Remus
2025-07-07 21:28 ` Steven Rostedt
2025-07-01 4:46 ` Florian Weimer
2025-07-01 12:14 ` Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 03/14] unwind_user: Add compat mode " Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 04/14] unwind_user/deferred: Add unwind_user_faultable() Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 05/14] unwind_user/deferred: Add unwind cache Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 06/14] unwind_user/deferred: Add deferred unwinding interface Steven Rostedt
2025-07-02 16:36 ` Peter Zijlstra
2025-07-02 16:42 ` Steven Rostedt
2025-07-02 16:56 ` Linus Torvalds
2025-07-02 17:26 ` Steven Rostedt
2025-07-02 17:48 ` Steven Rostedt
2025-07-02 18:21 ` Linus Torvalds
2025-07-02 18:47 ` Mathieu Desnoyers
2025-07-02 19:05 ` Steven Rostedt
2025-07-02 19:12 ` Mathieu Desnoyers
2025-07-02 19:21 ` Steven Rostedt
2025-07-02 19:36 ` Steven Rostedt
2025-07-02 19:40 ` Steven Rostedt
2025-07-02 19:48 ` Mathieu Desnoyers
2025-07-02 20:10 ` Steven Rostedt
2025-07-02 19:43 ` Mathieu Desnoyers
2025-07-02 19:51 ` Steven Rostedt
2025-07-02 18:57 ` Steven Rostedt [this message]
2025-07-01 0:53 ` [PATCH v12 07/14] unwind_user/deferred: Make unwind deferral requests NMI-safe Steven Rostedt
2025-07-02 15:53 ` Jens Remus
2025-07-02 19:11 ` Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 08/14] unwind deferred: Use bitmask to determine which callbacks to call Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 09/14] unwind deferred: Use SRCU unwind_deferred_task_work() Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 10/14] unwind: Clear unwind_mask on exit back to user space Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 11/14] unwind: Add USED bit to only have one conditional on way " Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 12/14] unwind: Finish up unwind when a task exits Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 13/14] unwind_user/x86: Enable frame pointer unwinding on x86 Steven Rostedt
2025-07-01 0:53 ` [PATCH v12 14/14] unwind_user/x86: Enable compat mode " Steven Rostedt
2025-07-01 2:06 ` [PATCH v12 00/14] unwind_user: x86: Deferred unwinding infrastructure Linus Torvalds
2025-07-01 2:45 ` Steven Rostedt
2025-07-01 22:49 ` Kees Cook
2025-07-01 23:26 ` Steven Rostedt
2025-07-02 14:56 ` Kees Cook
2025-07-02 16:20 ` Mathieu Desnoyers
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=20250702145713.57062487@batman.local.home \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=axboe@kernel.dk \
--cc=beaub@linux.microsoft.com \
--cc=bpf@vger.kernel.org \
--cc=fweimer@redhat.com \
--cc=indu.bhagat@oracle.com \
--cc=jemarch@gnu.org \
--cc=jolsa@kernel.org \
--cc=jpoimboe@kernel.org \
--cc=jremus@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=x86@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®