Linux Trace Kernel
 help / color / mirror / Atom feed
* [PATCH v8 2/2] tools/bootconfig: fix fd leak in load_xbc_file() on fstat failure
From: Josh Law @ 2026-03-18 15:58 UTC (permalink / raw)
  To: Masami Hiramatsu, Andrew Morton
  Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Josh Law
In-Reply-To: <20260318155847.78065-1-objecting@objecting.org>

If fstat() fails after open() succeeds, the function returns without
closing the file descriptor. Also preserve errno across close(), since
close() may overwrite it before the error is returned.

Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
Signed-off-by: Josh Law <objecting@objecting.org>
---
 tools/bootconfig/main.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
index 55d59ed507d5..643f707b8f1d 100644
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -162,8 +162,11 @@ static int load_xbc_file(const char *path, char **buf)
 	if (fd < 0)
 		return -errno;
 	ret = fstat(fd, &stat);
-	if (ret < 0)
-		return -errno;
+	if (ret < 0) {
+		ret = -errno;
+		close(fd);
+		return ret;
+	}

 	ret = load_xbc_fd(fd, buf, stat.st_size);

--
2.34.1


^ permalink raw reply related

* [PATCH v8 1/2] lib/bootconfig: check xbc_init_node() return in override path
From: Josh Law @ 2026-03-18 15:58 UTC (permalink / raw)
  To: Masami Hiramatsu, Andrew Morton
  Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Josh Law
In-Reply-To: <20260318155847.78065-1-objecting@objecting.org>

The ':=' override path in xbc_parse_kv() calls xbc_init_node() to
re-initialize an existing value node but does not check the return
value. If xbc_init_node() fails (data offset out of range), parsing
silently continues with stale node data.

Add the missing error check to match the xbc_add_node() call path
which already checks for failure.

In practice, a bootconfig using ':=' to override a value near the
32KB data limit could silently retain the old value, meaning a
security-relevant boot parameter override (e.g., a trace filter or
debug setting) would not take effect as intended.

Fixes: e5efaeb8a8f5 ("bootconfig: Support mixing a value and subkeys under a key")
Signed-off-by: Josh Law <objecting@objecting.org>
---
 lib/bootconfig.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/bootconfig.c b/lib/bootconfig.c
index 1adf592cc038..ecc4e8d93547 100644
--- a/lib/bootconfig.c
+++ b/lib/bootconfig.c
@@ -728,7 +728,8 @@ static int __init xbc_parse_kv(char **k, char *v, int op)
 		if (op == ':') {
 			unsigned short nidx = child->next;

-			xbc_init_node(child, v, XBC_VALUE);
+			if (xbc_init_node(child, v, XBC_VALUE) < 0)
+				return xbc_parse_error("Failed to override value", v);
 			child->next = nidx;	/* keep subkeys */
 			goto array;
 		}
--
2.34.1


^ permalink raw reply related

* [PATCH v8 0/2] bootconfig: targeted fixes for stable
From: Josh Law @ 2026-03-18 15:58 UTC (permalink / raw)
  To: Masami Hiramatsu, Andrew Morton
  Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Josh Law

Two bug fixes with Fixes tags, split out from the larger cleanup series
(v7 patches 9/15 and 10/15) per Masami's request so they can go
cleanly into bootconfig/fixes and from there into stable.

Changes since v7:
  - Split fixes (this series) from cleanups/improvements into separate
    series per maintainer request, so fixes can go into bootconfig/fixes
    and the rest into bootconfig/for-next.

Bug fixes:
  - Check xbc_init_node() return value in the ':=' override path; a
    bootconfig using ':=' near the 32KB data limit could silently
    retain the old value, meaning a security-relevant boot parameter
    override would not take effect (patch 1).
  - Fix file descriptor leak in tools/bootconfig load_xbc_file() when
    fstat() fails, and preserve errno across close() on that error path
    (patch 2).

Build-tested with both the in-kernel build (lib/bootconfig.o,
init/main.o) and the userspace tools/bootconfig build. All 70
tools/bootconfig test cases pass.

Josh Law (2):
  lib/bootconfig: check xbc_init_node() return in override path
  tools/bootconfig: fix fd leak in load_xbc_file() on fstat failure

 lib/bootconfig.c        | 3 ++-
 tools/bootconfig/main.c | 7 +++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

--
2.34.1


^ permalink raw reply

* Re: [PATCH v9 2/4] ring-buffer: Flush and stop persistent ring buffer on panic
From: Mathieu Desnoyers @ 2026-03-18 15:51 UTC (permalink / raw)
  To: Masami Hiramatsu (Google)
  Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Ian Rogers
In-Reply-To: <20260319002918.5768a8ee053dd35373e215f2@kernel.org>

On 2026-03-18 11:29, Masami Hiramatsu (Google) wrote:
>>
>> - AFAIU, you are not trying to evince cache lines after creation
>>     of a new virtual mapping (which is the documented intent of
>>     flush_cache_vmap).
> 
> Ah, OK. That's a good point!
> (anyway I will replace it with do { } while (0) in the next version.)
> 
>>     
>> - AFAIU flush_cache_vmap maps to no-code on arm64 (asm-generic), what am
>>     I missing ? It makes sense to be a no-op because AFAIR arm64 does not
>>     have to deal with virtually aliasing caches.
> 
> Yeah, so my patch also introduces arm64 specific implementation.

Just make sure to call this something else than "flush_cache_vmap",
because you don't want to slow down vmap on arm64 which does not
require to evince and certainly not write back cache lines after
creation of a new virtual mapping.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com

^ permalink raw reply

* Re: [PATCH v7 08/15] sched: Add task enqueue/dequeue trace points
From: gmonaco @ 2026-03-18 15:44 UTC (permalink / raw)
  To: Peter Zijlstra, linux-trace-kernel, linux-kernel
  Cc: Steven Rostedt, Nam Cao, Juri Lelli, Masami Hiramatsu,
	Ingo Molnar, K Prateek Nayak, Tomas Glozar, Clark Williams,
	John Kacur
In-Reply-To: <20260310105627.332044-9-gmonaco@redhat.com>

Hi Peter,

On Tue, 2026-03-10 at 11:56 +0100, Gabriele Monaco wrote:
> From: Nam Cao <namcao@linutronix.de>
> 
> Add trace points into enqueue_task() and dequeue_task().
> 
> Signed-off-by: Nam Cao <namcao@linutronix.de>
> Suggested-by: Peter Zijlstra <peterz@infradead.org>
> Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
> Co-developed-by: Gabriele Monaco <gmonaco@redhat.com>
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
> ---

Could I get an Ack for this?

Thanks,
Gabriele

> 
> Notes:
>     V7:
>     * Use cpu_of(rq) helper in tracepoint calls
>     V5:
>     * Do not fire enqueue tracepoint for delayed enqueues
> 
>  include/trace/events/sched.h |  8 ++++++++
>  kernel/sched/core.c          | 12 +++++++++++-
>  kernel/sched/sched.h         |  2 ++
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/include/trace/events/sched.h
> b/include/trace/events/sched.h
> index 7b2645b50e78..5844147ec5fd 100644
> --- a/include/trace/events/sched.h
> +++ b/include/trace/events/sched.h
> @@ -896,6 +896,14 @@ DECLARE_TRACE(sched_set_need_resched,
>  	TP_PROTO(struct task_struct *tsk, int cpu, int tif),
>  	TP_ARGS(tsk, cpu, tif));
>  
> +DECLARE_TRACE(sched_enqueue,
> +	TP_PROTO(struct task_struct *tsk, int cpu),
> +	TP_ARGS(tsk, cpu));
> +
> +DECLARE_TRACE(sched_dequeue,
> +	TP_PROTO(struct task_struct *tsk, int cpu),
> +	TP_ARGS(tsk, cpu));
> +
>  #endif /* _TRACE_SCHED_H */
>  
>  /* This part must be outside protection */
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index b7f77c165a6e..c9ca1e048612 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -122,6 +122,8 @@
> EXPORT_TRACEPOINT_SYMBOL_GPL(sched_compute_energy_tp);
>  EXPORT_TRACEPOINT_SYMBOL_GPL(sched_entry_tp);
>  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);
>  
>  DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
>  DEFINE_PER_CPU(struct rnd_state, sched_rnd_state);
> @@ -2094,6 +2096,9 @@ unsigned long get_wchan(struct task_struct *p)
>  
>  void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
>  {
> +	if (trace_sched_enqueue_tp_enabled() && !(flags &
> ENQUEUE_DELAYED))
> +		trace_sched_enqueue_tp(p, cpu_of(rq));
> +
>  	if (!(flags & ENQUEUE_NOCLOCK))
>  		update_rq_clock(rq);
>  
> @@ -2120,6 +2125,8 @@ void enqueue_task(struct rq *rq, struct
> task_struct *p, int flags)
>   */
>  inline bool dequeue_task(struct rq *rq, struct task_struct *p, int
> flags)
>  {
> +	bool ret;
> +
>  	if (sched_core_enabled(rq))
>  		sched_core_dequeue(rq, p, flags);
>  
> @@ -2136,7 +2143,10 @@ inline bool dequeue_task(struct rq *rq, struct
> task_struct *p, int flags)
>  	 * and mark the task ->sched_delayed.
>  	 */
>  	uclamp_rq_dec(rq, p);
> -	return p->sched_class->dequeue_task(rq, p, flags);
> +	ret = p->sched_class->dequeue_task(rq, p, flags);
> +	if (trace_sched_dequeue_tp_enabled() && !(flags &
> DEQUEUE_SLEEP))
> +		trace_sched_dequeue_tp(p, cpu_of(rq));
> +	return ret;
>  }
>  
>  void activate_task(struct rq *rq, struct task_struct *p, int flags)
> diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
> index 43bbf0693cca..d7ab0aa58a70 100644
> --- a/kernel/sched/sched.h
> +++ b/kernel/sched/sched.h
> @@ -2955,6 +2955,8 @@ static inline void sub_nr_running(struct rq
> *rq, unsigned count)
>  
>  static inline void __block_task(struct rq *rq, struct task_struct
> *p)
>  {
> +	trace_sched_dequeue_tp(p, cpu_of(rq));
> +
>  	if (p->sched_contributes_to_load)
>  		rq->nr_uninterruptible++;
>  


^ permalink raw reply

* Re: [PATCH v7 00/15] bootconfig: fixes, cleanups, and modernization
From: Masami Hiramatsu @ 2026-03-18 15:34 UTC (permalink / raw)
  To: Josh Law; +Cc: Andrew Morton, Steven Rostedt, linux-kernel, linux-trace-kernel
In-Reply-To: <20260317160916.33576-1-objecting@objecting.org>

Hi Josh,

It is mostly OK, but can you reorder this series as the fixes (which
has "Fixes" tag, [9/15] and [10/15]) first and others second, so that
I can cleanly merge it to bootconfig/fixes and bootconfig/for-next?

The patches which has Fixes tag should go into stable tree, but other
improvements/cleanups should go to next merge window.

Thank you,


On Tue, 17 Mar 2026 16:09:01 +0000
Josh Law <objecting@objecting.org> wrote:

> This series addresses a collection of issues found during a review of
> lib/bootconfig.c, include/linux/bootconfig.h, and tools/bootconfig,
> ranging from off-by-one errors and unchecked return values to coding
> style, signedness/type cleanup, and API modernization.
> 
> Changes since v6:
>   - Dropped "add missing __init annotations to static helpers"
>     (v6 patch 1).
>   - Dropped "fix sign-compare in xbc_node_compose_key_after()"
>     (v6 patch 16).
>   - Updated "fix fd leak in load_xbc_file() on fstat failure" to save
>     errno before close(), since close() may overwrite it before the
>     error is returned (patch 10).
>   - Updated "fix signed comparison in xbc_node_get_data()" to use
>     size_t for the local offset variable, matching the warning and
>     xbc_data_size (patch 11).
>   - Updated "use signed type for offset in xbc_init_node()" to use a
>     signed long and explicitly check offset < 0 in WARN_ON(), making
>     the pre-base pointer case explicit instead of relying on unsigned
>     wraparound (patch 13).
> 
> Changes since v5:
>   - Folded typo fixes, kerneldoc blank line, and inconsistent bracing
>     patches (v5 02-05, 07) into a single patch (patch 1).
>   - Dropped "use __packed macro for struct xbc_node" (v5 11) and
>     "add __packed definition to tools/bootconfig shim header" (v5 14)
>     per review feedback.
>   - Added Fixes: tag to "check xbc_init_node() return in override
>     path" (patch 9).
>   - Added Fixes: tag to "fix fd leak in load_xbc_file() on fstat
>     failure" (patch 10).
> 
> Changes since v4:
>   - Added six follow-up patches found via static analysis with strict
>     GCC warnings (patches 11-15, plus the now-dropped v6 patch 16).
>   - Added "fix signed comparison in xbc_node_get_data()" to match the
>     local offset type to xbc_data_size and eliminate the sign-compare
>     warning (patch 11).
>   - Added "use size_t for strlen result in xbc_node_match_prefix()"
>     and "use size_t for key length tracking in xbc_verify_tree()" to
>     match strlen() return types (patches 12, 14).
>   - Added "use signed type for offset in xbc_init_node()" to make the
>     offset bounds check explicit and avoid sign-conversion warnings
>     from pointer subtraction (patch 13).
>   - Added "change xbc_node_index() return type to uint16_t" to match
>     the 16-bit storage fields and XBC_NODE_MAX bounds (patch 15).
> 
> Changes since v3:
>   - Added commit descriptions to all patches that were missing them.
>   - Added real-world impact statements to all bug-fix patches.
> 
> Changes since v2:
>   - Added "validate child node index in xbc_verify_tree()" (patch 8).
>   - Added "check xbc_init_node() return in override path" (patch 9).
>   - Added "fix fd leak in load_xbc_file() on fstat failure" (patch 10).
> 
> Changes since v1:
>   - Dropped "return empty string instead of NULL from
>     xbc_node_get_data()" -- returning "" causes false matches in
>     xbc_node_match_prefix() because strncmp(..., "", 0) always
>     returns 0.
> 
> Bug fixes:
>   - Fix off-by-one in xbc_verify_tree() where a next-node index equal
>     to xbc_node_num passes the bounds check despite being out of range;
>     a malformed bootconfig could cause an out-of-bounds read of kernel
>     memory during tree traversal at boot time (patch 3).
>   - Move xbc_node_num increment to after xbc_init_node() validation so
>     a failed init does not leave a partially initialized node counted
>     in the array; on a maximum-size bootconfig, the uninitialized node
>     could be traversed leading to unpredictable boot behavior (patch 4).
>   - Validate child node indices in xbc_verify_tree() alongside the
>     existing next-node check; without this, a corrupt bootconfig could
>     trigger an out-of-bounds memory access via an invalid child index
>     during tree traversal (patch 8).
>   - Check xbc_init_node() return value in the ':=' override path; a
>     bootconfig using ':=' near the 32KB data limit could silently
>     retain the old value, meaning a security-relevant boot parameter
>     override would not take effect (patch 9).
>   - Fix file descriptor leak in tools/bootconfig load_xbc_file() when
>     fstat() fails, and preserve errno across close() on that error path
>     (patch 10).
> 
> Correctness:
>   - Narrow the flag parameter in node creation helpers from uint32_t to
>     uint16_t to match the xbc_node.data field width (patch 2).
>   - Constify the xbc_calc_checksum() data parameter since it only reads
>     the buffer (patch 6).
>   - Fix strict-GCC signedness and narrowing warnings by aligning local
>     types with strlen() APIs and the node index/data storage in
>     xbc_node_get_data(), xbc_node_match_prefix(), xbc_init_node(),
>     xbc_verify_tree(), and xbc_node_index() (patches 11-15).
> 
> Cleanups:
>   - Fix comment typos, missing blank line before kerneldoc, and
>     inconsistent if/else bracing (patch 1).
>   - Drop redundant memset after memblock_alloc which already returns
>     zeroed memory; switch the userspace path from malloc to calloc to
>     match (patch 5).
> 
> Modernization:
>   - Replace the catch-all linux/kernel.h include with the specific
>     headers needed: linux/cache.h, linux/compiler.h, and
>     linux/sprintf.h (patch 7).
> 
> Build-tested with both the in-kernel build (lib/bootconfig.o,
> init/main.o) and the userspace tools/bootconfig build. All 70
> tools/bootconfig test cases pass.
> 
> Josh Law (15):
>   lib/bootconfig: clean up comment typos and bracing
>   lib/bootconfig: narrow flag parameter type from uint32_t to uint16_t
>   lib/bootconfig: fix off-by-one in xbc_verify_tree() next node check
>   lib/bootconfig: increment xbc_node_num after node init succeeds
>   lib/bootconfig: drop redundant memset of xbc_nodes
>   bootconfig: constify xbc_calc_checksum() data parameter
>   lib/bootconfig: replace linux/kernel.h with specific includes
>   lib/bootconfig: validate child node index in xbc_verify_tree()
>   lib/bootconfig: check xbc_init_node() return in override path
>   tools/bootconfig: fix fd leak in load_xbc_file() on fstat failure
>   lib/bootconfig: fix signed comparison in xbc_node_get_data()
>   lib/bootconfig: use size_t for strlen result in
>     xbc_node_match_prefix()
>   lib/bootconfig: use signed type for offset in xbc_init_node()
>   lib/bootconfig: use size_t for key length tracking in
>     xbc_verify_tree()
>   lib/bootconfig: change xbc_node_index() return type to uint16_t
> 
>  include/linux/bootconfig.h |  6 ++--
>  lib/bootconfig.c           | 65 ++++++++++++++++++++++----------------
>  tools/bootconfig/main.c    |  7 ++--
>  3 files changed, 46 insertions(+), 32 deletions(-)
> 
> -- 
> 2.34.1


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [PATCH v9 2/4] ring-buffer: Flush and stop persistent ring buffer on panic
From: Masami Hiramatsu @ 2026-03-18 15:29 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Ian Rogers
In-Reply-To: <c91f37bf-97e9-4752-99a9-3d534ce9d2f0@efficios.com>

On Wed, 18 Mar 2026 10:53:26 -0400
Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote:

> On 2026-03-18 10:19, Masami Hiramatsu (Google) wrote:
> > On Wed, 11 Mar 2026 10:32:29 +0900
> > "Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
> > 
> >> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> >>
> >> On real hardware, panic and machine reboot may not flush hardware cache
> >> to memory. This means the persistent ring buffer, which relies on a
> >> coherent state of memory, may not have its events written to the buffer
> >> and they may be lost. Moreover, there may be inconsistency with the
> >> counters which are used for validation of the integrity of the
> >> persistent ring buffer which may cause all data to be discarded.
> >>
> >> To avoid this issue, stop recording of the ring buffer on panic and
> >> flush the cache of the ring buffer's memory.
> > 
> > Hmm, on some architectures, flush_cache_vmap() is implemented using
> > on_each_cpu() which waits IPI. But that does not safe in panic notifier
> > because it is called after smp_send_stop().
> > 
> > Since this cache flush issue is currently only confirmed on arm64,
> > I would like to make it doing nothing (do { } while (0)) by default.
> 
> FWIW, I've sent a related series a while ago about flushing pmem
> areas to memory on panic:
> 
> https://lore.kernel.org/lkml/20240618154157.334602-3-mathieu.desnoyers@efficios.com/
> 

Ah, nice!

> When reading your patch, I feel like I'm missing something, so please bear with
> me for a few questions:
> 
> - What exactly are you trying to flush ? By "flush" do you mean
>    evince cache lines or write back cache lines ? (I expect you aim
>    at the second option)

Yes, I need to write back cache lines, at least it can be
read after hot reboot. (not evict cache)

> 
> - AFAIU, you are not trying to evince cache lines after creation
>    of a new virtual mapping (which is the documented intent of
>    flush_cache_vmap).

Ah, OK. That's a good point!
(anyway I will replace it with do { } while (0) in the next version.)

>    
> - AFAIU flush_cache_vmap maps to no-code on arm64 (asm-generic), what am
>    I missing ? It makes sense to be a no-op because AFAIR arm64 does not
>    have to deal with virtually aliasing caches.

Yeah, so my patch also introduces arm64 specific implementation.

> 
> see commit 8690bbcf3b7 ("Introduce cpu_dcache_is_aliasing() across all architectures")

OK, let me check.

> 
> The arch_wb_cache_pmem is specific to pmem, which is not exactly what you want
> to use, but on arm64 it's implemented as:
> 
>          /* Ensure order against any prior non-cacheable writes */
>          dmb(osh);
>          dcache_clean_pop((unsigned long)addr, (unsigned long)addr + size);
> 
> Which I think has the writeback semantic you are looking for, and AFAIU should no
> require IPIs (at least on arm64) to flush cache lines across the entire system.

Yes, that's what I need.

Thank you!


> 
> Cheers,
> 
> Mathieu
> 
> -- 
> Mathieu Desnoyers
> EfficiOS Inc.
> https://www.efficios.com


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [PATCH v9 2/4] ring-buffer: Flush and stop persistent ring buffer on panic
From: Mathieu Desnoyers @ 2026-03-18 14:53 UTC (permalink / raw)
  To: Masami Hiramatsu (Google)
  Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Ian Rogers
In-Reply-To: <20260318231959.717f07ec491a731941aee1d9@kernel.org>

On 2026-03-18 10:19, Masami Hiramatsu (Google) wrote:
> On Wed, 11 Mar 2026 10:32:29 +0900
> "Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
> 
>> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>>
>> On real hardware, panic and machine reboot may not flush hardware cache
>> to memory. This means the persistent ring buffer, which relies on a
>> coherent state of memory, may not have its events written to the buffer
>> and they may be lost. Moreover, there may be inconsistency with the
>> counters which are used for validation of the integrity of the
>> persistent ring buffer which may cause all data to be discarded.
>>
>> To avoid this issue, stop recording of the ring buffer on panic and
>> flush the cache of the ring buffer's memory.
> 
> Hmm, on some architectures, flush_cache_vmap() is implemented using
> on_each_cpu() which waits IPI. But that does not safe in panic notifier
> because it is called after smp_send_stop().
> 
> Since this cache flush issue is currently only confirmed on arm64,
> I would like to make it doing nothing (do { } while (0)) by default.

FWIW, I've sent a related series a while ago about flushing pmem
areas to memory on panic:

https://lore.kernel.org/lkml/20240618154157.334602-3-mathieu.desnoyers@efficios.com/

When reading your patch, I feel like I'm missing something, so please bear with
me for a few questions:

- What exactly are you trying to flush ? By "flush" do you mean
   evince cache lines or write back cache lines ? (I expect you aim
   at the second option)

- AFAIU, you are not trying to evince cache lines after creation
   of a new virtual mapping (which is the documented intent of
   flush_cache_vmap).
   
- AFAIU flush_cache_vmap maps to no-code on arm64 (asm-generic), what am
   I missing ? It makes sense to be a no-op because AFAIR arm64 does not
   have to deal with virtually aliasing caches.

see commit 8690bbcf3b7 ("Introduce cpu_dcache_is_aliasing() across all architectures")

The arch_wb_cache_pmem is specific to pmem, which is not exactly what you want
to use, but on arm64 it's implemented as:

         /* Ensure order against any prior non-cacheable writes */
         dmb(osh);
         dcache_clean_pop((unsigned long)addr, (unsigned long)addr + size);

Which I think has the writeback semantic you are looking for, and AFAIU should no
require IPIs (at least on arm64) to flush cache lines across the entire system.

Cheers,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com

^ permalink raw reply

* Re: [PATCH 03/15] io_uring: Use trace_invoke_##name() at guarded tracepoint call sites
From: Vineeth Remanan Pillai @ 2026-03-18 14:51 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Keith Busch, Peter Zijlstra, Jens Axboe, io-uring, linux-kernel,
	linux-trace-kernel
In-Reply-To: <20260312113816.01de2b53@gandalf.local.home>

On Thu, Mar 12, 2026 at 11:38 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Thu, 12 Mar 2026 09:24:21 -0600
> Keith Busch <kbusch@kernel.org> wrote:
>
> > On Thu, Mar 12, 2026 at 11:04:58AM -0400, Vineeth Pillai (Google) wrote:
> > >     if (trace_io_uring_complete_enabled())
> > > -           trace_io_uring_complete(req->ctx, req, cqe);
> > > +           trace_invoke_io_uring_complete(req->ctx, req, cqe);
> >
> > Curious, this one doesn't follow that pattern of "if (enabed && cond)"
> > that this cover letter said it was addressing, so why doesn't this call
> > just drop the 'if' check and go straight to trace_io_uring_complete()? I
> > followed this usage to commit a0730c738309a06, which says that the
>
> You mean 'a0727c738309a06'? As I could not find the above 'a0730c738309a06'
>
> > compiler was generating code to move args before checking if the trace
> > was enabled. That commit was a while ago though, and suggests to remove
>
> It was only 2023.
>
> > the check if that problem is solved. Is it still a problem?
>
> We should check.

I shall leave this patch as is for now.

> Which reminds me. There's other places that have that tracepoint_enabled()
> in header files that do the above. The C wrapper functions should also
> convert the callback to the trace_invoke_<event>() call.
>

Thanks for pointing this out. I just had a look and its not too much.
But I feel it would be better to take it up as a new series. What do
you think?

Thanks,
Vineeth
> -- Steve

^ permalink raw reply

* Re: [PATCH v9 2/4] ring-buffer: Flush and stop persistent ring buffer on panic
From: Masami Hiramatsu @ 2026-03-18 14:19 UTC (permalink / raw)
  To: Masami Hiramatsu (Google)
  Cc: Steven Rostedt, Mathieu Desnoyers, linux-kernel,
	linux-trace-kernel, Ian Rogers
In-Reply-To: <177319274904.130641.3303707869402603363.stgit@mhiramat.tok.corp.google.com>

On Wed, 11 Mar 2026 10:32:29 +0900
"Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:

> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> 
> On real hardware, panic and machine reboot may not flush hardware cache
> to memory. This means the persistent ring buffer, which relies on a
> coherent state of memory, may not have its events written to the buffer
> and they may be lost. Moreover, there may be inconsistency with the
> counters which are used for validation of the integrity of the
> persistent ring buffer which may cause all data to be discarded.
> 
> To avoid this issue, stop recording of the ring buffer on panic and
> flush the cache of the ring buffer's memory.

Hmm, on some architectures, flush_cache_vmap() is implemented using
on_each_cpu() which waits IPI. But that does not safe in panic notifier
because it is called after smp_send_stop().

Since this cache flush issue is currently only confirmed on arm64,
I would like to make it doing nothing (do { } while (0)) by default.

Thanks,

> 
> Fixes: e645535a954a ("tracing: Add option to use memmapped memory for trace boot instance")
> Cc: stable@vger.kernel.org
> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> ---
>  Changes in v9:
>    - Fix typo of & to &&.
>    - Fix typo of "Generic"
>  Changes in v6:
>    - Introduce asm/ring_buffer.h for arch_ring_buffer_flush_range().
>    - Use flush_cache_vmap() instead of flush_cache_all().
>  Changes in v5:
>    - Use ring_buffer_record_off() instead of ring_buffer_record_disable().
>    - Use flush_cache_all() to ensure flush all cache.
>  Changes in v3:
>    - update patch description.
> ---
>  arch/alpha/include/asm/Kbuild        |    1 +
>  arch/arc/include/asm/Kbuild          |    1 +
>  arch/arm/include/asm/Kbuild          |    1 +
>  arch/arm64/include/asm/ring_buffer.h |   10 ++++++++++
>  arch/csky/include/asm/Kbuild         |    1 +
>  arch/hexagon/include/asm/Kbuild      |    1 +
>  arch/loongarch/include/asm/Kbuild    |    1 +
>  arch/m68k/include/asm/Kbuild         |    1 +
>  arch/microblaze/include/asm/Kbuild   |    1 +
>  arch/mips/include/asm/Kbuild         |    1 +
>  arch/nios2/include/asm/Kbuild        |    1 +
>  arch/openrisc/include/asm/Kbuild     |    1 +
>  arch/parisc/include/asm/Kbuild       |    1 +
>  arch/powerpc/include/asm/Kbuild      |    1 +
>  arch/riscv/include/asm/Kbuild        |    1 +
>  arch/s390/include/asm/Kbuild         |    1 +
>  arch/sh/include/asm/Kbuild           |    1 +
>  arch/sparc/include/asm/Kbuild        |    1 +
>  arch/um/include/asm/Kbuild           |    1 +
>  arch/x86/include/asm/Kbuild          |    1 +
>  arch/xtensa/include/asm/Kbuild       |    1 +
>  include/asm-generic/ring_buffer.h    |   13 +++++++++++++
>  kernel/trace/ring_buffer.c           |   22 ++++++++++++++++++++++
>  23 files changed, 65 insertions(+)
>  create mode 100644 arch/arm64/include/asm/ring_buffer.h
>  create mode 100644 include/asm-generic/ring_buffer.h
> 
> diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
> index 483965c5a4de..b154b4e3dfa8 100644
> --- a/arch/alpha/include/asm/Kbuild
> +++ b/arch/alpha/include/asm/Kbuild
> @@ -5,4 +5,5 @@ generic-y += agp.h
>  generic-y += asm-offsets.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
> +generic-y += ring_buffer.h
>  generic-y += text-patching.h
> diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
> index 4c69522e0328..483caacc6988 100644
> --- a/arch/arc/include/asm/Kbuild
> +++ b/arch/arc/include/asm/Kbuild
> @@ -5,5 +5,6 @@ generic-y += extable.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
>  generic-y += parport.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
>  generic-y += text-patching.h
> diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
> index 03657ff8fbe3..decad5f2c826 100644
> --- a/arch/arm/include/asm/Kbuild
> +++ b/arch/arm/include/asm/Kbuild
> @@ -3,6 +3,7 @@ generic-y += early_ioremap.h
>  generic-y += extable.h
>  generic-y += flat.h
>  generic-y += parport.h
> +generic-y += ring_buffer.h
>  
>  generated-y += mach-types.h
>  generated-y += unistd-nr.h
> diff --git a/arch/arm64/include/asm/ring_buffer.h b/arch/arm64/include/asm/ring_buffer.h
> new file mode 100644
> index 000000000000..62316c406888
> --- /dev/null
> +++ b/arch/arm64/include/asm/ring_buffer.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef _ASM_ARM64_RING_BUFFER_H
> +#define _ASM_ARM64_RING_BUFFER_H
> +
> +#include <asm/cacheflush.h>
> +
> +/* Flush D-cache on persistent ring buffer */
> +#define arch_ring_buffer_flush_range(start, end)	dcache_clean_pop(start, end)
> +
> +#endif /* _ASM_ARM64_RING_BUFFER_H */
> diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild
> index 3a5c7f6e5aac..7dca0c6cdc84 100644
> --- a/arch/csky/include/asm/Kbuild
> +++ b/arch/csky/include/asm/Kbuild
> @@ -9,6 +9,7 @@ generic-y += qrwlock.h
>  generic-y += qrwlock_types.h
>  generic-y += qspinlock.h
>  generic-y += parport.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
>  generic-y += vmlinux.lds.h
>  generic-y += text-patching.h
> diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
> index 1efa1e993d4b..0f887d4238ed 100644
> --- a/arch/hexagon/include/asm/Kbuild
> +++ b/arch/hexagon/include/asm/Kbuild
> @@ -5,4 +5,5 @@ generic-y += extable.h
>  generic-y += iomap.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
> +generic-y += ring_buffer.h
>  generic-y += text-patching.h
> diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild
> index 9034b583a88a..7e92957baf6a 100644
> --- a/arch/loongarch/include/asm/Kbuild
> +++ b/arch/loongarch/include/asm/Kbuild
> @@ -10,5 +10,6 @@ generic-y += qrwlock.h
>  generic-y += user.h
>  generic-y += ioctl.h
>  generic-y += mmzone.h
> +generic-y += ring_buffer.h
>  generic-y += statfs.h
>  generic-y += text-patching.h
> diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
> index b282e0dd8dc1..62543bf305ff 100644
> --- a/arch/m68k/include/asm/Kbuild
> +++ b/arch/m68k/include/asm/Kbuild
> @@ -3,5 +3,6 @@ generated-y += syscall_table.h
>  generic-y += extable.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
> +generic-y += ring_buffer.h
>  generic-y += spinlock.h
>  generic-y += text-patching.h
> diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
> index 7178f990e8b3..0030309b47ad 100644
> --- a/arch/microblaze/include/asm/Kbuild
> +++ b/arch/microblaze/include/asm/Kbuild
> @@ -5,6 +5,7 @@ generic-y += extable.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
>  generic-y += parport.h
> +generic-y += ring_buffer.h
>  generic-y += syscalls.h
>  generic-y += tlb.h
>  generic-y += user.h
> diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
> index 684569b2ecd6..9771c3d85074 100644
> --- a/arch/mips/include/asm/Kbuild
> +++ b/arch/mips/include/asm/Kbuild
> @@ -12,5 +12,6 @@ generic-y += mcs_spinlock.h
>  generic-y += parport.h
>  generic-y += qrwlock.h
>  generic-y += qspinlock.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
>  generic-y += text-patching.h
> diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
> index 28004301c236..0a2530964413 100644
> --- a/arch/nios2/include/asm/Kbuild
> +++ b/arch/nios2/include/asm/Kbuild
> @@ -5,6 +5,7 @@ generic-y += cmpxchg.h
>  generic-y += extable.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
> +generic-y += ring_buffer.h
>  generic-y += spinlock.h
>  generic-y += user.h
>  generic-y += text-patching.h
> diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
> index cef49d60d74c..8aa34621702d 100644
> --- a/arch/openrisc/include/asm/Kbuild
> +++ b/arch/openrisc/include/asm/Kbuild
> @@ -8,4 +8,5 @@ generic-y += spinlock_types.h
>  generic-y += spinlock.h
>  generic-y += qrwlock_types.h
>  generic-y += qrwlock.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
> diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
> index 4fb596d94c89..d48d158f7241 100644
> --- a/arch/parisc/include/asm/Kbuild
> +++ b/arch/parisc/include/asm/Kbuild
> @@ -4,4 +4,5 @@ generated-y += syscall_table_64.h
>  generic-y += agp.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
> diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
> index 2e23533b67e3..805b5aeebb6f 100644
> --- a/arch/powerpc/include/asm/Kbuild
> +++ b/arch/powerpc/include/asm/Kbuild
> @@ -5,4 +5,5 @@ generated-y += syscall_table_spu.h
>  generic-y += agp.h
>  generic-y += mcs_spinlock.h
>  generic-y += qrwlock.h
> +generic-y += ring_buffer.h
>  generic-y += early_ioremap.h
> diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
> index bd5fc9403295..7721b63642f4 100644
> --- a/arch/riscv/include/asm/Kbuild
> +++ b/arch/riscv/include/asm/Kbuild
> @@ -14,5 +14,6 @@ generic-y += ticket_spinlock.h
>  generic-y += qrwlock.h
>  generic-y += qrwlock_types.h
>  generic-y += qspinlock.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
>  generic-y += vmlinux.lds.h
> diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
> index 80bad7de7a04..0c1fc47c3ba0 100644
> --- a/arch/s390/include/asm/Kbuild
> +++ b/arch/s390/include/asm/Kbuild
> @@ -7,3 +7,4 @@ generated-y += unistd_nr.h
>  generic-y += asm-offsets.h
>  generic-y += mcs_spinlock.h
>  generic-y += mmzone.h
> +generic-y += ring_buffer.h
> diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
> index 4d3f10ed8275..f0403d3ee8ab 100644
> --- a/arch/sh/include/asm/Kbuild
> +++ b/arch/sh/include/asm/Kbuild
> @@ -3,4 +3,5 @@ generated-y += syscall_table.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
>  generic-y += parport.h
> +generic-y += ring_buffer.h
>  generic-y += text-patching.h
> diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
> index 17ee8a273aa6..49c6bb326b75 100644
> --- a/arch/sparc/include/asm/Kbuild
> +++ b/arch/sparc/include/asm/Kbuild
> @@ -4,4 +4,5 @@ generated-y += syscall_table_64.h
>  generic-y += agp.h
>  generic-y += kvm_para.h
>  generic-y += mcs_spinlock.h
> +generic-y += ring_buffer.h
>  generic-y += text-patching.h
> diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
> index 1b9b82bbe322..2a1629ba8140 100644
> --- a/arch/um/include/asm/Kbuild
> +++ b/arch/um/include/asm/Kbuild
> @@ -17,6 +17,7 @@ generic-y += module.lds.h
>  generic-y += parport.h
>  generic-y += percpu.h
>  generic-y += preempt.h
> +generic-y += ring_buffer.h
>  generic-y += runtime-const.h
>  generic-y += softirq_stack.h
>  generic-y += switch_to.h
> diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
> index 4566000e15c4..078fd2c0d69d 100644
> --- a/arch/x86/include/asm/Kbuild
> +++ b/arch/x86/include/asm/Kbuild
> @@ -14,3 +14,4 @@ generic-y += early_ioremap.h
>  generic-y += fprobe.h
>  generic-y += mcs_spinlock.h
>  generic-y += mmzone.h
> +generic-y += ring_buffer.h
> diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
> index 13fe45dea296..e57af619263a 100644
> --- a/arch/xtensa/include/asm/Kbuild
> +++ b/arch/xtensa/include/asm/Kbuild
> @@ -6,5 +6,6 @@ generic-y += mcs_spinlock.h
>  generic-y += parport.h
>  generic-y += qrwlock.h
>  generic-y += qspinlock.h
> +generic-y += ring_buffer.h
>  generic-y += user.h
>  generic-y += text-patching.h
> diff --git a/include/asm-generic/ring_buffer.h b/include/asm-generic/ring_buffer.h
> new file mode 100644
> index 000000000000..930d96571f23
> --- /dev/null
> +++ b/include/asm-generic/ring_buffer.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Generic arch dependent ring_buffer macros.
> + */
> +#ifndef __ASM_GENERIC_RING_BUFFER_H__
> +#define __ASM_GENERIC_RING_BUFFER_H__
> +
> +#include <linux/cacheflush.h>
> +
> +/* Flush cache on ring buffer range if needed */
> +#define arch_ring_buffer_flush_range(start, end)	flush_cache_vmap(start, end)
> +
> +#endif /* __ASM_GENERIC_RING_BUFFER_H__ */
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index 353a5aa1b612..9f4ee9e3803d 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -6,6 +6,7 @@
>   */
>  #include <linux/sched/isolation.h>
>  #include <linux/trace_recursion.h>
> +#include <linux/panic_notifier.h>
>  #include <linux/trace_events.h>
>  #include <linux/ring_buffer.h>
>  #include <linux/trace_clock.h>
> @@ -30,6 +31,7 @@
>  #include <linux/oom.h>
>  #include <linux/mm.h>
>  
> +#include <asm/ring_buffer.h>
>  #include <asm/local64.h>
>  #include <asm/local.h>
>  #include <asm/setup.h>
> @@ -589,6 +591,7 @@ struct trace_buffer {
>  
>  	unsigned long			range_addr_start;
>  	unsigned long			range_addr_end;
> +	struct notifier_block		flush_nb;
>  
>  	struct ring_buffer_meta		*meta;
>  
> @@ -2471,6 +2474,16 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
>  	kfree(cpu_buffer);
>  }
>  
> +/* Stop recording on a persistent buffer and flush cache if needed. */
> +static int rb_flush_buffer_cb(struct notifier_block *nb, unsigned long event, void *data)
> +{
> +	struct trace_buffer *buffer = container_of(nb, struct trace_buffer, flush_nb);
> +
> +	ring_buffer_record_off(buffer);
> +	arch_ring_buffer_flush_range(buffer->range_addr_start, buffer->range_addr_end);
> +	return NOTIFY_DONE;
> +}
> +
>  static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
>  					 int order, unsigned long start,
>  					 unsigned long end,
> @@ -2590,6 +2603,12 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
>  
>  	mutex_init(&buffer->mutex);
>  
> +	/* Persistent ring buffer needs to flush cache before reboot. */
> +	if (start && end) {
> +		buffer->flush_nb.notifier_call = rb_flush_buffer_cb;
> +		atomic_notifier_chain_register(&panic_notifier_list, &buffer->flush_nb);
> +	}
> +
>  	return_ptr(buffer);
>  
>   fail_free_buffers:
> @@ -2677,6 +2696,9 @@ ring_buffer_free(struct trace_buffer *buffer)
>  {
>  	int cpu;
>  
> +	if (buffer->range_addr_start && buffer->range_addr_end)
> +		atomic_notifier_chain_unregister(&panic_notifier_list, &buffer->flush_nb);
> +
>  	cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
>  
>  	irq_work_sync(&buffer->irq_work.work);
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [PATCH 3/8] mm: move free_reserved_area() to mm/memblock.c
From: Vlastimil Babka @ 2026-03-18 14:16 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Nicholas Piggin, H. Peter Anvin, Rob Herring,
	Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Will Deacon, Zi Yan, devicetree, iommu,
	kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-4-rppt@kernel.org>

On 3/18/26 11:58, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
> 
> free_reserved_area() is related to memblock as it frees reserved memory
> back to the buddy allocator, similar to what memblock_free_late() does.
> 
> Move free_reserved_area() to mm/memblock.c to prepare for further
> consolidation of the functions that free reserved memory.
> 
> No functional changes.
> 
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

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


> ---
>  mm/memblock.c   | 37 ++++++++++++++++++++++++++++++++++++-
>  mm/page_alloc.c | 36 ------------------------------------
>  2 files changed, 36 insertions(+), 37 deletions(-)
> 
> diff --git a/mm/memblock.c b/mm/memblock.c
> index b3ddfdec7a80..8f3010dddc58 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -893,6 +893,42 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
>  	return memblock_remove_range(&memblock.memory, base, size);
>  }
>  
> +unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
> +{
> +	void *pos;
> +	unsigned long pages = 0;
> +
> +	start = (void *)PAGE_ALIGN((unsigned long)start);
> +	end = (void *)((unsigned long)end & PAGE_MASK);
> +	for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
> +		struct page *page = virt_to_page(pos);
> +		void *direct_map_addr;
> +
> +		/*
> +		 * 'direct_map_addr' might be different from 'pos'
> +		 * because some architectures' virt_to_page()
> +		 * work with aliases.  Getting the direct map
> +		 * address ensures that we get a _writeable_
> +		 * alias for the memset().
> +		 */
> +		direct_map_addr = page_address(page);
> +		/*
> +		 * Perform a kasan-unchecked memset() since this memory
> +		 * has not been initialized.
> +		 */
> +		direct_map_addr = kasan_reset_tag(direct_map_addr);
> +		if ((unsigned int)poison <= 0xFF)
> +			memset(direct_map_addr, poison, PAGE_SIZE);
> +
> +		free_reserved_page(page);
> +	}
> +
> +	if (pages && s)
> +		pr_info("Freeing %s memory: %ldK\n", s, K(pages));
> +
> +	return pages;
> +}
> +
>  /**
>   * memblock_free - free boot memory allocation
>   * @ptr: starting address of the  boot memory allocation
> @@ -1776,7 +1812,6 @@ void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
>  		totalram_pages_inc();
>  	}
>  }
> -
>  /*
>   * Remaining API functions
>   */
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 2d4b6f1a554e..df3d61253001 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -6234,42 +6234,6 @@ void adjust_managed_page_count(struct page *page, long count)
>  }
>  EXPORT_SYMBOL(adjust_managed_page_count);
>  
> -unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
> -{
> -	void *pos;
> -	unsigned long pages = 0;
> -
> -	start = (void *)PAGE_ALIGN((unsigned long)start);
> -	end = (void *)((unsigned long)end & PAGE_MASK);
> -	for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
> -		struct page *page = virt_to_page(pos);
> -		void *direct_map_addr;
> -
> -		/*
> -		 * 'direct_map_addr' might be different from 'pos'
> -		 * because some architectures' virt_to_page()
> -		 * work with aliases.  Getting the direct map
> -		 * address ensures that we get a _writeable_
> -		 * alias for the memset().
> -		 */
> -		direct_map_addr = page_address(page);
> -		/*
> -		 * Perform a kasan-unchecked memset() since this memory
> -		 * has not been initialized.
> -		 */
> -		direct_map_addr = kasan_reset_tag(direct_map_addr);
> -		if ((unsigned int)poison <= 0xFF)
> -			memset(direct_map_addr, poison, PAGE_SIZE);
> -
> -		free_reserved_page(page);
> -	}
> -
> -	if (pages && s)
> -		pr_info("Freeing %s memory: %ldK\n", s, K(pages));
> -
> -	return pages;
> -}
> -
>  void free_reserved_page(struct page *page)
>  {
>  	clear_page_tag_ref(page);


^ permalink raw reply

* Re: [PATCH 04/15] net: Use trace_invoke_##name() at guarded tracepoint call sites
From: Vineeth Remanan Pillai @ 2026-03-18 14:13 UTC (permalink / raw)
  To: Aaron Conole
  Cc: Steven Rostedt, Peter Zijlstra, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Stanislav Fomichev, Eelco Chaudron, Ilya Maximets,
	Marcelo Ricardo Leitner, Xin Long, Jon Maloy, Kuniyuki Iwashima,
	Samiullah Khawaja, Hangbin Liu, netdev, linux-kernel, bpf, dev,
	linux-sctp, tipc-discussion, linux-trace-kernel
In-Reply-To: <CAO7JXPhfpUb1VM_=mwSUqHPQrLvBW=wurz_apWQkMXssPAQPJA@mail.gmail.com>

On Wed, Mar 18, 2026 at 9:40 AM Vineeth Remanan Pillai
<vineeth@bitbyteword.org> wrote:
>
> On Thu, Mar 12, 2026 at 11:31 AM Aaron Conole <aconole@redhat.com> wrote:
> >
> > "Vineeth Pillai (Google)" <vineeth@bitbyteword.org> writes:
> >
> > > Replace trace_foo() with the new trace_invoke_foo() at sites already
> > > guarded by trace_foo_enabled(), avoiding a redundant
> > > static_branch_unlikely() re-evaluation inside the tracepoint.
> > > trace_invoke_foo() calls the tracepoint callbacks directly without
> > > utilizing the static branch again.
> > >
> > > Suggested-by: Steven Rostedt <rostedt@goodmis.org>
> > > Suggested-by: Peter Zijlstra <peterz@infradead.org>
> > > Signed-off-by: Vineeth Pillai (Google) <vineeth@bitbyteword.org>
> > > Assisted-by: Claude:claude-sonnet-4-6
> > > ---
> > >  net/core/dev.c             | 2 +-
> > >  net/core/xdp.c             | 2 +-
> > >  net/openvswitch/actions.c  | 2 +-
> > >  net/openvswitch/datapath.c | 2 +-
> > >  net/sctp/outqueue.c        | 2 +-
> > >  net/tipc/node.c            | 2 +-
> > >  6 files changed, 6 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/net/core/dev.c b/net/core/dev.c
> > > index 14a83f2035b93..a48fae2bbf57e 100644
> > > --- a/net/core/dev.c
> > > +++ b/net/core/dev.c
> > > @@ -6444,7 +6444,7 @@ void netif_receive_skb_list(struct list_head *head)
> > >               return;
> > >       if (trace_netif_receive_skb_list_entry_enabled()) {
> > >               list_for_each_entry(skb, head, list)
> > > -                     trace_netif_receive_skb_list_entry(skb);
> > > +                     trace_invoke_netif_receive_skb_list_entry(skb);
> > >       }
> > >       netif_receive_skb_list_internal(head);
> > >       trace_netif_receive_skb_list_exit(0);
> > > diff --git a/net/core/xdp.c b/net/core/xdp.c
> > > index 9890a30584ba7..53acc887c3434 100644
> > > --- a/net/core/xdp.c
> > > +++ b/net/core/xdp.c
> > > @@ -362,7 +362,7 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq,
> > >               xsk_pool_set_rxq_info(allocator, xdp_rxq);
> > >
> > >       if (trace_mem_connect_enabled() && xdp_alloc)
> > > -             trace_mem_connect(xdp_alloc, xdp_rxq);
> > > +             trace_invoke_mem_connect(xdp_alloc, xdp_rxq);
> > >       return 0;
> > >  }
> > >
> > > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > > index 792ca44a461da..420eb19322e85 100644
> > > --- a/net/openvswitch/actions.c
> > > +++ b/net/openvswitch/actions.c
> > > @@ -1259,7 +1259,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
> > >               int err = 0;
> > >
> > >               if (trace_ovs_do_execute_action_enabled())
> > > -                     trace_ovs_do_execute_action(dp, skb, key, a, rem);
> > > +                     trace_invoke_ovs_do_execute_action(dp, skb, key, a, rem);
> >
> > Maybe we should just remove the guard here instead of calling the
> > invoke.  That seems better to me.  It wouldn't need to belong to this
> > series.
> >
> > >               /* Actions that rightfully have to consume the skb should do it
> > >                * and return directly.
> > > diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> > > index e209099218b41..02451629e888e 100644
> > > --- a/net/openvswitch/datapath.c
> > > +++ b/net/openvswitch/datapath.c
> > > @@ -335,7 +335,7 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
> > >       int err;
> > >
> > >       if (trace_ovs_dp_upcall_enabled())
> > > -             trace_ovs_dp_upcall(dp, skb, key, upcall_info);
> > > +             trace_invoke_ovs_dp_upcall(dp, skb, key, upcall_info);
> >
> > Same as above.  Seems OVS tracepoints are the only ones that include
> > the guard without any real reason.
> >
>
> Makes sense. Its simple enough that I think I will include it as a
> separate patch in v2 and remove these changes from this patch. Thanks
> for pointing it out.
>
On a second look, I'm not sure if this was for performance reasons.
The discussion in the io_uring patch in this series points out that
the check made there was deliberate and for performance reasons to
avoid 6 mov instruction in the hot path. Just wanted to double check
if that was the case here, before I remove the check?

Thanks,
Vineeth

^ permalink raw reply

* Re: [PATCH v4] lib/bootconfig: guard xbc_node_compose_key_after() buffer size
From: Steven Rostedt @ 2026-03-18 13:45 UTC (permalink / raw)
  To: Masami Hiramatsu (Google)
  Cc: Josh Law, Andrew Morton, linux-kernel, linux-trace-kernel
In-Reply-To: <20260318090243.7c437f2c5e07a1ce00375102@kernel.org>

On Wed, 18 Mar 2026 09:02:43 +0900
Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:

> > This was somewhat my idea. Why do you think it's over engineering?
> > 
> > This is your code, so you have final say. I'm not going to push it. I'm
> > just curious to your thoughts.  
> 
> I sent a mail why I thought this is over engineering. I think this
> comes from vsnprintf() interface design. If all user of that needs
> to do this, that is not fair. It should be checked in vsnprintf()
> and caller should just check the returned error.

I wouldn't call this over-engineering. The reason you gave is more about
the checks being simply in the inappropriate location.

Over-engineering is if the patch had created 5 different macros to see if
the value passed to snprintf() was size_t and could be greater than MAX_INT,
and it used the trick of TRACE_EVENT() to create the code to do those
checks. Now THAT would be over-engineering! ;-)

-- Steve

^ permalink raw reply

* Re: [PATCH 04/15] net: Use trace_invoke_##name() at guarded tracepoint call sites
From: Vineeth Remanan Pillai @ 2026-03-18 13:40 UTC (permalink / raw)
  To: Aaron Conole
  Cc: Steven Rostedt, Peter Zijlstra, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Stanislav Fomichev, Eelco Chaudron, Ilya Maximets,
	Marcelo Ricardo Leitner, Xin Long, Jon Maloy, Kuniyuki Iwashima,
	Samiullah Khawaja, Hangbin Liu, netdev, linux-kernel, bpf, dev,
	linux-sctp, tipc-discussion, linux-trace-kernel
In-Reply-To: <f7to6ktnjxi.fsf@redhat.com>

On Thu, Mar 12, 2026 at 11:31 AM Aaron Conole <aconole@redhat.com> wrote:
>
> "Vineeth Pillai (Google)" <vineeth@bitbyteword.org> writes:
>
> > Replace trace_foo() with the new trace_invoke_foo() at sites already
> > guarded by trace_foo_enabled(), avoiding a redundant
> > static_branch_unlikely() re-evaluation inside the tracepoint.
> > trace_invoke_foo() calls the tracepoint callbacks directly without
> > utilizing the static branch again.
> >
> > Suggested-by: Steven Rostedt <rostedt@goodmis.org>
> > Suggested-by: Peter Zijlstra <peterz@infradead.org>
> > Signed-off-by: Vineeth Pillai (Google) <vineeth@bitbyteword.org>
> > Assisted-by: Claude:claude-sonnet-4-6
> > ---
> >  net/core/dev.c             | 2 +-
> >  net/core/xdp.c             | 2 +-
> >  net/openvswitch/actions.c  | 2 +-
> >  net/openvswitch/datapath.c | 2 +-
> >  net/sctp/outqueue.c        | 2 +-
> >  net/tipc/node.c            | 2 +-
> >  6 files changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/net/core/dev.c b/net/core/dev.c
> > index 14a83f2035b93..a48fae2bbf57e 100644
> > --- a/net/core/dev.c
> > +++ b/net/core/dev.c
> > @@ -6444,7 +6444,7 @@ void netif_receive_skb_list(struct list_head *head)
> >               return;
> >       if (trace_netif_receive_skb_list_entry_enabled()) {
> >               list_for_each_entry(skb, head, list)
> > -                     trace_netif_receive_skb_list_entry(skb);
> > +                     trace_invoke_netif_receive_skb_list_entry(skb);
> >       }
> >       netif_receive_skb_list_internal(head);
> >       trace_netif_receive_skb_list_exit(0);
> > diff --git a/net/core/xdp.c b/net/core/xdp.c
> > index 9890a30584ba7..53acc887c3434 100644
> > --- a/net/core/xdp.c
> > +++ b/net/core/xdp.c
> > @@ -362,7 +362,7 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq,
> >               xsk_pool_set_rxq_info(allocator, xdp_rxq);
> >
> >       if (trace_mem_connect_enabled() && xdp_alloc)
> > -             trace_mem_connect(xdp_alloc, xdp_rxq);
> > +             trace_invoke_mem_connect(xdp_alloc, xdp_rxq);
> >       return 0;
> >  }
> >
> > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > index 792ca44a461da..420eb19322e85 100644
> > --- a/net/openvswitch/actions.c
> > +++ b/net/openvswitch/actions.c
> > @@ -1259,7 +1259,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
> >               int err = 0;
> >
> >               if (trace_ovs_do_execute_action_enabled())
> > -                     trace_ovs_do_execute_action(dp, skb, key, a, rem);
> > +                     trace_invoke_ovs_do_execute_action(dp, skb, key, a, rem);
>
> Maybe we should just remove the guard here instead of calling the
> invoke.  That seems better to me.  It wouldn't need to belong to this
> series.
>
> >               /* Actions that rightfully have to consume the skb should do it
> >                * and return directly.
> > diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
> > index e209099218b41..02451629e888e 100644
> > --- a/net/openvswitch/datapath.c
> > +++ b/net/openvswitch/datapath.c
> > @@ -335,7 +335,7 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
> >       int err;
> >
> >       if (trace_ovs_dp_upcall_enabled())
> > -             trace_ovs_dp_upcall(dp, skb, key, upcall_info);
> > +             trace_invoke_ovs_dp_upcall(dp, skb, key, upcall_info);
>
> Same as above.  Seems OVS tracepoints are the only ones that include
> the guard without any real reason.
>

Makes sense. Its simple enough that I think I will include it as a
separate patch in v2 and remove these changes from this patch. Thanks
for pointing it out.

Thanks,
Vineeth

^ permalink raw reply

* Re: [PATCH] blk-mq: add tracepoint block_rq_tag_wait
From: Aaron Tomlin @ 2026-03-18 13:21 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: axboe, rostedt, mhiramat, mathieu.desnoyers, johannes.thumshirn,
	kch, bvanassche, ritesh.list, neelx, sean, mproche, linux-block,
	linux-kernel, linux-trace-kernel
In-Reply-To: <e7db667e-2662-4ad9-89cd-309c457ce17e@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 2442 bytes --]

On Wed, Mar 18, 2026 at 08:38:20AM +0900, Damien Le Moal wrote:
> Looks OK to me, but I have some suggestions below.

Hi Damien,

Thank you for your feedback.

> > +/**
> > + * block_rq_tag_wait - triggered when an I/O request is starved of a
> > tag
> 
> when an I/O request -> when a request

Acknowledged.

> 
> > + * @q: queue containing the request
> 
> request queue of the target device
> 
> ("containing" is odd here)

Acknowledged.

> > + * @hctx: hardware context (queue) experiencing starvation
> 
> hardware context of the request

Acknowledged.

> > + *
> > + * Called immediately before the submitting thread is forced to block due
> 
> the submitting thread -> the submitting context

Acknowledged.

> 
> > + * to the exhaustion of available hardware tags. This tracepoint indicates
> 
> s/tracepoint/trace point

Acknowledged.

> 
> > + * that the thread will be placed into an uninterruptible state via
> 
> s/thread/context

Acknowledged.

> 
> > + * io_schedule() until an active block I/O operation completes and
> > + * relinquishes its assigned tag.
> 
> until an active request completes
> 

Acknowledged.

> > + */
> > +TRACE_EVENT(block_rq_tag_wait,
> > +
> > +	TP_PROTO(struct request_queue *q, struct blk_mq_hw_ctx *hctx),
> > +
> > +	TP_ARGS(q, hctx),
> > +
> > +	TP_STRUCT__entry(
> > +		__field( dev_t,		dev			)
> > +		__field( u32,		hctx_id			)
> > +		__field( u32,		nr_tags			)
> > +		__field( u32,		active_requests		)
> > +	),
> > +
> > +	TP_fast_assign(
> > +		__entry->dev		  = q->disk ? disk_devt(q->disk) : 0;
> 
> I do not think that q->disk can ever be NULL when there is a request being
> submitted.

Yes, I agree. In theory, a race with disk_release() cannot occur since the
gendisk reference counter would still be elevated here.

> 
> > +		__entry->hctx_id	  = hctx ? hctx->queue_num : 0;
> > +		__entry->nr_tags	  = hctx && hctx->tags ? hctx->tags->nr_tags : 0;
> > +		__entry->active_requests  = hctx ? atomic_read(&hctx->nr_active) : 0;
> > +	),
> > +
> > +	TP_printk("%d,%d hctx=%u starved (active=%u/%u)",
> > +		  MAJOR(__entry->dev), MINOR(__entry->dev),
> > +		  __entry->hctx_id, __entry->active_requests, __entry->nr_tags)
> > +);
> > +
> >  /**
> >   * block_rq_insert - insert block operation request into queue
> >   * @rq: block IO operation request


Kind regards,
-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] blk-mq: add tracepoint block_rq_tag_wait
From: Laurence Oberman @ 2026-03-18 13:10 UTC (permalink / raw)
  To: Damien Le Moal, Aaron Tomlin, axboe, rostedt, mhiramat,
	mathieu.desnoyers
  Cc: johannes.thumshirn, kch, bvanassche, ritesh.list, neelx, sean,
	mproche, linux-block, linux-kernel, linux-trace-kernel
In-Reply-To: <e7db667e-2662-4ad9-89cd-309c457ce17e@kernel.org>

On Wed, 2026-03-18 at 08:38 +0900, Damien Le Moal wrote:
> On 2026/03/18 3:28, Aaron Tomlin wrote:
> > In high-performance storage environments, particularly when
> > utilising
> > RAID controllers with shared tag sets (BLK_MQ_F_TAG_HCTX_SHARED),
> > severe
> > latency spikes can occur when fast devices (SSDs) are starved of
> > hardware
> > tags when sharing the same blk_mq_tag_set.
> > 
> > Currently, diagnosing this specific hardware queue contention is
> > difficult. When a CPU thread exhausts the tag pool,
> > blk_mq_get_tag()
> > forces the current thread to block uninterruptible via
> > io_schedule().
> > While this can be inferred via sched:sched_switch or dynamically
> > traced by attaching a kprobe to blk_mq_mark_tag_wait(), there is no
> > dedicated, out-of-the-box observability for this event.
> > 
> > This patch introduces the block_rq_tag_wait static tracepoint in
> > the tag allocation slow-path. It triggers immediately before the
> > thread yields the CPU, exposing the exact hardware context (hctx)
> > that is starved, the total pool size, and the current active
> > request
> > count.
> > 
> > This provides storage engineers and performance monitoring agents
> > with a zero-configuration, low-overhead mechanism to definitively
> > identify shared-tag bottlenecks and tune I/O schedulers or cgroup
> > throttling accordingly.
> > 
> > Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
> 
> Looks OK to me, but I have some suggestions below.
> 
> > ---
> >  block/blk-mq-tag.c           |  3 +++
> >  include/trace/events/block.h | 36
> > ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 39 insertions(+)
> > 
> > diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
> > index 33946cdb5716..f50993e86ca5 100644
> > --- a/block/blk-mq-tag.c
> > +++ b/block/blk-mq-tag.c
> > @@ -13,6 +13,7 @@
> >  #include <linux/kmemleak.h>
> >  
> >  #include <linux/delay.h>
> > +#include <trace/events/block.h>
> >  #include "blk.h"
> >  #include "blk-mq.h"
> >  #include "blk-mq-sched.h"
> > @@ -187,6 +188,8 @@ unsigned int blk_mq_get_tag(struct
> > blk_mq_alloc_data *data)
> >  		if (tag != BLK_MQ_NO_TAG)
> >  			break;
> >  
> > +		trace_block_rq_tag_wait(data->q, data->hctx);
> > +
> >  		bt_prev = bt;
> >  		io_schedule();
> >  
> > diff --git a/include/trace/events/block.h
> > b/include/trace/events/block.h
> > index 6aa79e2d799c..48e2ba433c87 100644
> > --- a/include/trace/events/block.h
> > +++ b/include/trace/events/block.h
> > @@ -226,6 +226,42 @@ DECLARE_EVENT_CLASS(block_rq,
> >  		  IOPRIO_PRIO_LEVEL(__entry->ioprio), __entry-
> > >comm)
> >  );
> >  
> > +/**
> > + * block_rq_tag_wait - triggered when an I/O request is starved of
> > a tag
> 
> when an I/O request -> when a request
> 
> > + * @q: queue containing the request
> 
> request queue of the target device
> 
> ("containing" is odd here)
> 
> > + * @hctx: hardware context (queue) experiencing starvation
> 
> hardware context of the request
> 
> > + *
> > + * Called immediately before the submitting thread is forced to
> > block due
> 
> the submitting thread -> the submitting context
> 
> > + * to the exhaustion of available hardware tags. This tracepoint
> > indicates
> 
> s/tracepoint/trace point
> 
> > + * that the thread will be placed into an uninterruptible state
> > via
> 
> s/thread/context
> 
> > + * io_schedule() until an active block I/O operation completes and
> > + * relinquishes its assigned tag.
> 
> until an active request completes
> 
> (BIOs do not have tags).
> 
> > + */
> > +TRACE_EVENT(block_rq_tag_wait,
> > +
> > +	TP_PROTO(struct request_queue *q, struct blk_mq_hw_ctx
> > *hctx),
> > +
> > +	TP_ARGS(q, hctx),
> > +
> > +	TP_STRUCT__entry(
> > +		__field(
> > dev_t,		dev			)
> > +		__field(
> > u32,		hctx_id			)
> > +		__field(
> > u32,		nr_tags			)
> > +		__field(
> > u32,		active_requests		)
> > +	),
> > +
> > +	TP_fast_assign(
> > +		__entry->dev		  = q->disk ? disk_devt(q-
> > >disk) : 0;
> 
> I do not think that q->disk can ever be NULL when there is a request
> being
> submitted.
> 
> > +		__entry->hctx_id	  = hctx ? hctx->queue_num
> > : 0;
> > +		__entry->nr_tags	  = hctx && hctx->tags ?
> > hctx->tags->nr_tags : 0;
> > +		__entry->active_requests  = hctx ?
> > atomic_read(&hctx->nr_active) : 0;
> > +	),
> > +
> > +	TP_printk("%d,%d hctx=%u starved (active=%u/%u)",
> > +		  MAJOR(__entry->dev), MINOR(__entry->dev),
> > +		  __entry->hctx_id, __entry->active_requests,
> > __entry->nr_tags)
> > +);
> > +
> >  /**
> >   * block_rq_insert - insert block operation request into queue
> >   * @rq: block IO operation request
> 

This visibility will be very useful. I plan to test it fully.
Updates to follow
Thanks
Laurence Oberman


^ permalink raw reply

* Re: [PATCH v7 14/15] rv: Add deadline monitors
From: gmonaco @ 2026-03-18 12:00 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: <abLBnlqIHVPEcisP@jlelli-thinkpadt14gen4.remote.csb>

Hello,

On Thu, 2026-03-12 at 14:37 +0100, Juri Lelli wrote:
> > +/* Used by other monitors */
> > +struct sched_class *rv_ext_sched_class;
> > +
> > +static int __init register_deadline(void)
> > +{
> > +	if (IS_ENABLED(CONFIG_SCHED_CLASS_EXT))
> > +		rv_ext_sched_class = (void
> > *)kallsyms_lookup_name("ext_sched_class");
> 
> Looks like the above look up can fail. I don't actually see how/why
> if would fail if things build correctly and EXT tasks are around.
> But, theoretically, we could end up with rv_ext_sched_class = NULL ?
> 
> > +static inline bool task_is_scx_enabled(struct task_struct *tsk)
> > +{
> > +	return IS_ENABLED(CONFIG_SCHED_CLASS_EXT) &&
> > +	       tsk->sched_class == rv_ext_sched_class;
> > +}
> > +
> > +/* Expand id and target as arguments for da functions */
> > +#define EXPAND_ID(dl_se, cpu, type) get_entity_id(dl_se, cpu,
> > type), dl_se
> > +#define EXPAND_ID_TASK(tsk) get_entity_id(&tsk->dl, task_cpu(tsk),
> > DL_TASK), &tsk->dl
> > +
> > +static inline uint8_t get_server_type(struct task_struct *tsk)
> > +{
> > +	if (tsk->policy == SCHED_NORMAL || tsk->policy ==
> > SCHED_EXT ||
> > +	    tsk->policy == SCHED_BATCH || tsk->policy ==
> > SCHED_IDLE)
> > +		return task_is_scx_enabled(tsk) ? DL_SERVER_EXT :
> > DL_SERVER_FAIR;
> > +	return DL_OTHER;
> > +}
> 
> Considering that, if that happens, get_server_type() will return
> DL_SERVER_FAIR for scx tasks as well (possibly confusing monitors?),
> shall we add a warn or something just in case. A 'no we don't need
> that
> because it can't happen' works for me, just thought I should still
> mention this. :)

I forgot answering..

Well, technically yes, this all can fail.
I figured a silent degradation in this remote case would be alright,
but probably just print it during initialisation wouldn't hurt.

We cannot do much if it really happened and, yes, monitors would likely
fail if both SCX and fair servers coexist.
I'd assume it /should/ never happen, but it costs nothing adding:

  pr_warn("Error detecting the ext class, monitors may report wrong
results.\n");

Thanks,
Gabriele


^ permalink raw reply

* [PATCH 8/8] memblock: warn when freeing reserved memory before memory map is initialized
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

When CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, freeing of reserved
memory before the memory map is fully initialized in deferred_init_memmap()
would cause access to uninitialized struct pages and may crash when
accessing spurious list pointers, like was recently discovered during
discussion about memory leaks in x86 EFI code [1].

The trace below is from an attempt to call free_reserved_page() before
page_alloc_init_late():

[    0.076840] BUG: unable to handle page fault for address: ffffce1a005a0788
[    0.078226] #PF: supervisor read access in kernel mode
[    0.078226] #PF: error_code(0x0000) - not-present page
[    0.078226] PGD 0 P4D 0
[    0.078226] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
[    0.078226] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.68-92.123.amzn2023.x86_64 #1
[    0.078226] Hardware name: Amazon EC2 t3a.nano/, BIOS 1.0 10/16/2017
[    0.078226] RIP: 0010:__list_del_entry_valid_or_report+0x32/0xb0
...
[    0.078226]  __free_one_page+0x170/0x520
[    0.078226]  free_pcppages_bulk+0x151/0x1e0
[    0.078226]  free_unref_page_commit+0x263/0x320
[    0.078226]  free_unref_page+0x2c8/0x5b0
[    0.078226]  ? srso_return_thunk+0x5/0x5f
[    0.078226]  free_reserved_page+0x1c/0x30
[    0.078226]  memblock_free_late+0x6c/0xc0

Currently there are not many callers of free_reserved_area() and they all
appear to be at the right timings.

Still, in order to protect against problematic code moves or additions of
new callers add a warning that will inform that reserved pages cannot be
freed until the memory map is fully initialized.

[1] https://lore.kernel.org/all/e5d5a1105d90ee1e7fe7eafaed2ed03bbad0c46b.camel@kernel.crashing.org/

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 mm/internal.h   | 10 ++++++++++
 mm/memblock.c   |  5 +++++
 mm/page_alloc.c | 10 ----------
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/mm/internal.h b/mm/internal.h
index cb0af847d7d9..f60c1edb2e02 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1233,7 +1233,17 @@ static inline void vunmap_range_noflush(unsigned long start, unsigned long end)
 #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
 DECLARE_STATIC_KEY_TRUE(deferred_pages);
 
+static inline bool deferred_pages_enabled(void)
+{
+	return static_branch_unlikely(&deferred_pages);
+}
+
 bool __init deferred_grow_zone(struct zone *zone, unsigned int order);
+#else
+static inline bool deferred_pages_enabled(void)
+{
+	return false;
+}
 #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
 
 void init_deferred_page(unsigned long pfn, int nid);
diff --git a/mm/memblock.c b/mm/memblock.c
index bd5758ff07f2..780e70d4971a 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -896,6 +896,11 @@ static unsigned long __free_reserved_area(phys_addr_t start, phys_addr_t end,
 {
 	unsigned long pages = 0, pfn;
 
+	if (deferred_pages_enabled()) {
+		WARN(1, "Cannot free reserved memory because of deferred initialization of the memory map");
+		return 0;
+	}
+
 	for_each_valid_pfn(pfn, PFN_UP(start), PFN_DOWN(end)) {
 		struct page *page = pfn_to_page(pfn);
 		void *direct_map_addr;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index df3d61253001..9ac47bab2ea7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -331,11 +331,6 @@ int page_group_by_mobility_disabled __read_mostly;
  */
 DEFINE_STATIC_KEY_TRUE(deferred_pages);
 
-static inline bool deferred_pages_enabled(void)
-{
-	return static_branch_unlikely(&deferred_pages);
-}
-
 /*
  * deferred_grow_zone() is __init, but it is called from
  * get_page_from_freelist() during early boot until deferred_pages permanently
@@ -348,11 +343,6 @@ _deferred_grow_zone(struct zone *zone, unsigned int order)
 	return deferred_grow_zone(zone, order);
 }
 #else
-static inline bool deferred_pages_enabled(void)
-{
-	return false;
-}
-
 static inline bool _deferred_grow_zone(struct zone *zone, unsigned int order)
 {
 	return false;
-- 
2.51.0


^ permalink raw reply related

* [PATCH 7/8] memblock, treewide: make memblock_free() handle late freeing
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

It shouldn't be responsibility of memblock users to detect if they free
memory allocated from memblock late and should use memblock_free_late().

Make memblock_free() and memblock_phys_free() take care of late memory
freeing and drop memblock_free_late().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 arch/sparc/kernel/mdesc.c               |  4 +--
 arch/x86/kernel/setup.c                 |  2 +-
 arch/x86/platform/efi/memmap.c          |  5 +---
 arch/x86/platform/efi/quirks.c          |  2 +-
 drivers/firmware/efi/apple-properties.c |  2 +-
 drivers/of/kexec.c                      |  2 +-
 include/linux/memblock.h                |  2 --
 kernel/dma/swiotlb.c                    |  6 ++--
 lib/bootconfig.c                        |  2 +-
 mm/kfence/core.c                        |  4 +--
 mm/memblock.c                           | 37 +++++++------------------
 11 files changed, 22 insertions(+), 46 deletions(-)

diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 30f171b7b00c..ecd6c8ae49c7 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -183,14 +183,12 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size
 static void __init mdesc_memblock_free(struct mdesc_handle *hp)
 {
 	unsigned int alloc_size;
-	unsigned long start;
 
 	BUG_ON(refcount_read(&hp->refcnt) != 0);
 	BUG_ON(!list_empty(&hp->list));
 
 	alloc_size = PAGE_ALIGN(hp->handle_size);
-	start = __pa(hp);
-	memblock_free_late(start, alloc_size);
+	memblock_free(hp, alloc_size);
 }
 
 static struct mdesc_mem_ops memblock_mdesc_ops = {
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index eebcc9db1a1b..46882ce79c3a 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,7 +426,7 @@ int __init ima_free_kexec_buffer(void)
 	if (!ima_kexec_buffer_size)
 		return -ENOENT;
 
-	memblock_free_late(ima_kexec_buffer_phys,
+	memblock_phys_free(ima_kexec_buffer_phys,
 			   ima_kexec_buffer_size);
 
 	ima_kexec_buffer_phys = 0;
diff --git a/arch/x86/platform/efi/memmap.c b/arch/x86/platform/efi/memmap.c
index 023697c88910..697a9a26a005 100644
--- a/arch/x86/platform/efi/memmap.c
+++ b/arch/x86/platform/efi/memmap.c
@@ -34,10 +34,7 @@ static
 void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags)
 {
 	if (flags & EFI_MEMMAP_MEMBLOCK) {
-		if (slab_is_available())
-			memblock_free_late(phys, size);
-		else
-			memblock_phys_free(phys, size);
+		memblock_phys_free(phys, size);
 	} else if (flags & EFI_MEMMAP_SLAB) {
 		struct page *p = pfn_to_page(PHYS_PFN(phys));
 		unsigned int order = get_order(size);
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 35caa5746115..a560bbcaa006 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -372,7 +372,7 @@ void __init efi_reserve_boot_services(void)
 		 * doesn't make sense as far as the firmware is
 		 * concerned, but it does provide us with a way to tag
 		 * those regions that must not be paired with
-		 * memblock_free_late().
+		 * memblock_phys_free().
 		 */
 		md->attribute |= EFI_MEMORY_RUNTIME;
 	}
diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c
index 13ac28754c03..2e525e17fba7 100644
--- a/drivers/firmware/efi/apple-properties.c
+++ b/drivers/firmware/efi/apple-properties.c
@@ -226,7 +226,7 @@ static int __init map_properties(void)
 		 */
 		data->len = 0;
 		memunmap(data);
-		memblock_free_late(pa_data + sizeof(*data), data_len);
+		memblock_phys_free(pa_data + sizeof(*data), data_len);
 
 		return ret;
 	}
diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
index c4cf3552c018..512d9be9d513 100644
--- a/drivers/of/kexec.c
+++ b/drivers/of/kexec.c
@@ -175,7 +175,7 @@ int __init ima_free_kexec_buffer(void)
 	if (ret)
 		return ret;
 
-	memblock_free_late(addr, size);
+	memblock_phys_free(addr, size);
 	return 0;
 }
 #endif
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 6ec5e9ac0699..6f6c5b5c4a4b 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -172,8 +172,6 @@ void __next_mem_range_rev(u64 *idx, int nid, enum memblock_flags flags,
 			  struct memblock_type *type_b, phys_addr_t *out_start,
 			  phys_addr_t *out_end, int *out_nid);
 
-void memblock_free_late(phys_addr_t base, phys_addr_t size);
-
 #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
 static inline void __next_physmem_range(u64 *idx, struct memblock_type *type,
 					phys_addr_t *out_start,
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index d8e6f1d889d5..e44e039e00d3 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -546,10 +546,10 @@ void __init swiotlb_exit(void)
 		free_pages(tbl_vaddr, get_order(tbl_size));
 		free_pages((unsigned long)mem->slots, get_order(slots_size));
 	} else {
-		memblock_free_late(__pa(mem->areas),
+		memblock_free(mem->areas,
 			array_size(sizeof(*mem->areas), mem->nareas));
-		memblock_free_late(mem->start, tbl_size);
-		memblock_free_late(__pa(mem->slots), slots_size);
+		memblock_phys_free(mem->start, tbl_size);
+		memblock_free(mem->slots, slots_size);
 	}
 
 	memset(mem, 0, sizeof(*mem));
diff --git a/lib/bootconfig.c b/lib/bootconfig.c
index 449369a60846..86a75bf636bc 100644
--- a/lib/bootconfig.c
+++ b/lib/bootconfig.c
@@ -64,7 +64,7 @@ static inline void __init xbc_free_mem(void *addr, size_t size, bool early)
 	if (early)
 		memblock_free(addr, size);
 	else if (addr)
-		memblock_free_late(__pa(addr), size);
+		memblock_free(addr, size);
 }
 
 #else /* !__KERNEL__ */
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 7393957f9a20..5c8268af533e 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -731,10 +731,10 @@ static bool __init kfence_init_pool_early(void)
 	 * fails for the first page, and therefore expect addr==__kfence_pool in
 	 * most failure cases.
 	 */
-	memblock_free_late(__pa(addr), KFENCE_POOL_SIZE - (addr - (unsigned long)__kfence_pool));
+	memblock_free((void *)addr, KFENCE_POOL_SIZE - (addr - (unsigned long)__kfence_pool));
 	__kfence_pool = NULL;
 
-	memblock_free_late(__pa(kfence_metadata_init), KFENCE_METADATA_SIZE);
+	memblock_free(kfence_metadata_init, KFENCE_METADATA_SIZE);
 	kfence_metadata_init = NULL;
 
 	return false;
diff --git a/mm/memblock.c b/mm/memblock.c
index 9f372a8e82f7..bd5758ff07f2 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -384,26 +384,24 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u
  */
 void __init memblock_discard(void)
 {
-	phys_addr_t addr, size;
+	phys_addr_t size;
 
 	if (memblock.reserved.regions != memblock_reserved_init_regions) {
-		addr = __pa(memblock.reserved.regions);
 		size = PAGE_ALIGN(sizeof(struct memblock_region) *
 				  memblock.reserved.max);
 		if (memblock_reserved_in_slab)
 			kfree(memblock.reserved.regions);
 		else
-			memblock_free_late(addr, size);
+			memblock_free(memblock.reserved.regions, size);
 	}
 
 	if (memblock.memory.regions != memblock_memory_init_regions) {
-		addr = __pa(memblock.memory.regions);
 		size = PAGE_ALIGN(sizeof(struct memblock_region) *
 				  memblock.memory.max);
 		if (memblock_memory_in_slab)
 			kfree(memblock.memory.regions);
 		else
-			memblock_free_late(addr, size);
+			memblock_free(memblock.memory.regions, size);
 	}
 
 	memblock_memory = NULL;
@@ -961,7 +959,8 @@ unsigned long free_reserved_area(void *start, void *end, int poison, const char
  * @size: size of the boot memory block in bytes
  *
  * Free boot memory block previously allocated by memblock_alloc_xx() API.
- * The freeing memory will not be released to the buddy allocator.
+ * If called after the buddy allocator is available, the memory is released to
+ * the buddy allocator.
  */
 void __init_memblock memblock_free(void *ptr, size_t size)
 {
@@ -975,7 +974,8 @@ void __init_memblock memblock_free(void *ptr, size_t size)
  * @size: size of the boot memory block in bytes
  *
  * Free boot memory block previously allocated by memblock_phys_alloc_xx() API.
- * The freeing memory will not be released to the buddy allocator.
+ * If called after the buddy allocator is available, the memory is released to
+ * the buddy allocator.
  */
 int __init_memblock memblock_phys_free(phys_addr_t base, phys_addr_t size)
 {
@@ -985,6 +985,9 @@ int __init_memblock memblock_phys_free(phys_addr_t base, phys_addr_t size)
 		     &base, &end, (void *)_RET_IP_);
 
 	kmemleak_free_part_phys(base, size);
+	if (slab_is_available())
+		__free_reserved_area(base, base + size, -1);
+
 	return memblock_remove_range(&memblock.reserved, base, size);
 }
 
@@ -1813,26 +1816,6 @@ void *__init __memblock_alloc_or_panic(phys_addr_t size, phys_addr_t align,
 	return addr;
 }
 
-/**
- * memblock_free_late - free pages directly to buddy allocator
- * @base: phys starting address of the  boot memory block
- * @size: size of the boot memory block in bytes
- *
- * This is only useful when the memblock allocator has already been torn
- * down, but we are still initializing the system.  Pages are released directly
- * to the buddy allocator.
- */
-void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
-{
-	phys_addr_t end = base + size - 1;
-
-	memblock_dbg("%s: [%pa-%pa] %pS\n",
-		     __func__, &base, &end, (void *)_RET_IP_);
-
-	kmemleak_free_part_phys(base, size);
-	__free_reserved_area(base, base + size, -1);
-}
-
 /*
  * Remaining API functions
  */
-- 
2.51.0


^ permalink raw reply related

* [PATCH 6/8] memblock: make free_reserved_area() update memblock if ARCH_KEEP_MEMBLOCK=y
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

On architectures that keep memblock after boot, freeing of reserved memory
with free_reserved_area() is paired with an update of memblock arrays,
usually by a call to memblock_free().

Make free_reserved_area() directly update memblock.reserved when
ARCH_KEEP_MEMBLOCK is enabled.

Remove the now-redundant explicit memblock_free() call from
arm64::free_initmem() and the #ifdef CONFIG_ARCH_KEEP_MEMBLOCK block
from the generic free_initrd_mem().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 arch/arm64/mm/init.c | 3 ---
 init/initramfs.c     | 7 -------
 mm/memblock.c        | 6 ++++++
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 96711b8578fd..07b17c708702 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -385,9 +385,6 @@ void free_initmem(void)
 	WARN_ON(!IS_ALIGNED((unsigned long)lm_init_begin, PAGE_SIZE));
 	WARN_ON(!IS_ALIGNED((unsigned long)lm_init_end, PAGE_SIZE));
 
-	/* Delete __init region from memblock.reserved. */
-	memblock_free(lm_init_begin, lm_init_end - lm_init_begin);
-
 	free_reserved_area(lm_init_begin, lm_init_end,
 			   POISON_FREE_INITMEM, "unused kernel");
 	/*
diff --git a/init/initramfs.c b/init/initramfs.c
index 139baed06589..bca0922b2850 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -652,13 +652,6 @@ void __init reserve_initrd_mem(void)
 
 void __weak __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-#ifdef CONFIG_ARCH_KEEP_MEMBLOCK
-	unsigned long aligned_start = ALIGN_DOWN(start, PAGE_SIZE);
-	unsigned long aligned_end = ALIGN(end, PAGE_SIZE);
-
-	memblock_free((void *)aligned_start, aligned_end - aligned_start);
-#endif
-
 	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
 			"initrd");
 }
diff --git a/mm/memblock.c b/mm/memblock.c
index 87bd200a8cc9..9f372a8e82f7 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -942,6 +942,12 @@ unsigned long free_reserved_area(void *start, void *end, int poison, const char
 		end_pa = __pa(end - 1) + 1;
 	}
 
+	if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK)) {
+		if (start_pa < end_pa)
+			memblock_remove_range(&memblock.reserved,
+					      start_pa, end_pa - start_pa);
+	}
+
 	pages = __free_reserved_area(start_pa, end_pa, poison);
 	if (pages && s)
 		pr_info("Freeing %s memory: %ldK\n", s, K(pages));
-- 
2.51.0


^ permalink raw reply related

* [PATCH 5/8] memblock: extract page freeing from free_reserved_area() into a helper
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

There are two functions that release pages to the buddy allocator late in
the boot: free_reserved_area() and memblock_free_late().

Currently they are using different underlying functionality,
free_reserved_area() runs each page being freed via free_reserved_page()
and memblock_free_late() uses memblock_free_pages() -> __free_pages_core(),
but in the end they both boil down to a loop that frees a range page by
page.

Extract the loop frees pages from free_reserved_area() into a helper and
use that helper in memblock_free_late().

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 mm/memblock.c | 55 +++++++++++++++++++++++++++------------------------
 1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 27d4c9889b59..87bd200a8cc9 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -893,26 +893,12 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
 	return memblock_remove_range(&memblock.memory, base, size);
 }
 
-unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
+static unsigned long __free_reserved_area(phys_addr_t start, phys_addr_t end,
+					  int poison)
 {
-	phys_addr_t start_pa, end_pa;
 	unsigned long pages = 0, pfn;
 
-	/*
-	 * end is the first address past the region and it may be beyond what
-	 * __pa() or __pa_symbol() can handle.
-	 * Use the address included in the range for the cnversion and add back
-	 * 1 afterwards.
-	 */
-	if (__is_kernel((unsigned long)start)) {
-		start_pa = __pa_symbol(start);
-		end_pa = __pa_symbol(end - 1) + 1;
-	} else {
-		start_pa = __pa(start);
-		end_pa = __pa(end - 1) + 1;
-	}
-
-	for_each_valid_pfn(pfn, PFN_UP(start_pa), PFN_DOWN(end_pa)) {
+	for_each_valid_pfn(pfn, PFN_UP(start), PFN_DOWN(end)) {
 		struct page *page = pfn_to_page(pfn);
 		void *direct_map_addr;
 
@@ -934,7 +920,29 @@ unsigned long free_reserved_area(void *start, void *end, int poison, const char
 		free_reserved_page(page);
 		pages++;
 	}
+	return pages;
+}
+
+unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
+{
+	phys_addr_t start_pa, end_pa;
+	unsigned long pages;
+
+	/*
+	 * end is the first address past the region and it may be beyond what
+	 * __pa() or __pa_symbol() can handle.
+	 * Use the address included in the range for the cnversion and add back
+	 * 1 afterwards.
+	 */
+	if (__is_kernel((unsigned long)start)) {
+		start_pa = __pa_symbol(start);
+		end_pa = __pa_symbol(end - 1) + 1;
+	} else {
+		start_pa = __pa(start);
+		end_pa = __pa(end - 1) + 1;
+	}
 
+	pages = __free_reserved_area(start_pa, end_pa, poison);
 	if (pages && s)
 		pr_info("Freeing %s memory: %ldK\n", s, K(pages));
 
@@ -1810,20 +1818,15 @@ void *__init __memblock_alloc_or_panic(phys_addr_t size, phys_addr_t align,
  */
 void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
 {
-	phys_addr_t cursor, end;
+	phys_addr_t end = base + size - 1;
 
-	end = base + size - 1;
 	memblock_dbg("%s: [%pa-%pa] %pS\n",
 		     __func__, &base, &end, (void *)_RET_IP_);
-	kmemleak_free_part_phys(base, size);
-	cursor = PFN_UP(base);
-	end = PFN_DOWN(base + size);
 
-	for (; cursor < end; cursor++) {
-		memblock_free_pages(cursor, 0);
-		totalram_pages_inc();
-	}
+	kmemleak_free_part_phys(base, size);
+	__free_reserved_area(base, base + size, -1);
 }
+
 /*
  * Remaining API functions
  */
-- 
2.51.0


^ permalink raw reply related

* [PATCH 4/8] memblock: make free_reserved_area() more robust
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

There are two potential problems in free_reserved_area():
* it may free a page with not-existent buddy page
* it may be passed a virtual address from an alias mapping that won't
  be properly translated by virt_to_page(), for example a symbol on arm64

While first issue is quite theoretical and the second one does not manifest
itself because all the callers do the right thing, it is easy to make
free_reserved_area() robust enough to avoid these potential issues.

Replace the loop by virtual address with a loop by pfn that uses
for_each_valid_pfn() and use __pa() or __pa_symbol() depending on the
virtual mapping alias to correctly determine the loop boundaries.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 mm/memblock.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 8f3010dddc58..27d4c9889b59 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -895,21 +895,32 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
 
 unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
 {
-	void *pos;
-	unsigned long pages = 0;
+	phys_addr_t start_pa, end_pa;
+	unsigned long pages = 0, pfn;
 
-	start = (void *)PAGE_ALIGN((unsigned long)start);
-	end = (void *)((unsigned long)end & PAGE_MASK);
-	for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
-		struct page *page = virt_to_page(pos);
+	/*
+	 * end is the first address past the region and it may be beyond what
+	 * __pa() or __pa_symbol() can handle.
+	 * Use the address included in the range for the cnversion and add back
+	 * 1 afterwards.
+	 */
+	if (__is_kernel((unsigned long)start)) {
+		start_pa = __pa_symbol(start);
+		end_pa = __pa_symbol(end - 1) + 1;
+	} else {
+		start_pa = __pa(start);
+		end_pa = __pa(end - 1) + 1;
+	}
+
+	for_each_valid_pfn(pfn, PFN_UP(start_pa), PFN_DOWN(end_pa)) {
+		struct page *page = pfn_to_page(pfn);
 		void *direct_map_addr;
 
 		/*
-		 * 'direct_map_addr' might be different from 'pos'
-		 * because some architectures' virt_to_page()
-		 * work with aliases.  Getting the direct map
-		 * address ensures that we get a _writeable_
-		 * alias for the memset().
+		 * 'direct_map_addr' might be different from the kernel virtual
+		 * address because some architectures use aliases.
+		 * Going via physical address, pfn_to_page() and page_address()
+		 * ensures that we get a _writeable_ alias for the memset().
 		 */
 		direct_map_addr = page_address(page);
 		/*
@@ -921,6 +932,7 @@ unsigned long free_reserved_area(void *start, void *end, int poison, const char
 			memset(direct_map_addr, poison, PAGE_SIZE);
 
 		free_reserved_page(page);
+		pages++;
 	}
 
 	if (pages && s)
-- 
2.51.0


^ permalink raw reply related

* [PATCH 3/8] mm: move free_reserved_area() to mm/memblock.c
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

free_reserved_area() is related to memblock as it frees reserved memory
back to the buddy allocator, similar to what memblock_free_late() does.

Move free_reserved_area() to mm/memblock.c to prepare for further
consolidation of the functions that free reserved memory.

No functional changes.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 mm/memblock.c   | 37 ++++++++++++++++++++++++++++++++++++-
 mm/page_alloc.c | 36 ------------------------------------
 2 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index b3ddfdec7a80..8f3010dddc58 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -893,6 +893,42 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
 	return memblock_remove_range(&memblock.memory, base, size);
 }
 
+unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
+{
+	void *pos;
+	unsigned long pages = 0;
+
+	start = (void *)PAGE_ALIGN((unsigned long)start);
+	end = (void *)((unsigned long)end & PAGE_MASK);
+	for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
+		struct page *page = virt_to_page(pos);
+		void *direct_map_addr;
+
+		/*
+		 * 'direct_map_addr' might be different from 'pos'
+		 * because some architectures' virt_to_page()
+		 * work with aliases.  Getting the direct map
+		 * address ensures that we get a _writeable_
+		 * alias for the memset().
+		 */
+		direct_map_addr = page_address(page);
+		/*
+		 * Perform a kasan-unchecked memset() since this memory
+		 * has not been initialized.
+		 */
+		direct_map_addr = kasan_reset_tag(direct_map_addr);
+		if ((unsigned int)poison <= 0xFF)
+			memset(direct_map_addr, poison, PAGE_SIZE);
+
+		free_reserved_page(page);
+	}
+
+	if (pages && s)
+		pr_info("Freeing %s memory: %ldK\n", s, K(pages));
+
+	return pages;
+}
+
 /**
  * memblock_free - free boot memory allocation
  * @ptr: starting address of the  boot memory allocation
@@ -1776,7 +1812,6 @@ void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
 		totalram_pages_inc();
 	}
 }
-
 /*
  * Remaining API functions
  */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2d4b6f1a554e..df3d61253001 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6234,42 +6234,6 @@ void adjust_managed_page_count(struct page *page, long count)
 }
 EXPORT_SYMBOL(adjust_managed_page_count);
 
-unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
-{
-	void *pos;
-	unsigned long pages = 0;
-
-	start = (void *)PAGE_ALIGN((unsigned long)start);
-	end = (void *)((unsigned long)end & PAGE_MASK);
-	for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
-		struct page *page = virt_to_page(pos);
-		void *direct_map_addr;
-
-		/*
-		 * 'direct_map_addr' might be different from 'pos'
-		 * because some architectures' virt_to_page()
-		 * work with aliases.  Getting the direct map
-		 * address ensures that we get a _writeable_
-		 * alias for the memset().
-		 */
-		direct_map_addr = page_address(page);
-		/*
-		 * Perform a kasan-unchecked memset() since this memory
-		 * has not been initialized.
-		 */
-		direct_map_addr = kasan_reset_tag(direct_map_addr);
-		if ((unsigned int)poison <= 0xFF)
-			memset(direct_map_addr, poison, PAGE_SIZE);
-
-		free_reserved_page(page);
-	}
-
-	if (pages && s)
-		pr_info("Freeing %s memory: %ldK\n", s, K(pages));
-
-	return pages;
-}
-
 void free_reserved_page(struct page *page)
 {
 	clear_page_tag_ref(page);
-- 
2.51.0


^ permalink raw reply related

* [PATCH 2/8] powerpc: opal-core: pair alloc_pages_exact() with free_pages_exact()
From: Mike Rapoport @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Alexander Potapenko, Alexander Viro, Andreas Larsson,
	Ard Biesheuvel, Borislav Petkov, Brendan Jackman,
	Christophe Leroy (CS GROUP), Catalin Marinas, Christian Brauner,
	David S. Miller, Dave Hansen, David Hildenbrand, Dmitry Vyukov,
	Ilias Apalodimas, Ingo Molnar, Jan Kara, Johannes Weiner,
	Liam R. Howlett, Lorenzo Stoakes, Madhavan Srinivasan,
	Marco Elver, Marek Szyprowski, Masami Hiramatsu, Michael Ellerman,
	Michal Hocko, Mike Rapoport, Nicholas Piggin, H. Peter Anvin,
	Rob Herring, Robin Murphy, Saravana Kannan, Suren Baghdasaryan,
	Thomas Gleixner, Vlastimil Babka, Will Deacon, Zi Yan, devicetree,
	iommu, kasan-dev, linux-arm-kernel, linux-efi, linux-fsdevel,
	linux-kernel, linux-mm, linux-trace-kernel, linuxppc-dev,
	sparclinux, x86
In-Reply-To: <20260318105827.1358927-1-rppt@kernel.org>

From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>

opal-core allocates buffers with alloc_pages_exact(), but then
marks them as reserved and frees using free_reserved_area().

This is completely unnecessary and the pages allocated with
alloc_pages_exact() can be naturally freed with free_pages_exact().

Replace freeing of memory in opalcore_cleanup() with
free_pages_exact() and simplify allocation code so that it won't mark
allocated pages as reserved.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
 arch/powerpc/platforms/powernv/opal-core.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index e76e462f55f6..abd99ddbf21f 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -303,7 +303,6 @@ static int __init create_opalcore(void)
 	struct device_node *dn;
 	struct opalcore *new;
 	loff_t opalcore_off;
-	struct page *page;
 	Elf64_Phdr *phdr;
 	Elf64_Ehdr *elf;
 	int i, ret;
@@ -329,9 +328,6 @@ static int __init create_opalcore(void)
 		return -ENOMEM;
 	}
 	count = oc_conf->opalcorebuf_sz / PAGE_SIZE;
-	page = virt_to_page(oc_conf->opalcorebuf);
-	for (i = 0; i < count; i++)
-		mark_page_reserved(page + i);
 
 	pr_debug("opalcorebuf = 0x%llx\n", (u64)oc_conf->opalcorebuf);
 
@@ -437,10 +433,7 @@ static void opalcore_cleanup(void)
 
 	/* free the buffer used for setting up OPAL core */
 	if (oc_conf->opalcorebuf) {
-		void *end = (void *)((u64)oc_conf->opalcorebuf +
-				     oc_conf->opalcorebuf_sz);
-
-		free_reserved_area(oc_conf->opalcorebuf, end, -1, NULL);
+		free_pages_exact(oc_conf->opalcorebuf, oc_conf->opalcorebuf_sz);
 		oc_conf->opalcorebuf = NULL;
 		oc_conf->opalcorebuf_sz = 0;
 	}
-- 
2.51.0


^ permalink raw reply related

* Re: [PATCH 00/15] tracepoint: Avoid double static_branch evaluation at guarded call sites
From: Vineeth Remanan Pillai @ 2026-03-18 10:58 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Steven Rostedt, Andrii Nakryiko, Peter Zijlstra, Dmitry Ilvokhin,
	Masami Hiramatsu, Ingo Molnar, Jens Axboe, io-uring,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Marcelo Ricardo Leitner,
	Xin Long, Jon Maloy, Aaron Conole, Eelco Chaudron, Ilya Maximets,
	netdev, bpf, linux-sctp, tipc-discussion, dev, Oded Gabbay,
	Koby Elbaz, dri-devel, Rafael J. Wysocki, Viresh Kumar,
	Gautham R. Shenoy, Huang Rui, Mario Limonciello, Len Brown,
	Srinivas Pandruvada, linux-pm, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Christian König, Sumit Semwal, linaro-mm-sig,
	Eddie James, Andrew Jeffery, Joel Stanley, linux-fsi,
	David Airlie, Simona Vetter, Alex Deucher, Danilo Krummrich,
	Matthew Brost, Philipp Stanner, Harry Wentland, Leo Li, amd-gfx,
	Jiri Kosina, Benjamin Tissoires, linux-input, Wolfram Sang,
	linux-i2c, Mark Brown, Michael Hennerich, Nuno Sá, linux-spi,
	James E.J. Bottomley, Martin K. Petersen, linux-scsi, Chris Mason,
	David Sterba, linux-btrfs, linux-trace-kernel, linux-kernel
In-Reply-To: <6ca9f884-9566-4a82-9995-4c802a0bf8a0@efficios.com>

On Tue, Mar 17, 2026 at 12:02 PM Mathieu Desnoyers
<mathieu.desnoyers@efficios.com> wrote:
>
> On 2026-03-17 12:00, Steven Rostedt wrote:
> > On Fri, 13 Mar 2026 10:02:32 -0400
> > Vineeth Remanan Pillai <vineeth@bitbyteword.org> wrote:
> >
> >>>
> >>> Perhaps: call_trace_foo() ?
> >>>
> >> call_trace_foo has one collision with the tracepoint
> >> sched_update_nr_running and a function
> >> call_trace_sched_update_nr_running. I had considered this and later
> >> moved to trace_invoke_foo() because of the collision. But I can rename
> >> call_trace_sched_update_nr_running to something else if call_trace_foo
> >> is the general consensus.
> >
> > OK, then lets go with: trace_call__foo()
> >
> > The double underscore should prevent any name collisions.
> >
> > Does anyone have an objections?
> I'm OK with it.
>
Great thanks! I shall send a v2 with s/trace_invoke_foo/trace_call__foo/ soon.

Thanks,
Vineeth

^ 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