Linux Trace Kernel
 help / color / mirror / Atom feed
* Re: [PATCH v4 1/5] mm: introduce zone lock wrappers
From: Vlastimil Babka (SUSE) @ 2026-03-02 13:34 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl
In-Reply-To: <849dee9c47df1e6fba97c9933af0d5a08b8e15d3.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Add thin wrappers around zone lock acquire/release operations. This
> prepares the code for future tracepoint instrumentation without
> modifying individual call sites.
> 
> Centralizing zone lock operations behind wrappers allows future
> instrumentation or debugging hooks to be added without touching
> all users.
> 
> No functional change intended. The wrappers are introduced in
> preparation for subsequent patches and are not yet used.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>

*checks patch 2 diffstat*

I think we could do it as mm/zone_lock.h even and not pollute include/linux/
Even kernel/power/snapshot.c could include it in a somewhat ugly way.
However we should also later look at moving that particular code somewhere
under mm/ really...

Anyway,

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>

> ---
>  MAINTAINERS                 |  1 +
>  include/linux/mmzone_lock.h | 38 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+)
>  create mode 100644 include/linux/mmzone_lock.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 55af015174a5..947298ecb111 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16672,6 +16672,7 @@ F:	include/linux/memory.h
>  F:	include/linux/mm.h
>  F:	include/linux/mm_*.h
>  F:	include/linux/mmzone.h
> +F:	include/linux/mmzone_lock.h
>  F:	include/linux/mmdebug.h
>  F:	include/linux/mmu_notifier.h
>  F:	include/linux/pagewalk.h
> diff --git a/include/linux/mmzone_lock.h b/include/linux/mmzone_lock.h
> new file mode 100644
> index 000000000000..a1cfba8408d6
> --- /dev/null
> +++ b/include/linux/mmzone_lock.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _LINUX_MMZONE_LOCK_H
> +#define _LINUX_MMZONE_LOCK_H
> +
> +#include <linux/mmzone.h>
> +#include <linux/spinlock.h>
> +
> +static inline void zone_lock_init(struct zone *zone)
> +{
> +	spin_lock_init(&zone->lock);
> +}
> +
> +#define zone_lock_irqsave(zone, flags)				\
> +do {								\
> +	spin_lock_irqsave(&(zone)->lock, flags);		\
> +} while (0)
> +
> +#define zone_trylock_irqsave(zone, flags)			\
> +({								\
> +	spin_trylock_irqsave(&(zone)->lock, flags);		\
> +})
> +
> +static inline void zone_unlock_irqrestore(struct zone *zone, unsigned long flags)
> +{
> +	spin_unlock_irqrestore(&zone->lock, flags);
> +}
> +
> +static inline void zone_lock_irq(struct zone *zone)
> +{
> +	spin_lock_irq(&zone->lock);
> +}
> +
> +static inline void zone_unlock_irq(struct zone *zone)
> +{
> +	spin_unlock_irq(&zone->lock);
> +}
> +
> +#endif /* _LINUX_MMZONE_LOCK_H */


^ permalink raw reply

* Re: [BUG] RCU stall / hung rcu_gp: process_srcu blocked in synchronize_rcu_normal triggered by perf trace teardown on 7.0.0-rc1
From: Sasha Levin @ 2026-03-02 13:36 UTC (permalink / raw)
  To: Zw Tang, paulmck, peterz, mhiramat
  Cc: Sasha Levin, jiangshanlai, mingo, acme, namhyung, rcu,
	linux-perf-users, linux-trace-kernel, linux-kernel, rostedt,
	mathieu.desnoyers, josh, bigeasy, ast, boqun.feng, mark.rutland
In-Reply-To: <CAPHJ_VLUpgBO7VfF4ih2oy2HDCxvxkHRkryFUjHAm8QTNdF6Sg@mail.gmail.com>

This response was AI-generated by bug-bot. The analysis may contain errors — please verify independently.

## Bug Summary

This is an RCU stall and hung task deadlock on 7.0.0-rc1, triggered by perf trace teardown under perf interrupt storm conditions. The perf subsystem's tracepoint unregistration path now blocks on SRCU (tracepoint_srcu), which in turn blocks on RCU grace period completion, creating a cascading stall when RCU progress is delayed by perf NMI interrupt storms. Severity: system hang (multiple tasks blocked >143s, eventual complete stall).

## Stack Trace Analysis

The bug involves three interacting blocked entities. Here are the decoded stack traces:

**1. repro2 (pid 4086) - blocked in perf trace teardown (close()):**
```
__x64_sys_close
  fput_close_sync
    __fput
      perf_release
        perf_event_release_kernel
          put_event
            __free_event
              perf_trace_destroy
                perf_trace_event_unreg         [kernel/trace/trace_event_perf.c:154]
                  tracepoint_synchronize_unregister [include/linux/tracepoint.h:116]
                    synchronize_srcu(&tracepoint_srcu)
                      __synchronize_srcu
                        wait_for_completion    ← BLOCKED
```

**2. kworker/0:0 (pid 9) and kworker/0:1 (pid 11) - SRCU grace period workers:**
```
Workqueue: rcu_gp process_srcu
process_srcu                                   [kernel/rcu/srcutree.c:1304]
  srcu_advance_state                           [kernel/rcu/srcutree.c:1161]
    try_check_zero                             [kernel/rcu/srcutree.c:1171]
      srcu_readers_active_idx_check            [kernel/rcu/srcutree.c:544]
        synchronize_rcu()                      ← SRCU-fast path, line 569
          synchronize_rcu_normal
            wait_for_completion                ← BLOCKED
```

**3. repro2 (pid 4093) - RCU stall source:**
```
rcu: Tasks blocked on level-0 rcu_node (CPUs 0-1): P4093
task:repro2   state:R  running task
  (running in futex_wake syscall, interrupted by timer IRQ)
  asm_sysvec_apic_timer_interrupt
    irqentry_exit → preempt_schedule_irq → __schedule
      finish_task_switch
```

The trace shows process context for the hung tasks and interrupt context (timer IRQ) for the RCU stall detection. The kworkers are in D (uninterruptible sleep) state, blocked in wait_for_completion() within the SRCU grace period state machine.

## Root Cause Analysis

This is a regression introduced by commit a46023d5616ed ("tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast"), which switched tracepoint read-side protection from preempt_disable()+RCU to SRCU-fast via DEFINE_SRCU_FAST(tracepoint_srcu).

The root cause is a new coupling between SRCU grace period processing and RCU grace period completion that did not exist before. The deadlock chain is:

1. The reproducer creates perf events using tracepoints, then closes them while generating heavy perf interrupt load. The perf NMI interrupt storms ("perf: interrupt took too long" messages escalating from 69ms to 336ms) consume most CPU time, starving RCU quiescent state detection.

2. When the perf fd is closed, perf_trace_event_unreg() (kernel/trace/trace_event_perf.c:154) calls tracepoint_synchronize_unregister() (include/linux/tracepoint.h:116), which now calls synchronize_srcu(&tracepoint_srcu) instead of synchronize_rcu().

3. The SRCU grace period for tracepoint_srcu is processed by process_srcu() running in the rcu_gp workqueue. Because tracepoint_srcu is DEFINE_SRCU_FAST, its srcu_reader_flavor includes SRCU_READ_FLAVOR_FAST, which is part of SRCU_READ_FLAVOR_SLOWGP.

4. In srcu_readers_active_idx_check() (kernel/rcu/srcutree.c:544), when SRCU_READ_FLAVOR_SLOWGP is detected, the function calls synchronize_rcu() (line 569) instead of smp_mb() (line 301 in non-fast path). This is the key design tradeoff of SRCU-fast: faster readers (no smp_mb() on read side) at the cost of slower grace periods (synchronize_rcu() on update side).

5. synchronize_rcu() → synchronize_rcu_normal() → wait_for_completion(), waiting for an RCU grace period to complete. But the RCU grace period is stalled because the perf interrupt storms are preventing CPUs from passing through quiescent states quickly enough.

6. Since process_srcu is blocked waiting for synchronize_rcu(), the tracepoint_srcu SRCU grace period cannot advance, so synchronize_srcu(&tracepoint_srcu) in the perf teardown path also blocks indefinitely.

The pre-existing condition (perf NMI storms causing RCU stalls) was previously tolerable because the perf teardown path used synchronize_rcu() directly (via the old tracepoint_synchronize_unregister()), which would eventually complete once the RCU stall resolved. Now, with SRCU-fast, there is an additional layer of indirection: perf teardown waits on SRCU, SRCU processing waits on RCU, and both the SRCU workqueue threads and the perf teardown task are stuck.

## Affected Versions

This is a regression in v7.0-rc1. The bug was introduced by commit a46023d5616ed ("tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast"), which was merged via the trace-v7.0 merge (3c6e577d5ae70). The underlying SRCU-fast infrastructure was added by commit c4020620528e4 ("srcu: Add SRCU-fast readers") and 4d86b1e7e1e98 ("srcu: Add SRCU_READ_FLAVOR_SLOWGP to flag need for synchronize_rcu()"), but the regression became triggerable only when a46023d5616ed applied SRCU-fast to the tracepoint_srcu used in the perf event teardown path.

Kernels before v7.0-rc1 (i.e., v6.x and earlier) are not affected, as they used preempt_disable()+RCU for tracepoint protection, and tracepoint_synchronize_unregister() called synchronize_rcu() directly without SRCU involvement.

## Relevant Commits and Fixes

Key commits in the causal chain:

- a46023d5616ed ("tracing: Guard __DECLARE_TRACE() use of __DO_TRACE_CALL() with SRCU-fast") - the commit that introduced the regression by switching tracepoints to SRCU-fast
- a77cb6a867667 ("srcu: Fix warning to permit SRCU-fast readers in NMI handlers") - immediate predecessor fix
- c4020620528e4 ("srcu: Add SRCU-fast readers") - added the SRCU-fast reader API
- 4d86b1e7e1e98 ("srcu: Add SRCU_READ_FLAVOR_SLOWGP to flag need for synchronize_rcu()") - added the synchronize_rcu()-instead-of-smp_mb() logic in SRCU grace period processing
- 16718274ee75d ("tracing: perf: Have perf tracepoint callbacks always disable preemption") - preparatory commit for the SRCU-fast switch

No fix for this specific issue was found in mainline or in any -next branches as of today.

## Prior Discussions

No prior reports of this specific RCU stall / SRCU deadlock triggered via perf trace teardown with SRCU-fast were found on lore.kernel.org. The original SRCU-fast tracepoint series was posted at https://lore.kernel.org/all/20260126231256.499701982@kernel.org/ (linked from the commit message), motivated by enabling preemptible BPF on tracepoints for RT systems (https://lore.kernel.org/all/20250613152218.1924093-1-bigeasy@linutronix.de/). No discussion of the synchronize_rcu()-from-workqueue stall scenario appears to have taken place in those threads.

## Suggested Actions

1. Confirm the regression by testing with the parent commit a77cb6a867667 (immediately before a46023d5616ed). If the issue disappears, this confirms the SRCU-fast tracepoint switch as the cause.

2. As a quick workaround, reverting a46023d5616ed (and its preparatory commits a77cb6a867667, f7d327654b886, 16718274ee75d if needed) should eliminate the deadlock, at the cost of losing preemptible BPF tracepoint support.

3. The fundamental issue is that process_srcu() for SRCU-fast structures calls synchronize_rcu() synchronously from workqueue context. Possible fixes include:
   - Using an asynchronous mechanism (e.g., call_rcu() with a callback to resume SRCU GP processing) instead of blocking synchronize_rcu() within the SRCU state machine.
   - Having srcu_readers_active_idx_check() use poll_state_synchronize_rcu() and defer retrying instead of blocking.
   - Bounding the perf interrupt rate escalation to prevent the RCU stall in the first place (though this would only mask the underlying SRCU↔RCU coupling issue).

4. If you can reproduce reliably, adding the following debug options would provide more information: CONFIG_RCU_TRACE=y, CONFIG_PROVE_RCU=y, and booting with rcutree.rcu_kick_kthreads=1 to see if kicking the RCU threads helps break the stall.


^ permalink raw reply

* Re: [PATCH v4 2/5] mm: convert zone lock users to wrappers
From: Vlastimil Babka (SUSE) @ 2026-03-02 13:42 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, SeongJae Park
In-Reply-To: <d26a43ebed2f0f1edb9cfe4fbed16dd31c7a069c.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Replace direct zone lock acquire/release operations with the
> newly introduced wrappers.
> 
> The changes are purely mechanical substitutions. No functional change
> intended. Locking semantics and ordering remain unchanged.
> 
> The compaction path is left unchanged for now and will be
> handled separately in the following patch due to additional
> non-trivial modifications.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> Reviewed-by: SeongJae Park <sj@kernel.org>

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [PATCH v6 05/16] Documentation/rv: Add documentation about hybrid automata
From: Juri Lelli @ 2026-03-02 13:58 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Jonathan Corbet, linux-trace-kernel, linux-doc, Tomas Glozar,
	Clark Williams, John Kacur
In-Reply-To: <20260225095122.80683-6-gmonaco@redhat.com>

Hello,

On 25/02/26 10:51, Gabriele Monaco wrote:
> Describe theory and implementation of hybrid automata in the dedicated
> page hybrid_automata.rst
> Include a section on how to integrate a hybrid automaton in
> monitor_synthesis.rst
> Also remove a hanging $ in deterministic_automata.rst
> 
> Reviewed-by: Nam Cao <namcao@linutronix.de>
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
> ---

...

> diff --git a/Documentation/trace/rv/hybrid_automata.rst b/Documentation/trace/rv/hybrid_automata.rst
> new file mode 100644
> index 000000000000..39c037a71b89
> --- /dev/null
> +++ b/Documentation/trace/rv/hybrid_automata.rst
> @@ -0,0 +1,341 @@
> +Hybrid Automata
> +===============

...

> +Stall model with invariants (iteration 2)
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The first iteration isn't exactly what was intended, we can change the model as:
> +
> +- *X* = { ``dequeued``, ``enqueued``, ``running``}
> +- *E* = { ``enqueue``, ``dequeue``, ``switch_in``}
> +- *V* = { ``clk`` }
> +- x\ :subscript:`0` = ``dequeue``
> +- X\ :subscript:`m` = {``dequeue``}
> +- *f* =
> +   - *f*\ (``enqueued``, ``switch_in``) = ``running``
> +   - *f*\ (``running``, ``dequeue``) = ``dequeued``
> +   - *f*\ (``dequeued``, ``enqueue``, ``reset(clk)``) = ``enqueued``
                              ^^^

> +- *i* =
> +   - *i*\ (``enqueued``) = ``clk < threshold``
> +
> +Graphically::
> +
> +    |
> +    |
> +    v
> +  #=========================#
> +  H        dequeued         H <+
> +  #=========================#  |
> +    |                          |
> +    | enqueue; reset(clk)      |
> +    v                          |
> +  +-------------------------+  |
> +  |        enqueued         |  |
> +  |    clk < threshold      |  | dequeue
> +  +-------------------------+  |
> +    |                          |
> +    | switch_in                |
> +    v                          |
> +  +-------------------------+  |
> +  |         running         | -+
> +  +-------------------------+

...

> +  static bool verify_constraint(enum states curr_state, enum events event,
> +                                enum states next_state)
> +  {
> +	bool res = true;
> +
> +	/* Validate guards as part of f */
> +	if (curr_state == enqueued && event == sched_switch_in)
> +		res = get_env(clk) < threshold;
> +	else if (curr_state == dequeued && event == sched_wakeup)
> +		reset_env(clk);

Considering the spec above, does the 'event' need to be 'enqueue'
instead of 'sched_wakeup' (or the other way around)? Or maybe it's
equivalent?

Thanks,
Juri


^ permalink raw reply

* Re: [PATCH v4 3/5] mm: convert compaction to zone lock wrappers
From: Vlastimil Babka (SUSE) @ 2026-03-02 14:02 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl
In-Reply-To: <3a09e46f52cf9f709b0725bc2b648cc5212843b2.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Compaction uses compact_lock_irqsave(), which currently operates
> on a raw spinlock_t pointer so it can be used for both zone->lock
> and lruvec->lru_lock. Since zone lock operations are now wrapped,
> compact_lock_irqsave() can no longer directly operate on a
> spinlock_t when the lock belongs to a zone.
> 
> Split the helper into compact_zone_lock_irqsave() and
> compact_lruvec_lock_irqsave(), duplicating the small amount of
> shared logic. As there are only two call sites and both statically
> know the lock type, this avoids introducing additional abstraction
> or runtime dispatch in the compaction path.
> 
> No functional change intended.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [PATCH v4 4/5] mm: rename zone->lock to zone->_lock
From: Vlastimil Babka (SUSE) @ 2026-03-02 14:10 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl, SeongJae Park
In-Reply-To: <d61500c5784c64e971f4d328c57639303c475f81.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> This intentionally breaks direct users of zone->lock at compile time so
> all call sites are converted to the zone lock wrappers. Without the
> rename, present and future out-of-tree code could continue using
> spin_lock(&zone->lock) and bypass the wrappers and tracing
> infrastructure.
> 
> No functional change intended.
> 
> Suggested-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> Acked-by: SeongJae Park <sj@kernel.org>

I see some more instances of 'zone->lock' in comments in
include/linux/mmzone.h and under Documentation/ but otherwise LGTM.

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [PATCH v6 12/16] sched: Add deadline tracepoints
From: Juri Lelli @ 2026-03-02 14:15 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Masami Hiramatsu, Ingo Molnar, Peter Zijlstra, linux-trace-kernel,
	Phil Auld, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <20260225095122.80683-13-gmonaco@redhat.com>

Hello,

On 25/02/26 10:51, Gabriele Monaco wrote:
> Add the following tracepoints:
> 
> * sched_dl_throttle(dl_se, cpu, type):
>     Called when a deadline entity is throttled
> * sched_dl_replenish(dl_se, cpu, type):
>     Called when a deadline entity's runtime is replenished
> * sched_dl_update(dl_se, cpu, type):
>     Called when a deadline entity updates without throttle or replenish
> * sched_dl_server_start(dl_se, cpu, type):
>     Called when a deadline server is started
> * sched_dl_server_stop(dl_se, cpu, type):
>     Called when a deadline server is stopped
> 
> Those tracepoints can be useful to validate the deadline scheduler with
> RV and are not exported to tracefs.
> 
> Reviewed-by: Phil Auld <pauld@redhat.com>
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
> ---
> 
> Notes:
>     V6:
>     * Add dl_se type to differentiate between fair and ext servers
>     * Add event to track dl_update_curr not firing other events
>     V3:
>     * Rename dl argument to dl_se in tracepoints
> 
>  include/trace/events/sched.h | 26 ++++++++++++++++++++++++++
>  kernel/sched/core.c          |  4 ++++
>  kernel/sched/deadline.c      | 25 ++++++++++++++++++++++++-
>  3 files changed, 54 insertions(+), 1 deletion(-)
> 
> diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
> index 5844147ec5fd..944d65750a64 100644
> --- a/include/trace/events/sched.h
> +++ b/include/trace/events/sched.h
> @@ -904,6 +904,32 @@ DECLARE_TRACE(sched_dequeue,
>  	TP_PROTO(struct task_struct *tsk, int cpu),
>  	TP_ARGS(tsk, cpu));
>  
> +#define DL_OTHER 0
> +#define DL_TASK 1
> +#define DL_SERVER_FAIR 2
> +#define DL_SERVER_EXT 3
> +
> +DECLARE_TRACE(sched_dl_throttle,
> +	TP_PROTO(struct sched_dl_entity *dl_se, int cpu, uint8_t type),
> +	TP_ARGS(dl_se, cpu, type));
> +
> +DECLARE_TRACE(sched_dl_replenish,
> +	TP_PROTO(struct sched_dl_entity *dl_se, int cpu, uint8_t type),
> +	TP_ARGS(dl_se, cpu, type));
> +
> +/* Call to update_curr_dl_se not involving throttle or replenish */
> +DECLARE_TRACE(sched_dl_update,
> +	TP_PROTO(struct sched_dl_entity *dl_se, int cpu, uint8_t type),
> +	TP_ARGS(dl_se, cpu, type));
> +
> +DECLARE_TRACE(sched_dl_server_start,
> +	TP_PROTO(struct sched_dl_entity *dl_se, int cpu, uint8_t type),
> +	TP_ARGS(dl_se, cpu, type));
> +
> +DECLARE_TRACE(sched_dl_server_stop,
> +	TP_PROTO(struct sched_dl_entity *dl_se, int cpu, uint8_t type),
> +	TP_ARGS(dl_se, cpu, type));
> +
>  #endif /* _TRACE_SCHED_H */
>  
>  /* This part must be outside protection */
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 4ca79ff58fca..b5bb2eb112bf 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -124,6 +124,10 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_exit_tp);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_set_need_resched_tp);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_enqueue_tp);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dequeue_tp);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_throttle_tp);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_replenish_tp);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_server_start_tp);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_server_stop_tp);

Don't we need to export sched_dl_update_tp as well?

>  DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
>  DEFINE_PER_CPU(struct rnd_state, sched_rnd_state);

...

> @@ -1532,7 +1551,8 @@ static void update_curr_dl_se(struct rq *rq, struct sched_dl_entity *dl_se, s64
>  
>  		if (!is_leftmost(dl_se, &rq->dl))
>  			resched_curr(rq);
> -	}
> +	} else
> +		trace_sched_dl_update_tp(dl_se, cpu_of(rq), dl_get_type(dl_se, rq));

This wants braces even if it's a single statement.

>  
>  	/*
>  	 * The dl_server does not account for real-time workload because it

Thanks,
Juri


^ permalink raw reply

* Re: [PATCH v4 5/5] mm: add tracepoints for zone lock
From: Vlastimil Babka (SUSE) @ 2026-03-02 14:16 UTC (permalink / raw)
  To: Dmitry Ilvokhin, Andrew Morton, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Rafael J. Wysocki, Pavel Machek, Len Brown, Brendan Jackman,
	Johannes Weiner, Zi Yan, Oscar Salvador, Qi Zheng, Shakeel Butt
  Cc: linux-kernel, linux-mm, linux-trace-kernel, linux-pm,
	"linux-cxl
In-Reply-To: <ae145fe890f028409f727b4921904b547346fa0b.1772206930.git.d@ilvokhin.com>

On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> Add tracepoint instrumentation to zone lock acquire/release operations
> via the previously introduced wrappers.
> 
> The implementation follows the mmap_lock tracepoint pattern: a
> lightweight inline helper checks whether the tracepoint is enabled and
> calls into an out-of-line helper when tracing is active. When
> CONFIG_TRACING is disabled, helpers compile to empty inline stubs.
> 
> The fast path is unaffected when tracing is disabled.
> 
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> Acked-by: Shakeel Butt <shakeel.butt@linux.dev>

Agree with Steven; otherwise

Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>


^ permalink raw reply

* Re: [PATCH v6 05/16] Documentation/rv: Add documentation about hybrid automata
From: Gabriele Monaco @ 2026-03-02 14:23 UTC (permalink / raw)
  To: Juri Lelli
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Jonathan Corbet, linux-trace-kernel, linux-doc, Tomas Glozar,
	Clark Williams, John Kacur
In-Reply-To: <aaWXmBVIvTlVtiRp@jlelli-thinkpadt14gen4.remote.csb>

Hello,

On Mon, 2026-03-02 at 14:58 +0100, Juri Lelli wrote:
> Considering the spec above, does the 'event' need to be 'enqueue'
> instead of 'sched_wakeup' (or the other way around)? Or maybe it's
> equivalent?

Good catch, in fact enqueue/dequeue don't work well for this model (the actual
stall monitor uses wakeup), but for the sake of the, already simplified, example
I should keep it consistent.

Thanks,
Gabriele


^ permalink raw reply

* Re: [PATCH v6 12/16] sched: Add deadline tracepoints
From: Gabriele Monaco @ 2026-03-02 14:24 UTC (permalink / raw)
  To: Juri Lelli
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Masami Hiramatsu, Ingo Molnar, Peter Zijlstra, linux-trace-kernel,
	Phil Auld, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <aaWblsXCWP-L0WbB@jlelli-thinkpadt14gen4.remote.csb>

Hello,

On Mon, 2026-03-02 at 15:15 +0100, Juri Lelli wrote:
> > diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> > index 4ca79ff58fca..b5bb2eb112bf 100644
> > --- a/kernel/sched/core.c
> > +++ b/kernel/sched/core.c
> > @@ -124,6 +124,10 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_exit_tp);
> >  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_set_need_resched_tp);
> >  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_enqueue_tp);
> >  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dequeue_tp);
> > +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_throttle_tp);
> > +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_replenish_tp);
> > +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_server_start_tp);
> > +EXPORT_TRACEPOINT_SYMBOL_GPL(sched_dl_server_stop_tp);
> 
> Don't we need to export sched_dl_update_tp as well?

Right, we do.

> 
> >  DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
> >  DEFINE_PER_CPU(struct rnd_state, sched_rnd_state);
> 
> ...
> 
> > @@ -1532,7 +1551,8 @@ static void update_curr_dl_se(struct rq *rq, struct
> > sched_dl_entity *dl_se, s64
> >  
> >  		if (!is_leftmost(dl_se, &rq->dl))
> >  			resched_curr(rq);
> > -	}
> > +	} else
> > +		trace_sched_dl_update_tp(dl_se, cpu_of(rq),
> > dl_get_type(dl_se, rq));
> 
> This wants braces even if it's a single statement.

Alright, will fix.

Thanks,
Gabriele


^ permalink raw reply

* Re: [PATCH v3 07/18] rtla: Add strscpy() and replace strncpy() calls
From: Tomas Glozar @ 2026-03-02 14:33 UTC (permalink / raw)
  To: Wander Lairson Costa
  Cc: Steven Rostedt, Crystal Wood, Ivan Pravdin, Costa Shulyupin,
	John Kacur, Tiezhu Yang, Haiyong Sun, Daniel Wagner,
	Daniel Bristot de Oliveira,
	open list:Real-time Linux Analysis (RTLA) tools,
	open list:Real-time Linux Analysis (RTLA) tools,
	open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260115163650.118910-8-wander@redhat.com>

čt 15. 1. 2026 v 18:26 odesílatel Wander Lairson Costa
<wander@redhat.com> napsal:
>
> Introduce a userspace strscpy() implementation that matches the Linux
> kernel's strscpy() semantics. The function is built on top of glibc's
> strlcpy() and provides guaranteed NUL-termination along with proper
> truncation detection through its return value.
>
> The previous strncpy() calls had potential issues: strncpy() does not
> guarantee NUL-termination when the source string length equals or
> exceeds the destination buffer size. This required defensive patterns
> like pre-zeroing buffers or manually setting the last byte to NUL.
> The new strscpy() function always NUL-terminates the destination buffer
> unless the size is zero, and returns -E2BIG on truncation, making error
> handling cleaner and more consistent with kernel code.
>
> Note that unlike the kernel's strscpy(), this implementation uses
> strlcpy() internally, which reads the entire source string to determine
> its length. The kernel avoids this to prevent potential DoS attacks from
> extremely long untrusted strings. This is harmless for a userspace CLI
> tool like rtla where input sources are bounded and trusted.
>

strlcpy() was only added in glibc 2.38 [1]. It is thus not available
on systems with older glibc, like RHEL 9. Using it for strscpy()
implementation causes RTLA to fail to build on those systems.

[1] https://www.gnu.org/software/gnulib/manual/html_node/strlcpy.html

> Replace all strncpy() calls in rtla with strscpy(), using sizeof() for
> buffer sizes instead of magic constants to ensure the sizes stay in
> sync with the actual buffer declarations. Also remove a now-redundant
> memset() call that was previously needed to work around strncpy()
> behavior.
>
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
> ---
>  tools/tracing/rtla/src/timerlat_aa.c |  6 ++---
>  tools/tracing/rtla/src/utils.c       | 34 ++++++++++++++++++++++++++--
>  tools/tracing/rtla/src/utils.h       |  1 +
>  3 files changed, 36 insertions(+), 5 deletions(-)
>

Tomas


^ permalink raw reply

* Re: [PATCH v6 15/16] rv: Add deadline monitors
From: Juri Lelli @ 2026-03-02 14:37 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Jonathan Corbet, Masami Hiramatsu, linux-trace-kernel, linux-doc,
	Peter Zijlstra, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <20260225095122.80683-16-gmonaco@redhat.com>

Hello,

On 25/02/26 10:51, Gabriele Monaco wrote:
> Add the deadline monitors collection to validate the deadline scheduler,
> both for deadline tasks and servers.
> 
> The currently implemented monitors are:
> * throttle:
>     validate dl entities are throttled when they use up their runtime
> * nomiss:
>     validate dl entities run to completion before their deadiline
> 
> Cc: Peter Zijlstra <peterz@infradead.org>
> Reviewed-by: Nam Cao <namcao@linutronix.de>
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
> ---

...

> +static inline int extract_params(struct pt_regs *regs, long id, struct task_struct **p)
> +{
> +	size_t size = offsetof(struct sched_attr, sched_nice);
> +	struct sched_attr __user *uattr, attr;
> +	int new_policy = -1, ret;
> +	unsigned long args[6];
> +	pid_t pid;
> +
> +	switch (id) {
> +	case __NR_sched_setscheduler:
> +		syscall_get_arguments(current, regs, args);
> +		pid = args[0];
> +		new_policy = args[1];
> +		break;
> +	case __NR_sched_setattr:
> +		syscall_get_arguments(current, regs, args);
> +		pid = args[0];
> +		uattr = (void *)args[1];
> +		/*
> +		 * Just copy up to sched_flags, we are not interested after that
> +		 */
> +		ret = copy_struct_from_user(&attr, size, uattr, size);
> +		if (ret)
> +			return ret;
> +		if (attr.sched_flags & SCHED_FLAG_KEEP_POLICY)
> +			return -EINVAL;
> +		new_policy = attr.sched_policy;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	if (!pid)
> +		*p = current;
> +	else {
> +		/*
> +		 * Required for find_task_by_vpid, make sure the caller doesn't
> +		 * need to get_task_struct().
> +		 */
> +		guard(rcu)();
> +		*p = find_task_by_vpid(pid);
> +		if (unlikely(!*p))
> +			return -EINVAL;
> +	}

Not sure I get this comment. RCU is released when the function returns,
but then the task pointer is dereferenced by callers?

Thanks,
Juri


^ permalink raw reply

* Re: [PATCHv6 bpf-next 9/9] bpf,x86: Use single ftrace_ops for direct calls
From: Steven Rostedt @ 2026-03-02 15:10 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Ihor Solodrai, Florent Revest, Mark Rutland, bpf, linux-kernel,
	linux-trace-kernel, linux-arm-kernel, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Menglong Dong, Song Liu,
	Kumar Kartikeya Dwivedi
In-Reply-To: <aaVFeafZb76l9L0m@krava>

On Mon, 2 Mar 2026 09:08:25 +0100
Jiri Olsa <olsajiri@gmail.com> wrote:

> > As there's nothing after the comment and before the end of the block.  
> 
> ok, will do.. the original changes:
> 
>   05dc5e9c1fe1 ("ftrace: Add update_ftrace_direct_add function")
>   8d2c1233f371 ("ftrace: Add update_ftrace_direct_del function")
> 
> went through bpf tree, so I'll send the fix the same way,
> please let me know otherwise

As long as I give a reviewed-by tag.

Thanks,

-- Steve

^ permalink raw reply

* Re: [PATCH] mm: add Adaptive Memory Pressure Signaling (AMPRESS)
From: Johannes Weiner @ 2026-03-02 15:11 UTC (permalink / raw)
  To: Andre Ramos
  Cc: akpm, linux-mm, linux-kernel, linux-trace-kernel, david, rostedt
In-Reply-To: <CALXtAv3u1hgLkBEbEgR3=r_iz3=KrnHB8B-=tg8Q3CEOWAPFiA@mail.gmail.com>

On Mon, Mar 02, 2026 at 12:45:33AM -0300, Andre Ramos wrote:
> Introduce /dev/ampress, a bidirectional fd-based interface for
> cooperative memory reclaim between the kernel and userspace.
> 
> Userspace processes open /dev/ampress and block on read() to receive
> struct ampress_event notifications carrying a graduated urgency level
> (LOW/MEDIUM/HIGH/FATAL), the NUMA node of the pressure source, and a
> suggested reclaim target in KiB. After freeing memory the process
> issues AMPRESS_IOC_ACK to close the feedback loop.
> 
> The feature hooks into balance_pgdat() in mm/vmscan.c, mapping the
> kswapd scan priority to urgency bands:
>   priority 10-12 -> LOW
>   priority  7-9  -> MEDIUM
>   priority  4-6  -> HIGH
>   priority  1-3  -> FATAL

The scan priority is not a good proxy for pressure. We actually export
reclaim efficiency-based pressure levels like this in memory cgroups
v1, but they're being deprecated[1] in favor of PSI [2].

What are you trying to accomplish?

[1] 340afb8027fa ("memcg: initiate deprecation of pressure_level")
[2] Documentation/accounting/psi.rst

^ permalink raw reply

* Re: [PATCH v6 15/16] rv: Add deadline monitors
From: Gabriele Monaco @ 2026-03-02 15:11 UTC (permalink / raw)
  To: Juri Lelli
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Jonathan Corbet, Masami Hiramatsu, linux-trace-kernel, linux-doc,
	Peter Zijlstra, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <aaWgvBXaNg48qYRl@jlelli-thinkpadt14gen4.remote.csb>

On Mon, 2026-03-02 at 15:37 +0100, Juri Lelli wrote:
> > +	if (!pid)
> > +		*p = current;
> > +	else {
> > +		/*
> > +		 * Required for find_task_by_vpid, make sure the caller
> > doesn't
> > +		 * need to get_task_struct().
> > +		 */
> > +		guard(rcu)();
> > +		*p = find_task_by_vpid(pid);
> > +		if (unlikely(!*p))
> > +			return -EINVAL;
> > +	}
> 
> Not sure I get this comment. RCU is released when the function returns,
> but then the task pointer is dereferenced by callers?

The idea was that the caller should ensure there's no need to do
get_task_struct() (which is fine within the syscall, I'm assuming).

But looking at it again, that's not even necessary as long as the caller locked
RCU, which they should do instead of guarding here.

So yeah, the comment is misleading and I should just do:

  guard(rcu)();
  extract_params(...);

Thanks for the observation,
Gabriele


^ permalink raw reply

* [PATCH 6.12.y] x86/uprobes: Fix XOL allocation failure for 32-bit tasks
From: Oleg Nesterov @ 2026-03-02 15:14 UTC (permalink / raw)
  To: Sasha Levin
  Cc: stable, Paulo Andrade, Peter Zijlstra (Intel), linux-trace-kernel,
	linux-perf-users
In-Reply-To: <20260301012146.1677811-1-sashal@kernel.org>

[ Upstream commit d55c571e4333fac71826e8db3b9753fadfbead6a ]

This script

	#!/usr/bin/bash

	echo 0 > /proc/sys/kernel/randomize_va_space

	echo 'void main(void) {}' > TEST.c

	# -fcf-protection to ensure that the 1st endbr32 insn can't be emulated
	gcc -m32 -fcf-protection=branch TEST.c -o test

	bpftrace -e 'uprobe:./test:main {}' -c ./test

"hangs", the probed ./test task enters an endless loop.

The problem is that with randomize_va_space == 0
get_unmapped_area(TASK_SIZE - PAGE_SIZE) called by xol_add_vma() can not
just return the "addr == TASK_SIZE - PAGE_SIZE" hint, this addr is used
by the stack vma.

arch_get_unmapped_area_topdown() doesn't take TIF_ADDR32 into account and
in_32bit_syscall() is false, this leads to info.high_limit > TASK_SIZE.
vm_unmapped_area() happily returns the high address > TASK_SIZE and then
get_unmapped_area() returns -ENOMEM after the "if (addr > TASK_SIZE - len)"
check.

handle_swbp() doesn't report this failure (probably it should) and silently
restarts the probed insn. Endless loop.

I think that the right fix should change the x86 get_unmapped_area() paths
to rely on TIF_ADDR32 rather than in_32bit_syscall(). Note also that if
CONFIG_X86_X32_ABI=y, in_x32_syscall() falsely returns true in this case
because ->orig_ax = -1.

But we need a simple fix for -stable, so this patch just sets TS_COMPAT if
the probed task is 32-bit to make in_ia32_syscall() true.

Fixes: 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: Paulo Andrade <pandrade@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/aV5uldEvV7pb4RA8@redhat.com/
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/aWO7Fdxn39piQnxu@redhat.com
---
 arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
 include/linux/uprobes.h   |  1 +
 kernel/events/uprobes.c   | 10 +++++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 9194695662b2..6abb25ca9cd1 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -1223,3 +1223,27 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
 	else
 		return regs->sp <= ret->stack;
 }
+
+#ifdef CONFIG_IA32_EMULATION
+unsigned long arch_uprobe_get_xol_area(void)
+{
+	struct thread_info *ti = current_thread_info();
+	unsigned long vaddr;
+
+	/*
+	 * HACK: we are not in a syscall, but x86 get_unmapped_area() paths
+	 * ignore TIF_ADDR32 and rely on in_32bit_syscall() to calculate
+	 * vm_unmapped_area_info.high_limit.
+	 *
+	 * The #ifdef above doesn't cover the CONFIG_X86_X32_ABI=y case,
+	 * but in this case in_32bit_syscall() -> in_x32_syscall() always
+	 * (falsely) returns true because ->orig_ax == -1.
+	 */
+	if (test_thread_flag(TIF_ADDR32))
+		ti->status |= TS_COMPAT;
+	vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+	ti->status &= ~TS_COMPAT;
+
+	return vaddr;
+}
+#endif
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index d0cb0e02cd6a..34be2d579045 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -146,6 +146,7 @@ extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 extern void uprobe_handle_trampoline(struct pt_regs *regs);
 extern void *arch_uprobe_trampoline(unsigned long *psize);
 extern unsigned long uprobe_get_trampoline_vaddr(void);
+extern unsigned long arch_uprobe_get_xol_area(void);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index e30c4dd345f4..80cd12eb5854 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1496,6 +1496,12 @@ static const struct vm_special_mapping xol_mapping = {
 	.fault = xol_fault,
 };
 
+unsigned long __weak arch_uprobe_get_xol_area(void)
+{
+	/* Try to map as high as possible, this is only a hint. */
+	return get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+}
+
 /* Slot allocation for XOL */
 static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 {
@@ -1511,9 +1517,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 	}
 
 	if (!area->vaddr) {
-		/* Try to map as high as possible, this is only a hint. */
-		area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
-						PAGE_SIZE, 0, 0);
+		area->vaddr = arch_uprobe_get_xol_area();
 		if (IS_ERR_VALUE(area->vaddr)) {
 			ret = area->vaddr;
 			goto fail;
-- 
2.52.0



^ permalink raw reply related

* Re: [PATCH v4 5/5] mm: add tracepoints for zone lock
From: Dmitry Ilvokhin @ 2026-03-02 15:18 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Axel Rasmussen, Yuanchu Xie,
	Wei Xu, Masami Hiramatsu, Mathieu Desnoyers, Rafael J. Wysocki,
	Pavel Machek, Len Brown, Brendan Jackman, Johannes Weiner, Zi Yan,
	Oscar Salvador, Qi Zheng, Shakeel Butt, linux-kernel, linux-mm,
	linux-trace-kernel, linux-pm
In-Reply-To: <20260227144649.3dbff742@gandalf.local.home>

On Fri, Feb 27, 2026 at 02:46:49PM -0500, Steven Rostedt wrote:
> On Fri, 27 Feb 2026 16:00:27 +0000
> Dmitry Ilvokhin <d@ilvokhin.com> wrote:
> 
> >  static inline void zone_lock_init(struct zone *zone)
> >  {
> > @@ -12,26 +59,41 @@ static inline void zone_lock_init(struct zone *zone)
> >  
> >  #define zone_lock_irqsave(zone, flags)				\
> >  do {								\
> > +	bool success = true;					\
> > +								\
> > +	__zone_lock_trace_start_locking(zone);			\
> >  	spin_lock_irqsave(&(zone)->_lock, flags);		\
> > +	__zone_lock_trace_acquire_returned(zone, success);	\
> 
> Why the "success" variable and not just:
> 
> 	__zone_lock_trace_acquire_returned(zone, true);
> 
>  ?

Good point, passing true directly is cleaner. Happy to respin if needed.

^ permalink raw reply

* Re: [PATCH v4 2/5] mm: convert zone lock users to wrappers
From: Dmitry Ilvokhin @ 2026-03-02 15:22 UTC (permalink / raw)
  To: David Hildenbrand (Arm)
  Cc: Andrew Morton, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
	Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Axel Rasmussen,
	Yuanchu Xie, Wei Xu, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, Rafael J. Wysocki, Pavel Machek, Len Brown,
	Brendan Jackman, Johannes Weiner, Zi Yan, Oscar Salvador,
	Qi Zheng, Shakeel Butt, linux-kernel, linux-mm,
	linux-trace-kernel, linux-pm, SeongJae Park
In-Reply-To: <7e93021d-53dd-4162-97e6-3bca1f46a0c6@kernel.org>

On Fri, Feb 27, 2026 at 09:39:11PM +0100, David Hildenbrand (Arm) wrote:
> On 2/27/26 17:00, Dmitry Ilvokhin wrote:
> > Replace direct zone lock acquire/release operations with the
> > newly introduced wrappers.
> > 
> > The changes are purely mechanical substitutions. No functional change
> > intended. Locking semantics and ordering remain unchanged.
> > 
> > The compaction path is left unchanged for now and will be
> > handled separately in the following patch due to additional
> > non-trivial modifications.
> > 
> > Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> > Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
> > Reviewed-by: SeongJae Park <sj@kernel.org>
> > ---
> 
> [...]
> 
> >  #ifdef CONFIG_COMPACTION
> > @@ -530,11 +531,14 @@ static bool compact_lock_irqsave(spinlock_t *lock, unsigned long *flags,
> >   * Returns true if compaction should abort due to fatal signal pending.
> >   * Returns false when compaction can continue.
> >   */
> > -static bool compact_unlock_should_abort(spinlock_t *lock,
> > -		unsigned long flags, bool *locked, struct compact_control *cc)
> > +
> > +static bool compact_unlock_should_abort(struct zone *zone,
> > +					unsigned long flags,
> > +					bool *locked,
> > +					struct compact_control *cc)
> 
> We tend to use two-tabs on second parameter line; like the existing code
> did.
> 
> 
> Besides that
> 
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> 

Thanks, David. Noted. Appreciate the review and ack.

> -- 
> Cheers,
> 
> David

^ permalink raw reply

* [PATCH 6.6.y] x86/uprobes: Fix XOL allocation failure for 32-bit tasks
From: Oleg Nesterov @ 2026-03-02 15:29 UTC (permalink / raw)
  To: Sasha Levin
  Cc: stable, Paulo Andrade, Peter Zijlstra (Intel), linux-trace-kernel,
	linux-perf-users
In-Reply-To: <20260301013253.1692011-1-sashal@kernel.org>

[ Upstream commit d55c571e4333fac71826e8db3b9753fadfbead6a ]

This script

	#!/usr/bin/bash

	echo 0 > /proc/sys/kernel/randomize_va_space

	echo 'void main(void) {}' > TEST.c

	# -fcf-protection to ensure that the 1st endbr32 insn can't be emulated
	gcc -m32 -fcf-protection=branch TEST.c -o test

	bpftrace -e 'uprobe:./test:main {}' -c ./test

"hangs", the probed ./test task enters an endless loop.

The problem is that with randomize_va_space == 0
get_unmapped_area(TASK_SIZE - PAGE_SIZE) called by xol_add_vma() can not
just return the "addr == TASK_SIZE - PAGE_SIZE" hint, this addr is used
by the stack vma.

arch_get_unmapped_area_topdown() doesn't take TIF_ADDR32 into account and
in_32bit_syscall() is false, this leads to info.high_limit > TASK_SIZE.
vm_unmapped_area() happily returns the high address > TASK_SIZE and then
get_unmapped_area() returns -ENOMEM after the "if (addr > TASK_SIZE - len)"
check.

handle_swbp() doesn't report this failure (probably it should) and silently
restarts the probed insn. Endless loop.

I think that the right fix should change the x86 get_unmapped_area() paths
to rely on TIF_ADDR32 rather than in_32bit_syscall(). Note also that if
CONFIG_X86_X32_ABI=y, in_x32_syscall() falsely returns true in this case
because ->orig_ax = -1.

But we need a simple fix for -stable, so this patch just sets TS_COMPAT if
the probed task is 32-bit to make in_ia32_syscall() true.

Fixes: 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: Paulo Andrade <pandrade@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/aV5uldEvV7pb4RA8@redhat.com/
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/aWO7Fdxn39piQnxu@redhat.com
---
 arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
 include/linux/uprobes.h   |  1 +
 kernel/events/uprobes.c   | 10 +++++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 6402fb3089d2..aac2a2c5c6c5 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -1102,3 +1102,27 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
 	else
 		return regs->sp <= ret->stack;
 }
+
+#ifdef CONFIG_IA32_EMULATION
+unsigned long arch_uprobe_get_xol_area(void)
+{
+	struct thread_info *ti = current_thread_info();
+	unsigned long vaddr;
+
+	/*
+	 * HACK: we are not in a syscall, but x86 get_unmapped_area() paths
+	 * ignore TIF_ADDR32 and rely on in_32bit_syscall() to calculate
+	 * vm_unmapped_area_info.high_limit.
+	 *
+	 * The #ifdef above doesn't cover the CONFIG_X86_X32_ABI=y case,
+	 * but in this case in_32bit_syscall() -> in_x32_syscall() always
+	 * (falsely) returns true because ->orig_ax == -1.
+	 */
+	if (test_thread_flag(TIF_ADDR32))
+		ti->status |= TS_COMPAT;
+	vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+	ti->status &= ~TS_COMPAT;
+
+	return vaddr;
+}
+#endif
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index d91e32aff5a1..a5ec2b024a22 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -140,6 +140,7 @@ extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check c
 extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs);
 extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 					 void *src, unsigned long len);
+extern unsigned long arch_uprobe_get_xol_area(void);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 6304238293ae..3b96952bd6ec 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1449,6 +1449,12 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
 		set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
 }
 
+unsigned long __weak arch_uprobe_get_xol_area(void)
+{
+	/* Try to map as high as possible, this is only a hint. */
+	return get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+}
+
 /* Slot allocation for XOL */
 static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 {
@@ -1464,9 +1470,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 	}
 
 	if (!area->vaddr) {
-		/* Try to map as high as possible, this is only a hint. */
-		area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
-						PAGE_SIZE, 0, 0);
+		area->vaddr = arch_uprobe_get_xol_area();
 		if (IS_ERR_VALUE(area->vaddr)) {
 			ret = area->vaddr;
 			goto fail;
-- 
2.52.0



^ permalink raw reply related

* [PATCH 6.1.y] x86/uprobes: Fix XOL allocation failure for 32-bit tasks
From: Oleg Nesterov @ 2026-03-02 15:36 UTC (permalink / raw)
  To: Sasha Levin
  Cc: stable, Paulo Andrade, Peter Zijlstra (Intel), linux-trace-kernel,
	linux-perf-users
In-Reply-To: <20260301014209.1703943-1-sashal@kernel.org>

[ Upstream commit d55c571e4333fac71826e8db3b9753fadfbead6a ]

This script

	#!/usr/bin/bash

	echo 0 > /proc/sys/kernel/randomize_va_space

	echo 'void main(void) {}' > TEST.c

	# -fcf-protection to ensure that the 1st endbr32 insn can't be emulated
	gcc -m32 -fcf-protection=branch TEST.c -o test

	bpftrace -e 'uprobe:./test:main {}' -c ./test

"hangs", the probed ./test task enters an endless loop.

The problem is that with randomize_va_space == 0
get_unmapped_area(TASK_SIZE - PAGE_SIZE) called by xol_add_vma() can not
just return the "addr == TASK_SIZE - PAGE_SIZE" hint, this addr is used
by the stack vma.

arch_get_unmapped_area_topdown() doesn't take TIF_ADDR32 into account and
in_32bit_syscall() is false, this leads to info.high_limit > TASK_SIZE.
vm_unmapped_area() happily returns the high address > TASK_SIZE and then
get_unmapped_area() returns -ENOMEM after the "if (addr > TASK_SIZE - len)"
check.

handle_swbp() doesn't report this failure (probably it should) and silently
restarts the probed insn. Endless loop.

I think that the right fix should change the x86 get_unmapped_area() paths
to rely on TIF_ADDR32 rather than in_32bit_syscall(). Note also that if
CONFIG_X86_X32_ABI=y, in_x32_syscall() falsely returns true in this case
because ->orig_ax = -1.

But we need a simple fix for -stable, so this patch just sets TS_COMPAT if
the probed task is 32-bit to make in_ia32_syscall() true.

Fixes: 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: Paulo Andrade <pandrade@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/aV5uldEvV7pb4RA8@redhat.com/
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/aWO7Fdxn39piQnxu@redhat.com
---
 arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
 include/linux/uprobes.h   |  1 +
 kernel/events/uprobes.c   | 10 +++++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 6c07f6daaa22..6b431589305b 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -1097,3 +1097,27 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
 	else
 		return regs->sp <= ret->stack;
 }
+
+#ifdef CONFIG_IA32_EMULATION
+unsigned long arch_uprobe_get_xol_area(void)
+{
+	struct thread_info *ti = current_thread_info();
+	unsigned long vaddr;
+
+	/*
+	 * HACK: we are not in a syscall, but x86 get_unmapped_area() paths
+	 * ignore TIF_ADDR32 and rely on in_32bit_syscall() to calculate
+	 * vm_unmapped_area_info.high_limit.
+	 *
+	 * The #ifdef above doesn't cover the CONFIG_X86_X32_ABI=y case,
+	 * but in this case in_32bit_syscall() -> in_x32_syscall() always
+	 * (falsely) returns true because ->orig_ax == -1.
+	 */
+	if (test_thread_flag(TIF_ADDR32))
+		ti->status |= TS_COMPAT;
+	vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+	ti->status &= ~TS_COMPAT;
+
+	return vaddr;
+}
+#endif
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index d91e32aff5a1..a5ec2b024a22 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -140,6 +140,7 @@ extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check c
 extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs);
 extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 					 void *src, unsigned long len);
+extern unsigned long arch_uprobe_get_xol_area(void);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 29c0e7c6a6d2..692c0fae8ce1 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1441,6 +1441,12 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
 		set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
 }
 
+unsigned long __weak arch_uprobe_get_xol_area(void)
+{
+	/* Try to map as high as possible, this is only a hint. */
+	return get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+}
+
 /* Slot allocation for XOL */
 static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 {
@@ -1456,9 +1462,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 	}
 
 	if (!area->vaddr) {
-		/* Try to map as high as possible, this is only a hint. */
-		area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
-						PAGE_SIZE, 0, 0);
+		area->vaddr = arch_uprobe_get_xol_area();
 		if (IS_ERR_VALUE(area->vaddr)) {
 			ret = area->vaddr;
 			goto fail;
-- 
2.52.0



^ permalink raw reply related

* Re: [PATCH] mm: add Adaptive Memory Pressure Signaling (AMPRESS)
From: Andre Ramos @ 2026-03-02 15:38 UTC (permalink / raw)
  To: Johannes Weiner
  Cc: akpm, linux-mm, linux-kernel, linux-trace-kernel, david, rostedt
In-Reply-To: <aaWonCzCLayQDXOT@cmpxchg.org>

Thank you all for the review.

  David, Lorenzo — understood on all counts: RFC tag, patch series,
  and the maintainer entry. Noted for future submissions.

  Johannes — your pointer to PSI is appreciated. Given that it already
  covers this use case more correctly and without the reclaim path
  overhead, I'll look into that direction instead.

  André

^ permalink raw reply

* [PATCH 5.15.y] x86/uprobes: Fix XOL allocation failure for 32-bit tasks
From: Oleg Nesterov @ 2026-03-02 15:42 UTC (permalink / raw)
  To: Sasha Levin
  Cc: stable, Paulo Andrade, Peter Zijlstra (Intel), linux-trace-kernel,
	linux-perf-users
In-Reply-To: <20260301015033.1716584-1-sashal@kernel.org>

[ Upstream commit d55c571e4333fac71826e8db3b9753fadfbead6a ]

This script

	#!/usr/bin/bash

	echo 0 > /proc/sys/kernel/randomize_va_space

	echo 'void main(void) {}' > TEST.c

	# -fcf-protection to ensure that the 1st endbr32 insn can't be emulated
	gcc -m32 -fcf-protection=branch TEST.c -o test

	bpftrace -e 'uprobe:./test:main {}' -c ./test

"hangs", the probed ./test task enters an endless loop.

The problem is that with randomize_va_space == 0
get_unmapped_area(TASK_SIZE - PAGE_SIZE) called by xol_add_vma() can not
just return the "addr == TASK_SIZE - PAGE_SIZE" hint, this addr is used
by the stack vma.

arch_get_unmapped_area_topdown() doesn't take TIF_ADDR32 into account and
in_32bit_syscall() is false, this leads to info.high_limit > TASK_SIZE.
vm_unmapped_area() happily returns the high address > TASK_SIZE and then
get_unmapped_area() returns -ENOMEM after the "if (addr > TASK_SIZE - len)"
check.

handle_swbp() doesn't report this failure (probably it should) and silently
restarts the probed insn. Endless loop.

I think that the right fix should change the x86 get_unmapped_area() paths
to rely on TIF_ADDR32 rather than in_32bit_syscall(). Note also that if
CONFIG_X86_X32_ABI=y, in_x32_syscall() falsely returns true in this case
because ->orig_ax = -1.

But we need a simple fix for -stable, so this patch just sets TS_COMPAT if
the probed task is 32-bit to make in_ia32_syscall() true.

Fixes: 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: Paulo Andrade <pandrade@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/aV5uldEvV7pb4RA8@redhat.com/
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/aWO7Fdxn39piQnxu@redhat.com
---
 arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
 include/linux/uprobes.h   |  1 +
 kernel/events/uprobes.c   | 10 +++++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 6c07f6daaa22..6b431589305b 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -1097,3 +1097,27 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
 	else
 		return regs->sp <= ret->stack;
 }
+
+#ifdef CONFIG_IA32_EMULATION
+unsigned long arch_uprobe_get_xol_area(void)
+{
+	struct thread_info *ti = current_thread_info();
+	unsigned long vaddr;
+
+	/*
+	 * HACK: we are not in a syscall, but x86 get_unmapped_area() paths
+	 * ignore TIF_ADDR32 and rely on in_32bit_syscall() to calculate
+	 * vm_unmapped_area_info.high_limit.
+	 *
+	 * The #ifdef above doesn't cover the CONFIG_X86_X32_ABI=y case,
+	 * but in this case in_32bit_syscall() -> in_x32_syscall() always
+	 * (falsely) returns true because ->orig_ax == -1.
+	 */
+	if (test_thread_flag(TIF_ADDR32))
+		ti->status |= TS_COMPAT;
+	vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+	ti->status &= ~TS_COMPAT;
+
+	return vaddr;
+}
+#endif
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index f46e0ca0169c..3461199c4ec0 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -138,6 +138,7 @@ extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check c
 extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs);
 extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 					 void *src, unsigned long len);
