* Re: [PATCH v9 1/2] lib: Introduce hierarchical per-cpu counters
From: Mathieu Desnoyers @ 2025-11-22 21:26 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Paul E. McKenney, Steven Rostedt, Masami Hiramatsu,
Dennis Zhou, Tejun Heo, Christoph Lameter, Martin Liu,
David Rientjes, christian.koenig, Shakeel Butt, SeongJae Park,
Michal Hocko, Johannes Weiner, Sweet Tea Dorminy, Lorenzo Stoakes,
Liam R . Howlett, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Christian Brauner, Wei Yang, David Hildenbrand,
Miaohe Lin, Al Viro, linux-mm, linux-trace-kernel, Yu Zhao,
Roman Gushchin, Mateusz Guzik, Matthew Wilcox, Baolin Wang,
Aboorva Devarajan
In-Reply-To: <a3652f6b-cd3b-45ad-a3ad-e92369cf4068@efficios.com>
On 2025-11-22 12:15, Mathieu Desnoyers wrote:
>...
> The fact that the max inaccuracy is bounded means that we can perform
> approximate comparisons in a fast path (which is enough if the values
> to compare greatly vary), and only have to do the more expensive
> "precise" comparison when values are close to each other and we
> actually care about their relative order.
>
> I'm thinking memory usage tracking, runtime usage (scheduler ?), cgroups
> ressource accounting.
Another use-case worth explicitly mentioning is accounting the
resources (memory, CPU, I/O) used by a given entity (process,
cgroup) and enforce quota validation based on a configured
capacity limit.
This is a comparison with a limit which can be much larger than
the current resource usage value. Therefore, because the inaccuracy
is known, it is possible to enforce the quota limit with an
approximate comparison, and only use a precise sum when the current
value is near the limit, and rate-limit the frequency at which precise
limit validation is done.
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
^ permalink raw reply
* [RFC PATCH 00/12] mm/damos/stat: introduce nr_snapshots, max_nr_snapshots and tracepoint
From: SeongJae Park @ 2025-11-23 18:43 UTC (permalink / raw)
Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Masami Hiramatsu,
Mathieu Desnoyers, Michal Hocko, Mike Rapoport, Steven Rostedt,
Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm, linux-trace-kernel
Introduce three changes for improving DAMOS stat's provided information,
deterministic control, and reading usability.
DAMOS provides stats that are important for understanding its behavior.
It lacks information about how many DAMON-generated monitoring output
snapshots it has worked on. Add a new stat, nr_snapshots, to show the
information.
Users can control DAMOS schemes in multiple ways. Using the online
parameters commit feature, they can install and uninstall DAMOS schemes
whenever they want while keeping DAMON runs. DAMOS quotas and
watermarks can be used for manually or automatically turning on/off or
adjusting the aggressiveness of the scheme. DAMOS filters can be used
for applying the scheme to specific memory entities based on their types
and locations. Some users want their DAMOS scheme to be applied to only
specific number of DAMON snapshots, for more deterministic control. One
example use case is tracepoint based snapshot reading. Add a new knob,
max_nr_snapshots, to support this. If the nr_snapshots parameter
becomes same to or greater than the value of this parameter, the scheme
is deactivated.
Users can read DAMOS stats via DAMON's sysfs interface. For deep level
investigations on environments having advanced tools like perf and
bpftrace, exposing the stats via a tracepoint can be useful. Implement
a new tracepoint, namely damon:damos_stat_after_apply_interval.
First five patches (patches 1-5) of this series implement the new stat,
nr_snapshots, on the core layer (patch 1), expose on DAMON sysfs user
interface (patch 2), and update documents (patches 3-5).
Following six patches (patches 6-11) are for the new stat based DAMOS
deactivation (max_nr_snapshots). The first one (patch 6) of this group
updates a kernel-doc comment before making further changes. Then an
implementation of it on the core layer (patch 7), an introduction of a
new DAMON sysfs interface file for users of the feature (patch 8), and
three updates of the documents (patches 9-11) follow.
The final one (patch 12) introduces the new tracepoint that exposes the
DAMOS stat values for each scheme apply interval.
SeongJae Park (12):
mm/damon/core: introduce nr_snapshots damos stat
mm/damon/sysfs-schemes: introduce nr_snapshots damos stat file
Docs/mm/damon/design: update for nr_snapshots damos stat
Docs/admin-guide/mm/damon/usage: update for nr_snapshots damos stat
Docs/ABI/damon: update for nr_snapshots damos stat
mm/damon: update damos kerneldoc for stat field
mm/damon/core: implement max_nr_snapshots
mm/damon/sysfs-schemes: implement max_nr_snapshots file
Docs/mm/damon/design: update for max_nr_snapshots
Docs/admin-guide/mm/damon/usage: update for max_nr_snapshots
Docs/ABI/damon: update for max_nr_snapshots
mm/damon/core: add trace point for damos stat per apply interval
.../ABI/testing/sysfs-kernel-mm-damon | 13 ++++++
Documentation/admin-guide/mm/damon/usage.rst | 11 ++---
Documentation/mm/damon/design.rst | 7 +++
include/linux/damon.h | 12 ++++--
include/trace/events/damon.h | 41 ++++++++++++++++++
mm/damon/core.c | 37 ++++++++++++++--
mm/damon/sysfs-schemes.c | 43 +++++++++++++++++++
7 files changed, 153 insertions(+), 11 deletions(-)
base-commit: 522f1a9fc5f1f0a11af39ba5bedae446322ca0a2
--
2.47.3
^ permalink raw reply
* [RFC PATCH 12/12] mm/damon/core: add trace point for damos stat per apply interval
From: SeongJae Park @ 2025-11-23 18:43 UTC (permalink / raw)
Cc: SeongJae Park, Andrew Morton, Masami Hiramatsu, Mathieu Desnoyers,
Steven Rostedt, damon, linux-kernel, linux-mm, linux-trace-kernel
In-Reply-To: <20251123184329.85287-1-sj@kernel.org>
DAMON users can read DAMOS stats via DAMON sysfs interface. It enables
efficient, simple and flexible usages of the stats. Especially for
systems not having advanced tools like perf or bpftrace, that can be
useful. But if the advanced tools are available, exposing the stats via
tracepoint can reduce unnecessary reimplementation of the wheels. Add a
new tracepoint for DAMOS stats, namely damos_stat_after_apply_interval.
The tracepoint is triggered for each scheme's apply interval and exposes
the whole stat values. If the user needs sub-apply interval information
for any chance, damos_before_apply tracepoint could be used.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
include/trace/events/damon.h | 41 ++++++++++++++++++++++++++++++++++++
mm/damon/core.c | 15 +++++++++++++
2 files changed, 56 insertions(+)
diff --git a/include/trace/events/damon.h b/include/trace/events/damon.h
index 852d725afea2..24fc402ab3c8 100644
--- a/include/trace/events/damon.h
+++ b/include/trace/events/damon.h
@@ -9,6 +9,47 @@
#include <linux/types.h>
#include <linux/tracepoint.h>
+TRACE_EVENT(damos_stat_after_apply_interval,
+
+ TP_PROTO(unsigned int context_idx, unsigned int scheme_idx,
+ struct damos_stat *stat),
+
+ TP_ARGS(context_idx, scheme_idx, stat),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, context_idx)
+ __field(unsigned int, scheme_idx)
+ __field(unsigned long, nr_tried)
+ __field(unsigned long, sz_tried)
+ __field(unsigned long, nr_applied)
+ __field(unsigned long, sz_applied)
+ __field(unsigned long, sz_ops_filter_passed)
+ __field(unsigned long, qt_exceeds)
+ __field(unsigned long, nr_snapshots)
+ ),
+
+ TP_fast_assign(
+ __entry->context_idx = context_idx;
+ __entry->scheme_idx = scheme_idx;
+ __entry->nr_tried = stat->nr_tried;
+ __entry->sz_tried = stat->sz_tried;
+ __entry->nr_applied = stat->nr_applied;
+ __entry->sz_applied = stat->sz_applied;
+ __entry->sz_ops_filter_passed = stat->sz_ops_filter_passed;
+ __entry->qt_exceeds = stat->qt_exceeds;
+ __entry->nr_snapshots = stat->nr_snapshots;
+ ),
+
+ TP_printk("ctx_idx=%u scheme_idx=%u nr_tried=%lu sz_tried=%lu "
+ "nr_applied=%lu sz_tried=%lu sz_ops_filter_passed=%lu "
+ "qt_exceeds=%lu nr_snapshots=%lu",
+ __entry->context_idx, __entry->scheme_idx,
+ __entry->nr_tried, __entry->sz_tried,
+ __entry->nr_applied, __entry->sz_applied,
+ __entry->sz_ops_filter_passed, __entry->qt_exceeds,
+ __entry->nr_snapshots)
+);
+
TRACE_EVENT(damos_esz,
TP_PROTO(unsigned int context_idx, unsigned int scheme_idx,
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 36313cd1ff1c..2f212a18e4a0 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -2256,6 +2256,19 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
quota->min_score = score;
}
+static void damos_trace_stat(struct damon_ctx *c, struct damos *s)
+{
+ unsigned int cidx = 0, sidx = 0;
+ struct damos *siter;
+
+ damon_for_each_scheme(siter, c) {
+ if (siter == s)
+ break;
+ sidx++;
+ }
+ trace_damos_stat_after_apply_interval(cidx, sidx, &s->stat);
+}
+
static void kdamond_apply_schemes(struct damon_ctx *c)
{
struct damon_target *t;
@@ -2294,6 +2307,8 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
(s->apply_interval_us ? s->apply_interval_us :
c->attrs.aggr_interval) / sample_interval;
s->last_applied = NULL;
+ if (trace_damos_stat_after_apply_interval_enabled())
+ damos_trace_stat(c, s);
}
mutex_unlock(&c->walk_control_lock);
}
--
2.47.3
^ permalink raw reply related
* Re: [RFC PATCH 00/12] mm/damos/stat: introduce nr_snapshots, max_nr_snapshots and tracepoint
From: SeongJae Park @ 2025-11-23 19:54 UTC (permalink / raw)
To: SeongJae Park
Cc: Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Masami Hiramatsu,
Mathieu Desnoyers, Michal Hocko, Mike Rapoport, Steven Rostedt,
Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm, linux-trace-kernel
In-Reply-To: <20251123184329.85287-1-sj@kernel.org>
On Sun, 23 Nov 2025 10:43:14 -0800 SeongJae Park <sj@kernel.org> wrote:
> Introduce three changes for improving DAMOS stat's provided information,
> deterministic control, and reading usability.
FYI, I'm not aiming to make this be merged in 6.19-rc1.
Thanks,
SJ
[...]
^ permalink raw reply
* Re: [PATCH 1/3] powerpc64: make clang cross-build friendly
From: Naveen N Rao @ 2025-11-24 5:49 UTC (permalink / raw)
To: Hari Bathini
Cc: linuxppc-dev, Madhavan Srinivasan, Christophe Leroy,
Michael Ellerman, linux-trace-kernel, Mark Rutland,
Steven Rostedt, Masami Hiramatsu, llvm, Maryam Moghadas
In-Reply-To: <20251108210405.2375472-2-hbathini@linux.ibm.com>
On Sun, Nov 09, 2025 at 02:34:03AM +0530, Hari Bathini wrote:
> ARCH_USING_PATCHABLE_FUNCTION_ENTRY depends on toolchain support for
> -fpatchable-function-entry option. The current script that checks
> for this support only handles GCC. Rename the script and extend it
> to detect support for -fpatchable-function-entry with Clang as well,
> allowing clean cross-compilation with Clang toolchains.
>
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
> arch/powerpc/Kconfig | 5 +++--
> ...-function-entry.sh => check-fpatchable-function-entry.sh} | 0
> 2 files changed, 3 insertions(+), 2 deletions(-)
> rename arch/powerpc/tools/{gcc-check-fpatchable-function-entry.sh => check-fpatchable-function-entry.sh} (100%)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 325c1171894d..dfb62e211c92 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -568,8 +568,9 @@ config ARCH_USING_PATCHABLE_FUNCTION_ENTRY
> depends on FUNCTION_TRACER && (PPC32 || PPC64_ELF_ABI_V2)
> depends on $(cc-option,-fpatchable-function-entry=2)
> def_bool y if PPC32
> - def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC) -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN
> - def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC) -mbig-endian) if PPC64 && CPU_BIG_ENDIAN
> + def_bool $(success,$(srctree)/arch/powerpc/tools/check-fpatchable-function-entry.sh $(CC) -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN && CC_IS_GCC
> + def_bool $(success,$(srctree)/arch/powerpc/tools/check-fpatchable-function-entry.sh $(CC) -target ppc64le -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN && CC_IS_CLANG
Can you instead pass $(CLANG_FLAGS) to retain the same command across
gcc/clang?
- Naveen
^ permalink raw reply
* Re: [PATCH 3/3] powerpc64/ftrace: workaround clang recording GEP in __patchable_function_entries
From: Naveen N Rao @ 2025-11-24 5:55 UTC (permalink / raw)
To: Hari Bathini
Cc: linuxppc-dev, Madhavan Srinivasan, Christophe Leroy,
Michael Ellerman, linux-trace-kernel, Mark Rutland,
Steven Rostedt, Masami Hiramatsu, llvm, Maryam Moghadas
In-Reply-To: <20251108210405.2375472-4-hbathini@linux.ibm.com>
On Sun, Nov 09, 2025 at 02:34:05AM +0530, Hari Bathini wrote:
> Support for -fpatchable-function-entry on ppc64le was added in Clang
> with [1]. However, when no prefix NOPs are specified - as is the case
> with CONFIG_PPC_FTRACE_OUT_OF_LINE - the first NOP is emitted at LEP,
> but Clang records the Global Entry Point (GEP) unlike GCC which does
> record the Local Entry Point (LEP). Issue [2] has been raised to align
> Clang's behavior with GCC. As a temporary workaround to ensure ftrace
Any reason to put in a "temporary" workaround rather than waiting for
this to be fixed?
- Naveen
^ permalink raw reply
* [PATCH v1] tools/rtla: Add common_usage()
From: Costa Shulyupin @ 2025-11-24 6:31 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Crystal Wood, Costa Shulyupin,
Wander Lairson Costa, Ivan Pravdin, linux-trace-kernel,
linux-kernel
The rtla tools have significant code quadruplication in their usage
functions. Each tool implements its own version of the same help text
formatting and option descriptions, leading to maintenance overhead and
inconsistencies. Documentation/tools/rtla/common_options.rst lists 14
common options.
Add common_usage() infrastructure to consolidate help formatting.
Subsequent patches will extend this to handle other common options.
The refactored output is almost identical to the original, with the
following changes:
- add square brackets to specify optionality: `usage: [rtla] ...`
- remove `-q` from timerlat hist because hist tools don't support it
- minor spacing
Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
---
tools/tracing/rtla/src/common.c | 39 ++++++++++++++++++++++++++
tools/tracing/rtla/src/common.h | 3 ++
tools/tracing/rtla/src/osnoise_hist.c | 22 ++++++---------
tools/tracing/rtla/src/osnoise_top.c | 37 ++++++++++--------------
tools/tracing/rtla/src/timerlat_hist.c | 22 ++++++---------
tools/tracing/rtla/src/timerlat_top.c | 22 ++++++---------
6 files changed, 81 insertions(+), 64 deletions(-)
diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
index b197037fc58b..18b92c5e4b1a 100644
--- a/tools/tracing/rtla/src/common.c
+++ b/tools/tracing/rtla/src/common.c
@@ -4,6 +4,7 @@
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "common.h"
@@ -348,3 +349,41 @@ int hist_main_loop(struct osnoise_tool *tool)
return retval;
}
+
+static void print_msg_array(const char * const *msgs)
+{
+ if (!msgs)
+ return;
+
+ for (int i = 0; msgs[i]; i++)
+ fprintf(stderr, "%s\n", msgs[i]);
+}
+
+/*
+ * common_usage - print complete usage information
+ */
+void common_usage(const char *tool, const char *mode,
+ const char *desc, const char * const *start_msgs, const char * const *opt_msgs)
+{
+ static const char * const common_options[] = {
+ " -h/--help: print this menu",
+ NULL
+ };
+ fprintf(stderr, "rtla %s", tool);
+ if (strcmp(mode, ""))
+ fprintf(stderr, " %s", mode);
+ fprintf(stderr, ": %s (version %s)\n\n", desc, VERSION);
+ fprintf(stderr, " usage: [rtla] %s ", tool);
+
+ if (strcmp(mode, "top") == 0)
+ fprintf(stderr, "[top] [-h] ");
+ else
+ fprintf(stderr, "%s [-h] ", mode);
+
+ print_msg_array(start_msgs);
+ fprintf(stderr, "\n");
+ print_msg_array(common_options);
+ print_msg_array(opt_msgs);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/tools/tracing/rtla/src/common.h b/tools/tracing/rtla/src/common.h
index 9ec2b7632c37..b44e910ba72c 100644
--- a/tools/tracing/rtla/src/common.h
+++ b/tools/tracing/rtla/src/common.h
@@ -156,3 +156,6 @@ bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record
int common_apply_config(struct osnoise_tool *tool, struct common_params *params);
int top_main_loop(struct osnoise_tool *tool);
int hist_main_loop(struct osnoise_tool *tool);
+
+void common_usage(const char *tool, const char *mode,
+ const char *desc, const char * const *start_msgs, const char * const *opt_msgs);
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
index ff8c231e47c4..372128db9e4a 100644
--- a/tools/tracing/rtla/src/osnoise_hist.c
+++ b/tools/tracing/rtla/src/osnoise_hist.c
@@ -409,16 +409,15 @@ osnoise_print_stats(struct osnoise_tool *tool)
*/
static void osnoise_hist_usage(void)
{
- int i;
-
- static const char * const msg[] = {
- "",
- " usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
+ static const char * const msg_start[] = {
+ "[-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
" [-T us] [-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
" [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
" [--no-index] [--with-zeros] [-C [cgroup_name]] [--warm-up]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char * const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
" -p/--period us: osnoise period in us",
" -r/--runtime us: osnoise runtime in us",
@@ -453,13 +452,8 @@ static void osnoise_hist_usage(void)
NULL,
};
- fprintf(stderr, "rtla osnoise hist: a per-cpu histogram of the OS noise (version %s)\n",
- VERSION);
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage("osnoise", "hist", "a per-cpu histogram of the OS noise",
+ msg_start, msg_opts);
}
/*
diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
index 04c699bdd736..1db1d946b600 100644
--- a/tools/tracing/rtla/src/osnoise_top.c
+++ b/tools/tracing/rtla/src/osnoise_top.c
@@ -257,14 +257,16 @@ osnoise_print_stats(struct osnoise_tool *top)
*/
static void osnoise_top_usage(struct osnoise_params *params)
{
- int i;
+ const char *tool, *mode, *desc;
- static const char * const msg[] = {
- " [-h] [-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
+ static const char * const msg_start[] = {
+ "[-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
" [-T us] [-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
" [-c cpu-list] [-H cpu-list] [-P priority] [-C [cgroup_name]] [--warm-up s]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char * const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
" -p/--period us: osnoise period in us",
" -r/--runtime us: osnoise runtime in us",
@@ -295,25 +297,16 @@ static void osnoise_top_usage(struct osnoise_params *params)
};
if (params->mode == MODE_OSNOISE) {
- fprintf(stderr,
- "rtla osnoise top: a per-cpu summary of the OS noise (version %s)\n",
- VERSION);
-
- fprintf(stderr, " usage: rtla osnoise [top]");
+ tool = "osnoise";
+ mode = "top";
+ desc = "a per-cpu summary of the OS noise";
+ } else {
+ tool = "hwnoise";
+ mode = "";
+ desc = "a summary of hardware-related noise";
}
- if (params->mode == MODE_HWNOISE) {
- fprintf(stderr,
- "rtla hwnoise: a summary of hardware-related noise (version %s)\n",
- VERSION);
-
- fprintf(stderr, " usage: rtla hwnoise");
- }
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage(tool, mode, desc, msg_start, msg_opts);
}
/*
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 1fb471a787b7..2a5c543217ba 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -696,17 +696,16 @@ timerlat_print_stats(struct osnoise_tool *tool)
*/
static void timerlat_hist_usage(void)
{
- int i;
-
- char *msg[] = {
- "",
- " usage: [rtla] timerlat hist [-h] [-q] [-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] \\",
+ static const char * const msg_start[] = {
+ "[-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] \\",
" [-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
" [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
" [--no-index] [--with-zeros] [--dma-latency us] [-C [cgroup_name]] [--no-aa] [--dump-task] [-u|-k]",
" [--warm-up s] [--deepest-idle-state n]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char * const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
" -p/--period us: timerlat period in us",
" -i/--irq us: stop trace if the irq latency is higher than the argument in us",
@@ -750,13 +749,8 @@ static void timerlat_hist_usage(void)
NULL,
};
- fprintf(stderr, "rtla timerlat hist: a per-cpu histogram of the timer latency (version %s)\n",
- VERSION);
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage("timerlat", "hist", "a per-cpu histogram of the timer latency",
+ msg_start, msg_opts);
}
/*
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 29c2c1f717ed..9ed8b931552f 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -476,15 +476,14 @@ timerlat_print_stats(struct osnoise_tool *top)
*/
static void timerlat_top_usage(void)
{
- int i;
-
- static const char *const msg[] = {
- "",
- " usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
+ static const char *const msg_start[] = {
+ "[-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
" [[-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
" [-P priority] [--dma-latency us] [--aa-only us] [-C [cgroup_name]] [-u|-k] [--warm-up s] [--deepest-idle-state n]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char *const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
" --aa-only us: stop if <us> latency is hit, only printing the auto analysis (reduces CPU usage)",
" -p/--period us: timerlat period in us",
@@ -522,13 +521,8 @@ static void timerlat_top_usage(void)
NULL,
};
- fprintf(stderr, "rtla timerlat top: a per-cpu summary of the timer latency (version %s)\n",
- VERSION);
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage("timerlat", "top", "a per-cpu summary of the timer latency",
+ msg_start, msg_opts);
}
/*
--
2.51.1
^ permalink raw reply related
* Re: [PATCH 00/44] Change a lot of min_t() that might mask high bits
From: Herbert Xu @ 2025-11-24 9:49 UTC (permalink / raw)
To: david.laight.linux
Cc: linux-kernel, Alan Stern, Alexander Viro, Alexei Starovoitov,
Andi Shyti, Andreas Dilger, Andrew Lunn, Andrew Morton,
Andrii Nakryiko, Andy Shevchenko, Ard Biesheuvel,
Arnaldo Carvalho de Melo, Bjorn Helgaas, Borislav Petkov,
Christian Brauner, Christian König, Christoph Hellwig,
Daniel Borkmann, Dan Williams, Dave Hansen, Dave Jiang,
David Ahern, David Hildenbrand, Davidlohr Bueso, David S. Miller,
Dennis Zhou, Eric Dumazet, Greg Kroah-Hartman, Ingo Molnar,
Jakub Kicinski, Jakub Sitnicki, James E.J. Bottomley,
Jarkko Sakkinen, Jason A. Donenfeld, Jens Axboe, Jiri Slaby,
Johannes Weiner, John Allen, Jonathan Cameron, Juergen Gross,
Kees Cook, KP Singh, Linus Walleij, Martin K. Petersen,
Matthew Wilcox (Oracle), Mika Westerberg, Mike Rapoport,
Miklos Szeredi, Namhyung Kim, Neal Cardwell, nic_swsd,
OGAWA Hirofumi, Olivia Mackall, Paolo Abeni, Paolo Bonzini,
Peter Huewe, Peter Zijlstra, Rafael J. Wysocki,
Sean Christopherson, Srinivas Kandagatla, Stefano Stabellini,
Steven Rostedt, Tejun Heo, Theodore Ts'o, Thomas Gleixner,
Tom Lendacky, Willem de Bruijn, x86, Yury Norov, amd-gfx, bpf,
cgroups, dri-devel, io-uring, kvm, linux-acpi, linux-block,
linux-crypto, linux-cxl, linux-efi, linux-ext4, linux-fsdevel,
linux-gpio, linux-i2c, linux-integrity, linux-mm, linux-nvme,
linux-pci, linux-perf-users, linux-scsi, linux-serial,
linux-trace-kernel, linux-usb, mptcp, netdev, usb-storage
In-Reply-To: <20251119224140.8616-1-david.laight.linux@gmail.com>
On Wed, Nov 19, 2025 at 10:40:56PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> It in not uncommon for code to use min_t(uint, a, b) when one of a or b
> is 64bit and can have a value that is larger than 2^32;
> This is particularly prevelant with:
> uint_var = min_t(uint, uint_var, uint64_expression);
>
> Casts to u8 and u16 are very likely to discard significant bits.
>
> These can be detected at compile time by changing min_t(), for example:
> #define CHECK_SIZE(fn, type, val) \
> BUILD_BUG_ON_MSG(sizeof (val) > sizeof (type) && \
> !statically_true(((val) >> 8 * (sizeof (type) - 1)) < 256), \
> fn "() significant bits of '" #val "' may be discarded")
>
> #define min_t(type, x, y) ({ \
> CHECK_SIZE("min_t", type, x); \
> CHECK_SIZE("min_t", type, y); \
> __cmp_once(min, type, x, y); })
>
> (and similar changes to max_t() and clamp_t().)
>
> This shows up some real bugs, some unlikely bugs and some false positives.
> In most cases both arguments are unsigned type (just different ones)
> and min_t() can just be replaced by min().
>
> The patches are all independant and are most of the ones needed to
> get the x86-64 kernel I build to compile.
> I've not tried building an allyesconfig or allmodconfig kernel.
> I've also not included the patch to minmax.h itself.
>
> I've tried to put the patches that actually fix things first.
> The last one is 0009.
>
> I gave up on fixing sched/fair.c - it is too broken for a single patch!
> The patch for net/ipv4/tcp.c is also absent because do_tcp_getsockopt()
> needs multiple/larger changes to make it 'sane'.
>
> I've had to trim the 124 maintainers/lists that get_maintainer.pl finds
> from 124 to under 100 to be able to send the cover letter.
> The individual patches only go to the addresses found for the associated files.
> That reduces the number of emails to a less unsane number.
>
> David Laight (44):
> x86/asm/bitops: Change the return type of variable__ffs() to unsigned
> int
> ext4: Fix saturation of 64bit inode times for old filesystems
> perf: Fix branch stack callchain limit
> io_uring/net: Change some dubious min_t()
> ipc/msg: Fix saturation of percpu counts in msgctl_info()
> bpf: Verifier, remove some unusual uses of min_t() and max_t()
> net/core/flow_dissector: Fix cap of __skb_flow_dissect() return value.
> net: ethtool: Use min3() instead of nested min_t(u16,...)
> ipv6: __ip6_append_data() don't abuse max_t() casts
> x86/crypto: ctr_crypt() use min() instead of min_t()
> arch/x96/kvm: use min() instead of min_t()
> block: use min() instead of min_t()
> drivers/acpi: use min() instead of min_t()
> drivers/char/hw_random: use min3() instead of nested min_t()
> drivers/char/tpm: use min() instead of min_t()
> drivers/crypto/ccp: use min() instead of min_t()
> drivers/cxl: use min() instead of min_t()
> drivers/gpio: use min() instead of min_t()
> drivers/gpu/drm/amd: use min() instead of min_t()
> drivers/i2c/busses: use min() instead of min_t()
> drivers/net/ethernet/realtek: use min() instead of min_t()
> drivers/nvme: use min() instead of min_t()
> arch/x86/mm: use min() instead of min_t()
> drivers/nvmem: use min() instead of min_t()
> drivers/pci: use min() instead of min_t()
> drivers/scsi: use min() instead of min_t()
> drivers/tty/vt: use umin() instead of min_t(u16, ...) for row/col
> limits
> drivers/usb/storage: use min() instead of min_t()
> drivers/xen: use min() instead of min_t()
> fs: use min() or umin() instead of min_t()
> block: bvec.h: use min() instead of min_t()
> nodemask: use min() instead of min_t()
> ipc: use min() instead of min_t()
> bpf: use min() instead of min_t()
> bpf_trace: use min() instead of min_t()
> lib/bucket_locks: use min() instead of min_t()
> lib/crypto/mpi: use min() instead of min_t()
> lib/dynamic_queue_limits: use max() instead of max_t()
> mm: use min() instead of min_t()
> net: Don't pass bitfields to max_t()
> net/core: Change loop conditions so min() can be used
> net: use min() instead of min_t()
> net/netlink: Use umin() to avoid min_t(int, ...) discarding high bits
> net/mptcp: Change some dubious min_t(int, ...) to min()
>
> arch/x86/crypto/aesni-intel_glue.c | 3 +-
> arch/x86/include/asm/bitops.h | 18 +++++-------
> arch/x86/kvm/emulate.c | 3 +-
> arch/x86/kvm/lapic.c | 2 +-
> arch/x86/kvm/mmu/mmu.c | 2 +-
> arch/x86/mm/pat/set_memory.c | 12 ++++----
> block/blk-iocost.c | 6 ++--
> block/blk-settings.c | 2 +-
> block/partitions/efi.c | 3 +-
> drivers/acpi/property.c | 2 +-
> drivers/char/hw_random/core.c | 2 +-
> drivers/char/tpm/tpm1-cmd.c | 2 +-
> drivers/char/tpm/tpm_tis_core.c | 4 +--
> drivers/crypto/ccp/ccp-dev.c | 2 +-
> drivers/cxl/core/mbox.c | 2 +-
> drivers/gpio/gpiolib-acpi-core.c | 2 +-
> .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c | 4 +--
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +-
> .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
> drivers/i2c/busses/i2c-designware-master.c | 2 +-
> drivers/net/ethernet/realtek/r8169_main.c | 3 +-
> drivers/nvme/host/pci.c | 3 +-
> drivers/nvme/host/zns.c | 3 +-
> drivers/nvmem/core.c | 2 +-
> drivers/pci/probe.c | 3 +-
> drivers/scsi/hosts.c | 2 +-
> drivers/tty/vt/selection.c | 9 +++---
> drivers/usb/storage/protocol.c | 3 +-
> drivers/xen/grant-table.c | 2 +-
> fs/buffer.c | 2 +-
> fs/exec.c | 2 +-
> fs/ext4/ext4.h | 2 +-
> fs/ext4/mballoc.c | 3 +-
> fs/ext4/resize.c | 2 +-
> fs/ext4/super.c | 2 +-
> fs/fat/dir.c | 4 +--
> fs/fat/file.c | 3 +-
> fs/fuse/dev.c | 2 +-
> fs/fuse/file.c | 8 ++---
> fs/splice.c | 2 +-
> include/linux/bvec.h | 3 +-
> include/linux/nodemask.h | 9 +++---
> include/linux/perf_event.h | 2 +-
> include/net/tcp_ecn.h | 5 ++--
> io_uring/net.c | 6 ++--
> ipc/mqueue.c | 4 +--
> ipc/msg.c | 6 ++--
> kernel/bpf/core.c | 4 +--
> kernel/bpf/log.c | 2 +-
> kernel/bpf/verifier.c | 29 +++++++------------
> kernel/trace/bpf_trace.c | 2 +-
> lib/bucket_locks.c | 2 +-
> lib/crypto/mpi/mpicoder.c | 2 +-
> lib/dynamic_queue_limits.c | 2 +-
> mm/gup.c | 4 +--
> mm/memblock.c | 2 +-
> mm/memory.c | 2 +-
> mm/percpu.c | 2 +-
> mm/truncate.c | 3 +-
> mm/vmscan.c | 2 +-
> net/core/datagram.c | 6 ++--
> net/core/flow_dissector.c | 7 ++---
> net/core/net-sysfs.c | 3 +-
> net/core/skmsg.c | 4 +--
> net/ethtool/cmis_cdb.c | 7 ++---
> net/ipv4/fib_trie.c | 2 +-
> net/ipv4/tcp_input.c | 4 +--
> net/ipv4/tcp_output.c | 5 ++--
> net/ipv4/tcp_timer.c | 4 +--
> net/ipv6/addrconf.c | 8 ++---
> net/ipv6/ip6_output.c | 7 +++--
> net/ipv6/ndisc.c | 5 ++--
> net/mptcp/protocol.c | 8 ++---
> net/netlink/genetlink.c | 9 +++---
> net/packet/af_packet.c | 2 +-
> net/unix/af_unix.c | 4 +--
> 76 files changed, 141 insertions(+), 176 deletions(-)
Patches 10,14,16,37 applied. Thanks.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v1 1/2] tools/rtla: Add for_each_monitored_cpu() helper
From: Tomas Glozar @ 2025-11-24 11:47 UTC (permalink / raw)
To: Costa Shulyupin
Cc: Steven Rostedt, Crystal Wood, John Kacur, Eder Zulian,
linux-trace-kernel, linux-kernel
In-Reply-To: <20251002123553.389467-1-costa.shul@redhat.com>
čt 2. 10. 2025 v 14:36 odesílatel Costa Shulyupin
<costa.shul@redhat.com> napsal:
> +#define for_each_monitored_cpu(cpu, nr_cpus, common) \
> + for (cpu = 0; cpu < nr_cpus; cpu++) \
> + if (!(common)->cpus || CPU_ISSET(cpu, &(common)->monitored_cpus))
> +
There is one case where this form of macro is not ideal. Consider this code:
if (something)
for_each_monitored_cpu(i, nr_cpus, ¶ms->common) {
do_something()
}
else
something_else();
Here, since the macro includes an "if" statement, it will eat the else
block (see [1]), and something_else() will be executed for all
non-monitored CPUs (which might be zero times, or many times, instead
of just once, as one would expect). This would not happen for the
other for_each_* macros used in the Linux kernel, since they do not
include an if.
This can be fixed by moving the if to a function called from inside
the for loop:
static inline int next_monitored_cpu(int cpu, int nr_cpus, struct
common_params *common)
{
for (cpu += 1; cpu < nr_cpus; cpu++)
if (!common->cpus || CPU_ISSET(cpu, &common->monitored_cpus))
break;
return cpu;
}
and then defining for_each_monitored_cpu() macro like this:
#define for_each_monitored_cpu(cpu, nr_cpus, common) \
for (cpu = 0; cpu < nr_cpus; cpu = next_monitored_cpu(cpu, nr_cpus, common))
Nevertheless, I took the patch already, and it is still better than
repeating the same code multiple times, so this is for a future
improvement.
[1] - https://en.wikipedia.org/wiki/Dangling_else
Tomas
^ permalink raw reply
* [PATCH] dma-buf: add some tracepoints to debug.
From: Xiang Gao @ 2025-11-24 13:36 UTC (permalink / raw)
To: sumit.semwal, christian.koenig, rostedt, mhiramat
Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel,
mathieu.desnoyers, dhowells, kuba, brauner, akpm,
linux-trace-kernel, gaoxiang17
From: gaoxiang17 <gaoxiang17@xiaomi.com>
With these tracepoints, we can track dmabuf in real time.
For example:
binder:3025_3-10524 [000] ..... 553.310313: dma_buf_export: exp_name=qcom,system name=(null) size=12771328 ino=2799
binder:3025_3-10524 [000] ..... 553.310318: dma_buf_fd: exp_name=qcom,system name=(null) size=12771328 ino=2799 fd=8
RenderThread-9307 [000] ..... 553.310869: dma_buf_get: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799 fd=673 f_ref=4
RenderThread-9307 [000] ..... 553.310871: dma_buf_attach: dev_name=kgsl-3d0 exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799
RenderThread-9307 [000] ..... 553.310946: dma_buf_mmap_internal: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799
RenderThread-9307 [004] ..... 553.315084: dma_buf_detach: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799
RenderThread-9307 [004] ..... 553.315084: dma_buf_put: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799 f_ref=5
Signed-off-by: gaoxiang17 <gaoxiang17@xiaomi.com>
---
drivers/dma-buf/dma-buf.c | 19 +++
include/trace/events/dma_buf.h | 245 +++++++++++++++++++++++++++++++++
2 files changed, 264 insertions(+)
create mode 100644 include/trace/events/dma_buf.h
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 2bcf9ceca997..8b5af73f0218 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -35,6 +35,9 @@
#include "dma-buf-sysfs-stats.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/dma_buf.h>
+
static inline int is_dma_buf_file(struct file *);
static DEFINE_MUTEX(dmabuf_list_mutex);
@@ -220,6 +223,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
dmabuf->size >> PAGE_SHIFT)
return -EINVAL;
+ trace_dma_buf_mmap_internal(dmabuf);
+
return dmabuf->ops->mmap(dmabuf, vma);
}
@@ -745,6 +750,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
__dma_buf_list_add(dmabuf);
+ trace_dma_buf_export(dmabuf);
+
return dmabuf;
err_dmabuf:
@@ -779,6 +786,8 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags)
fd_install(fd, dmabuf->file);
+ trace_dma_buf_fd(dmabuf, fd);
+
return fd;
}
EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
@@ -805,6 +814,8 @@ struct dma_buf *dma_buf_get(int fd)
return ERR_PTR(-EINVAL);
}
+ trace_dma_buf_get(fd, file);
+
return file->private_data;
}
EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF");
@@ -825,6 +836,8 @@ void dma_buf_put(struct dma_buf *dmabuf)
return;
fput(dmabuf->file);
+
+ trace_dma_buf_put(dmabuf);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
@@ -998,6 +1011,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
struct device *dev)
{
+ trace_dma_buf_attach(dmabuf, dev);
+
return dma_buf_dynamic_attach(dmabuf, dev, NULL, NULL);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF");
@@ -1024,6 +1039,8 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
dmabuf->ops->detach(dmabuf, attach);
kfree(attach);
+
+ trace_dma_buf_detach(dmabuf);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
@@ -1488,6 +1505,8 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
vma_set_file(vma, dmabuf->file);
vma->vm_pgoff = pgoff;
+ trace_dma_buf_mmap(dmabuf);
+
return dmabuf->ops->mmap(dmabuf, vma);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF");
diff --git a/include/trace/events/dma_buf.h b/include/trace/events/dma_buf.h
new file mode 100644
index 000000000000..796ae444f6ae
--- /dev/null
+++ b/include/trace/events/dma_buf.h
@@ -0,0 +1,245 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dma_buf
+
+#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DMA_BUF_H
+
+#include <linux/dma-buf.h>
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(dma_buf_export,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino)
+);
+
+TRACE_EVENT(dma_buf_fd,
+
+ TP_PROTO(struct dma_buf *dmabuf, int fd),
+
+ TP_ARGS(dmabuf, fd),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ __field(int, fd)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ __entry->fd = fd;
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu fd=%d",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino,
+ __entry->fd)
+);
+
+TRACE_EVENT(dma_buf_mmap_internal,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino)
+);
+
+TRACE_EVENT(dma_buf_mmap,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino)
+);
+
+TRACE_EVENT(dma_buf_attach,
+
+ TP_PROTO(struct dma_buf *dmabuf, struct device *dev),
+
+ TP_ARGS(dmabuf, dev),
+
+ TP_STRUCT__entry(
+ __string(dname, dev_name(dev))
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dname);
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ ),
+
+ TP_printk("dev_name=%s exp_name=%s name=%s size=%zu ino=%lu",
+ __get_str(dname),
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino)
+);
+
+TRACE_EVENT(dma_buf_detach,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino)
+);
+
+TRACE_EVENT(dma_buf_get,
+
+ TP_PROTO(int fd, struct file *file),
+
+ TP_ARGS(fd, file),
+
+ TP_STRUCT__entry(
+ __string(exp_name, ((struct dma_buf *)file->private_data)->exp_name)
+ __string(name, ((struct dma_buf *)file->private_data)->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ __field(int, fd)
+ __field(long, f_ref)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = ((struct dma_buf *)file->private_data)->size;
+ __entry->ino = ((struct dma_buf *)file->private_data)->file->f_inode->i_ino;
+ __entry->fd = fd;
+ __entry->f_ref = file_ref_get(&file->f_ref);
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu fd=%d f_ref=%ld",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino,
+ __entry->fd,
+ __entry->f_ref)
+);
+
+TRACE_EVENT(dma_buf_put,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __string(name, dmabuf->name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ __field(long, f_ref)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __assign_str(name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ __entry->f_ref = file_ref_get(&dmabuf->file->f_ref);
+ ),
+
+ TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_ref=%ld",
+ __get_str(exp_name),
+ __get_str(name),
+ __entry->size,
+ __entry->ino,
+ __entry->f_ref)
+);
+
+#endif /* _TRACE_DMA_BUF_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] dma-buf: add some tracepoints to debug.
From: Christian König @ 2025-11-24 14:21 UTC (permalink / raw)
To: Xiang Gao, sumit.semwal, rostedt, mhiramat
Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel,
mathieu.desnoyers, dhowells, kuba, brauner, akpm,
linux-trace-kernel, gaoxiang17
In-Reply-To: <20251124133648.72668-1-gxxa03070307@gmail.com>
On 11/24/25 14:36, Xiang Gao wrote:
> From: gaoxiang17 <gaoxiang17@xiaomi.com>
>
> With these tracepoints, we can track dmabuf in real time.
>
> For example:
> binder:3025_3-10524 [000] ..... 553.310313: dma_buf_export: exp_name=qcom,system name=(null) size=12771328 ino=2799
> binder:3025_3-10524 [000] ..... 553.310318: dma_buf_fd: exp_name=qcom,system name=(null) size=12771328 ino=2799 fd=8
> RenderThread-9307 [000] ..... 553.310869: dma_buf_get: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799 fd=673 f_ref=4
> RenderThread-9307 [000] ..... 553.310871: dma_buf_attach: dev_name=kgsl-3d0 exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799
> RenderThread-9307 [000] ..... 553.310946: dma_buf_mmap_internal: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799
> RenderThread-9307 [004] ..... 553.315084: dma_buf_detach: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799
> RenderThread-9307 [004] ..... 553.315084: dma_buf_put: exp_name=qcom,system name=blastBufferQueue for scaleUpDow size=12771328 ino=2799 f_ref=5
In general quite nice to have, but this needs a bit more explanation why you need it.
>
> Signed-off-by: gaoxiang17 <gaoxiang17@xiaomi.com>
I have strongly doubts that this is your legal name :)
Please google the requirements for a Signed-off-by line.
> ---
> drivers/dma-buf/dma-buf.c | 19 +++
> include/trace/events/dma_buf.h | 245 +++++++++++++++++++++++++++++++++
> 2 files changed, 264 insertions(+)
> create mode 100644 include/trace/events/dma_buf.h
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 2bcf9ceca997..8b5af73f0218 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -35,6 +35,9 @@
>
> #include "dma-buf-sysfs-stats.h"
>
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/dma_buf.h>
> +
> static inline int is_dma_buf_file(struct file *);
>
> static DEFINE_MUTEX(dmabuf_list_mutex);
> @@ -220,6 +223,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
> dmabuf->size >> PAGE_SHIFT)
> return -EINVAL;
>
> + trace_dma_buf_mmap_internal(dmabuf);
> +
> return dmabuf->ops->mmap(dmabuf, vma);
> }
>
> @@ -745,6 +750,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
>
> __dma_buf_list_add(dmabuf);
>
> + trace_dma_buf_export(dmabuf);
> +
> return dmabuf;
>
> err_dmabuf:
> @@ -779,6 +786,8 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags)
>
> fd_install(fd, dmabuf->file);
>
> + trace_dma_buf_fd(dmabuf, fd);
> +
> return fd;
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
> @@ -805,6 +814,8 @@ struct dma_buf *dma_buf_get(int fd)
> return ERR_PTR(-EINVAL);
> }
>
> + trace_dma_buf_get(fd, file);
> +
> return file->private_data;
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF");
> @@ -825,6 +836,8 @@ void dma_buf_put(struct dma_buf *dmabuf)
> return;
>
> fput(dmabuf->file);
> +
> + trace_dma_buf_put(dmabuf);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
>
> @@ -998,6 +1011,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
> struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
> struct device *dev)
> {
> + trace_dma_buf_attach(dmabuf, dev);
> +
> return dma_buf_dynamic_attach(dmabuf, dev, NULL, NULL);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF");
> @@ -1024,6 +1039,8 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
> dmabuf->ops->detach(dmabuf, attach);
>
> kfree(attach);
> +
> + trace_dma_buf_detach(dmabuf);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
>
> @@ -1488,6 +1505,8 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
> vma_set_file(vma, dmabuf->file);
> vma->vm_pgoff = pgoff;
>
> + trace_dma_buf_mmap(dmabuf);
> +
> return dmabuf->ops->mmap(dmabuf, vma);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF");
> diff --git a/include/trace/events/dma_buf.h b/include/trace/events/dma_buf.h
> new file mode 100644
> index 000000000000..796ae444f6ae
> --- /dev/null
> +++ b/include/trace/events/dma_buf.h
> @@ -0,0 +1,245 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM dma_buf
> +
> +#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_DMA_BUF_H
> +
> +#include <linux/dma-buf.h>
> +#include <linux/tracepoint.h>
> +
> +TRACE_EVENT(dma_buf_export,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
dmabuf->name can't be accessed without holding the appropriate lock, same of all other cases.
Regards,
Christian.
> + __field(size_t, size)
> + __field(ino_t, ino)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino)
> +);
> +
> +TRACE_EVENT(dma_buf_fd,
> +
> + TP_PROTO(struct dma_buf *dmabuf, int fd),
> +
> + TP_ARGS(dmabuf, fd),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + __field(int, fd)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + __entry->fd = fd;
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu fd=%d",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino,
> + __entry->fd)
> +);
> +
> +TRACE_EVENT(dma_buf_mmap_internal,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino)
> +);
> +
> +TRACE_EVENT(dma_buf_mmap,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino)
> +);
> +
> +TRACE_EVENT(dma_buf_attach,
> +
> + TP_PROTO(struct dma_buf *dmabuf, struct device *dev),
> +
> + TP_ARGS(dmabuf, dev),
> +
> + TP_STRUCT__entry(
> + __string(dname, dev_name(dev))
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(dname);
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + ),
> +
> + TP_printk("dev_name=%s exp_name=%s name=%s size=%zu ino=%lu",
> + __get_str(dname),
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino)
> +);
> +
> +TRACE_EVENT(dma_buf_detach,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino)
> +);
> +
> +TRACE_EVENT(dma_buf_get,
> +
> + TP_PROTO(int fd, struct file *file),
> +
> + TP_ARGS(fd, file),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, ((struct dma_buf *)file->private_data)->exp_name)
> + __string(name, ((struct dma_buf *)file->private_data)->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + __field(int, fd)
> + __field(long, f_ref)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = ((struct dma_buf *)file->private_data)->size;
> + __entry->ino = ((struct dma_buf *)file->private_data)->file->f_inode->i_ino;
> + __entry->fd = fd;
> + __entry->f_ref = file_ref_get(&file->f_ref);
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu fd=%d f_ref=%ld",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino,
> + __entry->fd,
> + __entry->f_ref)
> +);
> +
> +TRACE_EVENT(dma_buf_put,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __string(name, dmabuf->name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + __field(long, f_ref)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __assign_str(name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + __entry->f_ref = file_ref_get(&dmabuf->file->f_ref);
> + ),
> +
> + TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_ref=%ld",
> + __get_str(exp_name),
> + __get_str(name),
> + __entry->size,
> + __entry->ino,
> + __entry->f_ref)
> +);
> +
> +#endif /* _TRACE_DMA_BUF_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>
^ permalink raw reply
* Re: [PATCH bpf-next v3 6/6] bpf: implement "jmp" mode for trampoline
From: Steven Rostedt @ 2025-11-24 14:50 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Menglong Dong, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau, Eduard,
Song Liu, Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo,
Jiri Olsa, Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers,
jiang.biao, bpf, LKML, linux-trace-kernel
In-Reply-To: <CAADnVQLs-kBMi7VCizH5be8q8Nyzx=KYNPcnF-EDNx7OPs4Aiw@mail.gmail.com>
On Fri, 21 Nov 2025 18:37:02 -0800
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> On Tue, Nov 18, 2025 at 5:02 PM Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > On Tue, 18 Nov 2025 16:59:59 -0800
> > Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >
> > > Steven,
> > > are you happy with patch 1?
> > > Can you pls Ack?
> >
> > Let me run patch 1 and 2 through my tests.
>
> gentle ping.
Yeah, sorry forgot to reply. They did pass.
Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-- Steve
^ permalink raw reply
* Re: [RFC PATCH 12/12] mm/damon/core: add trace point for damos stat per apply interval
From: Steven Rostedt @ 2025-11-24 15:15 UTC (permalink / raw)
To: SeongJae Park
Cc: Andrew Morton, Masami Hiramatsu, Mathieu Desnoyers, damon,
linux-kernel, linux-mm, linux-trace-kernel
In-Reply-To: <20251123184329.85287-13-sj@kernel.org>
On Sun, 23 Nov 2025 10:43:26 -0800
SeongJae Park <sj@kernel.org> wrote:
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
> @@ -2256,6 +2256,19 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
> quota->min_score = score;
> }
>
> +static void damos_trace_stat(struct damon_ctx *c, struct damos *s)
> +{
> + unsigned int cidx = 0, sidx = 0;
> + struct damos *siter;
> +
> + damon_for_each_scheme(siter, c) {
> + if (siter == s)
> + break;
> + sidx++;
> + }
> + trace_damos_stat_after_apply_interval(cidx, sidx, &s->stat);
> +}
> +
> static void kdamond_apply_schemes(struct damon_ctx *c)
> {
> struct damon_target *t;
> @@ -2294,6 +2307,8 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
> (s->apply_interval_us ? s->apply_interval_us :
> c->attrs.aggr_interval) / sample_interval;
> s->last_applied = NULL;
> + if (trace_damos_stat_after_apply_interval_enabled())
> + damos_trace_stat(c, s);
> }
> mutex_unlock(&c->walk_control_lock);
> }
I wonder if the above would look better (and still produce good assembly)
if it was:
static inline void damos_trace_stat(struct damon_ctx *c, struct damos *s)
{
unsigned int cidx = 0, sidx = 0;
struct damos *siter;
if (!trace_damos_stat_after_apply_interval_enabled())
return;
damon_for_each_scheme(siter, c) {
if (siter == s)
break;
sidx++;
}
trace_damos_stat_after_apply_interval(cidx, sidx, &s->stat);
}
static void kdamond_apply_schemes(struct damon_ctx *c)
{
struct damon_target *t;
> @@ -2294,6 +2307,8 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
(s->apply_interval_us ? s->apply_interval_us :
c->attrs.aggr_interval) / sample_interval;
s->last_applied = NULL;
damos_trace_stat(c, s);
}
mutex_unlock(&c->walk_control_lock);
}
I have no real preference. I just think keeping the "if ()" statement out
of the main code as a more aesthetic look. But the above should be
equivalent in actual functionality.
-- Steve
^ permalink raw reply
* Re: [RFC PATCH 12/12] mm/damon/core: add trace point for damos stat per apply interval
From: SeongJae Park @ 2025-11-24 15:37 UTC (permalink / raw)
To: Steven Rostedt
Cc: SeongJae Park, Andrew Morton, Masami Hiramatsu, Mathieu Desnoyers,
damon, linux-kernel, linux-mm, linux-trace-kernel
In-Reply-To: <20251124101545.0250445c@gandalf.local.home>
On Mon, 24 Nov 2025 10:15:45 -0500 Steven Rostedt <rostedt@goodmis.org> wrote:
> On Sun, 23 Nov 2025 10:43:26 -0800
> SeongJae Park <sj@kernel.org> wrote:
>
> > --- a/mm/damon/core.c
> > +++ b/mm/damon/core.c
[...]
> I wonder if the above would look better (and still produce good assembly)
> if it was:
[...]
> I have no real preference. I just think keeping the "if ()" statement out
> of the main code as a more aesthetic look. But the above should be
> equivalent in actual functionality.
Thank you for this suggestion, Steve! I'll update this patch as you suggested
in the next version.
Thanks,
SJ
[...]
^ permalink raw reply
* Re: [PATCH bpf-next v3 0/6] bpf trampoline support "jmp" mode
From: patchwork-bot+netdevbpf @ 2025-11-24 18:00 UTC (permalink / raw)
To: Menglong Dong
Cc: ast, rostedt, daniel, john.fastabend, andrii, martin.lau, eddyz87,
song, yonghong.song, kpsingh, sdf, haoluo, jolsa, mhiramat,
mark.rutland, mathieu.desnoyers, jiang.biao, bpf, linux-kernel,
linux-trace-kernel
In-Reply-To: <20251118123639.688444-1-dongml2@chinatelecom.cn>
Hello:
This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Tue, 18 Nov 2025 20:36:28 +0800 you wrote:
> For now, the bpf trampoline is called by the "call" instruction. However,
> it break the RSB and introduce extra overhead in x86_64 arch.
>
> For example, we hook the function "foo" with fexit, the call and return
> logic will be like this:
> call foo -> call trampoline -> call foo-body ->
> return foo-body -> return foo
>
> [...]
Here is the summary with links:
- [bpf-next,v3,1/6] ftrace: introduce FTRACE_OPS_FL_JMP
https://git.kernel.org/bpf/bpf-next/c/25e4e3565d45
- [bpf-next,v3,2/6] x86/ftrace: implement DYNAMIC_FTRACE_WITH_JMP
https://git.kernel.org/bpf/bpf-next/c/0c3772a8db1f
- [bpf-next,v3,3/6] bpf: fix the usage of BPF_TRAMP_F_SKIP_FRAME
https://git.kernel.org/bpf/bpf-next/c/47c9214dcbea
- [bpf-next,v3,4/6] bpf,x86: adjust the "jmp" mode for bpf trampoline
https://git.kernel.org/bpf/bpf-next/c/373f2f44c300
- [bpf-next,v3,5/6] bpf: specify the old and new poke_type for bpf_arch_text_poke
https://git.kernel.org/bpf/bpf-next/c/ae4a3160d19c
- [bpf-next,v3,6/6] bpf: implement "jmp" mode for trampoline
https://git.kernel.org/bpf/bpf-next/c/402e44b31e9d
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [RFC PATCH 5/8] uprobe/x86: Add support to optimize on top of emulated instructions
From: Oleg Nesterov @ 2025-11-24 18:01 UTC (permalink / raw)
To: Jiri Olsa
Cc: Masami Hiramatsu, Peter Zijlstra, Andrii Nakryiko, bpf,
linux-kernel, linux-trace-kernel, x86, Song Liu, Yonghong Song,
John Fastabend, Steven Rostedt, Ingo Molnar, David Laight
In-Reply-To: <20251117124057.687384-6-jolsa@kernel.org>
Hi Jiri,
I am trying to understand this series, will try to read it more carefully
later...
(damn why do you always send the patches when I am on PTO? ;)
On 11/17, Jiri Olsa wrote:
>
> struct arch_uprobe {
> union {
> - u8 insn[MAX_UINSN_BYTES];
> + u8 insn[5*MAX_UINSN_BYTES];
Hmm. OK, this matches the "for (i = 0; i < 5; i++)" loop in
opt_setup_xol_ops(), but do we really need this change? Please see
the question at the end.
> +static int opt_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
> +{
> + unsigned long offset = insn->length;
> + struct insn insnX;
> + int i, ret;
> +
> + if (test_bit(ARCH_UPROBE_FLAG_CAN_OPTIMIZE, &auprobe->flags))
> + return -ENOSYS;
I think this logic needs some cleanups... If ARCH_UPROBE_FLAG_CAN_OPTIMIZE
is set by the caller, the it doesn't make sense to call xxx_setup_xol_ops(),
right? But lets forget it for now.
> + ret = opt_setup_xol_insns(auprobe, &auprobe->opt.xol[0], insn);
I think this should go into the main loop, see below
> + for (i = 1; i < 5; i++) {
> + ret = uprobe_init_insn_offset(auprobe, offset, &insnX, true);
> + if (ret)
> + break;
> + ret = opt_setup_xol_insns(auprobe, &auprobe->opt.xol[i], &insnX);
> + if (ret)
> + break;
> + offset += insnX.length;
> + auprobe->opt.cnt++;
> + if (offset >= 5)
> + goto optimize;
> + }
> +
> + return -ENOSYS;
I don't think -ENOSYS makes sense if opt_setup_xol_insns() succeeds at least once.
IOW, how about
static int opt_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
{
unsigned long offset = 0;
struct insn insnX;
int i, ret;
if (test_bit(ARCH_UPROBE_FLAG_CAN_OPTIMIZE, &auprobe->flags))
return -ENOSYS;
for (i = 0; i < 5; i++) {
ret = opt_setup_xol_insns(auprobe, &auprobe->opt.xol[i], insn);
if (ret)
break;
offset += insn->length;
if (offset >= 5)
break;
insn = &insnX;
ret = uprobe_init_insn_offset(auprobe, offset, insn, true);
if (ret)
break;
}
if (!offset)
return -ENOSYS;
if (offset >= 5) {
auprobe->opt.cnt = i + 1;
auprobe->xol.ops = &opt_xol_ops;
set_bit(ARCH_UPROBE_FLAG_CAN_OPTIMIZE, &auprobe->flags);
set_bit(ARCH_UPROBE_FLAG_OPTIMIZE_EMULATE, &auprobe->flags);
}
return 0;
}
?
This way the caller, arch_uprobe_analyze_insn(), doesn't need to call
push/mov/sub/_setup_xol_ops(), and the code looks a bit simpler to me.
No?
> + * TODO perhaps we could 'emulate' nop, so there would be no need for
> + * ARCH_UPROBE_FLAG_OPTIMIZE_EMULATE flag, because we would emulate
> + * allways.
Agreed... and this connects to "this logic needs some cleanups" above.
I guess we need nop_setup_xol_ops() extracted from branch_setup_xol_ops()
but again, lets forget it for now.
-------------------------------------------------------------------------------
Now the main question. What if we avoid this change
- u8 insn[MAX_UINSN_BYTES];
+ u8 insn[5*MAX_UINSN_BYTES];
mentioned above, and change opt_setup_xol_ops() to just do
- for (i = 0; i < 5; i++)
+ for (i = 0;; i++)
?
The main loop stops when offset >= 5 anyway.
And. if auprobe->insn[offset:MAX_UINSN_BYTES] doesn't contain a full/valid
insn at the start, then uprobe_init_insn_offset()->insn_decode() should fail?
Most probably I missed something, but I can't understand this part.
Oleg.
^ permalink raw reply
* Re: [RFC PATCH 0/8] uprobe/x86: Add support to optimize prologue
From: Oleg Nesterov @ 2025-11-24 18:12 UTC (permalink / raw)
To: Jiri Olsa
Cc: Masami Hiramatsu, Peter Zijlstra, Andrii Nakryiko, bpf,
linux-kernel, linux-trace-kernel, x86, Song Liu, Yonghong Song,
John Fastabend, Steven Rostedt, Ingo Molnar, David Laight
In-Reply-To: <20251117124057.687384-1-jolsa@kernel.org>
On 11/17, Jiri Olsa wrote:
>
> This patchset adds support to optimize uprobe on top of instruction
> that could be emulated and also adds support to emulate particular
> versions of mov and sub instructions to cover some of the user space
> functions prologues, like:
>
> pushq %rbp
> movq %rsp,%rbp
> subq $0xb0,%rsp
...
> There's an additional issue that single instruction replacement does
> not have and it's the possibility of the user space code to jump in the
> middle of those 5 bytes. I think it's unlikely to happen at the function
> prologue, but uprobe could be placed anywhere. I'm not sure how to
> mitigate this other than having some enable/disable switch or config
> option, which is unfortunate.
plus this breaks single-stepping... Although perhaps we don't really care.
Oleg.
^ permalink raw reply
* [PATCH] ring-buffer: Add helper functions for allocations
From: Steven Rostedt @ 2025-11-24 19:09 UTC (permalink / raw)
To: LKML, Linux Trace Kernel
Cc: Masami Hiramatsu, Mathieu Desnoyers, Linus Torvalds
From: Steven Rostedt <rostedt@goodmis.org>
The allocation of the per CPU buffer descriptor, the buffer page
descriptors and the buffer page data itself can be pretty ugly:
kzalloc_node(ALIGN(sizeof(struct buffer_page), cache_line_size()),
GFP_KERNEL, cpu_to_node(cpu));
And the data pages:
page = alloc_pages_node(cpu_to_node(cpu),
GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO, order);
if (!page)
return NULL;
bpage->page = page_address(page);
rb_init_page(bpage->page);
Add helper functions to make the code easier to read.
This does make all allocations of the data page (bpage->page) allocated
with the __GFP_RETRY_MAYFAIL flag (and not just the bulk allocator). Which
is actually better, as allocating the data page for the ring buffer tracing
should try hard but not trigger the OOM killer.
Link: https://lore.kernel.org/all/CAHk-=wjMMSAaqTjBSfYenfuzE1bMjLj+2DLtLWJuGt07UGCH_Q@mail.gmail.com/
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
kernel/trace/ring_buffer.c | 86 +++++++++++++++++++++++---------------
1 file changed, 53 insertions(+), 33 deletions(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 1244d2c5c384..36330986b604 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -401,6 +401,41 @@ static void free_buffer_page(struct buffer_page *bpage)
kfree(bpage);
}
+/*
+ * For best performance, allocate cpu buffer data cache line sized
+ * and per CPU.
+ */
+#define alloc_cpu_buffer(cpu) (struct ring_buffer_per_cpu *) \
+ kzalloc_node(ALIGN(sizeof(struct ring_buffer_per_cpu), \
+ cache_line_size()), GFP_KERNEL, cpu_to_node(cpu));
+
+#define alloc_cpu_page(cpu) (struct buffer_page *) \
+ kzalloc_node(ALIGN(sizeof(struct buffer_page), \
+ cache_line_size()), GFP_KERNEL, cpu_to_node(cpu));
+
+static struct buffer_data_page *alloc_cpu_data(int cpu, int order)
+{
+ struct buffer_data_page *dpage;
+ struct page *page;
+ gfp_t mflags;
+
+ /*
+ * __GFP_RETRY_MAYFAIL flag makes sure that the allocation fails
+ * gracefully without invoking oom-killer and the system is not
+ * destabilized.
+ */
+ mflags = GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO;
+
+ page = alloc_pages_node(cpu_to_node(cpu), mflags, order);
+ if (!page)
+ return NULL;
+
+ dpage = page_address(page);
+ rb_init_page(dpage);
+
+ return dpage;
+}
+
/*
* We need to fit the time_stamp delta into 27 bits.
*/
@@ -2243,8 +2278,7 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
for (i = 0; i < nr_pages; i++) {
struct page *page;
- bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()),
- mflags, cpu_to_node(cpu_buffer->cpu));
+ bpage = alloc_cpu_page(cpu_buffer->cpu);
if (!bpage)
goto free_pages;
@@ -2267,13 +2301,10 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
bpage->range = 1;
bpage->id = i + 1;
} else {
- page = alloc_pages_node(cpu_to_node(cpu_buffer->cpu),
- mflags | __GFP_COMP | __GFP_ZERO,
- cpu_buffer->buffer->subbuf_order);
- if (!page)
+ int order = cpu_buffer->buffer->subbuf_order;
+ bpage->page = alloc_cpu_data(cpu_buffer->cpu, order);
+ if (!bpage->page)
goto free_pages;
- bpage->page = page_address(page);
- rb_init_page(bpage->page);
}
bpage->order = cpu_buffer->buffer->subbuf_order;
@@ -2324,14 +2355,13 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
static struct ring_buffer_per_cpu *
rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
{
- struct ring_buffer_per_cpu *cpu_buffer __free(kfree) = NULL;
+ struct ring_buffer_per_cpu *cpu_buffer __free(kfree) =
+ alloc_cpu_buffer(cpu);
struct ring_buffer_cpu_meta *meta;
struct buffer_page *bpage;
struct page *page;
int ret;
- cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()),
- GFP_KERNEL, cpu_to_node(cpu));
if (!cpu_buffer)
return NULL;
@@ -2347,8 +2377,7 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
init_waitqueue_head(&cpu_buffer->irq_work.full_waiters);
mutex_init(&cpu_buffer->mapping_lock);
- bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()),
- GFP_KERNEL, cpu_to_node(cpu));
+ bpage = alloc_cpu_page(cpu);
if (!bpage)
return NULL;
@@ -2370,13 +2399,10 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
rb_meta_buffer_update(cpu_buffer, bpage);
bpage->range = 1;
} else {
- page = alloc_pages_node(cpu_to_node(cpu),
- GFP_KERNEL | __GFP_COMP | __GFP_ZERO,
- cpu_buffer->buffer->subbuf_order);
- if (!page)
+ int order = cpu_buffer->buffer->subbuf_order;
+ bpage->page = alloc_cpu_data(cpu, order);
+ if (!bpage->page)
goto fail_free_reader;
- bpage->page = page_address(page);
- rb_init_page(bpage->page);
}
INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
@@ -6486,22 +6512,16 @@ ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu)
arch_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
- if (bpage->data)
- goto out;
-
- page = alloc_pages_node(cpu_to_node(cpu),
- GFP_KERNEL | __GFP_NORETRY | __GFP_COMP | __GFP_ZERO,
- cpu_buffer->buffer->subbuf_order);
- if (!page) {
- kfree(bpage);
- return ERR_PTR(-ENOMEM);
+ if (bpage->data) {
+ rb_init_page(bpage->data);
+ } else {
+ bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
+ if (!bpage->data) {
+ kfree(bpage);
+ return ERR_PTR(-ENOMEM);
+ }
}
- bpage->data = page_address(page);
-
- out:
- rb_init_page(bpage->data);
-
return bpage;
}
EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
--
2.51.0
^ permalink raw reply related
* Re: [PATCH] MAINTAINERS: add tracepoint core-api doc files to TRACING
From: Steven Rostedt @ 2025-11-24 20:13 UTC (permalink / raw)
To: Masami Hiramatsu (Google)
Cc: Lukas Bulwahn, Mathieu Desnoyers, linux-trace-kernel,
kernel-janitors, linux-kernel, Lukas Bulwahn
In-Reply-To: <20251105182505.6efad861@gandalf.local.home>
On Wed, 5 Nov 2025 18:25:05 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > Yeah, that should be maintained by us.
> >
> > Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> Agreed:
>
> Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
BTW, should I be taking this through my tree?
-- Steve
^ permalink raw reply
* Re: [PATCH v6 3/6] perf record: Add --call-graph fp,defer option for deferred callchains
From: Namhyung Kim @ 2025-11-24 20:27 UTC (permalink / raw)
To: Thomas Richter
Cc: Arnaldo Carvalho de Melo, Ian Rogers, James Clark, Jiri Olsa,
Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML,
linux-perf-users, Steven Rostedt, Josh Poimboeuf, Indu Bhagat,
Jens Remus, Mathieu Desnoyers, linux-trace-kernel, bpf
In-Reply-To: <947ef366-435d-4b05-b0b1-685e569d0a1e@linux.ibm.com>
Hello,
On Fri, Nov 21, 2025 at 07:26:34AM +0100, Thomas Richter wrote:
> On 11/21/25 00:48, Namhyung Kim wrote:
> > Add a new callchain record mode option for deferred callchains. For now
> > it only works with FP (frame-pointer) mode.
> >
> > And add the missing feature detection logic to clear the flag on old
> > kernels.
> >
> > $ perf record --call-graph fp,defer -vv true
>
> Does this also works for dwarf format?
> # perf record --call-graph dwarf,defer ....
No, it's not supported. Maybe we can do similar just to dump stack
content and registers for dwarf before returning to user.
Thanks,
Namhyung
^ permalink raw reply
* Re: [PATCH v1] sched/numa: Add tracepoint to track NUMA migration cost
From: Steven Rostedt @ 2025-11-24 20:33 UTC (permalink / raw)
To: Jiayuan Chen
Cc: linux-kernel, Jiayuan Chen, Masami Hiramatsu, Mathieu Desnoyers,
Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
Andrii Nakryiko, Oleg Nesterov, Gabriele Monaco, Libo Chen,
linux-trace-kernel
In-Reply-To: <20251029132300.23519-1-jiayuan.chen@linux.dev>
On Wed, 29 Oct 2025 21:22:55 +0800
Jiayuan Chen <jiayuan.chen@linux.dev> wrote:
> From: Jiayuan Chen <jiayuan.chen@shopee.com>
>
> In systems with multiple NUMA nodes, memory imbalance between nodes often
> occurs. To address this, we typically tune parameters like scan_size_mb or
> scan_period_{min,max}_ms to allow processes to migrate pages between NUMA
> nodes.
>
> Currently, the migration task task_numa_work() holds the mmap_lock during
> the entire migration process, which can significantly impact process
> performance, especially for memory operations. This patch introduces a new
> tracepoint that records the migration duration, along with the number of
> scanned pages and migrated pages. These metrics can be used to calculate
> efficiency metrics similar to %vmeff in 'sar -B'.
>
> These metrics help evaluate whether the adjusted NUMA balancing parameters
> are properly tuned.
>
> Here's an example bpftrace script:
> ```bash
>
> bpftrace -e '
> tracepoint:sched:sched_numa_balance_start
> {
> @start_time[cpu] = nsecs;
> }
>
> tracepoint:sched:sched_numa_balance_end {
> if (@start_time[cpu] > 0) {
> $cost = nsecs - @start_time[cpu];
> printf("task '%s' migrate cost %lu, scanned %lu, migrated %lu\n",
> args.comm, $cost, args.scanned, args.migrated);
> }
> }
> '
BTW, you don't need bpf for this either:
# trace-cmd sqlhist -e -n numa_balance SELECT end.comm, TIMESTAMP_DELTA_USECS as cost, \
end.scanned, end.migrated FROM sched_numa_balance_start AS start \
JOIN sched_numa_balance_end AS end ON start.common_pid = end.common_pid
# trace-cmd start -e numa_balance
[ I'd show the output, but my test boxes don't have NUMA ]
You could also make a histogram with it:
# trace-cmd sqlhist -e SELECT start.comm, 'CAST(start.cost AS BUCKETS=50)' FROM numa_balance AS start
And then cat /sys/kernel/tracing/events/synthetic/numa_balance/hist
Just to give you an idea.
> ```
> Sample output:
> Attaching 2 probes...
> task 'rs:main Q:Reg' migrate cost 5584655, scanned 24516, migrated 22373
> task 'systemd-journal' migrate cost 123191, scanned 6308, migrated 0
> task 'wrk' migrate cost 894026, scanned 5842, migrated 5841
>
> Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
> ---
> include/trace/events/sched.h | 60 ++++++++++++++++++++++++++++++++++++
> kernel/sched/fair.c | 14 +++++++--
> 2 files changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
> index 7b2645b50e78..e24bf700a614 100644
> --- a/include/trace/events/sched.h
> +++ b/include/trace/events/sched.h
> @@ -804,6 +804,66 @@ TRACE_EVENT(sched_skip_cpuset_numa,
> __entry->ngid,
> MAX_NUMNODES, __entry->mem_allowed)
> );
> +
> +TRACE_EVENT(sched_numa_balance_start,
> +
> + TP_PROTO(struct task_struct *tsk),
> +
> + TP_ARGS(tsk),
> +
> + TP_STRUCT__entry(
> + __array(char, comm, TASK_COMM_LEN)
Please use __string() and not __array(). I'm trying to get rid of these for
task comm.
> + __field(pid_t, pid)
> + __field(pid_t, tgid)
> + __field(pid_t, ngid)
> + ),
> +
> + TP_fast_assign(
> + memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
> + __entry->pid = task_pid_nr(tsk);
> + __entry->tgid = task_tgid_nr(tsk);
> + __entry->ngid = task_numa_group_id(tsk);
> + ),
> +
> + TP_printk("comm=%s pid=%d tgid=%d ngid=%d",
> + __entry->comm,
> + __entry->pid,
> + __entry->tgid,
> + __entry->ngid)
> +);
> +
> +TRACE_EVENT(sched_numa_balance_end,
> +
> + TP_PROTO(struct task_struct *tsk, unsigned long scanned, unsigned long migrated),
> +
> + TP_ARGS(tsk, scanned, migrated),
> +
> + TP_STRUCT__entry(
> + __array(char, comm, TASK_COMM_LEN)
> + __field(pid_t, pid)
> + __field(pid_t, tgid)
> + __field(pid_t, ngid)
> + __field(unsigned long, migrated)
> + __field(unsigned long, scanned)
> + ),
> +
> + TP_fast_assign(
> + memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
> + __entry->pid = task_pid_nr(tsk);
> + __entry->tgid = task_tgid_nr(tsk);
> + __entry->ngid = task_numa_group_id(tsk);
> + __entry->migrated = migrated;
> + __entry->scanned = scanned;
> + ),
> +
> + TP_printk("comm=%s pid=%d tgid=%d ngid=%d scanned=%lu migrated=%lu",
> + __entry->comm,
> + __entry->pid,
> + __entry->tgid,
> + __entry->ngid,
> + __entry->scanned,
> + __entry->migrated)
> +);
> #endif /* CONFIG_NUMA_BALANCING */
>
> /*
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 25970dbbb279..173c9c8397e2 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -3294,6 +3294,9 @@ static void task_numa_work(struct callback_head *work)
> struct vm_area_struct *vma;
> unsigned long start, end;
> unsigned long nr_pte_updates = 0;
> + unsigned long nr_scanned = 0;
> + unsigned long total_migrated = 0;
> + unsigned long total_scanned = 0;
> long pages, virtpages;
> struct vma_iterator vmi;
> bool vma_pids_skipped;
> @@ -3359,6 +3362,7 @@ static void task_numa_work(struct callback_head *work)
> if (!mmap_read_trylock(mm))
> return;
>
> + trace_sched_numa_balance_start(p);
> /*
> * VMAs are skipped if the current PID has not trapped a fault within
> * the VMA recently. Allow scanning to be forced if there is no
> @@ -3477,6 +3481,10 @@ static void task_numa_work(struct callback_head *work)
> end = min(end, vma->vm_end);
> nr_pte_updates = change_prot_numa(vma, start, end);
>
> + nr_scanned = (end - start) >> PAGE_SHIFT;
> + total_migrated += nr_pte_updates;
> + total_scanned += nr_scanned;
> +
This will require the scheduler maintainers agreeing on this for acceptance.
Will kprobes not due?
-- Steve
> /*
> * Try to scan sysctl_numa_balancing_size worth of
> * hpages that have at least one present PTE that
> @@ -3486,8 +3494,8 @@ static void task_numa_work(struct callback_head *work)
> * areas faster.
> */
> if (nr_pte_updates)
> - pages -= (end - start) >> PAGE_SHIFT;
> - virtpages -= (end - start) >> PAGE_SHIFT;
> + pages -= nr_scanned;
> + virtpages -= nr_scanned;
>
> start = end;
> if (pages <= 0 || virtpages <= 0)
> @@ -3528,6 +3536,8 @@ static void task_numa_work(struct callback_head *work)
> mm->numa_scan_offset = start;
> else
> reset_ptenuma_scan(p);
> +
> + trace_sched_numa_balance_end(p, total_scanned, total_migrated);
> mmap_read_unlock(mm);
>
> /*
^ permalink raw reply
* Re: [PATCH] selftests: tracing: Add tprobe enable/disable testcase
From: Steven Rostedt @ 2025-11-24 20:39 UTC (permalink / raw)
To: Shuah Khan
Cc: Masami Hiramatsu (Google), Shuah Khan, Mathieu Desnoyers,
linux-kernel, linux-trace-kernel, linux-kselftest
In-Reply-To: <f0774852-fe3c-4236-91b1-f38045ea26f7@linuxfoundation.org>
On Thu, 20 Nov 2025 09:40:28 -0700
Shuah Khan <skhan@linuxfoundation.org> wrote:
> > Thanks Shuah! This and other regression fixes is better to go
> > through selftests tree because those are checking existing
> > features. Maybe better to add [PATCH -selftests] or something
> > like that?
> >
>
> Let me know which ones you would like to pick up and apply to my tree.
This one and I believe this one:
https://lore.kernel.org/linux-trace-kernel/176295318112.431538.11780280333728368327.stgit@devnote2
-- Steve
^ permalink raw reply
* Re: [PATCH v7] function_graph: Enable funcgraph-args and funcgraph-retaddr to work simultaneously
From: Steven Rostedt @ 2025-11-24 21:47 UTC (permalink / raw)
To: Donglin Peng
Cc: linux-trace-kernel, linux-kernel, Donglin Peng, Sven Schnelle,
Masami Hiramatsu
In-Reply-To: <20251114025522.2115359-1-dolinux.peng@gmail.com>
On Fri, 14 Nov 2025 10:55:22 +0800
Donglin Peng <dolinux.peng@gmail.com> wrote:
> --- a/kernel/trace/trace_entries.h
> +++ b/kernel/trace/trace_entries.h
> @@ -95,14 +95,14 @@ FTRACE_ENTRY_PACKED(fgraph_retaddr_entry, fgraph_retaddr_ent_entry,
> TRACE_GRAPH_RETADDR_ENT,
>
> F_STRUCT(
> - __field_struct( struct fgraph_retaddr_ent, graph_ent )
> + __field_struct( struct ftrace_graph_ent, graph_ent )
> __field_packed( unsigned long, graph_ent, func )
> __field_packed( unsigned int, graph_ent, depth )
> - __field_packed( unsigned long, graph_ent, retaddr )
You can't delete the retaddr without breaking user space.
Please keep that here.
Thanks,
-- Steve
> + __dynamic_array(unsigned long, args )
> ),
>
> F_printk("--> %ps (%u) <- %ps", (void *)__entry->func, __entry->depth,
> - (void *)__entry->retaddr)
> + (void *)__entry->args[0])
> );
>
^ permalink raw reply
* Re: [PATCH v7] function_graph: Enable funcgraph-args and funcgraph-retaddr to work simultaneously
From: Steven Rostedt @ 2025-11-24 21:49 UTC (permalink / raw)
To: Donglin Peng
Cc: linux-trace-kernel, linux-kernel, Donglin Peng, Sven Schnelle,
Masami Hiramatsu
In-Reply-To: <20251124164701.1216a073@gandalf.local.home>
On Mon, 24 Nov 2025 16:47:01 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Fri, 14 Nov 2025 10:55:22 +0800
> Donglin Peng <dolinux.peng@gmail.com> wrote:
>
> > --- a/kernel/trace/trace_entries.h
> > +++ b/kernel/trace/trace_entries.h
> > @@ -95,14 +95,14 @@ FTRACE_ENTRY_PACKED(fgraph_retaddr_entry, fgraph_retaddr_ent_entry,
> > TRACE_GRAPH_RETADDR_ENT,
> >
> > F_STRUCT(
> > - __field_struct( struct fgraph_retaddr_ent, graph_ent )
> > + __field_struct( struct ftrace_graph_ent, graph_ent )
> > __field_packed( unsigned long, graph_ent, func )
> > __field_packed( unsigned int, graph_ent, depth )
> > - __field_packed( unsigned long, graph_ent, retaddr )
>
> You can't delete the retaddr without breaking user space.
>
> Please keep that here.
>
Also, please rebase on top of:
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git trace/for-next
Thanks!
-- Steve
^ permalink raw reply
* Re: [PATCH v7] function_graph: Enable funcgraph-args and funcgraph-retaddr to work simultaneously
From: Steven Rostedt @ 2025-11-24 21:54 UTC (permalink / raw)
To: Donglin Peng
Cc: linux-trace-kernel, linux-kernel, Donglin Peng, Sven Schnelle,
Masami Hiramatsu
In-Reply-To: <20251124164701.1216a073@gandalf.local.home>
On Mon, 24 Nov 2025 16:47:01 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> > --- a/kernel/trace/trace_entries.h
> > +++ b/kernel/trace/trace_entries.h
> > @@ -95,14 +95,14 @@ FTRACE_ENTRY_PACKED(fgraph_retaddr_entry, fgraph_retaddr_ent_entry,
> > TRACE_GRAPH_RETADDR_ENT,
> >
> > F_STRUCT(
> > - __field_struct( struct fgraph_retaddr_ent, graph_ent )
> > + __field_struct( struct ftrace_graph_ent, graph_ent )
> > __field_packed( unsigned long, graph_ent, func )
> > __field_packed( unsigned int, graph_ent, depth )
> > - __field_packed( unsigned long, graph_ent, retaddr )
>
> You can't delete the retaddr without breaking user space.
>
> Please keep that here.
I added this, and user space works again:
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
index 593a74663c65..4666b6179056 100644
--- a/kernel/trace/trace_entries.h
+++ b/kernel/trace/trace_entries.h
@@ -98,6 +98,7 @@ FTRACE_ENTRY_PACKED(fgraph_retaddr_entry, fgraph_retaddr_ent_entry,
__field_struct( struct ftrace_graph_ent, graph_ent )
__field_packed( unsigned long, graph_ent, func )
__field_packed( unsigned int, graph_ent, depth )
+ __field_packed( unsigned long, graph_ent, retaddr )
__dynamic_array(unsigned long, args )
),
-- Steve
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox