Linux Trace Kernel
 help / color / mirror / Atom feed
* [PATCH 1/2] rtla/timerlat: Add --stack-format option
From: Tomas Glozar @ 2026-01-19 11:52 UTC (permalink / raw)
  To: Steven Rostedt, Tomas Glozar
  Cc: Costa Shulyupin, Crystal Wood, John Kacur, Luis Goncalves,
	Wander Lairson Costa, LKML, Linux Trace Kernel

In the current implementation, the auto-analysis code for printing the
stack captured in the tracefs buffer of the aa instance stops at the
first encountered address that cannot be resolved into a function
symbol.

This is not always the desired behavior on all platforms; sometimes,
there might be resolvable entries after unresolvable ones, and
sometimes, the user might want to inspect the raw pointers for the
unresolvable entries.

Add a new option, --stack-format, with three values:

- truncate: stop at first unresolvable entry. This is the current
  behavior, and is kept as the default.
- skip: skip unresolvable entries, but do not stop on them.
- full: print all entries, including unresolvable ones.

To make this work, the "size" field of the stack entry is now also read
and used as the maximum number of entries to print, capped at 64, since
that is the fixed length of the "caller" field.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 tools/tracing/rtla/src/timerlat.c      |  2 +-
 tools/tracing/rtla/src/timerlat.h      |  1 +
 tools/tracing/rtla/src/timerlat_aa.c   | 36 +++++++++++++++++++++-----
 tools/tracing/rtla/src/timerlat_aa.h   |  2 +-
 tools/tracing/rtla/src/timerlat_hist.c | 10 +++++++
 tools/tracing/rtla/src/timerlat_top.c  | 10 +++++++
 tools/tracing/rtla/src/utils.c         | 18 +++++++++++++
 tools/tracing/rtla/src/utils.h         |  7 +++++
 8 files changed, 77 insertions(+), 9 deletions(-)

diff --git a/tools/tracing/rtla/src/timerlat.c b/tools/tracing/rtla/src/timerlat.c
index 8f8811f7a13b..9e4daed0aafc 100644
--- a/tools/tracing/rtla/src/timerlat.c
+++ b/tools/tracing/rtla/src/timerlat.c
@@ -134,7 +134,7 @@ int timerlat_enable(struct osnoise_tool *tool)
 		if (!tool->aa)
 			return -1;
 
-		retval = timerlat_aa_init(tool->aa, params->dump_tasks);
+		retval = timerlat_aa_init(tool->aa, params->dump_tasks, params->stack_format);
 		if (retval) {
 			err_msg("Failed to enable the auto analysis instance\n");
 			return retval;
diff --git a/tools/tracing/rtla/src/timerlat.h b/tools/tracing/rtla/src/timerlat.h
index 8dd5d134ce08..364203a29abd 100644
--- a/tools/tracing/rtla/src/timerlat.h
+++ b/tools/tracing/rtla/src/timerlat.h
@@ -28,6 +28,7 @@ struct timerlat_params {
 	int			deepest_idle_state;
 	enum timerlat_tracing_mode mode;
 	const char		*bpf_action_program;
+	enum stack_format	stack_format;
 };
 
 #define to_timerlat_params(ptr) container_of(ptr, struct timerlat_params, common)
diff --git a/tools/tracing/rtla/src/timerlat_aa.c b/tools/tracing/rtla/src/timerlat_aa.c
index 31e66ea2b144..178de60dcef9 100644
--- a/tools/tracing/rtla/src/timerlat_aa.c
+++ b/tools/tracing/rtla/src/timerlat_aa.c
@@ -104,6 +104,7 @@ struct timerlat_aa_data {
 struct timerlat_aa_context {
 	int nr_cpus;
 	int dump_tasks;
+	enum stack_format stack_format;
 
 	/* per CPU data */
 	struct timerlat_aa_data *taa_data;
@@ -481,23 +482,43 @@ static int timerlat_aa_stack_handler(struct trace_seq *s, struct tep_record *rec
 {
 	struct timerlat_aa_context *taa_ctx = timerlat_aa_get_ctx();
 	struct timerlat_aa_data *taa_data = timerlat_aa_get_data(taa_ctx, record->cpu);
+	enum stack_format stack_format = taa_ctx->stack_format;
 	unsigned long *caller;
 	const char *function;
-	int val, i;
+	int val;
+	unsigned long long i;
 
 	trace_seq_reset(taa_data->stack_seq);
 
 	trace_seq_printf(taa_data->stack_seq, "    Blocking thread stack trace\n");
 	caller = tep_get_field_raw(s, event, "caller", record, &val, 1);
+
 	if (caller) {
-		for (i = 0; ; i++) {
+		unsigned long long size;
+		unsigned long long max_entries;
+
+		if (tep_get_field_val(s, event, "size", record, &size, 1) == 0)
+			max_entries = size < 64 ? size : 64;
+		else
+			max_entries = 64;
+
+		for (i = 0; i < max_entries; i++) {
 			function = tep_find_function(taa_ctx->tool->trace.tep, caller[i]);
-			if (!function)
-				break;
-			trace_seq_printf(taa_data->stack_seq, " %.*s -> %s\n",
-					 14, spaces, function);
+			if (!function) {
+				if (stack_format == STACK_FORMAT_TRUNCATE)
+					break;
+				else if (stack_format == STACK_FORMAT_SKIP)
+					continue;
+				else if (stack_format == STACK_FORMAT_FULL)
+					trace_seq_printf(taa_data->stack_seq, " %.*s -> 0x%lx\n",
+						     14, spaces, caller[i]);
+			} else {
+				trace_seq_printf(taa_data->stack_seq, " %.*s -> %s\n",
+						 14, spaces, function);
+			}
 		}
 	}
+
 	return 0;
 }
 
@@ -1020,7 +1041,7 @@ void timerlat_aa_destroy(void)
  *
  * Returns 0 on success, -1 otherwise.
  */
-int timerlat_aa_init(struct osnoise_tool *tool, int dump_tasks)
+int timerlat_aa_init(struct osnoise_tool *tool, int dump_tasks, enum stack_format stack_format)
 {
 	int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
 	struct timerlat_aa_context *taa_ctx;
@@ -1035,6 +1056,7 @@ int timerlat_aa_init(struct osnoise_tool *tool, int dump_tasks)
 	taa_ctx->nr_cpus = nr_cpus;
 	taa_ctx->tool = tool;
 	taa_ctx->dump_tasks = dump_tasks;
+	taa_ctx->stack_format = stack_format;
 
 	taa_ctx->taa_data = calloc(nr_cpus, sizeof(*taa_ctx->taa_data));
 	if (!taa_ctx->taa_data)
diff --git a/tools/tracing/rtla/src/timerlat_aa.h b/tools/tracing/rtla/src/timerlat_aa.h
index cea4bb1531a8..a11b5f30cdce 100644
--- a/tools/tracing/rtla/src/timerlat_aa.h
+++ b/tools/tracing/rtla/src/timerlat_aa.h
@@ -3,7 +3,7 @@
  * Copyright (C) 2023 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
  */
 
-int timerlat_aa_init(struct osnoise_tool *tool, int dump_task);
+int timerlat_aa_init(struct osnoise_tool *tool, int dump_task, enum stack_format stack_format);
 void timerlat_aa_destroy(void);
 
 void timerlat_auto_analysis(int irq_thresh, int thread_thresh);
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 4e8c38a61197..e5b3d4f098b2 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -747,6 +747,7 @@ static void timerlat_hist_usage(void)
 		"	     --on-threshold <action>: define action to be executed at latency threshold, multiple are allowed",
 		"	     --on-end <action>: define action to be executed at measurement end, multiple are allowed",
 		"	     --bpf-action <program>: load and execute BPF program when latency threshold is exceeded",
+		"	     --stack-format <format>: set the stack format (truncate, skip, full)",
 		NULL,
 	};
 
@@ -787,6 +788,9 @@ static struct common_params
 	/* default to BPF mode */
 	params->mode = TRACING_MODE_BPF;
 
+	/* default to truncate stack format */
+	params->stack_format = STACK_FORMAT_TRUNCATE;
+
 	while (1) {
 		static struct option long_options[] = {
 			{"auto",		required_argument,	0, 'a'},
@@ -819,6 +823,7 @@ static struct common_params
 			{"on-threshold",	required_argument,	0, '\5'},
 			{"on-end",		required_argument,	0, '\6'},
 			{"bpf-action",		required_argument,	0, '\7'},
+			{"stack-format",	required_argument,	0, '\10'},
 			{0, 0, 0, 0}
 		};
 
@@ -966,6 +971,11 @@ static struct common_params
 		case '\7':
 			params->bpf_action_program = optarg;
 			break;
+		case '\10':
+			params->stack_format = parse_stack_format(optarg);
+			if (params->stack_format == -1)
+				fatal("Invalid --stack-format option");
+			break;
 		default:
 			fatal("Invalid option");
 		}
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 284b74773c2b..d6ce7dcb8e82 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -518,6 +518,7 @@ static void timerlat_top_usage(void)
 		"	     --on-threshold <action>: define action to be executed at latency threshold, multiple are allowed",
 		"	     --on-end: define action to be executed at measurement end, multiple are allowed",
 		"	     --bpf-action <program>: load and execute BPF program when latency threshold is exceeded",
+		"	     --stack-format <format>: set the stack format (truncate, skip, full)",
 		NULL,
 	};
 
@@ -556,6 +557,9 @@ static struct common_params
 	/* default to BPF mode */
 	params->mode = TRACING_MODE_BPF;
 
+	/* default to truncate stack format */
+	params->stack_format = STACK_FORMAT_TRUNCATE;
+
 	while (1) {
 		static struct option long_options[] = {
 			{"auto",		required_argument,	0, 'a'},
@@ -582,6 +586,7 @@ static struct common_params
 			{"on-threshold",	required_argument,	0, '9'},
 			{"on-end",		required_argument,	0, '\1'},
 			{"bpf-action",		required_argument,	0, '\2'},
+			{"stack-format",	required_argument,	0, '\3'},
 			{0, 0, 0, 0}
 		};
 
@@ -716,6 +721,11 @@ static struct common_params
 		case '\2':
 			params->bpf_action_program = optarg;
 			break;
+		case '\3':
+			params->stack_format = parse_stack_format(optarg);
+			if (params->stack_format == -1)
+				fatal("Invalid --stack-format option");
+			break;
 		default:
 			fatal("Invalid option");
 		}
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index 0da3b2470c31..d979159f6b70 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -164,6 +164,24 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set)
 	return 1;
 }
 
+/*
+ * parse_stack_format - parse the stack format
+ *
+ * Return: the stack format on success, -1 otherwise.
+ */
+int parse_stack_format(char *arg)
+{
+	if (!strcmp(arg, "truncate"))
+		return STACK_FORMAT_TRUNCATE;
+	if (!strcmp(arg, "skip"))
+		return STACK_FORMAT_SKIP;
+	if (!strcmp(arg, "full"))
+		return STACK_FORMAT_FULL;
+
+	debug_msg("Error parsing the stack format %s\n", arg);
+	return -1;
+}
+
 /*
  * parse_duration - parse duration with s/m/h/d suffix converting it to seconds
  */
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index f7c2a52a0ab5..80d5ec0cf934 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -62,8 +62,15 @@ struct sched_attr {
 };
 #endif /* SCHED_ATTR_SIZE_VER0 */
 
+enum stack_format {
+	STACK_FORMAT_TRUNCATE,
+	STACK_FORMAT_SKIP,
+	STACK_FORMAT_FULL
+};
+
 int parse_prio(char *arg, struct sched_attr *sched_param);
 int parse_cpu_set(char *cpu_list, cpu_set_t *set);
+int parse_stack_format(char *arg);
 int __set_sched_attr(int pid, struct sched_attr *attr);
 int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr);
 int set_comm_cgroup(const char *comm_prefix, const char *cgroup);
-- 
2.52.0


^ permalink raw reply related

* [PATCH v2] scripts/tracepoint-update: fix memory leak in add_string() on failure
From: Weigang He @ 2026-01-19 11:45 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu
  Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel, Weigang He

When realloc() fails in add_string(), the function returns -1 but leaves
*vals pointing to the previously allocated memory. This can cause memory
leaks in callers like make_trace_array() that return on error without
freeing the partially built array.

Fix this by freeing *vals and setting it to NULL when realloc() fails.
This makes the error handling self-contained in add_string() so callers
don't need to handle cleanup on failure.

This bug is found by my static analysis tool and my code review.

Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
---
 scripts/tracepoint-update.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/scripts/tracepoint-update.c b/scripts/tracepoint-update.c
index 90046aedc97b9..5cf43c0aac891 100644
--- a/scripts/tracepoint-update.c
+++ b/scripts/tracepoint-update.c
@@ -49,6 +49,8 @@ static int add_string(const char *str, const char ***vals, int *count)
 		array = realloc(array, sizeof(char *) * size);
 		if (!array) {
 			fprintf(stderr, "Failed memory allocation\n");
+			free(*vals);
+			*vals = NULL;
 			return -1;
 		}
 		*vals = array;
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v4 14/15] rv: Add deadline monitors
From: Gabriele Monaco @ 2026-01-19 11:35 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: <aW4PvcDxBJnDLJFq@jlelli-thinkpadt14gen4.remote.csb>

On Mon, 2026-01-19 at 12:04 +0100, Juri Lelli wrote:
> Why use pi_of() in above cases?
> 
> For the first, in case the macro is called while the task is actually
> boosted, we then might continue to use that even after such task gets
> deboosted?

Mmh, yeah thinking about it again it doesn't make much sense considering we are
not tracking when a task is deboosted, unless that always corresponds to a
replenish. Thought that doesn't seem the case..

> For the second, current PI implementation (even if admittedly not ideal)
> uses donor's static dl_runtime to replenish boosted task runtime, but
> then accounting is performed again the task dynamic runtime, not the
> donor's (this all will hopefully change soon with proxy exec..)?

At this point I should probably just ignore the pi_of() right?
I'm assuming the original (non-boosted) parameters are more conservative anyway
so it shouldn't be a problem for the model.

Thanks,
Gabriele


^ permalink raw reply

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

Hello,

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

...

> +/*
> + * User configurable deadline threshold. If the total utilisation of deadline
> + * tasks is larger than 1, they are only guaranteed bounded tardiness. See
> + * Documentation/scheduler/sched-deadline.rst for more details.
> + * The minimum tardiness without sched_feat(HRTICK_DL) is 1 tick to accommodate
> + * for throttle enforced on the next tick.
> + */
> +static u64 deadline_thresh = TICK_NSEC;
> +module_param(deadline_thresh, ullong, 0644);
> +#define DEADLINE_NS(ha_mon) (pi_of(ha_get_target(ha_mon))->dl_deadline + deadline_thresh)

...

> +static inline u64 runtime_left_ns(struct ha_monitor *ha_mon)
> +{
> +	return pi_of(ha_get_target(ha_mon))->runtime + RUNTIME_THRESH;
> +}

Why use pi_of() in above cases?

For the first, in case the macro is called while the task is actually
boosted, we then might continue to use that even after such task gets
deboosted?

For the second, current PI implementation (even if admittedly not ideal)
uses donor's static dl_runtime to replenish boosted task runtime, but
then accounting is performed again the task dynamic runtime, not the
donor's (this all will hopefully change soon with proxy exec..)?

Thanks,
Juri


^ permalink raw reply

* [PATCH v2 2/2] tools/rtla: Add unit tests for utils.c
From: Costa Shulyupin @ 2026-01-19 10:58 UTC (permalink / raw)
  To: Steven Rostedt, Tomas Glozar, Ian Rogers,
	Arnaldo Carvalho de Melo, Namhyung Kim, Alexandre Chartre,
	Costa Shulyupin, Blake Jones, Yuzhuo Jing, Leo Yan, linux-kernel,
	linux-trace-kernel
In-Reply-To: <20260119105857.797498-1-costa.shul@redhat.com>

Add unit tests for utility functions in src/utils.c using the Check
testing framework. The tests verify parse_cpu_set(), strtoi(), and
parse_prio() functions.

Unit tests are built conditionally when libcheck is available.
Run tests with 'make unit-test'.

The test framework uses the Check library which provides process
isolation for each test, preventing failures in one test from
affecting others.

Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
---

v2: Address feedback from Tomas Glozar
- Split the patch.
- Extract separate target unit-test.
- use build system

- libcheck: document, add to tools/build dependency detection
---
 tools/tracing/rtla/Build                    |   1 +
 tools/tracing/rtla/Makefile                 |   5 +
 tools/tracing/rtla/Makefile.config          |   8 ++
 tools/tracing/rtla/README.txt               |   1 +
 tools/tracing/rtla/tests/unit/Build         |   2 +
 tools/tracing/rtla/tests/unit/Makefile.unit |  17 +++
 tools/tracing/rtla/tests/unit/unit_tests.c  | 123 ++++++++++++++++++++
 7 files changed, 157 insertions(+)
 create mode 100644 tools/tracing/rtla/tests/unit/Build
 create mode 100644 tools/tracing/rtla/tests/unit/Makefile.unit
 create mode 100644 tools/tracing/rtla/tests/unit/unit_tests.c

diff --git a/tools/tracing/rtla/Build b/tools/tracing/rtla/Build
index 6c9d5b36a315..3ce2e0f567fd 100644
--- a/tools/tracing/rtla/Build
+++ b/tools/tracing/rtla/Build
@@ -1 +1,2 @@
 rtla-y += src/
+unit_tests-y += tests/unit/
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
index 2701256abaf3..45690ee14544 100644
--- a/tools/tracing/rtla/Makefile
+++ b/tools/tracing/rtla/Makefile
@@ -33,12 +33,14 @@ DOCSRC		:= ../../../Documentation/tools/rtla/
 FEATURE_TESTS	:= libtraceevent
 FEATURE_TESTS	+= libtracefs
 FEATURE_TESTS	+= libcpupower
+FEATURE_TESTS	+= libcheck
 FEATURE_TESTS	+= libbpf
 FEATURE_TESTS	+= clang-bpf-co-re
 FEATURE_TESTS	+= bpftool-skeletons
 FEATURE_DISPLAY	:= libtraceevent
 FEATURE_DISPLAY	+= libtracefs
 FEATURE_DISPLAY	+= libcpupower
+FEATURE_DISPLAY	+= libcheck
 FEATURE_DISPLAY	+= libbpf
 FEATURE_DISPLAY	+= clang-bpf-co-re
 FEATURE_DISPLAY	+= bpftool-skeletons
@@ -47,6 +49,7 @@ all: $(RTLA)
 
 include $(srctree)/tools/build/Makefile.include
 include Makefile.rtla
+include tests/unit/Makefile.unit
 
 # check for dependencies only on required targets
 NON_CONFIG_TARGETS := clean install tarball doc doc_clean doc_install
@@ -109,6 +112,8 @@ clean: doc_clean fixdep-clean
 	$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
 	$(Q)rm -rf feature
 	$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h example/timerlat_bpf_action.o
+	$(Q)rm -f $(UNIT_TESTS)
+
 check: $(RTLA) tests/bpf/bpf_action_map.o
 	RTLA=$(RTLA) BPFTOOL=$(SYSTEM_BPFTOOL) prove -o -f -v tests/
 examples: example/timerlat_bpf_action.o
diff --git a/tools/tracing/rtla/Makefile.config b/tools/tracing/rtla/Makefile.config
index 07ff5e8f3006..0bdd258b76de 100644
--- a/tools/tracing/rtla/Makefile.config
+++ b/tools/tracing/rtla/Makefile.config
@@ -61,6 +61,14 @@ else
   $(info Please install libcpupower-dev/kernel-tools-libs-devel)
 endif
 
+$(call feature_check,libcheck)
+ifeq ($(feature-libcheck), 1)
+  $(call detected,CONFIG_LIBCHECK)
+else
+  $(info libcheck is missing, building without unit tests support.)
+  $(info Please install check-devel/check)
+endif
+
 ifndef BUILD_BPF_SKEL
   # BPF skeletons are used to implement improved sample collection, enable
   # them by default.
diff --git a/tools/tracing/rtla/README.txt b/tools/tracing/rtla/README.txt
index 43e98311d10f..a9faee4dbb3a 100644
--- a/tools/tracing/rtla/README.txt
+++ b/tools/tracing/rtla/README.txt
@@ -12,6 +12,7 @@ RTLA depends on the following libraries and tools:
  - libtracefs
  - libtraceevent
  - libcpupower (optional, for --deepest-idle-state)
+ - libcheck (optional, for unit tests)
 
 For BPF sample collection support, the following extra dependencies are
 required:
diff --git a/tools/tracing/rtla/tests/unit/Build b/tools/tracing/rtla/tests/unit/Build
new file mode 100644
index 000000000000..5f1e531ea8c9
--- /dev/null
+++ b/tools/tracing/rtla/tests/unit/Build
@@ -0,0 +1,2 @@
+unit_tests-y += unit_tests.o
+unit_tests-y +=../../src/utils.o
diff --git a/tools/tracing/rtla/tests/unit/Makefile.unit b/tools/tracing/rtla/tests/unit/Makefile.unit
new file mode 100644
index 000000000000..2088c9cc3571
--- /dev/null
+++ b/tools/tracing/rtla/tests/unit/Makefile.unit
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+UNIT_TESTS := $(OUTPUT)unit_tests
+UNIT_TESTS_IN := $(UNIT_TESTS)-in.o
+
+$(UNIT_TESTS): $(UNIT_TESTS_IN)
+	$(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $^ -lcheck
+
+$(UNIT_TESTS_IN):
+	make $(build)=unit_tests
+
+unit-tests: FORCE
+	$(Q)if [ "$(feature-libcheck)" = "1" ]; then \
+		$(MAKE) $(UNIT_TESTS) && $(UNIT_TESTS); \
+	else \
+		echo "libcheck is missing, skipping unit tests. Please install check-devel/check"; \
+	fi
diff --git a/tools/tracing/rtla/tests/unit/unit_tests.c b/tools/tracing/rtla/tests/unit/unit_tests.c
new file mode 100644
index 000000000000..aa53f8605e36
--- /dev/null
+++ b/tools/tracing/rtla/tests/unit/unit_tests.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "../../src/utils.h"
+
+START_TEST(test_strtoi)
+{
+	int result;
+	char buf[64];
+
+	ck_assert_int_eq(strtoi("123", &result), 0);
+	ck_assert_int_eq(result, 123);
+	ck_assert_int_eq(strtoi(" -456", &result), 0);
+	ck_assert_int_eq(result, -456);
+
+	snprintf(buf, sizeof(buf), "%d", INT_MAX);
+	ck_assert_int_eq(strtoi(buf, &result), 0);
+	snprintf(buf, sizeof(buf), "%ld", (long)INT_MAX + 1);
+	ck_assert_int_eq(strtoi(buf, &result), -1);
+
+	ck_assert_int_eq(strtoi("", &result), -1);
+	ck_assert_int_eq(strtoi("123abc", &result), -1);
+	ck_assert_int_eq(strtoi("123 ", &result), -1);
+}
+END_TEST
+
+START_TEST(test_parse_cpu_set)
+{
+	cpu_set_t set;
+	int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+	ck_assert_int_eq(parse_cpu_set("0", &set), 0);
+	ck_assert(CPU_ISSET(0, &set));
+	ck_assert(!CPU_ISSET(1, &set));
+
+	if (nr_cpus > 2) {
+		ck_assert_int_eq(parse_cpu_set("0,2", &set), 0);
+		ck_assert(CPU_ISSET(0, &set));
+		ck_assert(CPU_ISSET(2, &set));
+	}
+
+	if (nr_cpus > 3) {
+		ck_assert_int_eq(parse_cpu_set("0-3", &set), 0);
+		ck_assert(CPU_ISSET(0, &set));
+		ck_assert(CPU_ISSET(1, &set));
+		ck_assert(CPU_ISSET(2, &set));
+		ck_assert(CPU_ISSET(3, &set));
+	}
+
+	if (nr_cpus > 5) {
+		ck_assert_int_eq(parse_cpu_set("1-3,5", &set), 0);
+		ck_assert(!CPU_ISSET(0, &set));
+		ck_assert(CPU_ISSET(1, &set));
+		ck_assert(CPU_ISSET(2, &set));
+		ck_assert(CPU_ISSET(3, &set));
+		ck_assert(!CPU_ISSET(4, &set));
+		ck_assert(CPU_ISSET(5, &set));
+	}
+
+	ck_assert_int_eq(parse_cpu_set("-1", &set), 1);
+	ck_assert_int_eq(parse_cpu_set("abc", &set), 1);
+	ck_assert_int_eq(parse_cpu_set("9999", &set), 1);
+}
+END_TEST
+
+START_TEST(test_parse_prio)
+{
+	struct sched_attr attr;
+
+	ck_assert_int_eq(parse_prio("f:50", &attr), 0);
+	ck_assert_uint_eq(attr.sched_policy, SCHED_FIFO);
+	ck_assert_uint_eq(attr.sched_priority, 50U);
+
+	ck_assert_int_eq(parse_prio("r:30", &attr), 0);
+	ck_assert_uint_eq(attr.sched_policy, SCHED_RR);
+
+	ck_assert_int_eq(parse_prio("o:0", &attr), 0);
+	ck_assert_uint_eq(attr.sched_policy, SCHED_OTHER);
+	ck_assert_int_eq(attr.sched_nice, 0);
+
+	ck_assert_int_eq(parse_prio("d:10ms:100ms", &attr), 0);
+	ck_assert_uint_eq(attr.sched_policy, 6U);
+
+	ck_assert_int_eq(parse_prio("f:999", &attr), -1);
+	ck_assert_int_eq(parse_prio("o:-20", &attr), -1);
+	ck_assert_int_eq(parse_prio("d:100ms:10ms", &attr), -1);
+	ck_assert_int_eq(parse_prio("x:50", &attr), -1);
+}
+END_TEST
+
+Suite *utils_suite(void)
+{
+	Suite *s = suite_create("utils");
+	TCase *tc = tcase_create("core");
+
+	tcase_add_test(tc, test_strtoi);
+	tcase_add_test(tc, test_parse_cpu_set);
+	tcase_add_test(tc, test_parse_prio);
+
+	suite_add_tcase(s, tc);
+	return s;
+}
+
+int main(void)
+{
+	int num_failed;
+	SRunner *sr;
+
+	sr = srunner_create(utils_suite());
+	srunner_run_all(sr, CK_NORMAL);
+	num_failed = srunner_ntests_failed(sr);
+
+	srunner_free(sr);
+
+	return (num_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
-- 
2.52.0


^ permalink raw reply related

* [PATCH v2 1/2] tools/build: Add feature test for libcheck
From: Costa Shulyupin @ 2026-01-19 10:58 UTC (permalink / raw)
  To: Steven Rostedt, Tomas Glozar, Ian Rogers,
	Arnaldo Carvalho de Melo, Namhyung Kim, Alexandre Chartre,
	Costa Shulyupin, Blake Jones, Yuzhuo Jing, Leo Yan, linux-kernel,
	linux-trace-kernel
In-Reply-To: <20260119105857.797498-1-costa.shul@redhat.com>

Enable support for unit tests in rtla.

Note that the pkg-config file for libcheck is named check.pc.

Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
---
 tools/build/Makefile.feature        | 3 +++
 tools/build/feature/Makefile        | 4 ++++
 tools/build/feature/test-libcheck.c | 8 ++++++++
 3 files changed, 15 insertions(+)
 create mode 100644 tools/build/feature/test-libcheck.c

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 362cf8f4a0a0..ec0b21207fab 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -115,6 +115,7 @@ FEATURE_TESTS_EXTRA :=                  \
          hello                          \
          libbabeltrace                  \
          libcapstone                    \
+         libcheck                       \
          libbfd-liberty                 \
          libbfd-liberty-z               \
          libopencsd                     \
@@ -175,6 +176,8 @@ ifneq ($(PKG_CONFIG),)
   $(foreach package,$(FEATURE_PKG_CONFIG),$(call feature_pkg_config,$(package)))
 endif
 
+FEATURE_CHECK_LDFLAGS-libcheck = -lcheck
+
 # Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
 # If in the future we need per-feature checks/flags for features not
 # mentioned in this list we need to refactor this ;-).
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 0d5a15654b17..15d8cce9f52a 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -50,6 +50,7 @@ FILES=                                          \
          test-timerfd.bin                       \
          test-libbabeltrace.bin                 \
          test-libcapstone.bin			\
+         test-libcheck.bin			\
          test-compile-32.bin                    \
          test-compile-x32.bin                   \
          test-zlib.bin                          \
@@ -306,6 +307,9 @@ $(OUTPUT)test-libbabeltrace.bin:
 $(OUTPUT)test-libcapstone.bin:
 	$(BUILD) # -lcapstone provided by $(FEATURE_CHECK_LDFLAGS-libcapstone)
 
+$(OUTPUT)test-libcheck.bin:
+	$(BUILD) # -lcheck is provided by $(FEATURE_CHECK_LDFLAGS-libcheck)
+
 $(OUTPUT)test-compile-32.bin:
 	$(CC) -m32 -Wall -Werror -o $@ test-compile.c
 
diff --git a/tools/build/feature/test-libcheck.c b/tools/build/feature/test-libcheck.c
new file mode 100644
index 000000000000..cfb8d452e9ef
--- /dev/null
+++ b/tools/build/feature/test-libcheck.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <check.h>
+
+int main(void)
+{
+	Suite *s = suite_create("test");
+	return s == 0;
+}
-- 
2.52.0


^ permalink raw reply related

* [PATCH v2 0/2] tools/rtla: Add unit tests
From: Costa Shulyupin @ 2026-01-19 10:58 UTC (permalink / raw)
  To: Steven Rostedt, Tomas Glozar, Ian Rogers,
	Arnaldo Carvalho de Melo, Namhyung Kim, Alexandre Chartre,
	Costa Shulyupin, Blake Jones, Yuzhuo Jing, Leo Yan, linux-kernel,
	linux-trace-kernel

v2: Address feedback from Tomas Glozar
- Split the patch.
- Extract separate target unit-tests.
- Use build system
- Add libcheck to tools/build dependency detection

Costa Shulyupin (2):
  tools/build: Add feature test for libcheck
  tools/rtla: Add unit tests for utils.c

 tools/build/Makefile.feature                |   3 +
 tools/build/feature/Makefile                |   4 +
 tools/build/feature/test-libcheck.c         |   8 ++
 tools/tracing/rtla/Build                    |   1 +
 tools/tracing/rtla/Makefile                 |   5 +
 tools/tracing/rtla/Makefile.config          |   8 ++
 tools/tracing/rtla/README.txt               |   1 +
 tools/tracing/rtla/tests/unit/Build         |   2 +
 tools/tracing/rtla/tests/unit/Makefile.unit |  17 +++
 tools/tracing/rtla/tests/unit/unit_tests.c  | 123 ++++++++++++++++++++
 10 files changed, 172 insertions(+)
 create mode 100644 tools/build/feature/test-libcheck.c
 create mode 100644 tools/tracing/rtla/tests/unit/Build
 create mode 100644 tools/tracing/rtla/tests/unit/Makefile.unit
 create mode 100644 tools/tracing/rtla/tests/unit/unit_tests.c

-- 
2.52.0


^ permalink raw reply

* Re: [PATCH V5 0/2] mm/khugepaged: fix dirty page handling for MADV_COLLAPSE
From: Lorenzo Stoakes @ 2026-01-19 10:54 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat)
  Cc: Garg, Shivank, Andrew Morton, Zi Yan, Baolin Wang,
	Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, Masami Hiramatsu, Steven Rostedt, linux-trace-kernel,
	Mathieu Desnoyers, Zach O'Keefe, linux-mm, linux-kernel,
	Stephen Rothwell
In-Reply-To: <c63df10d-c61c-4337-9c88-ed1ce81204a1@kernel.org>

On Mon, Jan 19, 2026 at 10:58:39AM +0100, David Hildenbrand (Red Hat) wrote:
> On 1/19/26 06:07, Garg, Shivank wrote:
> >
> >
> > On 1/19/2026 1:52 AM, Andrew Morton wrote:
> > > Please tolerate a little whining about the timeliess here.  We're at
> > > -rc6, v4 was added to mm.git over a month ago, had quite a lot of
> > > review, this is very close to being moved into the mm-stable branch and now
> > > we get v5.  Argh.

As co-maintainer of THP:

Can I explicitly request that you not merge anything in THP without EXPLICIT
sub-M sign-off, i.e. either me or David.

Obviously I have publicly and privately request that we do this for all of mm,
but in THP especially, we CANNOT accept series landing without this.

THP workload is one of the worst in mm and is completely overwhelming.

Again - David is working whilst being on holiday to handle the load because by
default we auto-merge.

And here you are complaining that you can't auto-merge (...!), it's completely
unworkable.

People can just _wait_ for things to land sometimes. It's OK. It's part of why
the whole rc- approach was added - I think Greg KH explicitly wrote about this
elsewhere - people can just wait for the next cycle and not be too disappointed,
it realy isn't that long.

Stability trumps speed of merge.

I don't want to have to write a script to auto-NAK anything that doesn't match
this requirement, but I'm starting to feel like I have to... Let's try to avoid
that.

> > >
> > I sincerely apologize for this.

You don't need to apologise Shivank, you just might have to wait a cycle.

> >
> > I had this doubt on sending an incremental patch or V5:
> > https://lore.kernel.org/linux-mm/7a42515f-ae57-4f4d-831c-87689930a797@amd.com
> >
> >
> > > > V5:
> > > > - In patch 2/2, Simplify dirty writeback retry logic (David)
> > > Are you sure this is the only change?  It looks like a lot for a
> > > simplification and I'm wondering if we should retain the v4 series and
> > > defer a simplification for separate consideration during the next
> > > cycle.
> >
> > Yes, patch 1/2 is unchanged and patch 2/2 is the only change.
> > The diff looks larger due to code movement but logic is actually simpler now.
> >
> > I completely understand if you prefer to keep V4 and defer this
> > refactoring. I'm sorry for creating this late-cycle churn. Please let me
> > know what you'd prefer and I'll follow your guidance.
>
> There is no reason to rush any of this. :)

Yes absolutely.

It's patently INSANE and in fact a ongoing security risk to rush things in mm in
general, and we really need to stop this.

>
> Review was not over and due to multiple factors my review on v4 came in
> later than I wanted.

Also you're on leave from work :)

I have taken a step back from review somewhat due to this insanity, but now feel
like I have to step it back up... due to this insanity.

Or maybe write a script...

>
> Andrew, if you prefer, I can start sending as a reply to every patch set
> that I want to review so you are aware that it is on my review backlog.

This is ridiculous and shouldn't be necessary.

>
> Unfortunately we can't have nice things (sub-maintainer acks).

Well we can start having less nice things like a NAK script if this unworkable
situation continues.

>
> --
> Cheers
>
> David

Again Andrew - as THP co-maintainer - I politely ask that, while you might not
want to implement a sub-M A-b/R-b requirement across mm (though you should),
that you implement one for THP explicitly.

If you don't then I don't really see any other option than to start NAK'ing
everything in THP that hits mm-stable which either David or I have not
explicitly tagged.

Thanks, Lorenzo

^ permalink raw reply

* [PATCH net-next v4] page_pool: Add page_pool_release_stalled tracepoint
From: Leon Hwang @ 2026-01-19 10:21 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Ilias Apalodimas, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	kerneljasonxing, lance.yang, jiayuan.chen, linux-kernel,
	linux-trace-kernel, Leon Hwang, Leon Huang Fu

Introduce a new tracepoint to track stalled page pool releases,
providing better observability for page pool lifecycle issues.

Problem:
Currently, when a page pool shutdown is stalled due to inflight pages,
the kernel only logs a warning message via pr_warn(). This has several
limitations:

1. The warning floods the kernel log after the initial DEFER_WARN_INTERVAL,
   making it difficult to track the progression of stalled releases
2. There's no structured way to monitor or analyze these events
3. Debugging tools cannot easily capture and correlate stalled pool
   events with other network activity

Solution:
Add a new tracepoint, page_pool_release_stalled, that fires when a page
pool shutdown is stalled. The tracepoint captures:
- pool: pointer to the stalled page_pool
- inflight: number of pages still in flight
- sec: seconds since the release was deferred

The implementation also modifies the logging behavior:
- pr_warn() is only emitted during the first warning interval
  (DEFER_WARN_INTERVAL to DEFER_WARN_INTERVAL*2)
- The tracepoint is fired always, reducing log noise while still
  allowing monitoring tools to track the issue

This allows developers and system administrators to:
- Use tools like perf, ftrace, or eBPF to monitor stalled releases
- Correlate page pool issues with network driver behavior
- Analyze patterns without parsing kernel logs
- Track the progression of inflight page counts over time

Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: Leon Huang Fu <leon.huangfu@shopee.com>
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
v3 -> v4:
 - Collect Reviewed-by from Steven, thanks.
 - Collect Acked-by from Jesper, thanks.
 - https://lore.kernel.org/netdev/20260102071745.291969-1-leon.hwang@linux.dev/

v2 -> v3:
 - Print id using '%u'.
 - https://lore.kernel.org/netdev/20260102061718.210248-1-leon.hwang@linux.dev/

v1 -> v2:
 - Drop RFC.
 - Store 'pool->user.id' to '__entry->id' (per Steven Rostedt).
 - https://lore.kernel.org/netdev/20251125082207.356075-1-leon.hwang@linux.dev/
---
 include/trace/events/page_pool.h | 24 ++++++++++++++++++++++++
 net/core/page_pool.c             |  6 ++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/include/trace/events/page_pool.h b/include/trace/events/page_pool.h
index 31825ed30032..a851e0f6a384 100644
--- a/include/trace/events/page_pool.h
+++ b/include/trace/events/page_pool.h
@@ -113,6 +113,30 @@ TRACE_EVENT(page_pool_update_nid,
 		  __entry->pool, __entry->pool_nid, __entry->new_nid)
 );
 
+TRACE_EVENT(page_pool_release_stalled,
+
+	TP_PROTO(const struct page_pool *pool, int inflight, int sec),
+
+	TP_ARGS(pool, inflight, sec),
+
+	TP_STRUCT__entry(
+		__field(const struct page_pool *, pool)
+		__field(u32,			  id)
+		__field(int,			  inflight)
+		__field(int,			  sec)
+	),
+
+	TP_fast_assign(
+		__entry->pool		= pool;
+		__entry->id		= pool->user.id;
+		__entry->inflight	= inflight;
+		__entry->sec		= sec;
+	),
+
+	TP_printk("page_pool=%p id=%u inflight=%d sec=%d",
+		  __entry->pool, __entry->id, __entry->inflight, __entry->sec)
+);
+
 #endif /* _TRACE_PAGE_POOL_H */
 
 /* This part must be outside protection */
diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 265a729431bb..01564aa84c89 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -1222,8 +1222,10 @@ static void page_pool_release_retry(struct work_struct *wq)
 	    (!netdev || netdev == NET_PTR_POISON)) {
 		int sec = (s32)((u32)jiffies - (u32)pool->defer_start) / HZ;
 
-		pr_warn("%s() stalled pool shutdown: id %u, %d inflight %d sec\n",
-			__func__, pool->user.id, inflight, sec);
+		if (sec >= DEFER_WARN_INTERVAL / HZ && sec < DEFER_WARN_INTERVAL * 2 / HZ)
+			pr_warn("%s() stalled pool shutdown: id %u, %d inflight %d sec\n",
+				__func__, pool->user.id, inflight, sec);
+		trace_page_pool_release_stalled(pool, inflight, sec);
 		pool->defer_warn = jiffies + DEFER_WARN_INTERVAL;
 	}
 
-- 
2.52.0


^ permalink raw reply related

* Re: [PATCH v4 09/15] sched: Add deadline tracepoints
From: Juri Lelli @ 2026-01-19 10:20 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
	Masami Hiramatsu, Ingo Molnar, Peter Zijlstra, linux-trace-kernel,
	Phil Auld, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <20260116123911.130300-10-gmonaco@redhat.com>

Hello,

On 16/01/26 13:39, Gabriele Monaco wrote:
> Add the following tracepoints:
> 
> * sched_dl_throttle(dl_se, cpu):
>     Called when a deadline entity is throttled
> * sched_dl_replenish(dl_se, cpu):
>     Called when a deadline entity's runtime is replenished
> * sched_dl_server_start(dl_se, cpu):
>     Called when a deadline server is started
> * sched_dl_server_stop(dl_se, cpu):
>     Called when a deadline server is stopped
> 
> Those tracepoints can be useful to validate the deadline scheduler with
> RV and are not exported to tracefs.
> 
> Reviewed-by: Phil Auld <pauld@redhat.com>
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>

Looks good!

Acked-by: Juri Lelli <juri.lelli@redhat.com>

Thanks,
Juri


^ permalink raw reply

* Re: [PATCH v4 13/15] sched/deadline: Move some utility functions to deadline.h
From: Juri Lelli @ 2026-01-19 10:08 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli, Ingo Molnar,
	Peter Zijlstra, Tomas Glozar, Clark Williams, John Kacur,
	linux-trace-kernel
In-Reply-To: <20260116123911.130300-14-gmonaco@redhat.com>

Hello,

On 16/01/26 13:39, Gabriele Monaco wrote:
> Some utility functions on sched_dl_entity can be useful outside of
> deadline.c , for instance for modelling, without relying on raw
> structure fields.
> 
> Move functions like pi_of, is_dl_boosted, dl_is_implicit to deadline.h
> to make them available outside.
> 
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
> ---
>  include/linux/sched/deadline.h | 51 ++++++++++++++++++++++++++++++++++
>  kernel/sched/deadline.c        | 50 +--------------------------------
>  2 files changed, 52 insertions(+), 49 deletions(-)
> 
> diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h
> index c40115d4e34d..9468a9b1090c 100644
> --- a/include/linux/sched/deadline.h
> +++ b/include/linux/sched/deadline.h
> @@ -37,4 +37,55 @@ extern void dl_clear_root_domain_cpu(int cpu);
>  extern u64 dl_cookie;
>  extern bool dl_bw_visited(int cpu, u64 cookie);
>  
> +extern struct rv_monitor rv_deadline;
> +
> +static bool dl_server(struct sched_dl_entity *dl_se)

Think we want to make this 'inline'? Just in case compiler decides not
to inline it.

> +{
> +	return dl_se->dl_server;
> +}

Thanks,
Juri


^ permalink raw reply

* Re: [PATCH V5 2/2] mm/khugepaged: retry with sync writeback for MADV_COLLAPSE
From: David Hildenbrand (Red Hat) @ 2026-01-19 10:08 UTC (permalink / raw)
  To: Shivank Garg, Andrew Morton, Lorenzo Stoakes
  Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
	Dev Jain, Barry Song, Lance Yang, Masami Hiramatsu,
	Steven Rostedt, linux-trace-kernel, Mathieu Desnoyers,
	Zach O'Keefe, linux-mm, linux-kernel, Stephen Rothwell,
	Branden Moore
In-Reply-To: <20260118190939.8986-7-shivankg@amd.com>

On 1/18/26 20:09, Shivank Garg wrote:
> When MADV_COLLAPSE is called on file-backed mappings (e.g., executable
> text sections), the pages may still be dirty from recent writes.
> collapse_file() will trigger async writeback and fail with
> SCAN_PAGE_DIRTY_OR_WRITEBACK (-EAGAIN).
> 
> MADV_COLLAPSE is a synchronous operation where userspace expects
> immediate results. If the collapse fails due to dirty pages, perform
> synchronous writeback on the specific range and retry once.
> 
> This avoids spurious failures for freshly written executables while
> avoiding unnecessary synchronous I/O for mappings that are already clean.
> 
> Reported-by: Branden Moore <Branden.Moore@amd.com>
> Closes: https://lore.kernel.org/all/4e26fe5e-7374-467c-a333-9dd48f85d7cc@amd.com
> Fixes: 34488399fa08 ("mm/madvise: add file and shmem support to MADV_COLLAPSE")
> Suggested-by: David Hildenbrand <david@kernel.org>
> Tested-by: Lance Yang <lance.yang@linux.dev>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---

Looks good to me now, thanks Shivank!

Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>

-- 
Cheers

David

^ permalink raw reply

* Re: [PATCH V5 0/2] mm/khugepaged: fix dirty page handling for MADV_COLLAPSE
From: David Hildenbrand (Red Hat) @ 2026-01-19  9:58 UTC (permalink / raw)
  To: Garg, Shivank, Andrew Morton
  Cc: Lorenzo Stoakes, Zi Yan, Baolin Wang, Liam R . Howlett,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Masami Hiramatsu, Steven Rostedt, linux-trace-kernel,
	Mathieu Desnoyers, Zach O'Keefe, linux-mm, linux-kernel,
	Stephen Rothwell
In-Reply-To: <12b6747e-b844-4931-9918-fd095a6d772b@amd.com>

On 1/19/26 06:07, Garg, Shivank wrote:
> 
> 
> On 1/19/2026 1:52 AM, Andrew Morton wrote:
>> Please tolerate a little whining about the timeliess here.  We're at
>> -rc6, v4 was added to mm.git over a month ago, had quite a lot of
>> review, this is very close to being moved into the mm-stable branch and now
>> we get v5.  Argh.
>>
> I sincerely apologize for this.
> 
> I had this doubt on sending an incremental patch or V5:
> https://lore.kernel.org/linux-mm/7a42515f-ae57-4f4d-831c-87689930a797@amd.com
> 
> 
>>> V5:
>>> - In patch 2/2, Simplify dirty writeback retry logic (David)
>> Are you sure this is the only change?  It looks like a lot for a
>> simplification and I'm wondering if we should retain the v4 series and
>> defer a simplification for separate consideration during the next
>> cycle.
> 
> Yes, patch 1/2 is unchanged and patch 2/2 is the only change.
> The diff looks larger due to code movement but logic is actually simpler now.
> 
> I completely understand if you prefer to keep V4 and defer this
> refactoring. I'm sorry for creating this late-cycle churn. Please let me
> know what you'd prefer and I'll follow your guidance.

There is no reason to rush any of this. :)

Review was not over and due to multiple factors my review on v4 came in 
later than I wanted.

Andrew, if you prefer, I can start sending as a reply to every patch set 
that I want to review so you are aware that it is on my review backlog.

Unfortunately we can't have nice things (sub-maintainer acks).

-- 
Cheers

David

^ permalink raw reply

* Re: [PATCH net-next v3] page_pool: Add page_pool_release_stalled tracepoint
From: Jesper Dangaard Brouer @ 2026-01-19  9:54 UTC (permalink / raw)
  To: Leon Hwang, Jakub Kicinski
  Cc: netdev, Ilias Apalodimas, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, kerneljasonxing, lance.yang, jiayuan.chen,
	linux-kernel, linux-trace-kernel, Leon Huang Fu, Dragos Tatulea,
	kernel-team, Yan Zhai
In-Reply-To: <8dc3765b-e97f-4937-b6b9-872a83ba1e26@linux.dev>



On 19/01/2026 09.49, Leon Hwang wrote:
> 
> 
> On 5/1/26 00:43, Jakub Kicinski wrote:
>> On Fri, 2 Jan 2026 12:43:46 +0100 Jesper Dangaard Brouer wrote:
>>> On 02/01/2026 08.17, Leon Hwang wrote:
>>>> Introduce a new tracepoint to track stalled page pool releases,
>>>> providing better observability for page pool lifecycle issues.
>>>
>>> In general I like/support adding this tracepoint for "debugability" of
>>> page pool lifecycle issues.
>>>
>>> For "observability" @Kuba added a netlink scheme[1][2] for page_pool[3],
>>> which gives us the ability to get events and list page_pools from userspace.
>>> I've not used this myself (yet) so I need input from others if this is
>>> something that others have been using for page pool lifecycle issues?
>>
>> My input here is the least valuable (since one may expect the person
>> who added the code uses it) - but FWIW yes, we do use the PP stats to
>> monitor PP lifecycle issues at Meta. That said - we only monitor for
>> accumulation of leaked memory from orphaned pages, as the whole reason
>> for adding this code was that in practice the page may be sitting in
>> a socket rx queue (or defer free queue etc.) IOW a PP which is not
>> getting destroyed for a long time is not necessarily a kernel issue.
>>

What monitoring tool did production people add metrics to?

People at CF recommend that I/we add this to prometheus/node_exporter.
Perhaps somebody else already added this to some other FOSS tool?

https://github.com/prometheus/node_exporter


>>> Need input from @Kuba/others as the "page-pool-get"[4] state that "Only
>>> Page Pools associated with a net_device can be listed".  Don't we want
>>> the ability to list "invisible" page_pool's to allow debugging issues?
>>>
>>>    [1] https://docs.kernel.org/userspace-api/netlink/intro-specs.html
>>>    [2] https://docs.kernel.org/userspace-api/netlink/index.html
>>>    [3] https://docs.kernel.org/netlink/specs/netdev.html
>>>    [4] https://docs.kernel.org/netlink/specs/netdev.html#page-pool-get
>>
>> The documentation should probably be updated :(
>> I think what I meant is that most _drivers_ didn't link their PP to the
>> netdev via params when the API was added. So if the user doesn't see the
>> page pools - the driver is probably not well maintained.
>>
>> In practice only page pools which are not accessible / visible via the
>> API are page pools from already destroyed network namespaces (assuming
>> their netdevs were also destroyed and not re-parented to init_net).
>> Which I'd think is a rare case?
>>
>>> Looking at the code, I see that NETDEV_CMD_PAGE_POOL_CHANGE_NTF netlink
>>> notification is only generated once (in page_pool_destroy) and not when
>>> we retry in page_pool_release_retry (like this patch).  In that sense,
>>> this patch/tracepoint is catching something more than netlink provides.
>>> First I though we could add a netlink notification, but I can imagine
>>> cases this could generate too many netlink messages e.g. a netdev with
>>> 128 RX queues generating these every second for every RX queue.
>>
>> FWIW yes, we can add more notifications. Tho, as I mentioned at the
>> start of my reply - the expectation is that page pools waiting for
>> a long time to be destroyed is something that _will_ happen in
>> production.
>>
>>> Guess, I've talked myself into liking this change, what do other
>>> maintainers think?  (e.g. netlink scheme and debugging balance)
>>
>> We added the Netlink API to mute the pr_warn() in all practical cases.
>> If Xiang Mei is seeing the pr_warn() I think we should start by asking
>> what kernel and driver they are using, and what the usage pattern is :(
>> As I mentioned most commonly the pr_warn() will trigger because driver
>> doesn't link the pp to a netdev.
> 
> Hi Jakub, Jesper,
> 
> Thanks for the discussion. Since netlink notifications are only emitted
> at page_pool_destroy(), the tracepoint still provides additional
> debugging visibility for prolonged page_pool_release_retry() cases.
> 
> Steven has reviewed the tracepoint [1]. Any further feedback would be
> appreciated.

This change looks good as-is:

Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>

Your patch[0] is marked as "Changes Requested".
I suggest you send a V4 with my Acked-by added.

--Jesper

[0] 
https://patchwork.kernel.org/project/netdevbpf/patch/20260102071745.291969-1-leon.hwang@linux.dev/




^ permalink raw reply

* Re: [PATCH net-next v3] page_pool: Add page_pool_release_stalled tracepoint
From: Leon Hwang @ 2026-01-19  8:49 UTC (permalink / raw)
  To: Jakub Kicinski, Jesper Dangaard Brouer
  Cc: netdev, Ilias Apalodimas, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, David S . Miller, Eric Dumazet, Paolo Abeni,
	Simon Horman, kerneljasonxing, lance.yang, jiayuan.chen,
	linux-kernel, linux-trace-kernel, Leon Huang Fu, Dragos Tatulea,
	kernel-team, Yan Zhai
In-Reply-To: <20260104084347.5de3a537@kernel.org>



On 5/1/26 00:43, Jakub Kicinski wrote:
> On Fri, 2 Jan 2026 12:43:46 +0100 Jesper Dangaard Brouer wrote:
>> On 02/01/2026 08.17, Leon Hwang wrote:
>>> Introduce a new tracepoint to track stalled page pool releases,
>>> providing better observability for page pool lifecycle issues.
>>
>> In general I like/support adding this tracepoint for "debugability" of
>> page pool lifecycle issues.
>>
>> For "observability" @Kuba added a netlink scheme[1][2] for page_pool[3], 
>> which gives us the ability to get events and list page_pools from userspace.
>> I've not used this myself (yet) so I need input from others if this is 
>> something that others have been using for page pool lifecycle issues?
> 
> My input here is the least valuable (since one may expect the person
> who added the code uses it) - but FWIW yes, we do use the PP stats to
> monitor PP lifecycle issues at Meta. That said - we only monitor for
> accumulation of leaked memory from orphaned pages, as the whole reason
> for adding this code was that in practice the page may be sitting in
> a socket rx queue (or defer free queue etc.) IOW a PP which is not
> getting destroyed for a long time is not necessarily a kernel issue.
> 
>> Need input from @Kuba/others as the "page-pool-get"[4] state that "Only 
>> Page Pools associated with a net_device can be listed".  Don't we want 
>> the ability to list "invisible" page_pool's to allow debugging issues?
>>
>>   [1] https://docs.kernel.org/userspace-api/netlink/intro-specs.html
>>   [2] https://docs.kernel.org/userspace-api/netlink/index.html
>>   [3] https://docs.kernel.org/netlink/specs/netdev.html
>>   [4] https://docs.kernel.org/netlink/specs/netdev.html#page-pool-get
> 
> The documentation should probably be updated :(
> I think what I meant is that most _drivers_ didn't link their PP to the
> netdev via params when the API was added. So if the user doesn't see the
> page pools - the driver is probably not well maintained.
> 
> In practice only page pools which are not accessible / visible via the
> API are page pools from already destroyed network namespaces (assuming
> their netdevs were also destroyed and not re-parented to init_net).
> Which I'd think is a rare case?
> 
>> Looking at the code, I see that NETDEV_CMD_PAGE_POOL_CHANGE_NTF netlink
>> notification is only generated once (in page_pool_destroy) and not when
>> we retry in page_pool_release_retry (like this patch).  In that sense,
>> this patch/tracepoint is catching something more than netlink provides.
>> First I though we could add a netlink notification, but I can imagine
>> cases this could generate too many netlink messages e.g. a netdev with
>> 128 RX queues generating these every second for every RX queue.
> 
> FWIW yes, we can add more notifications. Tho, as I mentioned at the
> start of my reply - the expectation is that page pools waiting for
> a long time to be destroyed is something that _will_ happen in
> production.
> 
>> Guess, I've talked myself into liking this change, what do other
>> maintainers think?  (e.g. netlink scheme and debugging balance)
> 
> We added the Netlink API to mute the pr_warn() in all practical cases.
> If Xiang Mei is seeing the pr_warn() I think we should start by asking
> what kernel and driver they are using, and what the usage pattern is :(
> As I mentioned most commonly the pr_warn() will trigger because driver
> doesn't link the pp to a netdev.

Hi Jakub, Jesper,

Thanks for the discussion. Since netlink notifications are only emitted
at page_pool_destroy(), the tracepoint still provides additional
debugging visibility for prolonged page_pool_release_retry() cases.

Steven has reviewed the tracepoint [1]. Any further feedback would be
appreciated.

Thanks,
Leon

[1]
https://lore.kernel.org/netdev/20260102104504.7f593441@gandalf.local.home/



^ permalink raw reply

* Re: [RFC PATCH v1 01/37] KVM: guest_memfd: Introduce per-gmem attributes, use to guard user mappings
From: Yan Zhao @ 2026-01-19  7:58 UTC (permalink / raw)
  To: Ackerley Tng
  Cc: cgroups, kvm, linux-doc, linux-fsdevel, linux-kernel,
	linux-kselftest, linux-mm, linux-trace-kernel, x86, akpm,
	binbin.wu, bp, brauner, chao.p.peng, chenhuacai, corbet,
	dave.hansen, dave.hansen, david, dmatlack, erdemaktas, fan.du,
	fvdl, haibo1.xu, hannes, hch, hpa, hughd, ira.weiny,
	isaku.yamahata, jack, james.morse, jarkko, jgg, jgowans, jhubbard,
	jroedel, jthoughton, jun.miao, kai.huang, keirf, kent.overstreet,
	liam.merwick, maciej.wieczor-retman, mail, maobibo,
	mathieu.desnoyers, maz, mhiramat, mhocko, mic, michael.roth,
	mingo, mlevitsk, mpe, muchun.song, nikunj, nsaenz, oliver.upton,
	palmer, pankaj.gupta, paul.walmsley, pbonzini, peterx, pgonda,
	prsampat, pvorel, qperret, richard.weiyang, rick.p.edgecombe,
	rientjes, rostedt, roypat, rppt, seanjc, shakeel.butt, shuah,
	steven.price, steven.sistare, suzuki.poulose, tabba, tglx,
	thomas.lendacky, vannapurve, vbabka, viro, vkuznets, wei.w.wang,
	will, willy, wyihan, xiaoyao.li, yilun.xu, yuzenghui, zhiquan1.li
In-Reply-To: <638600e19c6e23959bad60cf61582f387dff6445.1760731772.git.ackerleytng@google.com>

On Fri, Oct 17, 2025 at 01:11:42PM -0700, Ackerley Tng wrote:
> Use the filemap invalidation lock to protect the maple tree, as taking the
> lock for read when faulting in memory (for userspace or the guest) isn't
> expected to result in meaningful contention, and using a separate lock
> would add significant complexity (avoid deadlock is quite difficult).
... 
> +static u64 kvm_gmem_get_attributes(struct inode *inode, pgoff_t index)
> +{
> +	void *entry = mtree_load(&GMEM_I(inode)->attributes, index);
> +
> +	return WARN_ON_ONCE(!entry) ? 0 : xa_to_value(entry);
> +}
It looks like kvm_gmem_get_attributes() is possible to be invoked outside the
protection of inode->i_mapping->invalidate_lock.

kvm_tdp_mmu_page_fault
    kvm_mmu_faultin_pfn(vcpu, fault, ACC_ALL)
        kvm_mem_is_private(kvm, fault->gfn)
            kvm_get_memory_attributes
	        kvm_gmem_get_memory_attributes
		    kvm_gmem_get_attributes

> +static int kvm_gmem_init_inode(struct inode *inode, loff_t size, u64 flags)
> +{
> +	struct gmem_inode *gi = GMEM_I(inode);
> +	MA_STATE(mas, &gi->attributes, 0, (size >> PAGE_SHIFT) - 1);
> +	u64 attrs;
> +	int r;
> +
> +	inode->i_op = &kvm_gmem_iops;
> +	inode->i_mapping->a_ops = &kvm_gmem_aops;
> +	inode->i_mode |= S_IFREG;
> +	inode->i_size = size;
> +	mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
> +	mapping_set_inaccessible(inode->i_mapping);
> +	/* Unmovable mappings are supposed to be marked unevictable as well. */
> +	WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));
> +
> +	gi->flags = flags;
> +
> +	mt_set_external_lock(&gi->attributes,
> +			     &inode->i_mapping->invalidate_lock);
> +
But here, it's declared that mtree is protected by the invalidate_lock.

> +	/*
> +	 * Store default attributes for the entire gmem instance. Ensuring every
> +	 * index is represented in the maple tree at all times simplifies the
> +	 * conversion and merging logic.
> +	 */
> +	attrs = gi->flags & GUEST_MEMFD_FLAG_INIT_SHARED ? 0 : KVM_MEMORY_ATTRIBUTE_PRIVATE;
> +
> +	/*
> +	 * Acquire the invalidation lock purely to make lockdep happy. There
> +	 * should be no races at this time since the inode hasn't yet been fully
> +	 * created.
> +	 */
> +	filemap_invalidate_lock(inode->i_mapping);
> +	r = mas_store_gfp(&mas, xa_mk_value(attrs), GFP_KERNEL);
> +	filemap_invalidate_unlock(inode->i_mapping);
> +
> +	return r;
> +}
> +

> @@ -925,13 +986,39 @@ static struct inode *kvm_gmem_alloc_inode(struct super_block *sb)
> 
>  	mpol_shared_policy_init(&gi->policy, NULL);
> 
> +	/*
> +	 * Memory attributes are protected the filemap invalidation lock, but
> +	 * the lock structure isn't available at this time.  Immediately mark
> +	 * maple tree as using external locking so that accessing the tree
> +	 * before its fully initialized results in NULL pointer dereferences
> +	 * and not more subtle bugs.
> +	 */
> +	mt_init_flags(&gi->attributes, MT_FLAGS_LOCK_EXTERN);
And here.
>  	gi->flags = 0;
>  	return &gi->vfs_inode;
>  }

So, it's possible for kvm_mem_is_private() to access invalid mtree data and hit
the WARN_ON_ONCE() in kvm_gmem_get_attributes().

I reported a similar error in [*].

[*] https://lore.kernel.org/all/aIwD5kGbMibV7ksk@yzhao56-desk.sh.intel.com
 

^ permalink raw reply

* Re: [PATCH v2] kprobes: Use dedicated kthread for kprobe optimizer
From: kernel test robot @ 2026-01-19  7:29 UTC (permalink / raw)
  To: Masami Hiramatsu (Google)
  Cc: oe-lkp, lkp, Steven Rostedt, linux-kernel, linux-trace-kernel,
	Naveen N Rao, David S . Miller, Masami Hiramatsu, oliver.sang
In-Reply-To: <176826884613.429923.16578111751623731056.stgit@devnote2>



Hello,

kernel test robot noticed "INFO:task_blocked_for_more_than#seconds" on:

commit: 62f65c2531ad66e84c1a5ef91389322357ef6db4 ("[PATCH v2] kprobes: Use dedicated kthread for kprobe optimizer")
url: https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu-Google/kprobes-Use-dedicated-kthread-for-kprobe-optimizer/20260113-094928
base: https://git.kernel.org/cgit/linux/kernel/git/trace/linux-trace for-next
patch link: https://lore.kernel.org/all/176826884613.429923.16578111751623731056.stgit@devnote2/
patch subject: [PATCH v2] kprobes: Use dedicated kthread for kprobe optimizer

in testcase: trinity
version: trinity-x86_64-294c4652-1_20251011
with following parameters:

	runtime: 300s
	group: group-03
	nr_groups: 5



config: x86_64-kexec
compiler: clang-20
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 32G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+-----------------------------------------+------------+------------+
|                                         | 78a419b44e | 62f65c2531 |
+-----------------------------------------+------------+------------+
| INFO:task_blocked_for_more_than#seconds | 0          | 6          |
+-----------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202601191507.74fccd0c-lkp@intel.com



[  972.359932][   T32] INFO: task kprobe-optimize:18 blocked for more than 491 seconds.
[  972.361221][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[  972.362516][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  972.364322][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[  972.366628][   T32] Call Trace:
[  972.367378][   T32]  <TASK>
[  972.368066][   T32]  __schedule (kernel/sched/core.c:5259)
[  972.370837][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[  972.371679][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[  972.373219][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[  972.374017][   T32]  kthread (kernel/kthread.c:465)
[  972.374573][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[  972.375364][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[  972.376005][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[  972.376679][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[  972.377305][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[  972.377958][   T32]  </TASK>
[ 1463.879952][   T32] INFO: task kprobe-optimize:18 blocked for more than 983 seconds.
[ 1463.882239][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 1463.884371][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1463.887443][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 1463.891867][   T32] Call Trace:
[ 1463.893396][   T32]  <TASK>
[ 1463.894468][   T32]  __schedule (kernel/sched/core.c:5259)
[ 1463.903984][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 1463.904926][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 1463.905949][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 1463.907111][   T32]  kthread (kernel/kthread.c:465)
[ 1463.907954][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 1463.909157][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 1463.910045][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 1463.910939][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 1463.911933][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 1463.912947][   T32]  </TASK>
[ 1955.399991][   T32] INFO: task kprobe-optimize:18 blocked for more than 1474 seconds.
[ 1955.404266][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 1955.407452][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1955.414557][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 1955.416961][   T32] Call Trace:
[ 1955.417705][   T32]  <TASK>
[ 1955.418382][   T32]  __schedule (kernel/sched/core.c:5259)
[ 1955.419274][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 1955.419929][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 1955.421071][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 1955.422303][   T32]  kthread (kernel/kthread.c:465)
[ 1955.423217][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 1955.424452][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 1955.425189][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 1955.425913][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 1955.426645][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 1955.427357][   T32]  </TASK>
[ 2446.919964][   T32] INFO: task kprobe-optimize:18 blocked for more than 1966 seconds.
[ 2446.922105][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 2446.925697][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 2446.926569][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 2446.927775][   T32] Call Trace:
[ 2446.928242][   T32]  <TASK>
[ 2446.928609][   T32]  __schedule (kernel/sched/core.c:5259)
[ 2446.929827][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 2446.930256][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 2446.930789][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 2446.931434][   T32]  kthread (kernel/kthread.c:465)
[ 2446.931926][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 2446.932624][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 2446.933079][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 2446.933534][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 2446.933983][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 2446.934450][   T32]  </TASK>
[ 2938.439916][   T32] INFO: task kprobe-optimize:18 blocked for more than 2457 seconds.
[ 2938.441278][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 2938.442281][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 2938.444599][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 2938.446316][   T32] Call Trace:
[ 2938.446892][   T32]  <TASK>
[ 2938.447449][   T32]  __schedule (kernel/sched/core.c:5259)
[ 2938.449286][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 2938.450230][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 2938.451347][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 2938.452611][   T32]  kthread (kernel/kthread.c:465)
[ 2938.453462][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 2938.454622][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 2938.455583][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 2938.456604][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 2938.457614][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 2938.458645][   T32]  </TASK>
[ 3429.960057][   T32] INFO: task kprobe-optimize:18 blocked for more than 2949 seconds.
[ 3429.962853][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 3429.965133][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 3429.967986][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 3429.971731][   T32] Call Trace:
[ 3429.973021][   T32]  <TASK>
[ 3429.974169][   T32]  __schedule (kernel/sched/core.c:5259)
[ 3429.975713][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 3429.977206][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 3429.978375][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 3429.979623][   T32]  kthread (kernel/kthread.c:465)
[ 3429.980602][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 3429.981810][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 3429.982797][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 3429.983793][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 3429.984838][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 3429.985864][   T32]  </TASK>
[ 3921.480064][   T32] INFO: task kprobe-optimize:18 blocked for more than 3440 seconds.
[ 3921.482942][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 3921.485260][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 3921.488269][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 3921.491811][   T32] Call Trace:
[ 3921.493488][   T32]  <TASK>
[ 3921.494960][   T32]  __schedule (kernel/sched/core.c:5259)
[ 3921.508616][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 3921.509430][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 3921.510413][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 3921.511467][   T32]  kthread (kernel/kthread.c:465)
[ 3921.512331][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 3921.513388][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 3921.514202][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 3921.514976][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 3921.515773][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 3921.516817][   T32]  </TASK>
[ 4413.000017][   T32] INFO: task kprobe-optimize:18 blocked for more than 3932 seconds.
[ 4413.004653][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 4413.007745][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 4413.010446][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 4413.013906][   T32] Call Trace:
[ 4413.015027][   T32]  <TASK>
[ 4413.016134][   T32]  __schedule (kernel/sched/core.c:5259)
[ 4413.017465][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 4413.018294][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 4413.019366][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 4413.020594][   T32]  kthread (kernel/kthread.c:465)
[ 4413.021350][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 4413.022331][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 4413.023124][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 4413.023925][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 4413.025015][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 4413.026074][   T32]  </TASK>
[ 4904.520028][   T32] INFO: task kprobe-optimize:18 blocked for more than 4423 seconds.
[ 4904.521949][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 4904.528612][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 4904.529924][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 4904.531461][   T32] Call Trace:
[ 4904.531896][   T32]  <TASK>
[ 4904.532406][   T32]  __schedule (kernel/sched/core.c:5259)
[ 4904.532947][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 4904.533381][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 4904.533944][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 4904.534547][   T32]  kthread (kernel/kthread.c:465)
[ 4904.534985][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 4904.535670][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 4904.536359][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 4904.536831][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 4904.537310][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 4904.537788][   T32]  </TASK>
[ 5396.039936][   T32] INFO: task kprobe-optimize:18 blocked for more than 4915 seconds.
[ 5396.040939][   T32]       Not tainted 6.19.0-rc5-00040-g62f65c2531ad #1
[ 5396.041631][   T32] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 5396.042742][   T32] task:kprobe-optimize state:D stack:0     pid:18    tgid:18    ppid:2      task_flags:0x208040 flags:0x00080000
[ 5396.045182][   T32] Call Trace:
[ 5396.045723][   T32]  <TASK>
[ 5396.046266][   T32]  __schedule (kernel/sched/core.c:5259)
[ 5396.046928][   T32]  schedule (arch/x86/include/asm/preempt.h:85 kernel/sched/core.c:6946 kernel/sched/core.c:6960)
[ 5396.047542][   T32]  kprobe_optimizer_thread (kernel/kprobes.c:656)
[ 5396.048329][   T32]  ? __pfx_autoremove_wake_function (kernel/sched/wait.c:402)
[ 5396.049182][   T32]  kthread (kernel/kthread.c:465)
[ 5396.049803][   T32]  ? __pfx_kprobe_optimizer_thread (kernel/kprobes.c:654)
[ 5396.050654][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 5396.051353][   T32]  ret_from_fork (arch/x86/kernel/process.c:164)
[ 5396.052048][   T32]  ? __pfx_kthread (kernel/kthread.c:412)
[ 5396.052723][   T32]  ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
[ 5396.053187][   T32]  </TASK>
[ 5396.053524][   T32] Future hung task reports are suppressed, see sysctl kernel.hung_task_warnings
BUG: kernel hang in test stage



The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20260119/202601191507.74fccd0c-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
From: Menglong Dong @ 2026-01-19  5:59 UTC (permalink / raw)
  To: Menglong Dong, Yonghong Song
  Cc: andrii, ast, daniel, john.fastabend, martin.lau, eddyz87, song,
	kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
	mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
In-Reply-To: <53c55a34-5b24-4481-91fe-290dc1b2d2e8@linux.dev>

On 2026/1/19 13:11 Yonghong Song <yonghong.song@linux.dev> write:
> 
> On 1/18/26 6:37 PM, Menglong Dong wrote:
> > For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
> > the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
> > tracepoint, especially for the case that the position of the arguments in
> > a tracepoint can change.
> >
> > The target tracepoint BTF type id is specified during loading time,
> > therefore we can get the function argument count from the function
> > prototype instead of the stack.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > v3:
> > - remove unnecessary NULL checking for prog->aux->attach_func_proto
> >
> > v2:
> > - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> >    typedef
> > ---
> >   kernel/bpf/verifier.c    | 32 ++++++++++++++++++++++++++++----
> >   kernel/trace/bpf_trace.c |  4 ++--
> >   2 files changed, 30 insertions(+), 6 deletions(-)
> >
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index faa1ecc1fe9d..4f52342573f0 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> >   		/* Implement bpf_get_func_arg inline. */
> >   		if (prog_type == BPF_PROG_TYPE_TRACING &&
> >   		    insn->imm == BPF_FUNC_get_func_arg) {
> > -			/* Load nr_args from ctx - 8 */
> > -			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > +			if (eatype == BPF_TRACE_RAW_TP) {
> > +				int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> > +
> > +				/*
> > +				 * skip first 'void *__data' argument in btf_trace_##name
> > +				 * typedef
> > +				 */
> > +				nr_args--;
> > +				/* Save nr_args to reg0 */
> > +				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > +			} else {
> > +				/* Load nr_args from ctx - 8 */
> > +				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > +			}
> >   			insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
> >   			insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
> >   			insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
> > @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> >   		/* Implement get_func_arg_cnt inline. */
> >   		if (prog_type == BPF_PROG_TYPE_TRACING &&
> >   		    insn->imm == BPF_FUNC_get_func_arg_cnt) {
> > -			/* Load nr_args from ctx - 8 */
> > -			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > +			if (eatype == BPF_TRACE_RAW_TP) {
> > +				int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> > +
> > +				/*
> > +				 * skip first 'void *__data' argument in btf_trace_##name
> > +				 * typedef
> > +				 */
> > +				nr_args--;
> > +				/* Save nr_args to reg0 */
> > +				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > +			} else {
> > +				/* Load nr_args from ctx - 8 */
> > +				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > +			}
> >   
> >   			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
> >   			if (!new_prog)
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index 6e076485bf70..9b1b56851d26 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> > @@ -1734,11 +1734,11 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> >   	case BPF_FUNC_d_path:
> >   		return &bpf_d_path_proto;
> >   	case BPF_FUNC_get_func_arg:
> > -		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
> > +		return &bpf_get_func_arg_proto;
> 
> BPF_TRACE_ITER is a tracing attach type. It should not support bpf_get_func_arg() or
> bpf_get_func_arg_cnt().

Ah, my bad, I forgot BPF_TRACE_ITER. I'll fix it in the next version.

Thanks!
Menglong Dong

> 
> >   	case BPF_FUNC_get_func_ret:
> >   		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
> >   	case BPF_FUNC_get_func_arg_cnt:
> > -		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
> > +		return &bpf_get_func_arg_cnt_proto;
> >   	case BPF_FUNC_get_attach_cookie:
> >   		if (prog->type == BPF_PROG_TYPE_TRACING &&
> >   		    prog->expected_attach_type == BPF_TRACE_RAW_TP)
> 
> 
> 





^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
From: Yonghong Song @ 2026-01-19  5:11 UTC (permalink / raw)
  To: Menglong Dong, andrii, ast
  Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
	haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
	mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
In-Reply-To: <20260119023732.130642-2-dongml2@chinatelecom.cn>



On 1/18/26 6:37 PM, Menglong Dong wrote:
> For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
> the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
> tracepoint, especially for the case that the position of the arguments in
> a tracepoint can change.
>
> The target tracepoint BTF type id is specified during loading time,
> therefore we can get the function argument count from the function
> prototype instead of the stack.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> v3:
> - remove unnecessary NULL checking for prog->aux->attach_func_proto
>
> v2:
> - for nr_args, skip first 'void *__data' argument in btf_trace_##name
>    typedef
> ---
>   kernel/bpf/verifier.c    | 32 ++++++++++++++++++++++++++++----
>   kernel/trace/bpf_trace.c |  4 ++--
>   2 files changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index faa1ecc1fe9d..4f52342573f0 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
>   		/* Implement bpf_get_func_arg inline. */
>   		if (prog_type == BPF_PROG_TYPE_TRACING &&
>   		    insn->imm == BPF_FUNC_get_func_arg) {
> -			/* Load nr_args from ctx - 8 */
> -			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> +			if (eatype == BPF_TRACE_RAW_TP) {
> +				int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> +
> +				/*
> +				 * skip first 'void *__data' argument in btf_trace_##name
> +				 * typedef
> +				 */
> +				nr_args--;
> +				/* Save nr_args to reg0 */
> +				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> +			} else {
> +				/* Load nr_args from ctx - 8 */
> +				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> +			}
>   			insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
>   			insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
>   			insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
> @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
>   		/* Implement get_func_arg_cnt inline. */
>   		if (prog_type == BPF_PROG_TYPE_TRACING &&
>   		    insn->imm == BPF_FUNC_get_func_arg_cnt) {
> -			/* Load nr_args from ctx - 8 */
> -			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> +			if (eatype == BPF_TRACE_RAW_TP) {
> +				int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> +
> +				/*
> +				 * skip first 'void *__data' argument in btf_trace_##name
> +				 * typedef
> +				 */
> +				nr_args--;
> +				/* Save nr_args to reg0 */
> +				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> +			} else {
> +				/* Load nr_args from ctx - 8 */
> +				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> +			}
>   
>   			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
>   			if (!new_prog)
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 6e076485bf70..9b1b56851d26 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1734,11 +1734,11 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
>   	case BPF_FUNC_d_path:
>   		return &bpf_d_path_proto;
>   	case BPF_FUNC_get_func_arg:
> -		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
> +		return &bpf_get_func_arg_proto;

BPF_TRACE_ITER is a tracing attach type. It should not support bpf_get_func_arg() or
bpf_get_func_arg_cnt().

>   	case BPF_FUNC_get_func_ret:
>   		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
>   	case BPF_FUNC_get_func_arg_cnt:
> -		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
> +		return &bpf_get_func_arg_cnt_proto;
>   	case BPF_FUNC_get_attach_cookie:
>   		if (prog->type == BPF_PROG_TYPE_TRACING &&
>   		    prog->expected_attach_type == BPF_TRACE_RAW_TP)


^ permalink raw reply

* Re: [PATCH V5 0/2] mm/khugepaged: fix dirty page handling for MADV_COLLAPSE
From: Garg, Shivank @ 2026-01-19  5:07 UTC (permalink / raw)
  To: Andrew Morton
  Cc: David Hildenbrand, Lorenzo Stoakes, Zi Yan, Baolin Wang,
	Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, Masami Hiramatsu, Steven Rostedt, linux-trace-kernel,
	Mathieu Desnoyers, Zach O'Keefe, linux-mm, linux-kernel,
	Stephen Rothwell
In-Reply-To: <20260118122229.dcdda884bbb19a9c30ec6f1e@linux-foundation.org>



On 1/19/2026 1:52 AM, Andrew Morton wrote:
> Please tolerate a little whining about the timeliess here.  We're at
> -rc6, v4 was added to mm.git over a month ago, had quite a lot of
> review, this is very close to being moved into the mm-stable branch and now
> we get v5.  Argh.
> 
I sincerely apologize for this.

I had this doubt on sending an incremental patch or V5:
https://lore.kernel.org/linux-mm/7a42515f-ae57-4f4d-831c-87689930a797@amd.com


>> V5:
>> - In patch 2/2, Simplify dirty writeback retry logic (David)
> Are you sure this is the only change?  It looks like a lot for a
> simplification and I'm wondering if we should retain the v4 series and
> defer a simplification for separate consideration during the next
> cycle.

Yes, patch 1/2 is unchanged and patch 2/2 is the only change. 
The diff looks larger due to code movement but logic is actually simpler now.

I completely understand if you prefer to keep V4 and defer this 
refactoring. I'm sorry for creating this late-cycle churn. Please let me 
know what you'd prefer and I'll follow your guidance.
Thank you for your patience.

Regards,
Shivank

^ permalink raw reply

* Re: [PATCH v3 1/2] mm/vmscan: mitigate spurious kswapd_failures reset from direct reclaim
From: Jiayuan Chen @ 2026-01-19  3:04 UTC (permalink / raw)
  To: Johannes Weiner
  Cc: linux-mm, shakeel.butt, Jiayuan Chen, Andrew Morton,
	David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Brendan Jackman, Zi Yan,
	Qi Zheng, linux-kernel, linux-trace-kernel
In-Reply-To: <aWpukFnKRoeSrcEZ@cmpxchg.org>

2026/1/17 01:00, "Johannes Weiner" <hannes@cmpxchg.org mailto:hannes@cmpxchg.org?to=%22Johannes%20Weiner%22%20%3Channes%40cmpxchg.org%3E > wrote:

[...]
> > 
> Great analysis, and I agree with both the fix and adding tracepoints.
> 
> Two minor nits:
> 
> > 
> > @@ -2650,6 +2650,25 @@ static bool can_age_anon_pages(struct lruvec *lruvec,
> >  lruvec_memcg(lruvec));
> >  }
> >  
> >  +static void pgdat_reset_kswapd_failures(pg_data_t *pgdat)
> >  +{
> >  + atomic_set(&pgdat->kswapd_failures, 0);
> >  +/*
> >  + * Reset kswapd_failures only when the node is balanced. Without this
> >  + * check, successful direct reclaim (e.g., from cgroup memory.high
> >  + * throttling) can keep resetting kswapd_failures even when the node
> >  + * cannot be balanced, causing kswapd to run endlessly.
> >  + */
> >  +static bool pgdat_balanced(pg_data_t *pgdat, int order, int highest_zoneidx);
> >  +static inline void pgdat_try_reset_kswapd_failures(struct pglist_data *pgdat,
> > 
> Please remove the inline, the compiler will figure it out.
> 
> > 
> > + struct scan_control *sc)
> >  +{
> >  + if (pgdat_balanced(pgdat, sc->order, sc->reclaim_idx))
> >  + pgdat_reset_kswapd_failures(pgdat);
> >  +}
> > 
> As this is kswapd API, please move these down to after wakeup_kswapd().
> 
> I think we can streamline the names a bit. We already use "hopeless"
> for that state in the comments; can you please rename the functions
> kswapd_clear_hopeless() and kswapd_try_clear_hopeless()?
> 
> We should then also replace the open-coded kswapd_failure checks with
> kswapd_test_hopeless(). But I can send a follow-up patch if you don't
> want to, just let me know.
>

Thanks, Johannes and Shakeel. I'll send an updated version with these fixes.

^ permalink raw reply

* Re: [RFC 5/5] ext4: mark group extend fast-commit ineligible
From: Theodore Tso @ 2026-01-19  3:03 UTC (permalink / raw)
  To: Li Chen
  Cc: Andreas Dilger, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-ext4, linux-kernel, linux-trace-kernel
In-Reply-To: <20260119025857.GC19954@macsyma.local>

On Sun, Jan 18, 2026 at 04:58:57PM -1000, Theodore Tso wrote:
> 
> I'm curious what version of the kernel you were testing against?  I
> needed to mnake the final fix up to allow the patch to compile:

Oops, sorry, I replied to the wrong patch.  This fix is relevant to:

       [RFC 3/5] ext4: mark move extents fast-commit ineligible

       	    	       	    	 - Ted
				 

^ permalink raw reply

* Re: [RFC 5/5] ext4: mark group extend fast-commit ineligible
From: Theodore Tso @ 2026-01-19  2:58 UTC (permalink / raw)
  To: Li Chen
  Cc: Andreas Dilger, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, linux-ext4, linux-kernel, linux-trace-kernel
In-Reply-To: <20251211115146.897420-6-me@linux.beauty>

On Thu, Dec 11, 2025 at 07:51:42PM +0800, Li Chen wrote:
> Fast commits only log operations that have dedicated replay support.
> EXT4_IOC_GROUP_EXTEND grows the filesystem to the end of the last
> block group and updates the same on-disk metadata without going
> through the fast commit tracking paths.
> In practice these operations are rare and usually followed by further
> updates, but mixing them into a fast commit makes the overall
> semantics harder to reason about and risks replay gaps if new call
> sites appear.
> 
> Teach ext4 to mark the filesystem fast-commit ineligible when
> EXT4_IOC_GROUP_EXTEND grows the filesystem.
> This forces those transactions to fall back to a full commit,
> ensuring that the group extension changes are captured by the normal
> journal rather than partially encoded in fast commit TLVs.
> This change should not affect common workloads but makes online
> resize via GROUP_EXTEND safer and easier to reason about under fast
> commit.
> 
> Testing:
> 1. prepare:
>     dd if=/dev/zero of=/root/fc_resize.img bs=1M count=0 seek=256
>     mkfs.ext4 -O fast_commit -F /root/fc_resize.img
>     mkdir -p /mnt/fc_resize && mount -t ext4 -o loop /root/fc_resize.img /mnt/fc_resize
> 2. Extended the filesystem to the end of the last block group using a
>    helper that calls EXT4_IOC_GROUP_EXTEND on the mounted filesystem
>    and checked fc_info:
>     ./group_extend_helper /mnt/fc_resize
>     cat /proc/fs/ext4/loop0/fc_info
>    shows the "Resize" ineligible reason increased.
> 3. Fsynced a file on the resized filesystem and confirmed that the fast
>    commit ineligible counter incremented for the resize transaction:
>     touch /mnt/fc_resize/file
>     /root/fsync_file /mnt/fc_resize/file
>     sync
>     cat /proc/fs/ext4/loop0/fc_info
> 
> Signed-off-by: Li Chen <me@linux.beauty>

I'm curious what version of the kernel you were testing against?  I
needed to mnake the final fix up to allow the patch to compile:

diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 9354083222b1..ce1f738dff93 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -321,7 +321,8 @@ static int mext_move_extent(struct mext_data *mext, u64 *m_len)
 		ret = PTR_ERR(handle);
 		goto out;
 	}
-	ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_MOVE_EXT, handle);
+	ext4_fc_mark_ineligible(orig_inode->i_sb, EXT4_FC_REASON_MOVE_EXT,
+				handle);
 
 	ret = mext_move_begin(mext, folio, &move_type);
 	if (ret)

						- Ted

^ permalink raw reply related

* [PATCH bpf-next v3 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf
From: Menglong Dong @ 2026-01-19  2:37 UTC (permalink / raw)
  To: andrii, ast
  Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
	kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
	mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
In-Reply-To: <20260119023732.130642-1-dongml2@chinatelecom.cn>

Test bpf_get_func_arg() and bpf_get_func_arg_cnt() for tp_btf. The code
is most copied from test1 and test2.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
 .../bpf/prog_tests/get_func_args_test.c       |  3 ++
 .../selftests/bpf/progs/get_func_args_test.c  | 44 +++++++++++++++++++
 .../bpf/test_kmods/bpf_testmod-events.h       | 10 +++++
 .../selftests/bpf/test_kmods/bpf_testmod.c    |  4 ++
 4 files changed, 61 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c b/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
index 64a9c95d4acf..fadee95d3ae8 100644
--- a/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
@@ -33,11 +33,14 @@ void test_get_func_args_test(void)
 
 	ASSERT_EQ(topts.retval >> 16, 1, "test_run");
 	ASSERT_EQ(topts.retval & 0xffff, 1234 + 29, "test_run");
+	ASSERT_OK(trigger_module_test_read(1), "trigger_read");
 
 	ASSERT_EQ(skel->bss->test1_result, 1, "test1_result");
 	ASSERT_EQ(skel->bss->test2_result, 1, "test2_result");
 	ASSERT_EQ(skel->bss->test3_result, 1, "test3_result");
 	ASSERT_EQ(skel->bss->test4_result, 1, "test4_result");
+	ASSERT_EQ(skel->bss->test5_result, 1, "test5_result");
+	ASSERT_EQ(skel->bss->test6_result, 1, "test6_result");
 
 cleanup:
 	get_func_args_test__destroy(skel);
diff --git a/tools/testing/selftests/bpf/progs/get_func_args_test.c b/tools/testing/selftests/bpf/progs/get_func_args_test.c
index e0f34a55e697..5b7233afef05 100644
--- a/tools/testing/selftests/bpf/progs/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/progs/get_func_args_test.c
@@ -121,3 +121,47 @@ int BPF_PROG(fexit_test, int _a, int *_b, int _ret)
 	test4_result &= err == 0 && ret == 1234;
 	return 0;
 }
+
+__u64 test5_result = 0;
+SEC("tp_btf/bpf_testmod_fentry_test1_tp")
+int BPF_PROG(tp_test1)
+{
+	__u64 cnt = bpf_get_func_arg_cnt(ctx);
+	__u64 a = 0, z = 0;
+	__s64 err;
+
+	test5_result = cnt == 1;
+
+	err = bpf_get_func_arg(ctx, 0, &a);
+	test5_result &= err == 0 && ((int) a == 1);
+
+	/* not valid argument */
+	err = bpf_get_func_arg(ctx, 1, &z);
+	test5_result &= err == -EINVAL;
+
+	return 0;
+}
+
+__u64 test6_result = 0;
+SEC("tp_btf/bpf_testmod_fentry_test2_tp")
+int BPF_PROG(tp_test2)
+{
+	__u64 cnt = bpf_get_func_arg_cnt(ctx);
+	__u64 a = 0, b = 0, z = 0;
+	__s64 err;
+
+	test6_result = cnt == 2;
+
+	/* valid arguments */
+	err = bpf_get_func_arg(ctx, 0, &a);
+	test6_result &= err == 0 && (int) a == 2;
+
+	err = bpf_get_func_arg(ctx, 1, &b);
+	test6_result &= err == 0 && b == 3;
+
+	/* not valid argument */
+	err = bpf_get_func_arg(ctx, 2, &z);
+	test6_result &= err == -EINVAL;
+
+	return 0;
+}
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
index aeef86b3da74..45a5e41f3a92 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
@@ -63,6 +63,16 @@ BPF_TESTMOD_DECLARE_TRACE(bpf_testmod_test_writable_bare,
 	sizeof(struct bpf_testmod_test_writable_ctx)
 );
 
+DECLARE_TRACE(bpf_testmod_fentry_test1,
+	TP_PROTO(int a),
+	TP_ARGS(a)
+);
+
+DECLARE_TRACE(bpf_testmod_fentry_test2,
+	TP_PROTO(int a, u64 b),
+	TP_ARGS(a, b)
+);
+
 #endif /* _BPF_TESTMOD_EVENTS_H */
 
 #undef TRACE_INCLUDE_PATH
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index bc07ce9d5477..f3698746f033 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -396,11 +396,15 @@ __weak noinline struct file *bpf_testmod_return_ptr(int arg)
 
 noinline int bpf_testmod_fentry_test1(int a)
 {
+	trace_bpf_testmod_fentry_test1_tp(a);
+
 	return a + 1;
 }
 
 noinline int bpf_testmod_fentry_test2(int a, u64 b)
 {
+	trace_bpf_testmod_fentry_test2_tp(a, b);
+
 	return a + b;
 }
 
-- 
2.52.0


^ permalink raw reply related

* [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
From: Menglong Dong @ 2026-01-19  2:37 UTC (permalink / raw)
  To: andrii, ast
  Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
	kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
	mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
In-Reply-To: <20260119023732.130642-1-dongml2@chinatelecom.cn>

For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
tracepoint, especially for the case that the position of the arguments in
a tracepoint can change.

The target tracepoint BTF type id is specified during loading time,
therefore we can get the function argument count from the function
prototype instead of the stack.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v3:
- remove unnecessary NULL checking for prog->aux->attach_func_proto

v2:
- for nr_args, skip first 'void *__data' argument in btf_trace_##name
  typedef
---
 kernel/bpf/verifier.c    | 32 ++++++++++++++++++++++++++++----
 kernel/trace/bpf_trace.c |  4 ++--
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index faa1ecc1fe9d..4f52342573f0 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 		/* Implement bpf_get_func_arg inline. */
 		if (prog_type == BPF_PROG_TYPE_TRACING &&
 		    insn->imm == BPF_FUNC_get_func_arg) {
-			/* Load nr_args from ctx - 8 */
-			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+			if (eatype == BPF_TRACE_RAW_TP) {
+				int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
+
+				/*
+				 * skip first 'void *__data' argument in btf_trace_##name
+				 * typedef
+				 */
+				nr_args--;
+				/* Save nr_args to reg0 */
+				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
+			} else {
+				/* Load nr_args from ctx - 8 */
+				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+			}
 			insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
 			insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
 			insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
@@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
 		/* Implement get_func_arg_cnt inline. */
 		if (prog_type == BPF_PROG_TYPE_TRACING &&
 		    insn->imm == BPF_FUNC_get_func_arg_cnt) {
-			/* Load nr_args from ctx - 8 */
-			insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+			if (eatype == BPF_TRACE_RAW_TP) {
+				int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
+
+				/*
+				 * skip first 'void *__data' argument in btf_trace_##name
+				 * typedef
+				 */
+				nr_args--;
+				/* Save nr_args to reg0 */
+				insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
+			} else {
+				/* Load nr_args from ctx - 8 */
+				insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+			}
 
 			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
 			if (!new_prog)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 6e076485bf70..9b1b56851d26 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1734,11 +1734,11 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 	case BPF_FUNC_d_path:
 		return &bpf_d_path_proto;
 	case BPF_FUNC_get_func_arg:
-		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
+		return &bpf_get_func_arg_proto;
 	case BPF_FUNC_get_func_ret:
 		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
 	case BPF_FUNC_get_func_arg_cnt:
-		return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
+		return &bpf_get_func_arg_cnt_proto;
 	case BPF_FUNC_get_attach_cookie:
 		if (prog->type == BPF_PROG_TYPE_TRACING &&
 		    prog->expected_attach_type == BPF_TRACE_RAW_TP)
-- 
2.52.0


^ permalink raw reply related


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