+extern unsigned long arch_uprobe_get_xol_area(void);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 4e6ada6a11c7..3bd85f043881 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1437,6 +1437,12 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
 		set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
 }
 
+unsigned long __weak arch_uprobe_get_xol_area(void)
+{
+	/* Try to map as high as possible, this is only a hint. */
+	return get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+}
+
 /* Slot allocation for XOL */
 static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 {
@@ -1452,9 +1458,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 	}
 
 	if (!area->vaddr) {
-		/* Try to map as high as possible, this is only a hint. */
-		area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
-						PAGE_SIZE, 0, 0);
+		area->vaddr = arch_uprobe_get_xol_area();
 		if (IS_ERR_VALUE(area->vaddr)) {
 			ret = area->vaddr;
 			goto fail;
-- 
2.52.0



^ permalink raw reply related

* [PATCH 5.10.y] x86/uprobes: Fix XOL allocation failure for 32-bit tasks
From: Oleg Nesterov @ 2026-03-02 15:51 UTC (permalink / raw)
  To: Sasha Levin
  Cc: stable, Paulo Andrade, Peter Zijlstra (Intel), linux-trace-kernel,
	linux-perf-users
In-Reply-To: <20260301020027.1726538-1-sashal@kernel.org>

[ Upstream commit d55c571e4333fac71826e8db3b9753fadfbead6a ]

This script

	#!/usr/bin/bash

	echo 0 > /proc/sys/kernel/randomize_va_space

	echo 'void main(void) {}' > TEST.c

	# -fcf-protection to ensure that the 1st endbr32 insn can't be emulated
	gcc -m32 -fcf-protection=branch TEST.c -o test

	bpftrace -e 'uprobe:./test:main {}' -c ./test

"hangs", the probed ./test task enters an endless loop.

The problem is that with randomize_va_space == 0
get_unmapped_area(TASK_SIZE - PAGE_SIZE) called by xol_add_vma() can not
just return the "addr == TASK_SIZE - PAGE_SIZE" hint, this addr is used
by the stack vma.

arch_get_unmapped_area_topdown() doesn't take TIF_ADDR32 into account and
in_32bit_syscall() is false, this leads to info.high_limit > TASK_SIZE.
vm_unmapped_area() happily returns the high address > TASK_SIZE and then
get_unmapped_area() returns -ENOMEM after the "if (addr > TASK_SIZE - len)"
check.

handle_swbp() doesn't report this failure (probably it should) and silently
restarts the probed insn. Endless loop.

I think that the right fix should change the x86 get_unmapped_area() paths
to rely on TIF_ADDR32 rather than in_32bit_syscall(). Note also that if
CONFIG_X86_X32_ABI=y, in_x32_syscall() falsely returns true in this case
because ->orig_ax = -1.

But we need a simple fix for -stable, so this patch just sets TS_COMPAT if
the probed task is 32-bit to make in_ia32_syscall() true.

Fixes: 1b028f784e8c ("x86/mm: Introduce mmap_compat_base() for 32-bit mmap()")
Reported-by: Paulo Andrade <pandrade@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/aV5uldEvV7pb4RA8@redhat.com/
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/aWO7Fdxn39piQnxu@redhat.com
---
 arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
 include/linux/uprobes.h   |  1 +
 kernel/events/uprobes.c   | 10 +++++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 9f948b2d26f6..099ca674e3de 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -1095,3 +1095,27 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
 	else
 		return regs->sp <= ret->stack;
 }
+
+#ifdef CONFIG_IA32_EMULATION
+unsigned long arch_uprobe_get_xol_area(void)
+{
+	struct thread_info *ti = current_thread_info();
+	unsigned long vaddr;
+
+	/*
+	 * HACK: we are not in a syscall, but x86 get_unmapped_area() paths
+	 * ignore TIF_ADDR32 and rely on in_32bit_syscall() to calculate
+	 * vm_unmapped_area_info.high_limit.
+	 *
+	 * The #ifdef above doesn't cover the CONFIG_X86_X32_ABI=y case,
+	 * but in this case in_32bit_syscall() -> in_x32_syscall() always
+	 * (falsely) returns true because ->orig_ax == -1.
+	 */
+	if (test_thread_flag(TIF_ADDR32))
+		ti->status |= TS_COMPAT;
+	vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+	ti->status &= ~TS_COMPAT;
+
+	return vaddr;
+}
+#endif
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index f46e0ca0169c..3461199c4ec0 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -138,6 +138,7 @@ extern bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check c
 extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs);
 extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 					 void *src, unsigned long len);
+extern unsigned long arch_uprobe_get_xol_area(void);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 4f2a9fab8ae8..f3bc64c4fa78 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1438,6 +1438,12 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
 		set_bit(MMF_RECALC_UPROBES, &vma->vm_mm->flags);
 }
 
+unsigned long __weak arch_uprobe_get_xol_area(void)
+{
+	/* Try to map as high as possible, this is only a hint. */
+	return get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
+}
+
 /* Slot allocation for XOL */
 static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 {
@@ -1453,9 +1459,7 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
 	}
 
 	if (!area->vaddr) {
-		/* Try to map as high as possible, this is only a hint. */
-		area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
-						PAGE_SIZE, 0, 0);
+		area->vaddr = arch_uprobe_get_xol_area();
 		if (IS_ERR_VALUE(area->vaddr)) {
 			ret = area->vaddr;
 			goto fail;
-- 
2.52.0



^ permalink raw reply related

* Re: [PATCH bpf] ftrace: Add missing ftrace_lock to update_ftrace_direct_add/del
From: Alexei Starovoitov @ 2026-03-02 15:58 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Steven Rostedt, Alexei Starovoitov, Ihor Solodrai,
	Kumar Kartikeya Dwivedi, bpf, LKML, linux-trace-kernel,
	Daniel Borkmann, Andrii Nakryiko, Menglong Dong, Song Liu
In-Reply-To: <20260302081622.165713-1-jolsa@kernel.org>

On Mon, Mar 2, 2026 at 12:16 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Ihor and Kumar reported splat from ftrace_get_addr_curr [1], which happened
> because of the missing ftrace_lock in update_ftrace_direct_add/del functions
> allowing concurrent access to ftrace internals.
>
> The ftrace_update_ops function must be guarded by ftrace_lock, adding that.
>
> Fixes: 05dc5e9c1fe1 ("ftrace: Add update_ftrace_direct_add function")
> Fixes: 8d2c1233f371 ("ftrace: Add update_ftrace_direct_del function")
> Reported-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> Reported-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Closes: https://lore.kernel.org/bpf/1b58ffb2-92ae-433a-ba46-95294d6edea2@linux.dev/
> Tested-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>

lgtm.

Steven,
should it land through ftrace tree?

^ permalink raw reply

* Re: [PATCH V2] blktrace: fix __this_cpu_read/write in preemptible context
From: Steven Rostedt @ 2026-03-02 15:59 UTC (permalink / raw)
  To: Chaitanya Kulkarni
  Cc: axboe, mhiramat, mathieu.desnoyers, shinichiro.kawasaki,
	linux-block, linux-trace-kernel
In-Reply-To: <20260302002207.12165-1-kch@nvidia.com>

On Sun, 1 Mar 2026 16:22:07 -0800
Chaitanya Kulkarni <kch@nvidia.com> wrote:

> With this fix blktests for blktrace pass:
> 
>   blktests (master) # ./check blktrace
>   blktrace/001 (blktrace zone management command tracing)      [passed]
>       runtime  3.650s  ...  3.647s
>   blktrace/002 (blktrace ftrace corruption with sysfs trace)   [passed]
>       runtime  0.411s  ...  0.384s
> 
> Fixes: 7ffbd48d5cab ("tracing: Cache comms only after an event occurred")
> Reported-by: Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> Suggested-by: Steven Rostedt <rostedt@goodmis.org>
> Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com>

Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>

-- Steve

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox