* Re: [PATCH] tracing: Fix NULL pointer dereference in func_set_flag()
From: Steven Rostedt @ 2026-07-07 15:14 UTC (permalink / raw)
To: Yuanhe Shu
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel, sashiko-bot@kernel.org,
sashiko-reviews@lists.linux.dev
In-Reply-To: <20260624061715.1445655-1-xiangzao@linux.alibaba.com>
From: https://sashiko.dev/#/patchset/20260624061715.1445655-1-xiangzao%40linux.alibaba.com
> commit 2140381622b995438751cdb59eb4bae6923f6a60
> Author: Yuanhe Shu <xiangzao@linux.alibaba.com>
> tracing: Fix NULL pointer dereference in func_set_flag()
> This commit fixes a NULL pointer dereference in func_set_flag() by
> moving the tracer type check before dereferencing tr->current_trace_flags.
> > diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
> > index f283391a4dc80..cd37f20137581 100644
> > --- a/kernel/trace/trace_functions.c
> > +++ b/kernel/trace/trace_functions.c
> > @@ -458,12 +458,12 @@ func_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)
> > ftrace_func_t func;
> > u32 new_flags;
> >
> > - /* Do nothing if already set. */
> > - if (!!set == !!(tr->current_trace_flags->val & bit))
> > + /* We can change this flag only when current tracer is function. */
> > + if (tr->current_trace != &function_trace)
> > return 0;
> >
> > - /* We can change this flag only when not running. */
> > - if (tr->current_trace != &function_trace)
> > + /* Do nothing if already set. */
> > + if (!!set == !!(tr->current_trace_flags->val & bit))
> > return 0;
>
> This isn't a bug introduced by this patch, but while reviewing this fix for
> tr->current_trace_flags, I noticed a similar NULL pointer dereference
> can occur in print_graph_function() in kernel/trace/trace_functions_graph.c.
> If a user enables the function_graph tracer, populating the ring buffer
> with graph events, and then switches to a tracer that lacks flags and
> does not automatically clear the ring buffer (such as hwlat, osnoise, or
> timerlat), tr->current_trace_flags becomes NULL.
> When the user subsequently reads the trace buffer, the fallback event handler
> calls print_graph_function(), which unconditionally dereferences
> tr->current_trace_flags:
>
> kernel/trace/trace_functions_graph.c:print_graph_function() {
> struct trace_array *tr = iter->tr;
> return print_graph_function_flags(iter, tr->current_trace_flags->val);
> }
>
> Does this unconditional dereference of tr->current_trace_flags->val also
> need a similar safety check to prevent a kernel crash?
No, because even though hwlat, osnoise and timerlat may not clear the main
ring buffer, it reads it differently. Thus the print_graph_function will
not be called.
Unless you can figure out a way to get to that function with one of those
other tracers?
-- Steve
^ permalink raw reply
* Re: [PATCH] tracing: Add "within" filter for call-stack-based event filtering
From: Steven Rostedt @ 2026-07-07 15:20 UTC (permalink / raw)
To: Chen Jun
Cc: mhiramat, mathieu.desnoyers, linux-kernel, linux-trace-kernel,
sashiko-bot@kernel.org, sashiko-reviews@lists.linux.dev
In-Reply-To: <20260608145556.94931-1-chenjun102@huawei.com>
From: https://sashiko.dev/#/patchset/20260608145556.94931-1-chenjun102%40huawei.com
> commit dfbe6e67884d4ff73b44c46b51995f1945758a89
> Author: Chen Jun <chenjun102@huawei.com>
> tracing: Add "within" filter for call-stack-based event filtering
> This commit introduces a "within" filter predicate for trace events, allowing
> users to filter events based on whether a specific function appears in the
> current call stack. It uses kallsyms_lookup_name() to resolve the function to
> an address range during setup, and stack_trace_save() to capture the stack at
> runtime to evaluate the filter condition.
>
> > diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
> > index 609325f579427..34e1a7f0b3cd0 100644
> > --- a/kernel/trace/trace_events_filter.c
> > +++ b/kernel/trace/trace_events_filter.c
> [ ... ]
> > @@ -1009,6 +1010,22 @@ static int filter_pred_function(struct filter_pred *pred, void *event)
> > return pred->op == OP_EQ ? ret : !ret;
> > }
> >
> > +/* Filter predicate for within. */
> > +static int filter_pred_within(struct filter_pred *pred, void *event)
> > +{
> > +#ifdef CONFIG_STACKTRACE
> > + unsigned long entries[16];
> > + unsigned int nr_entries;
> > + int i;
> > +
> > + nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 0);
>
> Is an array size of 16 entries sufficient here? Since the skipnr parameter is
> 0, several of these frames will be consumed by internal tracing and filter
> evaluation functions (such as filter_pred_within() and
> trace_event_buffer_commit()).
>
> This leaves very few slots for the actual call chain, meaning higher-level
> functions like "vfs_read" will likely be truncated from the stack trace.
> Could this cause the filter condition to evaluate to false incorrectly,
> missing the events we are trying to capture?
>
This is a current limitation that may be dealt with in the future.
> > + for (i = 0; i < nr_entries; i++)
> > + if (pred->val <= entries[i] && entries[i] < pred->val2)
> > + return !pred->not;
> > +#endif
> > + return pred->not;
> > +}
>
> [ ... ]
> > @@ -2002,10 +2021,28 @@ static int parse_pred(const char *str, void *data,
> >
> > } else if (field->filter_type == FILTER_DYN_STRING) {
> > pred->fn_num = FILTER_PRED_FN_STRLOC;
> > - } else if (field->filter_type == FILTER_RDYN_STRING)
> > + } else if (field->filter_type == FILTER_RDYN_STRING) {
> > pred->fn_num = FILTER_PRED_FN_STRRELLOC;
> > - else {
> > + } else if (field->filter_type == FILTER_WITHIN) {
> > + unsigned long func;
> > +
> > + if (op == OP_GLOB)
> > + goto err_free;
>
> Does this goto need a preceding call to parse_error()? Other error paths in
> this function initialize the error state before jumping to err_free.
> Without it, users might see an unhelpful generic error message instead of a
> syntax error indicating that the glob operator isn't supported here.
This is a legitimate issue.
Chen, can you send a v2 and add a proper error message here?
Thanks,
-- Steve
> > +
> > + pred->fn_num = FILTER_PRED_FN_WITHIN;
> > + func = kallsyms_lookup_name(pred->regex->pattern);
^ permalink raw reply
* Re: [PATCH] tracing/user_events: fix use-after-free of enabler in user_event_mm_dup()
From: Steven Rostedt @ 2026-07-07 15:27 UTC (permalink / raw)
To: Michael Bommarito
Cc: Beau Belgrave, XIAO WU, Masami Hiramatsu, Mathieu Desnoyers,
linux-trace-kernel, linux-kernel, stable
In-Reply-To: <CAJJ9bXy78yKmOb+x-THk4EwJxY=0si04YAMtmOu-SzarVJwRBQ@mail.gmail.com>
On Tue, 7 Jul 2026 10:43:40 -0400
Michael Bommarito <michael.bommarito@gmail.com> wrote:
> > Ah, you're going to send a new version. I'll drop the one I pulled then.
>
> Saw your pull for-linus and I was just about to send a separate patch
> set for the second UAF with a ktest (as 2/2). I can do either way,
> just let me know which is easier
I'll drop it and take your new one.
-- Steve
^ permalink raw reply
* Re: [PATCH bpf-next v2 0/3] tracing: Expose tracepoint BTF ids via tracefs
From: Steven Rostedt @ 2026-07-07 16:00 UTC (permalink / raw)
To: Mykyta Yatsenko
Cc: bpf, ast, andrii, daniel, kafai, kernel-team, eddyz87, memxor,
Mykyta Yatsenko, linux-trace-kernel
In-Reply-To: <20260518-generic_tracepoint-v2-0-b755a5cf67bb@meta.com>
On Mon, 18 May 2026 08:23:14 -0700
Mykyta Yatsenko <mykyta.yatsenko5@gmail.com> wrote:
> BPF and other consumers that want to attach to or decode a generic
> tracepoint need three pieces of BTF information for it:
>
> - the BTF of the object that owns the tracepoint's types
> - the FUNC_PROTO describing the tracepoint arguments (with names),
> consumed by raw_tp / tp_btf BPF programs
> - the STRUCT id of trace_event_raw_<call>, the ring-buffer record
> consumed by classic BPF_PROG_TYPE_TRACEPOINT programs
>
> Today none of this is easily discoverable from userspace. The kernel
> knows the ids - resolve_btfids fills them in at link time - but
> consumers have to search them by the naming convention
> ("__bpf_trace_<name>", "trace_event_raw_<name>"), walking BTF for
> every tracepoint.
I'll pull this in even though it adds 100K to the kernel:
text data bss dec hex filename
40506047 15709518 16661184 72876749 45802cd /tmp/vmlinux.new
40499064 15615294 16661184 72775542 4567776 /tmp/vmlinux.old
-- Steve
^ permalink raw reply
* Re: [PATCH net-next] net/tcp: Add explicit tracepoint for tcp_syn_ack_timeout()
From: Emil Tsalapatis @ 2026-07-07 16:08 UTC (permalink / raw)
To: Eric Dumazet, Emil Tsalapatis
Cc: netdev, linux-trace-kernel, ncardwell, kuniyu, rostedt, mhiramat,
davem, kuba, pabeni
In-Reply-To: <CANn89iL23Rsu3iGXxhw4pAnCB-JgU7fnrryDLXKj4jHqSs=HOw@mail.gmail.com>
On Tue Jul 7, 2026 at 3:52 AM EDT, Eric Dumazet wrote:
> On Mon, Jul 6, 2026 at 6:01 PM Emil Tsalapatis <emil@etsalapatis.com> wrote:
>>
>> Clang can inline the tcp_syn_ack_timeout() function during compilation,
>> making it impossible to use kprobes for tracing without preventing
>> inlining. Add an explicit tracepoint to it instead.
>
> So much copy/pasting for a very small issue :/
>
>>
>> Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
>> ---
>> include/trace/events/tcp.h | 72 ++++++++++++++++++++++++++++++++++++++
>> net/ipv4/tcp_timer.c | 3 ++
>> 2 files changed, 75 insertions(+)
>>
>
> tcp_syn_ack_timeout() is hardly a fast path, so you can instead:
>
> diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
> index 322db13333c7..ab2c3de19e46 100644
> --- a/net/ipv4/tcp_timer.c
> +++ b/net/ipv4/tcp_timer.c
> @@ -748,7 +748,7 @@ static void tcp_write_timer(struct timer_list *t)
> sock_put(sk);
> }
>
> -void tcp_syn_ack_timeout(const struct request_sock *req)
> +noinline_for_tracing void tcp_syn_ack_timeout(const struct request_sock *req)
> {
> struct net *net = read_pnet(&inet_rsk(req)->ireq_net);
Sounds good, I will respin and just mark it noinline.
^ permalink raw reply
* Re: [PATCH 11/30] mm/vma: introduce and use vmg_pages(), vmg_[start, end]_pgoff()
From: Gregory Price @ 2026-07-07 16:25 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, Russell King, Dinh Nguyen, Simon Schuster,
James E . J . Bottomley, Helge Deller, Jarkko Sakkinen,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
Ian Abbott, H Hartley Sweeten, Lucas Stach, David Airlie,
Simona Vetter, Patrik Jakobsson, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Clark, Dmitry Baryshkov, Tomi Valkeinen,
Thierry Reding, Mikko Perttunen, Jonathan Hunter,
Christian Koenig, Huang Rui, Ankit Agrawal, Alex Williamson,
Alexander Viro, Christian Brauner, Dan Williams, Muchun Song,
Oscar Salvador, David Hildenbrand, Suren Baghdasaryan,
Liam R . Howlett, Matthew Wilcox, Marek Szyprowski,
Peter Zijlstra, Arnaldo Carvalho de Melo, Namhyung Kim,
Masami Hiramatsu, Oleg Nesterov, Steven Rostedt, SeongJae Park,
Miaohe Lin, Hugh Dickins, Mike Rapoport, Kees Cook, Paolo Bonzini,
linux-kernel, linux-arm-kernel, linux-parisc, linux-sgx, etnaviv,
dri-devel, linux-arm-msm, freedreno, linux-tegra, kvm,
linux-fsdevel, nvdimm, linux-mm, iommu, linux-perf-users,
linux-trace-kernel, kasan-dev, damon, Pedro Falcato, Rik van Riel,
Harry Yoo, Jann Horn
In-Reply-To: <f7b4f8a611ab4d36eb3cf2e394610a3744a93895.1782735110.git.ljs@kernel.org>
On Mon, Jun 29, 2026 at 01:23:22PM +0100, Lorenzo Stoakes wrote:
> In the VMA logic we often need to determine the number of pages in the
> specified merge range, as well as the start and end page offsets of that
> range.
>
> Introduce and use helpers for these purposes.
>
> No functional change intended.
>
> Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>
Reviewed-by: Gregory Price <gourry@gourry.net>
^ permalink raw reply
* Re: [PATCH 12/30] mm/vma: clean up anon_vma_compatible()
From: Gregory Price @ 2026-07-07 16:26 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, Russell King, Dinh Nguyen, Simon Schuster,
James E . J . Bottomley, Helge Deller, Jarkko Sakkinen,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
Ian Abbott, H Hartley Sweeten, Lucas Stach, David Airlie,
Simona Vetter, Patrik Jakobsson, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Clark, Dmitry Baryshkov, Tomi Valkeinen,
Thierry Reding, Mikko Perttunen, Jonathan Hunter,
Christian Koenig, Huang Rui, Ankit Agrawal, Alex Williamson,
Alexander Viro, Christian Brauner, Dan Williams, Muchun Song,
Oscar Salvador, David Hildenbrand, Suren Baghdasaryan,
Liam R . Howlett, Matthew Wilcox, Marek Szyprowski,
Peter Zijlstra, Arnaldo Carvalho de Melo, Namhyung Kim,
Masami Hiramatsu, Oleg Nesterov, Steven Rostedt, SeongJae Park,
Miaohe Lin, Hugh Dickins, Mike Rapoport, Kees Cook, Paolo Bonzini,
linux-kernel, linux-arm-kernel, linux-parisc, linux-sgx, etnaviv,
dri-devel, linux-arm-msm, freedreno, linux-tegra, kvm,
linux-fsdevel, nvdimm, linux-mm, iommu, linux-perf-users,
linux-trace-kernel, kasan-dev, damon, Pedro Falcato, Rik van Riel,
Harry Yoo, Jann Horn
In-Reply-To: <5a7a07bd2a774989849b0fea84f758059ed914df.1782735110.git.ljs@kernel.org>
On Mon, Jun 29, 2026 at 01:23:23PM +0100, Lorenzo Stoakes wrote:
> Break up the existing very large conditional, add comments and use
> vma_[start/end]_pgoff() to make clearer what we're doing here.
>
> No functional change intended.
>
> Signed-off-by: Lorenzo Stoakes <ljs@kernel.org>
Reviewed-by: Gregory Price <gourry@gourry.net>
^ permalink raw reply
* [PATCH 0/2] tracing/user_events: fix use-after-free in user_event_mm_dup()
From: Michael Bommarito @ 2026-07-07 16:59 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
Cc: Beau Belgrave, XIAO WU, linux-trace-kernel, linux-kernel, stable
This replaces the earlier single patch "tracing/user_events: fix
use-after-free of enabler in user_event_mm_dup()" that is in the tracing
for-linus branch; Steven agreed to drop that one and take this instead.
user_event_enabler_destroy() removes an enabler from the mm enabler list
that user_event_mm_dup() walks locklessly under rcu_read_lock() during
fork(), then drops the enabler's event reference and frees the enabler
without waiting for a grace period. A concurrent fork() walker can
therefore both dereference the freed enabler and take a reference on a
user_event that the put has already freed -- two use-after-frees, one on
the enabler and one on the user_event. The enabler use-after-free was
found first; XIAO WU then reported the user_event one, with a PoC and a
KASAN slab-use-after-free (write) in user_event_mm_dup(), and the
enabler-only fix did not address it.
Patch 1 holds both the enabler and its event reference until an RCU grace
period has elapsed, by deferring the put and the free to a work item
queued with queue_rcu_work(). The approach was suggested by Beau
Belgrave; it supersedes the enabler-only fix.
Patch 2 adjusts two user_events selftests that assumed the event is torn
down the instant an unregister returns; with the deferred put, DIAG_IOCSDEL
can briefly return -EBUSY, so they now wait for the delete to take effect.
Verified under KASAN on x86-64: the race faults on the unpatched kernel
(and panics with kasan.fault=panic), a benign serialized control is clean,
and the patched kernel is clean across repeated runs. The user_events
selftests pass on both kernels with patch 2 applied.
Michael Bommarito (2):
tracing/user_events: fix use-after-free in user_event_mm_dup()
selftests/user_events: wait for deferred event teardown after
unregister
kernel/trace/trace_events_user.c | 39 +++++++++++++++----
.../testing/selftests/user_events/abi_test.c | 24 +++++++++++-
.../testing/selftests/user_events/perf_test.c | 26 +++++++++++--
3 files changed, 78 insertions(+), 11 deletions(-)
base-commit: f24ca6729076623c9a0547ecc71e4fc1c4b65c3c
--
2.53.0
^ permalink raw reply
* [PATCH 1/2] tracing/user_events: fix use-after-free in user_event_mm_dup()
From: Michael Bommarito @ 2026-07-07 16:59 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
Cc: Beau Belgrave, XIAO WU, linux-trace-kernel, linux-kernel, stable
In-Reply-To: <20260707165912.2560537-1-michael.bommarito@gmail.com>
user_event_mm_dup() walks the parent mm's enabler list locklessly under
rcu_read_lock() during fork() (from copy_process()); it does not take
event_mutex:
rcu_read_lock();
list_for_each_entry_rcu(enabler, &old_mm->enablers, mm_enablers_link)
enabler->event = user_event_get(orig->event);
user_event_enabler_destroy() removes an enabler from that list with
list_del_rcu() and then, without waiting for a grace period, drops the
enabler's user_event reference with user_event_put() and frees the enabler
with kfree(). A reader that loaded the enabler before the list_del_rcu()
can still be walking it, which leads to two use-after-frees:
- kfree(enabler) frees the enabler while that reader dereferences
enabler->event.
- user_event_put() may drop the last reference to the user_event, which
is then freed (via delayed_destroy_user_event() on a work queue), while
the same reader does user_event_get(orig->event) on it.
Both are reachable by an unprivileged task that can open user_events_data:
one multithreaded process that registers an enabler and then concurrently
unregisters it and calls fork() triggers the race. KASAN reports a
slab-use-after-free in user_event_mm_dup() during clone(), with a
"refcount_t: addition on 0" warning when the user_event is freed.
The enabler use-after-free was found first; the user_event one was reported
by XIAO WU, and the earlier enabler-only fix did not address it.
Defer both the user_event_put() and the kfree(enabler) to a work item
queued with queue_rcu_work(), so they run only after an RCU grace period,
once all readers walking the enabler list have finished. The put must run
in process context because user_event_put() takes event_mutex on the last
reference, so a work queue is used rather than call_rcu(). The now-unlocked
put lets the locked argument of user_event_enabler_destroy() be removed;
all callers are updated.
Fixes: 7235759084a4 ("tracing/user_events: Use remote writes for event enablement")
Cc: stable@vger.kernel.org
Reported-by: XIAO WU <xiaowu.417@qq.com>
Closes: https://lore.kernel.org/all/tencent_89647CE40DC452B891C65C94D1B271DE8E07@qq.com/
Suggested-by: Beau Belgrave <beaub@linux.microsoft.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
Since v1 (the enabler-only fix "tracing/user_events: fix use-after-free
of enabler in user_event_mm_dup()", being dropped from for-linus):
- also fix the user_event-object UAF reported by XIAO WU; defer both the
put and the free with queue_rcu_work() instead of kfree_rcu().
- drop the locked argument now that the put runs from the work item.
- add patch 2 for the selftest teardown timing.
kernel/trace/trace_events_user.c | 39 ++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index c4ba484f7b38b..8c82ecb735f41 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -109,6 +109,9 @@ struct user_event_enabler {
/* Track enable bit, flags, etc. Aligned for bitops. */
unsigned long values;
+
+ /* Defer the event put and enabler free past an RCU grace period. */
+ struct rcu_work put_rwork;
};
/* Bits 0-5 are for the bit to update upon enable/disable (0-63 allowed) */
@@ -396,17 +399,39 @@ static struct user_event_group *user_event_group_create(void)
return NULL;
};
-static void user_event_enabler_destroy(struct user_event_enabler *enabler,
- bool locked)
+static void delayed_user_event_enabler_put(struct work_struct *work)
{
- list_del_rcu(&enabler->mm_enablers_link);
+ struct user_event_enabler *enabler = container_of(to_rcu_work(work),
+ struct user_event_enabler, put_rwork);
/* No longer tracking the event via the enabler */
- user_event_put(enabler->event, locked);
+ user_event_put(enabler->event, false);
+ /* Run from queue_rcu_work(), the RCU grace period has elapsed */
kfree(enabler);
}
+static void user_event_enabler_destroy(struct user_event_enabler *enabler)
+{
+ list_del_rcu(&enabler->mm_enablers_link);
+
+ /*
+ * The enabler is removed from an RCU-traversed list
+ * (user_event_mm_dup() walks mm->enablers under rcu_read_lock() only),
+ * and readers there dereference enabler->event and take a new ref on
+ * it. Both the put of that event reference and the free of the enabler
+ * therefore have to wait for a grace period so no reader can be looking
+ * at the enabler or racing the last put of its event.
+ *
+ * The put itself must not run in RCU context: when it drops the last
+ * reference user_event_put() takes event_mutex, which cannot be taken
+ * from a softirq/RCU callback. Defer both to a work item scheduled
+ * after a grace period via queue_rcu_work().
+ */
+ INIT_RCU_WORK(&enabler->put_rwork, delayed_user_event_enabler_put);
+ queue_rcu_work(system_percpu_wq, &enabler->put_rwork);
+}
+
static int user_event_mm_fault_in(struct user_event_mm *mm, unsigned long uaddr,
int attempt)
{
@@ -464,7 +489,7 @@ static void user_event_enabler_fault_fixup(struct work_struct *work)
/* User asked for enabler to be removed during fault */
if (test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(enabler))) {
- user_event_enabler_destroy(enabler, true);
+ user_event_enabler_destroy(enabler);
goto out;
}
@@ -764,7 +789,7 @@ static void user_event_mm_destroy(struct user_event_mm *mm)
struct user_event_enabler *enabler, *next;
list_for_each_entry_safe(enabler, next, &mm->enablers, mm_enablers_link)
- user_event_enabler_destroy(enabler, false);
+ user_event_enabler_destroy(enabler);
mmdrop(mm->mm);
kfree(mm);
@@ -2645,7 +2670,7 @@ static long user_events_ioctl_unreg(unsigned long uarg)
flags |= enabler->values & ENABLE_VAL_COMPAT_MASK;
if (!test_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler)))
- user_event_enabler_destroy(enabler, true);
+ user_event_enabler_destroy(enabler);
/* Removed at least one */
ret = 0;
--
2.53.0
^ permalink raw reply related
* [PATCH 2/2] selftests/user_events: wait for deferred event teardown after unregister
From: Michael Bommarito @ 2026-07-07 16:59 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
Cc: Beau Belgrave, XIAO WU, linux-trace-kernel, linux-kernel, stable
In-Reply-To: <20260707165912.2560537-1-michael.bommarito@gmail.com>
Unregistering a user event now defers the drop of the enabler's event
reference (and the freeing of the enabler) past an RCU grace period. As a
result DIAG_IOCSDEL can transiently fail with -EBUSY while that last
reference is still being dropped, where it previously succeeded
immediately.
Two tests assumed the delete takes effect the instant the unregister
returns:
- abi_test "flags" deletes the event right after disabling it.
- perf_test's fixture teardown clear() deletes __test_event before the
next test registers the same name; a stale event makes the following
registration fail with -EADDRINUSE.
Retry the delete until it succeeds (or the event is already gone) with a
bounded wait, matching the existing wait_for_delete() idiom in the same
suite, so the tests are robust to the deferred teardown.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
.../testing/selftests/user_events/abi_test.c | 24 ++++++++++++++++-
.../testing/selftests/user_events/perf_test.c | 26 ++++++++++++++++---
2 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/user_events/abi_test.c b/tools/testing/selftests/user_events/abi_test.c
index 85892b3b719cc..9e2f84d281afc 100644
--- a/tools/testing/selftests/user_events/abi_test.c
+++ b/tools/testing/selftests/user_events/abi_test.c
@@ -132,6 +132,28 @@ static int event_delete(void)
return ret;
}
+/*
+ * Deleting an event drops its last reference, but an unregister may defer
+ * that put (and the freeing of the associated enabler) past an RCU grace
+ * period. The delete can therefore transiently fail with -EBUSY while the
+ * previous reference is still being dropped. Retry for up to ~10 seconds.
+ */
+static int wait_for_event_delete(void)
+{
+ int i, ret;
+
+ for (i = 0; i < 10000; ++i) {
+ ret = event_delete();
+
+ if (ret == 0)
+ return 0;
+
+ usleep(1000);
+ }
+
+ return ret;
+}
+
static int reg_enable_multi(void *enable, int size, int bit, int flags,
char *args)
{
@@ -262,7 +284,7 @@ TEST_F(user, flags) {
ASSERT_TRUE(event_exists());
/* Ensure we can delete it */
- ASSERT_EQ(0, event_delete());
+ ASSERT_EQ(0, wait_for_event_delete());
/* USER_EVENT_REG_MAX or above is not allowed */
ASSERT_EQ(-1, reg_enable_flags(&self->check, sizeof(int), 0,
diff --git a/tools/testing/selftests/user_events/perf_test.c b/tools/testing/selftests/user_events/perf_test.c
index cafec0e52eb31..5727cb5b914cf 100644
--- a/tools/testing/selftests/user_events/perf_test.c
+++ b/tools/testing/selftests/user_events/perf_test.c
@@ -85,6 +85,7 @@ static int get_offset(void)
static int clear(int *check)
{
struct user_unreg unreg = {0};
+ int i, ret;
unreg.size = sizeof(unreg);
unreg.disable_bit = 31;
@@ -99,13 +100,32 @@ static int clear(int *check)
if (errno != ENOENT)
return -1;
- if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1)
- if (errno != ENOENT)
+ /*
+ * Deleting the event drops its last reference, but the unregister
+ * above defers that put (and the freeing of the enabler) past an RCU
+ * grace period. The delete can therefore transiently fail with -EBUSY
+ * until that reference is dropped. Retry for up to ~10 seconds so the
+ * event is actually gone before the next test registers the same name.
+ */
+ for (i = 0; i < 10000; ++i) {
+ ret = ioctl(fd, DIAG_IOCSDEL, "__test_event");
+
+ if (ret == 0 || errno == ENOENT) {
+ ret = 0;
+ break;
+ }
+
+ if (errno != EBUSY) {
+ close(fd);
return -1;
+ }
+
+ usleep(1000);
+ }
close(fd);
- return 0;
+ return ret;
}
FIXTURE(user) {
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 2/2] selftests/user_events: wait for deferred event teardown after unregister
From: Steven Rostedt @ 2026-07-07 17:41 UTC (permalink / raw)
To: Michael Bommarito
Cc: Masami Hiramatsu, Mathieu Desnoyers, Beau Belgrave, XIAO WU,
linux-trace-kernel, linux-kernel, stable
In-Reply-To: <20260707165912.2560537-3-michael.bommarito@gmail.com>
On Tue, 7 Jul 2026 12:59:12 -0400
Michael Bommarito <michael.bommarito@gmail.com> wrote:
>
> +/*
> + * Deleting an event drops its last reference, but an unregister may defer
> + * that put (and the freeing of the associated enabler) past an RCU grace
> + * period. The delete can therefore transiently fail with -EBUSY while the
> + * previous reference is still being dropped. Retry for up to ~10 seconds.
> + */
> +static int wait_for_event_delete(void)
> +{
> + int i, ret;
> +
> + for (i = 0; i < 10000; ++i) {
> + ret = event_delete();
> +
> + if (ret == 0)
> + return 0;
> +
> + usleep(1000);
> + }
> +
> + return ret;
> +}
> +
Care to address Sashiko's comment: https://sashiko.dev/#/patchset/20260707165912.2560537-2-michael.bommarito%40gmail.com
I'll pull in patch 1 and start testing it as this one is just the tools
change, it doesn't need my testing (my tests only tests kernel changes)
-- Steve
^ permalink raw reply
* Re: [PATCH] rtla: Also link in ctype.c
From: Bastian Blank @ 2026-07-07 17:43 UTC (permalink / raw)
To: Tomas Glozar; +Cc: Steven Rostedt, linux-trace-kernel
In-Reply-To: <CAP4=nvTH5HhUk19w06aH6-xqWGOUQKesGbKCfvgpwmefLom0VQ@mail.gmail.com>
On Tue, Jul 07, 2026 at 12:22:37PM +0200, Tomas Glozar wrote:
> Thank you. It appears that GCC LTO drops the symbol use of "_ctype",
> so I didn't see it earlier. With removed -flto=auto from
> Makefile.rtla, I can reproduce it:
Ah, yes, we override LTO to disabled.
Bastian
--
There are certain things men must do to remain men.
-- Kirk, "The Ultimate Computer", stardate 4929.4
^ permalink raw reply
* Re: [PATCH v2] tracing/synthetic: Free type string on error path
From: Steven Rostedt @ 2026-07-07 17:54 UTC (permalink / raw)
To: Yu Peng; +Cc: mhiramat, mathieu.desnoyers, linux-trace-kernel, linux-kernel
In-Reply-To: <20260707132417.2193412-1-pengyu@kylinos.cn>
On Tue, 7 Jul 2026 21:24:17 +0800
Yu Peng <pengyu@kylinos.cn> wrote:
> parse_synth_field() builds a "__data_loc ..." type string before
> assigning it to field->type. If the seq_buf check fails, the temporary
> string is not owned by field and is leaked. Free it before leaving.
>
> Suggested-by: Steven Rostedt <rostedt@goodmis.org>
> Signed-off-by: Yu Peng <pengyu@kylinos.cn>
> ---
> Changes in v2:
> - Use __free(kfree) and no_free_ptr() as suggested by Steven.
>
> kernel/trace/trace_events_synth.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
> index e6871230bde96..ad2e70258291b 100644
> --- a/kernel/trace/trace_events_synth.c
> +++ b/kernel/trace/trace_events_synth.c
> @@ -828,7 +828,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
> } else if (size == 0) {
> if (synth_field_is_string(field->type) ||
> synth_field_is_stack(field->type)) {
> - char *type;
> + char *type __free(kfree) = NULL;
Ah, we can't do this here.
(Sashiko pointed this out: https://sashiko.dev/#/patchset/20260707132417.2193412-1-pengyu%40kylinos.cn )
>
> len = sizeof("__data_loc ") + strlen(field->type) + 1;
> type = kzalloc(len, GFP_KERNEL);
Because after this code we have:
type = kzalloc(len, GFP_KERNEL);
if (!type)
goto free;
Which jumps out of the if block, and that will break the cleanup.
I'll take you original version for now.
-- Steve
> @@ -844,7 +844,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
> s.buffer[s.len] = '\0';
>
> kfree(field->type);
> - field->type = type;
> + field->type = no_free_ptr(type);
>
> field->is_dynamic = true;
> size = sizeof(u64);
^ permalink raw reply
* [PATCH v3] selftests/user_events: wait for deferred event teardown after unregister
From: Michael Bommarito @ 2026-07-07 18:02 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
Cc: Beau Belgrave, XIAO WU, Shuah Khan, linux-trace-kernel,
linux-kselftest, linux-kernel
Unregistering a user event now defers the drop of the enabler's event
reference (and the freeing of the enabler) past an RCU grace period. As a
result DIAG_IOCSDEL can transiently fail with -EBUSY while that last
reference is still being dropped, where it previously succeeded
immediately.
Two tests assumed the delete takes effect the instant the unregister
returns:
- abi_test "flags" deletes the event right after disabling it.
- perf_test's fixture teardown clear() deletes __test_event before the
next test registers the same name; a stale event makes the following
registration fail with -EADDRINUSE.
Retry the delete until it succeeds (or the event is already gone) with a
bounded wait, matching the existing wait_for_delete() idiom in the same
suite, so the tests are robust to the deferred teardown.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
This resends only the selftest patch; the tracing/user_events fix that
was patch 1/2 of the v2 series is unchanged and being applied separately.
v2 -> v3:
- abi_test wait_for_event_delete(): only retry the delete on -EBUSY,
treat an already-deleted event (-ENOENT) as success, and return any
other error immediately instead of spinning for the full 10s timeout.
perf_test's clear() already discriminated on errno this way; the two
now match. Reported by Sashiko automated review.
.../testing/selftests/user_events/abi_test.c | 29 ++++++++++++++++++-
.../testing/selftests/user_events/perf_test.c | 26 +++++++++++++++--
2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/user_events/abi_test.c b/tools/testing/selftests/user_events/abi_test.c
index 85892b3b719cc..b71813eaf5c04 100644
--- a/tools/testing/selftests/user_events/abi_test.c
+++ b/tools/testing/selftests/user_events/abi_test.c
@@ -132,6 +132,33 @@ static int event_delete(void)
return ret;
}
+/*
+ * Deleting an event drops its last reference, but an unregister may defer
+ * that put (and the freeing of the associated enabler) past an RCU grace
+ * period. The delete can therefore transiently fail with -EBUSY while the
+ * previous reference is still being dropped. Retry only on that transient
+ * failure; treat an already-deleted event (-ENOENT) as success and return
+ * any other error immediately rather than spinning for the full timeout.
+ */
+static int wait_for_event_delete(void)
+{
+ int i, ret;
+
+ for (i = 0; i < 10000; ++i) {
+ ret = event_delete();
+
+ if (ret == 0 || errno == ENOENT)
+ return 0;
+
+ if (errno != EBUSY)
+ return ret;
+
+ usleep(1000);
+ }
+
+ return ret;
+}
+
static int reg_enable_multi(void *enable, int size, int bit, int flags,
char *args)
{
@@ -262,7 +289,7 @@ TEST_F(user, flags) {
ASSERT_TRUE(event_exists());
/* Ensure we can delete it */
- ASSERT_EQ(0, event_delete());
+ ASSERT_EQ(0, wait_for_event_delete());
/* USER_EVENT_REG_MAX or above is not allowed */
ASSERT_EQ(-1, reg_enable_flags(&self->check, sizeof(int), 0,
diff --git a/tools/testing/selftests/user_events/perf_test.c b/tools/testing/selftests/user_events/perf_test.c
index cafec0e52eb31..5727cb5b914cf 100644
--- a/tools/testing/selftests/user_events/perf_test.c
+++ b/tools/testing/selftests/user_events/perf_test.c
@@ -85,6 +85,7 @@ static int get_offset(void)
static int clear(int *check)
{
struct user_unreg unreg = {0};
+ int i, ret;
unreg.size = sizeof(unreg);
unreg.disable_bit = 31;
@@ -99,13 +100,32 @@ static int clear(int *check)
if (errno != ENOENT)
return -1;
- if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1)
- if (errno != ENOENT)
+ /*
+ * Deleting the event drops its last reference, but the unregister
+ * above defers that put (and the freeing of the enabler) past an RCU
+ * grace period. The delete can therefore transiently fail with -EBUSY
+ * until that reference is dropped. Retry for up to ~10 seconds so the
+ * event is actually gone before the next test registers the same name.
+ */
+ for (i = 0; i < 10000; ++i) {
+ ret = ioctl(fd, DIAG_IOCSDEL, "__test_event");
+
+ if (ret == 0 || errno == ENOENT) {
+ ret = 0;
+ break;
+ }
+
+ if (errno != EBUSY) {
+ close(fd);
return -1;
+ }
+
+ usleep(1000);
+ }
close(fd);
- return 0;
+ return ret;
}
FIXTURE(user) {
--
2.53.0
^ permalink raw reply related
* Re: [RFC 1/3] arm64: kprobes: Do not handle non-XOL faults as kprobe faults
From: Masami Hiramatsu @ 2026-07-08 0:46 UTC (permalink / raw)
To: Pu Hu
Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
davem@davemloft.net, Hongyan Xia, Jiazi Li,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260706083636.159883-2-hupu@transsion.com>
On Mon, 6 Jul 2026 08:36:48 +0000
Pu Hu <hupu@transsion.com> wrote:
> From: Pu Hu <hupu@transsion.com>
>
> kprobe_fault_handler() handles faults taken while kprobes is in
> KPROBE_HIT_SS or KPROBE_REENTER state as faults caused by the
> single-stepped instruction.
>
> That assumption is not always true. While a kprobe is preparing or
> executing the out-of-line single-step instruction, other code may run
> in that window. For example, perf or trace code can be invoked from the
> debug exception path and may take a fault of its own. In that case the
> fault did not happen on the kprobe XOL instruction, but the kprobe fault
> handler may still try to recover it as a kprobe single-step fault.
>
> This can corrupt the exception recovery flow and leave the real fault to
> be handled with a wrong PC. A typical reproducer is running simpleperf
> with preemptirq tracepoints and dwarf callchains while a kprobe is
> installed on a frequently executed kernel function.
>
> Fix this by handling faults in KPROBE_HIT_SS/KPROBE_REENTER only when
> the faulting PC points at the current kprobe's XOL instruction. Faults
> from any other PC are left to the normal fault handling path.
>
> This follows the same idea as the x86 fix in commit 6381c24cd6d5
> ("kprobes/x86: Fix page-fault handling logic").
>
> Signed-off-by: Pu Hu <hupu@transsion.com>
> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
> ---
> arch/arm64/kernel/probes/kprobes.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index 43a0361a8bf0..e4d2852ce2fb 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -285,6 +285,20 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
> switch (kcb->kprobe_status) {
> case KPROBE_HIT_SS:
> case KPROBE_REENTER:
> + /*
> + * A fault taken while a kprobe is single-stepping is not
> + * necessarily caused by the instruction in the XOL slot. For
> + * example, tracing or perf code running in this window may take
> + * an unrelated fault.
> + *
> + * Handle the fault here only when the faulting PC is the XOL
> + * instruction of the current kprobe. Otherwise let the normal
> + * fault handling path deal with it.
> + */
> + if (cur->ainsn.xol_insn &&
> + instruction_pointer(regs) != (unsigned long)cur->ainsn.xol_insn)
> + break;
Can you check Sashiko's comments[1]?
[1] https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=1
It seems that it complains about simulated kprobe's case.
In that case, cur->ainsn.xol_insn == NULL. The simulation should be done
in the kprobe context (which is a debug trap). I'm not sure the arm64
can cause NMI in that context, but if it happens and causes a fault,
it may cause a problem.
So I think we can just ignore the fault on the simulated kprobes.
To ensure that, you can just add:
if (cur && !cur->ainsn.xol_insn)
return 0;
at the entry of this function. (and remove redundant cur->ainsn.xol_insn check)
Thank you,
> +
> /*
> * We are here because the instruction being single
> * stepped caused a page fault. We reset the current
> --
> 2.43.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [RFC 2/3] arm64: kprobes: Allow reentering kprobes while single-stepping
From: Masami Hiramatsu @ 2026-07-08 0:54 UTC (permalink / raw)
To: Pu Hu
Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
davem@davemloft.net, Hongyan Xia, Jiazi Li,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260706083636.159883-3-hupu@transsion.com>
On Mon, 6 Jul 2026 08:36:49 +0000
Pu Hu <hupu@transsion.com> wrote:
> From: Pu Hu <hupu@transsion.com>
>
> A kprobe can be hit while another kprobe is in KPROBE_HIT_SS state. This
> can happen when tracing or perf code runs from the debug exception path
> while the first kprobe is preparing or executing its out-of-line
> single-step instruction.
>
> Currently arm64 treats a kprobe hit in KPROBE_HIT_SS as unrecoverable,
> the same as a hit in KPROBE_REENTER. This is too strict. A hit in
> KPROBE_HIT_SS is still a one-level reentry and can be handled by saving
> the current kprobe state and setting up single-step for the new probe,
> just like reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
>
> The truly unrecoverable case is hitting another kprobe while already in
> KPROBE_REENTER, because the reentry save area has already been consumed.
>
> Move KPROBE_HIT_SS to the recoverable reentry cases and leave
> KPROBE_REENTER as the unrecoverable nested reentry case.
>
> This mirrors the x86 fix in commit 6a5022a56ac3
> ("kprobes/x86: Allow to handle reentered kprobe on single-stepping").
Can you also check the Sashiko comment?
https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=2
This seems indicating potentially brakage of reenter kprobes on arm64.
But is it possible to hit another kprobe while SS on arm64? It is
the same question about the previous one, can NMI happens during
the single stepping? (maybe yes, because it is non-maskable)
Anyway, for making it safer, we need to add saved_irqflags to prev_kprobe.
Thank you,
>
> Signed-off-by: Pu Hu <hupu@transsion.com>
> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
> ---
> arch/arm64/kernel/probes/kprobes.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index e4d2852ce2fb..764b2228cca0 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -240,10 +240,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
> switch (kcb->kprobe_status) {
> case KPROBE_HIT_SSDONE:
> case KPROBE_HIT_ACTIVE:
> + case KPROBE_HIT_SS:
> + /*
> + * A probe can be hit while another kprobe is preparing or
> + * executing its XOL single-step instruction. This is still a
> + * recoverable one-level reentry, so handle it in the same way as
> + * reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
> + */
> kprobes_inc_nmissed_count(p);
> setup_singlestep(p, regs, kcb, 1);
> break;
> - case KPROBE_HIT_SS:
> case KPROBE_REENTER:
> pr_warn("Failed to recover from reentered kprobes.\n");
> dump_kprobe(p);
> --
> 2.43.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [RFC 0/3] arm64: kprobes: Fix single-step fault and reentry handling
From: Masami Hiramatsu @ 2026-07-08 0:55 UTC (permalink / raw)
To: Pu Hu
Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
davem@davemloft.net, Hongyan Xia, Jiazi Li,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260706083636.159883-1-hupu@transsion.com>
Hi, Pu,
Thanks for updating the series. But even if it just update
the signed-off-by, please update the version.
Also, can you check the Sashiko's comments?
https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com
Thank you,
On Mon, 6 Jul 2026 08:36:46 +0000
Pu Hu <hupu@transsion.com> wrote:
> From: Pu Hu <hupu@transsion.com>
>
> This series fixes two arm64 kprobes issues observed when running
> simpleperf with preemptirq tracepoints and dwarf callchains while a
> kprobe is active on a frequently executed kernel function.
>
> The crash happens in the kprobe debug exception path. While a kprobe is
> preparing or executing its XOL single-step instruction, perf/trace code
> can run in the same window. That code may either take a fault of its own
> or hit another kprobe.
>
> Patch 1 makes kprobe_fault_handler() handle a fault in
> KPROBE_HIT_SS/KPROBE_REENTER only when the faulting PC points at the
> current kprobe's XOL instruction. Otherwise the fault is left to the
> normal fault handling path.
>
> Patch 2 allows a kprobe hit in KPROBE_HIT_SS to be handled as a
> recoverable one-level reentry. Only a hit while already in
> KPROBE_REENTER remains unrecoverable.
>
> Patch 3 adds a kprobes selftest which registers a kprobe on a frequently
> executed filemap fault path and drives repeated file-backed page faults
> from userspace. This provides a smaller reproducer for validating the
> fault handling fix.
>
> This follows the same logic as the existing x86 fixes:
> 6381c24cd6d5 ("kprobes/x86: Fix page-fault handling logic")
> 6a5022a56ac3 ("kprobes/x86: Allow to handle reentered kprobe on single-stepping")
>
> Reproducer:
>
> simpleperf record -p <pid> -f 10000 \
> -e preemptirq:preempt_disable \
> -e preemptirq:preempt_enable \
> --duration 9 --call-graph dwarf \
> -o /data/local/tmp/perf.data
>
> The new selftest can be built from tools/testing/selftests/kprobe/ and
> used to exercise the page fault handling path with the test kprobe
> module loaded.
>
> Before this series, the crash reproduced frequently. With both patches
> applied, it was no longer reproduced in our testing.
>
>
> Pu Hu (3):
> arm64: kprobes: Do not handle non-XOL faults as kprobe faults
> arm64: kprobes: Allow reentering kprobes while single-stepping
> selftests/kprobes: Add kprobe stress test for page fault handling
>
> arch/arm64/kernel/probes/kprobes.c | 22 +++-
> tools/testing/selftests/kprobe/.gitignore | 2 +
> tools/testing/selftests/kprobe/Makefile | 75 +++++++++++++
> tools/testing/selftests/kprobe/fault_stress.c | 105 ++++++++++++++++++
> .../selftests/kprobe/kprobe_folio_stress.c | 70 ++++++++++++
> 5 files changed, 273 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/kprobe/.gitignore
> create mode 100644 tools/testing/selftests/kprobe/Makefile
> create mode 100644 tools/testing/selftests/kprobe/fault_stress.c
> create mode 100644 tools/testing/selftests/kprobe/kprobe_folio_stress.c
>
> --
> 2.43.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [RFC PATCH 1/3] mm/compaction: skip isolate mlocked folios when compact_unevictable_allowed=0
From: Wandun @ 2026-07-08 1:31 UTC (permalink / raw)
To: Alexander Krabler, Vlastimil Babka (SUSE), linux-mm@kvack.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-rt-devel@lists.linux.dev
Cc: akpm@linux-foundation.org, surenb@google.com, mhocko@suse.com,
jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com,
rostedt@goodmis.org, mhiramat@kernel.org,
mathieu.desnoyers@efficios.com, david@kernel.org, ljs@kernel.org,
liam@infradead.org, rppt@kernel.org, bigeasy@linutronix.de,
clrkwllms@kernel.org, Hugh Dickins
In-Reply-To: <05d7369e-341c-49f4-ae13-df3d0ad930d7@gmail.com>
On 6/29/26 17:07, Wandun wrote:
>
>
> On 6/26/26 21:42, Alexander Krabler wrote:
>> On 6/26/26 11:38, Wandun wrote:
>>> On 6/26/26 16:45, Alexander Krabler wrote:
>>>> However, we were not able to reproduce the actual race
>>>> (mlockall() process waiting on a migration PTE),
>>>> not in the past, not now. Might be hard to trigger that race.
>>>
>>> Not hard to trigger that case, I added a debug message, such as below,
>>> lots of messages occur in a few second.
>>>
>>> diff --cc mm/memory.c
>>> index ff338c2abe92,ff338c2abe92..6552b3b14f78
>>> --- a/mm/memory.c
>>> +++ b/mm/memory.c
>>> @@@ -4768,6 -4768,6 +4768,8 @@@ vm_fault_t do_swap_page(struct vm_faul
>>> if (softleaf_is_migration(entry)) {
>>> migration_entry_wait(vma->vm_mm, vmf->pmd,
>>> vmf->address);
>>> + if (!strcmp(current->comm, "repro"))
>>> + pr_err("============== hit ================\n");
>>> } else if (softleaf_is_device_exclusive(entry)) {
>>> vmf->page = softleaf_to_page(entry);
>>> ret = remove_device_exclusive_entry(vmf);
>>
>> I have a kprobe on migration_entry_wait set and logged into a ftrace buffer
>> (including kernel stacktrace).
>> Yes, this function is hit, but only inside the mmap-syscall, which is okay,
>> memory allocation is not realtime-safe.
>>
>> repro-2090 [002] d.... 811.129549: frt_migration_entry_wait: (migration_entry_wait+0x0/0x100)
>> repro-2090 [002] d.... 811.129553: <stack trace>
>> => migration_entry_wait
>> => __handle_mm_fault
>> => handle_mm_fault
>> => __get_user_pages
>> => populate_vma_page_range
>> => __mm_populate
>> => vm_mmap_pgoff
>> => ksys_mmap_pgoff
>> => __arm64_sys_mmap
>> => el0_svc_common.constprop.0
>> => do_el0_svc
>> => el0_svc
>> => el0t_64_sync_handler
>> => el0t_64_sync
>>
>> The original race was an instruction abort interrupt out of nothing due
>> to the migration PTE set by kcompactd.
>> And these kind of races I see quite often on non mlockall()-processes,
>> but can't reproduce on memory locked processes.
>>
>> Example:
>> podman-832 [000] d.... 812.447820: frt_migration_entry_wait: (migration_entry_wait+0x0/0x100)
>> podman-832 [000] d.... 812.447823: <stack trace>
>> => migration_entry_wait
>> => __handle_mm_fault
>> => handle_mm_fault
>> => do_page_fault
>> => do_translation_fault
>> => do_mem_abort
>> => el0_da
>> => el0t_64_sync_handler
>> => el0t_64_sync
>
> Hi, Alexander
>
> From the perspective of the root cause, there is no fundamental difference
> between these two call stacks. I modified the reproduction program, and it
> can still reproduce the situation of the second call stack
> (although it doesn't occur as frequently). The complete reproduction program
> is as follows:
>
>
> #define _GNU_SOURCE
> #include <fcntl.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/mman.h>
> #include <sys/sysinfo.h>
> #include <unistd.h>
>
> #define PAGE_SIZE 4096
> #define NR_PAGES 10000
>
> static void *worker_fn(void *arg)
> {
> int fd = (long)arg;
> size_t len = NR_PAGES * PAGE_SIZE;
>
> while (1) {
> if (ftruncate(fd, 0) < 0) {}
> if (ftruncate(fd, len) < 0) {}
>
> char *p = mmap(NULL, len, PROT_READ | PROT_WRITE,
> MAP_SHARED, fd, 0);
> if (p == MAP_FAILED)
> continue;
>
> mlockall(MCL_ONFAULT | MCL_FUTURE);
>
> for (int i = 0; i < NR_PAGES; i++) {
> for (int j = 0; j < PAGE_SIZE; j++) {
> p[i * PAGE_SIZE + j] = 1;
> }
> }
>
> usleep(200);
> munmap(p, len);
> }
> return NULL;
> }
>
> static void *compact_fn(void *arg)
> {
> (void)arg;
> int fd = open("/proc/sys/vm/compact_memory", O_WRONLY);
> if (fd < 0)
> return NULL;
>
> while (1) {
> if (write(fd, "1", 1) < 0) {}
> usleep(5000);
> }
> }
>
> int main(void)
> {
> int nproc = sysconf(_SC_NPROCESSORS_ONLN);
> if (nproc < 1)
> nproc = 1;
>
> int *fds = calloc((size_t)nproc, sizeof(int));
> if (!fds)
> return 1;
>
> size_t len = NR_PAGES * PAGE_SIZE;
> for (int i = 0; i < nproc; i++) {
> char path[64];
> snprintf(path, sizeof(path), "./repro_%d.dat", i);
> unlink(path);
> fds[i] = open(path, O_RDWR | O_CREAT, 0600);
> if (fds[i] < 0)
> return 1;
> if (ftruncate(fds[i], len) < 0)
> return 1;
> }
>
> printf("repro: %d workers, %d pages, Ctrl-C to stop\n",
> nproc, NR_PAGES);
>
> pthread_t compact;
> pthread_create(&compact, NULL, compact_fn, NULL);
>
> pthread_t *threads = calloc((size_t)nproc, sizeof(pthread_t));
> for (int i = 0; i < nproc; i++)
> pthread_create(&threads[i], NULL, worker_fn, (void *)(long)fds[i]);
>
> pthread_join(compact, NULL);
> return 0;
> }
I found there are false positives in this reproducer.
I modified the program a little, the diff is as follows,
the problem can still be reproduced
diff --git a/repro.c b/repro.c
index b1b34d5..59cb417 100644
--- a/repro.c
+++ b/repro.c
@@ -15,6 +15,7 @@ static void *worker_fn(void *arg)
int fd = (long)arg;
size_t len = NR_PAGES * PAGE_SIZE;
+ mlockall(MCL_ONFAULT | MCL_FUTURE | MCL_CURRENT);
while (1) {
if (ftruncate(fd, 0) < 0) {}
if (ftruncate(fd, len) < 0) {}
@@ -24,8 +25,6 @@ static void *worker_fn(void *arg)
if (p == MAP_FAILED)
continue;
- mlockall(MCL_ONFAULT | MCL_FUTURE);
-
for (int i = 0; i < NR_PAGES; i++) {
for (int j = 0; j < PAGE_SIZE; j++) {
p[i * PAGE_SIZE + j] = 1;
>
>
>
>
>>
>> Thanks,
>> Alexander
>>
>> --
>>
>> KUKA Deutschland GmbH Board of Directors: Michael Jürgens (Chairman), Johan Naten, Hui Zhang Registered Office: Augsburg HRB 14914
>>
>> This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of contents of this e-mail is strictly forbidden.
>>
>> Please consider the environment before printing this e-mail.
>
^ permalink raw reply related
* Re: [RFC 1/3] arm64: kprobes: Do not handle non-XOL faults as kprobe faults
From: Hongyan Xia @ 2026-07-08 5:57 UTC (permalink / raw)
To: Masami Hiramatsu (Google), Pu Hu
Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
davem@davemloft.net, Jiazi Li,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260708094623.9a1d40bed37bce3c7969ad20@kernel.org>
Hi Masami,
On 7/8/2026 8:46 AM, Masami Hiramatsu wrote:
> On Mon, 6 Jul 2026 08:36:48 +0000
> Pu Hu <hupu@transsion.com> wrote:
>
>> From: Pu Hu <hupu@transsion.com>
>>
>> kprobe_fault_handler() handles faults taken while kprobes is in
>> KPROBE_HIT_SS or KPROBE_REENTER state as faults caused by the
>> single-stepped instruction.
>>
>> That assumption is not always true. While a kprobe is preparing or
>> executing the out-of-line single-step instruction, other code may run
>> in that window. For example, perf or trace code can be invoked from the
>> debug exception path and may take a fault of its own. In that case the
>> fault did not happen on the kprobe XOL instruction, but the kprobe fault
>> handler may still try to recover it as a kprobe single-step fault.
>>
>> This can corrupt the exception recovery flow and leave the real fault to
>> be handled with a wrong PC. A typical reproducer is running simpleperf
>> with preemptirq tracepoints and dwarf callchains while a kprobe is
>> installed on a frequently executed kernel function.
>>
>> Fix this by handling faults in KPROBE_HIT_SS/KPROBE_REENTER only when
>> the faulting PC points at the current kprobe's XOL instruction. Faults
>> from any other PC are left to the normal fault handling path.
>>
>> This follows the same idea as the x86 fix in commit 6381c24cd6d5
>> ("kprobes/x86: Fix page-fault handling logic").
>>
>> Signed-off-by: Pu Hu <hupu@transsion.com>
>> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
>> ---
>> arch/arm64/kernel/probes/kprobes.c | 14 ++++++++++++++
>> 1 file changed, 14 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
>> index 43a0361a8bf0..e4d2852ce2fb 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -285,6 +285,20 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
>> switch (kcb->kprobe_status) {
>> case KPROBE_HIT_SS:
>> case KPROBE_REENTER:
>> + /*
>> + * A fault taken while a kprobe is single-stepping is not
>> + * necessarily caused by the instruction in the XOL slot. For
>> + * example, tracing or perf code running in this window may take
>> + * an unrelated fault.
>> + *
>> + * Handle the fault here only when the faulting PC is the XOL
>> + * instruction of the current kprobe. Otherwise let the normal
>> + * fault handling path deal with it.
>> + */
>> + if (cur->ainsn.xol_insn &&
>> + instruction_pointer(regs) != (unsigned long)cur->ainsn.xol_insn)
>> + break;
>
> Can you check Sashiko's comments[1]?
>
> [1] https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=1
>
> It seems that it complains about simulated kprobe's case.
> In that case, cur->ainsn.xol_insn == NULL. The simulation should be done
> in the kprobe context (which is a debug trap). I'm not sure the arm64
> can cause NMI in that context, but if it happens and causes a fault,
> it may cause a problem.
>
> So I think we can just ignore the fault on the simulated kprobes.
>
> To ensure that, you can just add:
>
> if (cur && !cur->ainsn.xol_insn)
> return 0;
>
> at the entry of this function. (and remove redundant cur->ainsn.xol_insn check)
Right, both cases:
1. single-step XOL
2. simulated
have this problem and this patch fixed 1. 2 remains unchanged.
Ideally we should fix both, but the simulated case seems more
complicated, and at least we didn't make things worse for 2. So I wonder
if we can analyze 2 more thoroughly and fix it in a separate patch.
> Thank you,
>
>> +
>> /*
>> * We are here because the instruction being single
>> * stepped caused a page fault. We reset the current
>> --
>> 2.43.0
>>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal()
From: Mike Rapoport @ 2026-07-08 6:08 UTC (permalink / raw)
To: Thierry Reding
Cc: Will Deacon, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Hunter, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Sowjanya Komatineni,
Luca Ceresoli, Mikko Perttunen, Yury Norov, Rasmus Villemoes,
Russell King, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Marek Szyprowski, Robin Murphy, Sumit Semwal,
Benjamin Gaignard, Brian Starkey, John Stultz, T.J. Mercier,
Christian König, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Catalin Marinas, Thierry Reding, devicetree,
linux-tegra, linux-kernel, dri-devel, linux-media,
linux-arm-kernel, linux-s390, linux-mm, iommu, linaro-mm-sig,
linux-trace-kernel, Thierry Reding, Chun Ng
In-Reply-To: <akuvyu1Pq0ZVMZV0@orome>
On Mon, Jul 06, 2026 at 03:49:24PM +0200, Thierry Reding wrote:
> On Fri, Jul 03, 2026 at 06:13:31PM +0100, Will Deacon wrote:
> > >
> > > How about if I extract a common helper and provide set_memory_p() and
> > > set_memory_np() in terms of those. Those are available on x86 and
> > > PowerPC as well, so fairly standard. I suppose at that point we're
> > > closer to set_memory_valid().
> >
> > Why not just call set_direct_map_invalid_noflush() +
> > flush_tlb_kernel_range() for each page? We already have APIs for this.
>
> Having a "standard" helper with a fixed and documented purposed seemed
> like a preferable approach for this particular case. We also may want to
> make the driver that uses this buildable as a module, in which case we'd
> need to export these rather low-level APIs. And then there's also the
> fact that we typically call this on a rather large region of memory
> (usually something like 512 MiB), so doing it page-by-page is rather
> suboptimal.
There are discussions about adding numpages to set_direct_map, e.g.
https://lore.kernel.org/linux-mm/20260410151746.61150-2-kalyazin@amazon.com/
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal()
From: Mike Rapoport @ 2026-07-08 6:22 UTC (permalink / raw)
To: Robin Murphy
Cc: Will Deacon, Thierry Reding, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Hunter, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
Sowjanya Komatineni, Luca Ceresoli, Mikko Perttunen, Yury Norov,
Rasmus Villemoes, Russell King, Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, Andrew Morton,
David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Marek Szyprowski, Sumit Semwal, Benjamin Gaignard, Brian Starkey,
John Stultz, T.J. Mercier, Christian König, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Catalin Marinas,
Thierry Reding, devicetree, linux-tegra, linux-kernel, dri-devel,
linux-media, linux-arm-kernel, linux-s390, linux-mm, iommu,
linaro-mm-sig, linux-trace-kernel, Thierry Reding, Chun Ng
In-Reply-To: <f6e8b4d4-8b50-4cc7-b264-ae39929c619a@arm.com>
On Tue, Jul 07, 2026 at 03:15:24PM +0100, Robin Murphy wrote:
> On 07/07/2026 2:36 pm, Mike Rapoport wrote:
> > On Tue, Jul 07, 2026 at 02:17:29PM +0100, Robin Murphy wrote:
> > >
> > > Given the precedent of memblock_mark_nomap(), as long as the reusable
> > > reserved-memory regions also get split into distinct memblocks, then it
> > > seems like in principle we ought to be able to give them a new
> > > MEMBLOCK_PTEMAP (or whatever) flag which could then be picked up in
> > > map_mem() without needing to override force_pte_mapping() globally?
> >
> > Please don't. _nomap() caused enough pain.
>
> Indeed I was there for pretty much the whole pfn_valid() saga :)
>
> Bad example maybe - in this case the only actual similarity to nomap would
> be the fact that it would also be set by the of_reserved_mem code based on
> what it finds in DT; in all other aspects it should be functionally closer
> to something like MEMBLOCK_RSRV_NOINIT, i.e. just carrying information
> through the mm init phase, then ceasing to matter at all once the linear
> mapping is done.
Sounds simpler than nomap indeed :)
Although I'm not sure it won't be required after mm init in some way. There
is already a suggestion to allow collapsing PTE mappings into PMD in the
linear map [1] and it already adds a use-case for runtime check for
MEMBLOCK_PTEMAP.
That said, I don't hate the idea. The only thing is that such flag would be
very much arm64 specific.
I've been thinking for a while about splitting memblock flags to generic
and arch-specific parts and if you decide to take a memblock flag route it
seems like a good use case for memblock_{set,clear}_arch_flags().
[1] https://lore.kernel.org/linux-mm/20260611130144.1385343-7-abarnas@google.com/
> Cheers,
> Robin.
--
Sincerely yours,
Mike.
^ permalink raw reply
* Re: [RFC PATCH 1/3] mm/compaction: skip isolate mlocked folios when compact_unevictable_allowed=0
From: Alexander Krabler @ 2026-07-08 6:24 UTC (permalink / raw)
To: Wandun, Vlastimil Babka (SUSE), linux-mm@kvack.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-rt-devel@lists.linux.dev
Cc: akpm@linux-foundation.org, surenb@google.com, mhocko@suse.com,
jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com,
rostedt@goodmis.org, mhiramat@kernel.org,
mathieu.desnoyers@efficios.com, david@kernel.org, ljs@kernel.org,
liam@infradead.org, rppt@kernel.org, bigeasy@linutronix.de,
clrkwllms@kernel.org, Hugh Dickins
In-Reply-To: <e4761ca0-21d2-41d5-8d0f-ec14d0a5d3b9@gmail.com>
On 7/08/26 03:31, Wandun wrote:
> I found there are false positives in this reproducer.
> I modified the program a little, the diff is as follows,
> the problem can still be reproduced
>
>
> diff --git a/repro.c b/repro.c
> index b1b34d5..59cb417 100644
> --- a/repro.c
> +++ b/repro.c
> @@ -15,6 +15,7 @@ static void *worker_fn(void *arg)
> int fd = (long)arg;
> size_t len = NR_PAGES * PAGE_SIZE;
>
> + mlockall(MCL_ONFAULT | MCL_FUTURE | MCL_CURRENT);
> while (1) {
> if (ftruncate(fd, 0) < 0) {}
> if (ftruncate(fd, len) < 0) {}
> @@ -24,8 +25,6 @@ static void *worker_fn(void *arg)
> if (p == MAP_FAILED)
> continue;
>
> - mlockall(MCL_ONFAULT | MCL_FUTURE);
> -
> for (int i = 0; i < NR_PAGES; i++) {
> for (int j = 0; j < PAGE_SIZE; j++) {
No worries, I can reproduce with that program,
but I still think this is different.
The reproducer passes the MCL_ONFAULT flag to mlockall(),
delaying the actual memory allocation.
However, this is not what I would do in realtime programs and if I do,
these faults are basically memory allocations, where I can
not expect realtime performance guarantees.
If I remove MCL_ONFAULT, I did not manage to hit the migration_entry_wait
with the reproducer.
My guess is, that it only triggers when using CMA,
but I'm not deep enough into that topic to proof that.
--
KUKA Deutschland GmbH Board of Directors: Michael Jürgens (Chairman), Johan Naten, Hui Zhang Registered Office: Augsburg HRB 14914
This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of contents of this e-mail is strictly forbidden.
Please consider the environment before printing this e-mail.
^ permalink raw reply
* Re: [RFC PATCH 0/3] mm/compaction: honour compact_unevictable_allowed in mlock race and alloc_contig path
From: Lorenzo Stoakes @ 2026-07-08 6:31 UTC (permalink / raw)
To: Wandun Chen
Cc: linux-mm, linux-kernel, linux-trace-kernel, linux-rt-devel, akpm,
vbabka, surenb, mhocko, jackmanb, hannes, ziy, rostedt, mhiramat,
mathieu.desnoyers, david, liam, rppt, bigeasy, clrkwllms,
Alexander.Krabler
In-Reply-To: <20260604023812.3700316-1-chenwandun1@gmail.com>
Errr... how does this relate to your other, non-RFC patch series [0] "mm: honour
compact_unevictable_allowed in mlock and CMA paths"?
Why did you send this separately and why do you not mention the other series
here or there?
And why is one RFC and the other not?
You really need to add more context like this, I spent quite a bit of time
reviewing [0] and don't want to find out that actually you are abandoning that
for this or something?...
On Thu, Jun 04, 2026 at 10:38:09AM +0800, Wandun Chen wrote:
> From: Wandun Chen <chenwandun@lixiang.com>
>
> vm.compact_unevictable_allowed=0 is meant to keep compaction from
> touching unevictable folios. In practice there are still two paths
> where it does not take effect. This series fixes them and adds a
> tracepoint to make such issues easier to diagnose in the future.
>
> Wandun Chen (3):
> mm/compaction: skip isolate mlocked folios when
> compact_unevictable_allowed=0
> mm/compaction: add per-folio isolation tracepoint
> mm/compaction: respect compact_unevictable_allowed in alloc_contig
> path
>
> include/linux/compaction.h | 6 ++++++
> include/trace/events/compaction.h | 26 ++++++++++++++++++++++++++
> mm/compaction.c | 14 +++++++++++---
> mm/internal.h | 1 +
> mm/page_alloc.c | 2 ++
> 5 files changed, 46 insertions(+), 3 deletions(-)
>
> --
> 2.43.0
>
Thanks, Lorenzo
[0]:https://lore.kernel.org/all/20260707125925.3725177-1-chenwandun1@gmail.com/
^ permalink raw reply
* Re: [RFC PATCH 0/3] mm/compaction: honour compact_unevictable_allowed in mlock race and alloc_contig path
From: Lorenzo Stoakes @ 2026-07-08 6:35 UTC (permalink / raw)
To: Wandun Chen
Cc: linux-mm, linux-kernel, linux-trace-kernel, linux-rt-devel, akpm,
vbabka, surenb, mhocko, jackmanb, hannes, ziy, rostedt, mhiramat,
mathieu.desnoyers, david, liam, rppt, bigeasy, clrkwllms,
Alexander.Krabler
In-Reply-To: <ak3uV7L5EEi3aKyD@lucifer>
On Wed, Jul 08, 2026 at 07:31:26AM +0100, Lorenzo Stoakes wrote:
> Errr... how does this relate to your other, non-RFC patch series [0] "mm: honour
> compact_unevictable_allowed in mlock and CMA paths"?
>
> Why did you send this separately and why do you not mention the other series
> here or there?
>
> And why is one RFC and the other not?
>
> You really need to add more context like this, I spent quite a bit of time
> reviewing [0] and don't want to find out that actually you are abandoning that
> for this or something?...
Oh hang on... this is old, and [0] is new, my bad.
It just got pinged up my mail client because of recent replies :>)
Thanks, Lorenzo
>
> On Thu, Jun 04, 2026 at 10:38:09AM +0800, Wandun Chen wrote:
> > From: Wandun Chen <chenwandun@lixiang.com>
> >
> > vm.compact_unevictable_allowed=0 is meant to keep compaction from
> > touching unevictable folios. In practice there are still two paths
> > where it does not take effect. This series fixes them and adds a
> > tracepoint to make such issues easier to diagnose in the future.
> >
> > Wandun Chen (3):
> > mm/compaction: skip isolate mlocked folios when
> > compact_unevictable_allowed=0
> > mm/compaction: add per-folio isolation tracepoint
> > mm/compaction: respect compact_unevictable_allowed in alloc_contig
> > path
> >
> > include/linux/compaction.h | 6 ++++++
> > include/trace/events/compaction.h | 26 ++++++++++++++++++++++++++
> > mm/compaction.c | 14 +++++++++++---
> > mm/internal.h | 1 +
> > mm/page_alloc.c | 2 ++
> > 5 files changed, 46 insertions(+), 3 deletions(-)
> >
> > --
> > 2.43.0
> >
>
> Thanks, Lorenzo
>
> [0]:https://lore.kernel.org/all/20260707125925.3725177-1-chenwandun1@gmail.com/
^ permalink raw reply
* Reserving memory on ACPI systems (was: [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal())
From: Mike Rapoport @ 2026-07-08 6:36 UTC (permalink / raw)
To: Will Deacon
Cc: Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Hunter, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Sowjanya Komatineni,
Luca Ceresoli, Mikko Perttunen, Yury Norov, Rasmus Villemoes,
Russell King, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Marek Szyprowski, Robin Murphy, Sumit Semwal,
Benjamin Gaignard, Brian Starkey, John Stultz, T.J. Mercier,
Christian König, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Catalin Marinas, Thierry Reding, devicetree,
linux-tegra, linux-kernel, dri-devel, linux-media,
linux-arm-kernel, linux-s390, linux-mm, iommu, linaro-mm-sig,
linux-trace-kernel, Thierry Reding, Chun Ng, Shyam Saini
In-Reply-To: <akftuw9NyRy36fXA@willie-the-truck>
On Fri, Jul 03, 2026 at 06:13:31PM +0100, Will Deacon wrote:
> On Thu, Jul 02, 2026 at 06:41:23PM +0200, Thierry Reding wrote:
> > On Thu, Jul 02, 2026 at 03:46:44PM +0200, Thierry Reding wrote:
> > > On Thu, Jul 02, 2026 at 10:18:47AM +0100, Will Deacon wrote:
> > > > On Wed, Jul 01, 2026 at 06:08:15PM +0200, Thierry Reding wrote:
> > > > > From: Chun Ng <chunn@nvidia.com>
> > > > >
> > > > > Add helpers to swap PROT_NORMAL and PROT_DEVICE_nGnRnE protection bits
> > > > > on a kernel-linear-map range.
> > > >
> > > > That sounds like a really terrible idea. Why is this necessary and how
> > > > does it interact with things like load_unaligned_zeropad()?
> > >
> > > This is necessary because once the memory controller has walled off the
> > > new memory region the CPU must not access it under any circumstances or
> > > it'll cause the CPU to lock up (I think technically it'll hit an SError
> > > but in practice that just means it'll freeze, as far as I can tell).
> > >
> > > Probably doesn't interact well at all with load_unaligned_zeropad().
> > >
> > > > I think you should unmap the memory from the linear map and memremap()
> > > > it instead.
> > >
> > > Given that the memory can never be accessed by the CPU after the memory
> > > controller locks it down, I don't think we'll even need memremap(). The
> > > only thing we really need is the sg_table we hand out via the DMA BUFs
> > > so that they can be used by device drivers to program their DMA engines
> > > internally.
> > >
> > > Looking through some of the architecture code around this, shouldn't we
> > > simply be using set_memory_encrypted() and set_memory_decrypted() for
> > > this? While they might've been created for slightly other use-cases,
> > > they seem to be doing exactly what we want (i.e. remove the page range
> > > from the linear mapping and flushing it, or restoring the valid bit and
> > > standard permissions, respectively).
> >
> > Ah... I guess we can't do it because we're not in a realm world and so
> > the early checks in __set_memory_enc_dec() would return early and turn
> > it into a no-op.
> >
> > How about if I extract a common helper and provide set_memory_p() and
> > set_memory_np() in terms of those. Those are available on x86 and
> > PowerPC as well, so fairly standard. I suppose at that point we're
> > closer to set_memory_valid().
>
> Why not just call set_direct_map_invalid_noflush() +
> flush_tlb_kernel_range() for each page? We already have APIs for this.
>
> The big challenge I see with any linear map manipulation, however, is
> that it will rely on can_set_direct_map() which likely means you need to
> give up some performance and/or security to make this work. Does memory
> become inaccesible dynamically at runtime? If not, the best bet would
> be to describe it as a carveout in the DT and mark it as "no-map" so
> we avoid mapping it in the first place.
While I got your attention a bit off-topic but still related question.
AFAIK a lot in arm64 drivers ecosystem relies on that ranges defined as
"/reserved-memory" in DT are linked to devices that use that memory.
EFI/ACPI does not have a similar concept.
Given that more and more systems are using EFI/ACPI rather than DT as their
boot protocol we probably need some way to define such memory carveouts in
the ACPI world.
> Will
--
Sincerely yours,
Mike.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox