Linux Trace Kernel
 help / color / mirror / Atom feed
* [PATCH v9 00/30] Tracefs support for pKVM
From: Vincent Donnefort @ 2025-12-02  9:35 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, linux-trace-kernel, maz,
	oliver.upton, joey.gouly, suzuki.poulose, yuzenghui
  Cc: kvmarm, linux-arm-kernel, jstultz, qperret, will, aneesh.kumar,
	kernel-team, linux-kernel, Vincent Donnefort

The growing set of features supported by the hypervisor in protected
mode necessitates debugging and profiling tools. Tracefs is the
ideal candidate for this task:

  * It is simple to use and to script.

  * It is supported by various tools, from the trace-cmd CLI to the
    Android web-based perfetto.

  * The ring-buffer, where are stored trace events consists of linked
    pages, making it an ideal structure for sharing between kernel and
    hypervisor.

This series first introduces a new generic way of creating remote events and
remote buffers. Then it adds support to the pKVM hypervisor.

1. ring-buffer
--------------

To setup the per-cpu ring-buffers, a new interface is created:

  ring_buffer_remote:	Describes what the kernel needs to know about the
			remote writer, that is, the set of pages forming the
			ring-buffer and a callback for the reader/head
			swapping (enables consuming read)

  ring_buffer_remote():	Creates a read-only ring-buffer from a
			ring_buffer_remote.

To keep the internals of `struct ring_buffer` in sync with the remote,
the meta-page is used. It was originally introduced to enable user-space
mapping of the ring-buffer [1]. In this case, the kernel is not the
producer anymore but the reader. The function to read that meta-page is:

  ring_buffer_poll_remote():
			Update `struct ring_buffer` based on the remote
			meta-page. Wake-up readers if necessary.

The kernel has to poll the meta-page to be notified of newly written
events.

2. Tracefs
----------

This series introduce a new trace_remote that does the link between
tracefs and the remote ring-buffer.

The interface is found in the remotes/ directory at the root of the
tracefs mount point. Each remote is like an instance and you'll find
there a subset of the regular Tracefs user-space interface:

   remotes/test
	|-- buffer_size_kb
	|-- events
	|   |-- enable
	|   |-- header_event
	|   |-- header_page
	|   `-- test
	|       `-- selftest
	|           |-- enable
	|           |-- format
	|           `-- id
	|-- per_cpu
	|   `-- cpu0
	|       |-- trace
	|       `-- trace_pipe
	|-- trace
	|-- trace_pipe
	|-- tracing_on

Behind the scenes, kernel/trace/trace_remote.c creates this tracefs
hierarchy without relying on kernel/trace/trace.c. This is due to
fundamental differences:

  * Remote tracing doesn't support trace_array's system-specific
    features (snapshots, tracers, etc.).

  * Logged event formats differ (e.g., no PID for remote events).

  * Buffer operations require specific remote interactions.

3. Simple Ring-Buffer
---------------------

As the current ring-buffer.c implementation has too many dependencies to
be used directly by the pKVM hypervisor. A new simple implementation is
created and can be found in kernel/trace/simple-ring-buffer.c.

This implementation is write-only and is used by both the pKVM
hypervisor and a trace_remote test module.

4. Events
---------

A new REMOTE_EVENT() macro is added to simplify the creation of events
on the kernel side. As remote tracing buffer are read only, only the
event structure and a way of printing must be declared. The prototype of
the macro is very similar to the well-known TRACE_EVENT()

 REMOTE_EVENT(my_event, id,
     RE_STRUCT(
         re_field(u64, foobar)
     ),
     RE_PRINTK("foobar=%lld", __entry->foobar)
     )
  )

5. pKVM
-------

The pKVM support simply creates a "hypervisor" trace_remote on the
kernel side and inherits from simple-ring-buffer.c on the hypervisor
side.

A new event macro is created HYP_EVENT() that is under the hood re-using
REMOTE_EVENT() (defined in the previous paragaph) as well as generate
hypervisor specific struct and trace_<event>() functions.

5. Limitations:
---------------

Non-consuming reading of the buffer isn't supported (i.e. cat trace ->
-EPERM) due to current the lack of support in the ring-buffer meta-page.

[1] https://tracingsummit.org/ts/2022/hypervisortracing/
[2] https://lore.kernel.org/all/20240510140435.3550353-1-vdonnefort@google.com/

Changes since v8
  - Do not enable tracing if unstable cnvct (Marc)
  - Add support for nVHE (Marc)
  - Add PKVM_DISABLE_STAGE2_ON_PANIC (Marc)
  - NVHE_EL2_TRACING depends on NVHE_EL2_DEBUG (Marc)
  - Add a reason for hyp_enter/hyp_exit events (Marc)
  - Remove PKVM_SELFTESTS in favour of NVHE_EL2_DEBUG
  - Add wrapper for arm_smccc_1_2, now used in nvhe/ffa.c

Changes since v7
  - Add missing EXPORT_SYMBOL_GPL for remote_test.ko
  - Rebase on 6.18-rc4

Changes since v6

  - Add requires field to the selftest (Masami)
  - Use guard() for ring_buffer_poll_remote (Steven)
  - Rename ring_buffer_remote() to ring_buffer_alloc_remote() (Steven)
  - kerneldoc for trace_buffer_remote and simple_ring_buffer (Steven)
  - Validate trace_buffer_desc size in trace_remote_alloc_buffer
    (Steven)
  - Add non-consuming ring-buffer read (Steven)
  - Add spinning failsafe in simple_ring_buffer (Steven)
  - Range check for hyp_trace_desc::bpages_backing_* in hyp_trace_desc_validate()
  - unsigned int cpu in hyp_trace_desc_validate()
  - Fix event/format file
  - Add tests with an offline CPU
  - Add tests for non-consuming read
  - Add documentation
  - Rebase on 6.17

Changes since v5 (https://lore.kernel.org/all/20250516134031.661124-1-vdonnefort@google.com/)

  - Add tishift lib to the hyp (Aneesh)
  - Rebase on 6.17-rc2

Changes since v4 (https://lore.kernel.org/all/20250506164820.515876-1-vdonnefort@google.com/)

  - Extend meta-page with pages_touched and pages_lost
  - Create ring_buffer_types.h
  - Fix simple_ring_buffer build for 32-bits arch and x86
  - Try unload buffer on reset (+ test)
  - Minor renaming and comments

Changes since v3 (https://lore.kernel.org/all/20250224121353.98697-1-vdonnefort@google.com/)

  - Move tracefs support from kvm/hyp_trace.c into a generic trace_remote.c.
  - Move ring-buffer implementation from nvhe/trace.c into  a generic
    simple-ring-buffer.c
  - Rebase on 6.15-rc4.

Changes since v2 (https://lore.kernel.org/all/20250108114536.627715-1-vdonnefort@google.com/)

  - Fix ring-buffer remote reset
  - Fix fast-forward in rb_page_desc()
  - Refactor nvhe/trace.c
  - struct hyp_buffer_page more compact
  - Add a struct_len to trace_page_desc
  - Extend reset testing
  - Rebase on 6.14-rc3

Changes since v1 (https://lore.kernel.org/all/20240911093029.3279154-1-vdonnefort@google.com/)

  - Add 128-bits mult fallback in the unlikely event of an overflow. (John)
  - Fix ELF section sort.
  - __always_inline trace_* event macros.
  - Fix events/<event>/enable permissions.
  - Rename ring-buffer "writer" to "remote".
  - Rename CONFIG_PROTECTED_NVHE_TESTING to PKVM_SELFTEST to align with
    Quentin's upcoming selftest
  - Rebase on 6.13-rc3.

Changes since RFC (https://lore.kernel.org/all/20240805173234.3542917-1-vdonnefort@google.com/)

  - hypervisor trace clock:
     - mult/shift computed in hyp_trace.c. (John)
     - Update clock when it deviates from kernel boot clock. (John)
     - Add trace_clock file.
     - Separate patch for better readability.
  - Add a proper reset interface which does not need to teardown the
    tracing buffers. (Steven)
  - Return -EPERM on trace access. (Steven)
  - Add per-cpu trace file.
  - Automatically teardown and free the tracing buffer when it is empty,
    without readers and not currently tracing.
  - Show in buffer_size_kb if the buffer is loaded in the hypervisor or
    not.
  - Extend tests to cover reset and unload.
  - CC timekeeping folks on relevant patches (Marc)

Vincent Donnefort (30):
  ring-buffer: Add page statistics to the meta-page
  ring-buffer: Store bpage pointers into subbuf_ids
  ring-buffer: Introduce ring-buffer remotes
  ring-buffer: Add non-consuming read for ring-buffer remotes
  tracing: Introduce trace remotes
  tracing: Add reset to trace remotes
  tracing: Add non-consuming read to trace remotes
  tracing: Add init callback to trace remotes
  tracing: Add events to trace remotes
  tracing: Add events/ root files to trace remotes
  tracing: Add helpers to create trace remote events
  ring-buffer: Export buffer_data_page and macros
  tracing: Introduce simple_ring_buffer
  tracing: Add a trace remote module for testing
  tracing: selftests: Add trace remote tests
  Documentation: tracing: Add tracing remotes
  tracing: load/unload page callbacks for simple_ring_buffer
  tracing: Check for undefined symbols in simple_ring_buffer
  KVM: arm64: Add PKVM_DISABLE_STAGE2_ON_PANIC
  KVM: arm64: Add clock support to nVHE/pKVM hyp
  KVM: arm64: Initialise hyp_nr_cpus for nVHE hyp
  KVM: arm64: Support unaligned fixmap in the pKVM hyp
  KVM: arm64: Add tracing capability for the nVHE/pKVM hyp
  KVM: arm64: Add trace remote for the nVHE/pKVM hyp
  KVM: arm64: Sync boot clock with the nVHE/pKVM hyp
  KVM: arm64: Add trace reset to the nVHE/pKVM hyp
  KVM: arm64: Add event support to the nVHE/pKVM hyp and trace remote
  KVM: arm64: Add hyp_enter/hyp_exit events to nVHE/pKVM hyp
  KVM: arm64: Add selftest event support to nVHE/pKVM hyp
  tracing: selftests: Add hypervisor trace remote tests

 Documentation/trace/index.rst                 |   11 +
 Documentation/trace/remotes.rst               |   59 +
 arch/arm64/include/asm/kvm_asm.h              |    8 +
 arch/arm64/include/asm/kvm_define_hypevents.h |   16 +
 arch/arm64/include/asm/kvm_hyp.h              |    4 +-
 arch/arm64/include/asm/kvm_hypevents.h        |   56 +
 arch/arm64/include/asm/kvm_hyptrace.h         |   26 +
 arch/arm64/kernel/image-vars.h                |    4 +
 arch/arm64/kernel/vmlinux.lds.S               |   18 +
 arch/arm64/kvm/Kconfig                        |   64 +-
 arch/arm64/kvm/Makefile                       |    2 +
 arch/arm64/kvm/arm.c                          |   10 +-
 arch/arm64/kvm/handle_exit.c                  |    2 +-
 arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h   |   23 +
 arch/arm64/kvm/hyp/include/nvhe/clock.h       |   16 +
 .../kvm/hyp/include/nvhe/define_events.h      |   14 +
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |    2 -
 arch/arm64/kvm/hyp/include/nvhe/trace.h       |   58 +
 arch/arm64/kvm/hyp/nvhe/Makefile              |    6 +-
 arch/arm64/kvm/hyp/nvhe/clock.c               |   65 +
 arch/arm64/kvm/hyp/nvhe/events.c              |   25 +
 arch/arm64/kvm/hyp/nvhe/ffa.c                 |   28 +-
 arch/arm64/kvm/hyp/nvhe/host.S                |    2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |   91 +-
 arch/arm64/kvm/hyp/nvhe/hyp.lds.S             |    6 +
 arch/arm64/kvm/hyp/nvhe/mm.c                  |    4 +-
 arch/arm64/kvm/hyp/nvhe/psci-relay.c          |    7 +-
 arch/arm64/kvm/hyp/nvhe/setup.c               |    4 +-
 arch/arm64/kvm/hyp/nvhe/stacktrace.c          |    6 +-
 arch/arm64/kvm/hyp/nvhe/switch.c              |    5 +-
 arch/arm64/kvm/hyp/nvhe/trace.c               |  306 ++++
 arch/arm64/kvm/hyp_trace.c                    |  445 ++++++
 arch/arm64/kvm/hyp_trace.h                    |   11 +
 arch/arm64/kvm/stacktrace.c                   |    8 +-
 fs/tracefs/inode.c                            |    1 +
 include/linux/ring_buffer.h                   |   58 +
 include/linux/ring_buffer_types.h             |   41 +
 include/linux/simple_ring_buffer.h            |  120 ++
 include/linux/trace_remote.h                  |   92 ++
 include/linux/trace_remote_event.h            |   33 +
 include/trace/define_remote_events.h          |   73 +
 include/uapi/linux/trace_mmap.h               |    8 +-
 kernel/trace/Kconfig                          |   14 +
 kernel/trace/Makefile                         |   20 +
 kernel/trace/remote_test.c                    |  259 ++++
 kernel/trace/remote_test_events.h             |   10 +
 kernel/trace/ring_buffer.c                    |  356 ++++-
 kernel/trace/simple_ring_buffer.c             |  468 ++++++
 kernel/trace/trace.c                          |    2 +-
 kernel/trace/trace.h                          |    6 +
 kernel/trace/trace_remote.c                   | 1318 +++++++++++++++++
 .../ftrace/test.d/remotes/buffer_size.tc      |   25 +
 .../selftests/ftrace/test.d/remotes/functions |   88 ++
 .../test.d/remotes/hypervisor/buffer_size.tc  |   11 +
 .../ftrace/test.d/remotes/hypervisor/reset.tc |   11 +
 .../ftrace/test.d/remotes/hypervisor/trace.tc |   11 +
 .../test.d/remotes/hypervisor/trace_pipe.tc   |   11 +
 .../test.d/remotes/hypervisor/unloading.tc    |   11 +
 .../selftests/ftrace/test.d/remotes/reset.tc  |   90 ++
 .../selftests/ftrace/test.d/remotes/trace.tc  |  127 ++
 .../ftrace/test.d/remotes/trace_pipe.tc       |  127 ++
 .../ftrace/test.d/remotes/unloading.tc        |   41 +
 62 files changed, 4725 insertions(+), 119 deletions(-)
 create mode 100644 Documentation/trace/remotes.rst
 create mode 100644 arch/arm64/include/asm/kvm_define_hypevents.h
 create mode 100644 arch/arm64/include/asm/kvm_hypevents.h
 create mode 100644 arch/arm64/include/asm/kvm_hyptrace.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/clock.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/define_events.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/trace.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/clock.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/events.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/trace.c
 create mode 100644 arch/arm64/kvm/hyp_trace.c
 create mode 100644 arch/arm64/kvm/hyp_trace.h
 create mode 100644 include/linux/ring_buffer_types.h
 create mode 100644 include/linux/simple_ring_buffer.h
 create mode 100644 include/linux/trace_remote.h
 create mode 100644 include/linux/trace_remote_event.h
 create mode 100644 include/trace/define_remote_events.h
 create mode 100644 kernel/trace/remote_test.c
 create mode 100644 kernel/trace/remote_test_events.h
 create mode 100644 kernel/trace/simple_ring_buffer.c
 create mode 100644 kernel/trace/trace_remote.c
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/functions
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/hypervisor/buffer_size.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/hypervisor/reset.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace_pipe.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/hypervisor/unloading.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/reset.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/trace.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/remotes/unloading.tc


base-commit: 30f09200cc4aefbd8385b01e41bde2e4565a6f0e
-- 
2.52.0.107.ga0afd4fd5b-goog


^ permalink raw reply

* Re: [PATCH bpf v2 2/2] selftests/bpf: fix and consolidate d_path LSM regression test
From: Matt Bobrowski @ 2025-12-02  8:59 UTC (permalink / raw)
  To: Shuran Liu
  Cc: song, bpf, ast, daniel, andrii, martin.lau, eddyz87,
	yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa,
	rostedt, mhiramat, mathieu.desnoyers, linux-kernel,
	linux-trace-kernel, Zesen Liu, Peili Gao, Haoran Ni
In-Reply-To: <20251202075441.1409-3-electronlsr@gmail.com>

On Tue, Dec 02, 2025 at 03:54:41PM +0800, Shuran Liu wrote:
> Add a regression test for bpf_d_path() when invoked from an LSM program.
> The test attaches to the bprm_check_security hook, calls bpf_d_path() on
> the binary being executed, and verifies that a simple prefix comparison on
> the returned pathname behaves correctly after the fix in patch 1.
> 
> To avoid nondeterminism, the LSM program now filters based on the
> expected PID, which is populated from userspace before the test binary is
> executed. This prevents unrelated processes that also trigger the
> bprm_check_security LSM hook from overwriting test results. Parent and
> child processes are synchronized through a pipe to ensure the PID is set
> before the child execs the test binary.
> 
> Per review feedback, the new test is merged into the existing d_path
> selftest rather than adding new prog_tests/ or progs/ files.
> 
> Co-developed-by: Zesen Liu <ftyg@live.com>
> Signed-off-by: Zesen Liu <ftyg@live.com>
> Co-developed-by: Peili Gao <gplhust955@gmail.com>
> Signed-off-by: Peili Gao <gplhust955@gmail.com>
> Co-developed-by: Haoran Ni <haoran.ni.cs@gmail.com>
> Signed-off-by: Haoran Ni <haoran.ni.cs@gmail.com>
> Signed-off-by: Shuran Liu <electronlsr@gmail.com>

Feel free to add:

Reviewed-by: Matt Bobrowski <mattbobrowski@google.com>

> ---
>  .../testing/selftests/bpf/prog_tests/d_path.c | 64 +++++++++++++++++++
>  .../testing/selftests/bpf/progs/test_d_path.c | 33 ++++++++++
>  2 files changed, 97 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/d_path.c b/tools/testing/selftests/bpf/prog_tests/d_path.c
> index ccc768592e66..2909ca3bae0f 100644
> --- a/tools/testing/selftests/bpf/prog_tests/d_path.c
> +++ b/tools/testing/selftests/bpf/prog_tests/d_path.c
> @@ -195,6 +195,67 @@ static void test_d_path_check_types(void)
>  	test_d_path_check_types__destroy(skel);
>  }
>  
> +static void test_d_path_lsm(void)
> +{
> +	struct test_d_path *skel;
> +	int err;
> +	int pipefd[2];
> +	pid_t pid;
> +
> +	skel = test_d_path__open_and_load();
> +	if (!ASSERT_OK_PTR(skel, "d_path skeleton failed"))
> +		return;
> +
> +	err = test_d_path__attach(skel);
> +	if (!ASSERT_OK(err, "attach failed"))
> +		goto cleanup;
> +
> +	/* Prepare the test binary */
> +	system("cp /bin/true /tmp/bpf_d_path_test 2>/dev/null || :");

I'd much prefer if we also cleaned up after ourselves, but it's not
that much of an issue I guess.

> +	if (!ASSERT_OK(pipe(pipefd), "pipe failed"))
> +		goto cleanup;
> +
> +	pid = fork();
> +	if (!ASSERT_GE(pid, 0, "fork failed")) {
> +		close(pipefd[0]);
> +		close(pipefd[1]);
> +		goto cleanup;
> +	}
> +
> +	if (pid == 0) {
> +		/* Child */
> +		char buf;
> +
> +		close(pipefd[1]);
> +		/* Wait for parent to set PID in BPF map */
> +		if (read(pipefd[0], &buf, 1) != 1)
> +			exit(1);
> +		close(pipefd[0]);
> +		execl("/tmp/bpf_d_path_test", "/tmp/bpf_d_path_test", NULL);
> +		exit(1);
> +	}
> +
> +	/* Parent */
> +	close(pipefd[0]);
> +
> +	/* Update BPF map with child PID */
> +	skel->bss->my_pid = pid;
> +
> +	/* Signal child to proceed */
> +	write(pipefd[1], "G", 1);
> +	close(pipefd[1]);
> +
> +	/* Wait for child */
> +	waitpid(pid, NULL, 0);
> +
> +	ASSERT_EQ(skel->bss->called_lsm, 1, "lsm hook called");
> +	ASSERT_EQ(skel->bss->lsm_match, 1, "lsm match");
> +
> +cleanup:
> +	test_d_path__destroy(skel);
> +}
> +
>  void test_d_path(void)
>  {
>  	if (test__start_subtest("basic"))
> @@ -205,4 +266,7 @@ void test_d_path(void)
>  
>  	if (test__start_subtest("check_alloc_mem"))
>  		test_d_path_check_types();
> +
> +	if (test__start_subtest("lsm"))
> +		test_d_path_lsm();
>  }
> diff --git a/tools/testing/selftests/bpf/progs/test_d_path.c b/tools/testing/selftests/bpf/progs/test_d_path.c
> index 84e1f883f97b..7f65c282069a 100644
> --- a/tools/testing/selftests/bpf/progs/test_d_path.c
> +++ b/tools/testing/selftests/bpf/progs/test_d_path.c
> @@ -17,6 +17,8 @@ int rets_close[MAX_FILES] = {};
>  
>  int called_stat = 0;
>  int called_close = 0;
> +int called_lsm = 0;
> +int lsm_match = 0;
>  
>  SEC("fentry/security_inode_getattr")
>  int BPF_PROG(prog_stat, struct path *path, struct kstat *stat,
> @@ -62,4 +64,35 @@ int BPF_PROG(prog_close, struct file *file, void *id)
>  	return 0;
>  }
>  
> +SEC("lsm/bprm_check_security")
> +int BPF_PROG(prog_lsm, struct linux_binprm *bprm)
> +{
> +	pid_t pid = bpf_get_current_pid_tgid() >> 32;
> +	char path[MAX_PATH_LEN] = {};
> +	int ret;
> +
> +	if (pid != my_pid)
> +		return 0;
> +
> +	called_lsm = 1;
> +	ret = bpf_d_path(&bprm->file->f_path, path, MAX_PATH_LEN);
> +	if (ret < 0)
> +		return 0;
> +
> +	{
> +		static const char target_dir[] = "/tmp/";
> +
> +#pragma unroll
> +		for (int i = 0; i < sizeof(target_dir) - 1; i++) {
> +			if (path[i] != target_dir[i]) {
> +				lsm_match = -1; /* mismatch */
> +				return 0;
> +			}
> +		}
> +	}
> +
> +	lsm_match = 1; /* prefix match */
> +	return 0;
> +}
> +
>  char _license[] SEC("license") = "GPL";
> -- 
> 2.52.0
> 

^ permalink raw reply

* Re: [PATCH] MIPS: ftrace: Fix memory corruption when kernel is located beyond 32 bits
From: Thomas Bogendoerfer @ 2025-12-02  8:37 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Steven Rostedt, Masami Hiramatsu, Mark Rutland,
	Vladimir Kondratiev, Théo Lebrun, Benoît Monin,
	Thomas Petazzoni, linux-kernel, linux-trace-kernel, linux-mips
In-Reply-To: <20251128-fix_mips_ftrace-v1-1-e6169f8777f2@bootlin.com>

On Fri, Nov 28, 2025 at 09:30:06AM +0100, Gregory CLEMENT wrote:
> Since commit e424054000878 ("MIPS: Tracing: Reduce the overhead of
> dynamic Function Tracer"), the macro UASM_i_LA_mostly has been used,
> and this macro can generate more than 2 instructions. At the same
> time, the code in ftrace assumes that no more than 2 instructions can
> be generated, which is why it stores them in an int[2] array. However,
> as previously noted, the macro UASM_i_LA_mostly (and now UASM_i_LA)
> causes a buffer overflow when _mcount is beyond 32 bits. This leads to
> corruption of the variables located in the __read_mostly section.
> 
> This corruption was observed because the variable
> __cpu_primary_thread_mask was corrupted, causing a hang very early
> during boot.
> 
> This fix prevents the corruption by avoiding the generation of
> instructions if they could exceed 2 instructions in
> length. Fortunately, insn_la_mcount is only used if the instrumented
> code is located outside the kernel code section, so dynamic ftrace can
> still be used, albeit in a more limited scope. This is still
> preferable to corrupting memory and/or crashing the kernel.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
> ---
> To go further and remove the limitations of dynamic trace support, the
> ftrace implementation for MIPS should be completely rewritten and
> inspired by what was done for arm64. This approach was chosen by
> Loongson: instead of trying to manage multiple instructions added on
> the fly, the support relies on a breakpoint, which is more robust.
> 
> However, this effort is significant, so I’ll leave it to those who are
> motivated to work on it. If needed, I can provide some guidance on the
> topic.
> ---
>  arch/mips/kernel/ftrace.c | 25 +++++++++++++++++++++----
>  1 file changed, 21 insertions(+), 4 deletions(-)

applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply

* [bug report] function_graph: Enable funcgraph-args and funcgraph-retaddr to work simultaneously
From: Dan Carpenter @ 2025-12-02  8:32 UTC (permalink / raw)
  To: pengdonglin; +Cc: linux-trace-kernel

Hello pengdonglin,

Commit f83ac7544fbf ("function_graph: Enable funcgraph-args and
funcgraph-retaddr to work simultaneously") from Nov 25, 2025
(linux-next), leads to the following Smatch static checker warning:

kernel/trace/trace_functions_graph.c:1033 print_graph_entry_nested() warn: unsigned 'call->depth' is never less than zero.
kernel/trace/trace_functions_graph.c:975 print_graph_entry_leaf() warn: unsigned 'call->depth' is never less than zero.
kernel/trace/trace.h:1130 ftrace_graph_ignore_func() warn: unsigned 'trace->depth' is never less than zero.

kernel/trace/trace_functions_graph.c
    1012 static enum print_line_t
    1013 print_graph_entry_nested(struct trace_iterator *iter,
    1014                          struct ftrace_graph_ent_entry *entry,
    1015                          struct trace_seq *s, int cpu, u32 flags)
    1016 {
    1017         struct ftrace_graph_ent *call = &entry->graph_ent;
    1018         struct fgraph_data *data = iter->private;
    1019         struct trace_array *tr = iter->tr;
    1020         unsigned long func;
    1021         int args_size;
    1022         int i;
    1023 
    1024         if (data) {
    1025                 struct fgraph_cpu_data *cpu_data;
    1026                 int cpu = iter->cpu;
    1027 
    1028                 cpu_data = per_cpu_ptr(data->cpu_data, cpu);
    1029                 cpu_data->depth = call->depth;
    1030 
    1031                 /* Save this function pointer to see if the exit matches */
    1032                 if (call->depth < FTRACE_RETFUNC_DEPTH &&
--> 1033                     !WARN_ON_ONCE(call->depth < 0))
                                           ^^^^^^^^^^^^^^^
The patch changed call->depth from int to unsigned long.

    1034                         cpu_data->enter_funcs[call->depth] = call->func;
    1035         }
    1036 
    1037         /* No time */
    1038         print_graph_duration(tr, 0, s, flags | FLAGS_FILL_FULL);

regards,
dan carpenter

^ permalink raw reply

* Re: [PATCH bpf v2 1/2] bpf: mark bpf_d_path() buffer as writeable
From: Matt Bobrowski @ 2025-12-02  8:19 UTC (permalink / raw)
  To: Shuran Liu
  Cc: song, bpf, ast, daniel, andrii, martin.lau, eddyz87,
	yonghong.song, john.fastabend, kpsingh, sdf, haoluo, jolsa,
	rostedt, mhiramat, mathieu.desnoyers, linux-kernel,
	linux-trace-kernel, Zesen Liu, Peili Gao, Haoran Ni
In-Reply-To: <20251202075441.1409-2-electronlsr@gmail.com>

On Tue, Dec 02, 2025 at 03:54:40PM +0800, Shuran Liu wrote:
> Commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type
> tracking") started distinguishing read vs write accesses performed by
> helpers.
> 
> The second argument of bpf_d_path() is a pointer to a buffer that the
> helper fills with the resulting path. However, its prototype currently
> uses ARG_PTR_TO_MEM without MEM_WRITE.
> 
> Before 37cce22dbd51, helper accesses were conservatively treated as
> potential writes, so this mismatch did not cause issues. Since that
> commit, the verifier may incorrectly assume that the buffer contents
> are unchanged across the helper call and base its optimizations on this
> wrong assumption. This can lead to misbehaviour in BPF programs that
> read back the buffer, such as prefix comparisons on the returned path.
> 
> Fix this by marking the second argument of bpf_d_path() as
> ARG_PTR_TO_MEM | MEM_WRITE so that the verifier correctly models the
> write to the caller-provided buffer.
> 
> Fixes: 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking")
> Co-developed-by: Zesen Liu <ftyg@live.com>
> Signed-off-by: Zesen Liu <ftyg@live.com>
> Co-developed-by: Peili Gao <gplhust955@gmail.com>
> Signed-off-by: Peili Gao <gplhust955@gmail.com>
> Co-developed-by: Haoran Ni <haoran.ni.cs@gmail.com>
> Signed-off-by: Haoran Ni <haoran.ni.cs@gmail.com>
> Signed-off-by: Shuran Liu <electronlsr@gmail.com>

You forgot to include my Reviewed-by trailer from the initial patch
series (https://lore.kernel.org/bpf/aS3jARS7a-gh9UCa@google.com/), so
here it is again.

Reviewed-by: Matt Bobrowski <mattbobrowski@google.com>

> ---
>  kernel/trace/bpf_trace.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 4f87c16d915a..49e0bdaa7a1b 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -965,7 +965,7 @@ static const struct bpf_func_proto bpf_d_path_proto = {
>  	.ret_type	= RET_INTEGER,
>  	.arg1_type	= ARG_PTR_TO_BTF_ID,
>  	.arg1_btf_id	= &bpf_d_path_btf_ids[0],
> -	.arg2_type	= ARG_PTR_TO_MEM,
> +	.arg2_type	= ARG_PTR_TO_MEM | MEM_WRITE,
>  	.arg3_type	= ARG_CONST_SIZE_OR_ZERO,
>  	.allowed	= bpf_d_path_allowed,
>  };
> -- 
> 2.52.0
> 

^ permalink raw reply

* Re: [PATCH V3 1/2] mm/khugepaged: map dirty/writeback pages failures to EAGAIN
From: Baolin Wang @ 2025-12-02  7:56 UTC (permalink / raw)
  To: Shivank Garg, Andrew Morton, David Hildenbrand, Lorenzo Stoakes
  Cc: Zi Yan, Liam R . Howlett, Nico Pache, Ryan Roberts, Dev Jain,
	Barry Song, Lance Yang, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, Zach O'Keefe, linux-mm, linux-kernel,
	linux-trace-kernel, Branden Moore
In-Reply-To: <20251201185604.210634-8-shivankg@amd.com>



On 2025/12/2 02:56, Shivank Garg wrote:
> When collapse_file encounters dirty or writeback pages in file-backed
> mappings, it currently returns SCAN_FAIL which maps to -EINVAL. This is
> misleading as EINVAL suggests invalid arguments, whereas dirty/writeback
> pages represent transient conditions that may resolve on retry.
> 
> Introduce SCAN_PAGE_DIRTY_OR_WRITEBACK to cover both dirty and writeback
> states, mapping it to -EAGAIN. For MADV_COLLAPSE, this provides userspace
> with a clear signal that retry may succeed after writeback completes.
> For khugepaged, this is harmless as it will naturally revisit the range
> during periodic scans after async writeback completes.
> 
> 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")
> Reviewed-by: Dev Jain <dev.jain@arm.com>
> Reviewed-by: Lance Yang <lance.yang@linux.dev>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---

LGTM.
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>

^ permalink raw reply

* [PATCH bpf v2 2/2] selftests/bpf: fix and consolidate d_path LSM regression test
From: Shuran Liu @ 2025-12-02  7:54 UTC (permalink / raw)
  To: song, mattbobrowski, bpf
  Cc: ast, daniel, andrii, martin.lau, eddyz87, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, rostedt, mhiramat,
	mathieu.desnoyers, linux-kernel, linux-trace-kernel, electronlsr,
	Zesen Liu, Peili Gao, Haoran Ni
In-Reply-To: <20251202075441.1409-1-electronlsr@gmail.com>

Add a regression test for bpf_d_path() when invoked from an LSM program.
The test attaches to the bprm_check_security hook, calls bpf_d_path() on
the binary being executed, and verifies that a simple prefix comparison on
the returned pathname behaves correctly after the fix in patch 1.

To avoid nondeterminism, the LSM program now filters based on the
expected PID, which is populated from userspace before the test binary is
executed. This prevents unrelated processes that also trigger the
bprm_check_security LSM hook from overwriting test results. Parent and
child processes are synchronized through a pipe to ensure the PID is set
before the child execs the test binary.

Per review feedback, the new test is merged into the existing d_path
selftest rather than adding new prog_tests/ or progs/ files.

Co-developed-by: Zesen Liu <ftyg@live.com>
Signed-off-by: Zesen Liu <ftyg@live.com>
Co-developed-by: Peili Gao <gplhust955@gmail.com>
Signed-off-by: Peili Gao <gplhust955@gmail.com>
Co-developed-by: Haoran Ni <haoran.ni.cs@gmail.com>
Signed-off-by: Haoran Ni <haoran.ni.cs@gmail.com>
Signed-off-by: Shuran Liu <electronlsr@gmail.com>
---
 .../testing/selftests/bpf/prog_tests/d_path.c | 64 +++++++++++++++++++
 .../testing/selftests/bpf/progs/test_d_path.c | 33 ++++++++++
 2 files changed, 97 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/d_path.c b/tools/testing/selftests/bpf/prog_tests/d_path.c
index ccc768592e66..2909ca3bae0f 100644
--- a/tools/testing/selftests/bpf/prog_tests/d_path.c
+++ b/tools/testing/selftests/bpf/prog_tests/d_path.c
@@ -195,6 +195,67 @@ static void test_d_path_check_types(void)
 	test_d_path_check_types__destroy(skel);
 }
 
+static void test_d_path_lsm(void)
+{
+	struct test_d_path *skel;
+	int err;
+	int pipefd[2];
+	pid_t pid;
+
+	skel = test_d_path__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "d_path skeleton failed"))
+		return;
+
+	err = test_d_path__attach(skel);
+	if (!ASSERT_OK(err, "attach failed"))
+		goto cleanup;
+
+	/* Prepare the test binary */
+	system("cp /bin/true /tmp/bpf_d_path_test 2>/dev/null || :");
+
+	if (!ASSERT_OK(pipe(pipefd), "pipe failed"))
+		goto cleanup;
+
+	pid = fork();
+	if (!ASSERT_GE(pid, 0, "fork failed")) {
+		close(pipefd[0]);
+		close(pipefd[1]);
+		goto cleanup;
+	}
+
+	if (pid == 0) {
+		/* Child */
+		char buf;
+
+		close(pipefd[1]);
+		/* Wait for parent to set PID in BPF map */
+		if (read(pipefd[0], &buf, 1) != 1)
+			exit(1);
+		close(pipefd[0]);
+		execl("/tmp/bpf_d_path_test", "/tmp/bpf_d_path_test", NULL);
+		exit(1);
+	}
+
+	/* Parent */
+	close(pipefd[0]);
+
+	/* Update BPF map with child PID */
+	skel->bss->my_pid = pid;
+
+	/* Signal child to proceed */
+	write(pipefd[1], "G", 1);
+	close(pipefd[1]);
+
+	/* Wait for child */
+	waitpid(pid, NULL, 0);
+
+	ASSERT_EQ(skel->bss->called_lsm, 1, "lsm hook called");
+	ASSERT_EQ(skel->bss->lsm_match, 1, "lsm match");
+
+cleanup:
+	test_d_path__destroy(skel);
+}
+
 void test_d_path(void)
 {
 	if (test__start_subtest("basic"))
@@ -205,4 +266,7 @@ void test_d_path(void)
 
 	if (test__start_subtest("check_alloc_mem"))
 		test_d_path_check_types();
+
+	if (test__start_subtest("lsm"))
+		test_d_path_lsm();
 }
diff --git a/tools/testing/selftests/bpf/progs/test_d_path.c b/tools/testing/selftests/bpf/progs/test_d_path.c
index 84e1f883f97b..7f65c282069a 100644
--- a/tools/testing/selftests/bpf/progs/test_d_path.c
+++ b/tools/testing/selftests/bpf/progs/test_d_path.c
@@ -17,6 +17,8 @@ int rets_close[MAX_FILES] = {};
 
 int called_stat = 0;
 int called_close = 0;
+int called_lsm = 0;
+int lsm_match = 0;
 
 SEC("fentry/security_inode_getattr")
 int BPF_PROG(prog_stat, struct path *path, struct kstat *stat,
@@ -62,4 +64,35 @@ int BPF_PROG(prog_close, struct file *file, void *id)
 	return 0;
 }
 
+SEC("lsm/bprm_check_security")
+int BPF_PROG(prog_lsm, struct linux_binprm *bprm)
+{
+	pid_t pid = bpf_get_current_pid_tgid() >> 32;
+	char path[MAX_PATH_LEN] = {};
+	int ret;
+
+	if (pid != my_pid)
+		return 0;
+
+	called_lsm = 1;
+	ret = bpf_d_path(&bprm->file->f_path, path, MAX_PATH_LEN);
+	if (ret < 0)
+		return 0;
+
+	{
+		static const char target_dir[] = "/tmp/";
+
+#pragma unroll
+		for (int i = 0; i < sizeof(target_dir) - 1; i++) {
+			if (path[i] != target_dir[i]) {
+				lsm_match = -1; /* mismatch */
+				return 0;
+			}
+		}
+	}
+
+	lsm_match = 1; /* prefix match */
+	return 0;
+}
+
 char _license[] SEC("license") = "GPL";
-- 
2.52.0


^ permalink raw reply related

* [PATCH bpf v2 1/2] bpf: mark bpf_d_path() buffer as writeable
From: Shuran Liu @ 2025-12-02  7:54 UTC (permalink / raw)
  To: song, mattbobrowski, bpf
  Cc: ast, daniel, andrii, martin.lau, eddyz87, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, rostedt, mhiramat,
	mathieu.desnoyers, linux-kernel, linux-trace-kernel, electronlsr,
	Zesen Liu, Peili Gao, Haoran Ni
In-Reply-To: <20251202075441.1409-1-electronlsr@gmail.com>

Commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type
tracking") started distinguishing read vs write accesses performed by
helpers.

The second argument of bpf_d_path() is a pointer to a buffer that the
helper fills with the resulting path. However, its prototype currently
uses ARG_PTR_TO_MEM without MEM_WRITE.

Before 37cce22dbd51, helper accesses were conservatively treated as
potential writes, so this mismatch did not cause issues. Since that
commit, the verifier may incorrectly assume that the buffer contents
are unchanged across the helper call and base its optimizations on this
wrong assumption. This can lead to misbehaviour in BPF programs that
read back the buffer, such as prefix comparisons on the returned path.

Fix this by marking the second argument of bpf_d_path() as
ARG_PTR_TO_MEM | MEM_WRITE so that the verifier correctly models the
write to the caller-provided buffer.

Fixes: 37cce22dbd51 ("bpf: verifier: Refactor helper access type tracking")
Co-developed-by: Zesen Liu <ftyg@live.com>
Signed-off-by: Zesen Liu <ftyg@live.com>
Co-developed-by: Peili Gao <gplhust955@gmail.com>
Signed-off-by: Peili Gao <gplhust955@gmail.com>
Co-developed-by: Haoran Ni <haoran.ni.cs@gmail.com>
Signed-off-by: Haoran Ni <haoran.ni.cs@gmail.com>
Signed-off-by: Shuran Liu <electronlsr@gmail.com>
---
 kernel/trace/bpf_trace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 4f87c16d915a..49e0bdaa7a1b 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -965,7 +965,7 @@ static const struct bpf_func_proto bpf_d_path_proto = {
 	.ret_type	= RET_INTEGER,
 	.arg1_type	= ARG_PTR_TO_BTF_ID,
 	.arg1_btf_id	= &bpf_d_path_btf_ids[0],
-	.arg2_type	= ARG_PTR_TO_MEM,
+	.arg2_type	= ARG_PTR_TO_MEM | MEM_WRITE,
 	.arg3_type	= ARG_CONST_SIZE_OR_ZERO,
 	.allowed	= bpf_d_path_allowed,
 };
-- 
2.52.0


^ permalink raw reply related

* [PATCH bpf v2 0/2] bpf: fix bpf_d_path() helper prototype
From: Shuran Liu @ 2025-12-02  7:54 UTC (permalink / raw)
  To: song, mattbobrowski, bpf
  Cc: ast, daniel, andrii, martin.lau, eddyz87, yonghong.song,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, rostedt, mhiramat,
	mathieu.desnoyers, linux-kernel, linux-trace-kernel, electronlsr

Hi,

this series fixes a verifier regression for bpf_d_path() introduced by
commit 37cce22dbd51 ("bpf: verifier: Refactor helper access type
tracking") and adds a small selftest to exercise the helper from an
LSM program.

Commit 37cce22dbd51 started distinguishing read vs write accesses
performed by helpers. bpf_d_path()'s buffer argument was left as
ARG_PTR_TO_MEM without MEM_WRITE, so the verifier could incorrectly
assume that the buffer contents are unchanged across the helper call
and base its optimizations on this wrong assumption.

In practice this showed up as a misbehaving LSM BPF program that calls
bpf_d_path() and then does a simple prefix comparison on the returned
path: the program would sometimes take the "mismatch" branch even
though both bytes being compared were actually equal.

Patch 1 fixes bpf_d_path()'s helper prototype by marking the buffer
argument as ARG_PTR_TO_MEM | MEM_WRITE, so that the verifier correctly
models the write to the caller-provided buffer.

Patch 2 adds a regression test that exercises bpf_d_path() from an LSM
program attached to bprm_check_security. The test verifies that pathname
prefix comparisons behave correctly with the fix applied.

Changes in v2:
- Merge the new test into the existing d_path selftest rather than
creating new files.
- Add PID filtering in the LSM program to avoid nondeterministic failures
due to unrelated processes triggering bprm_check_security.
- Synchronize child execution using a pipe to ensure deterministic
updates to the PID.

Thanks,
Shuran Liu

Shuran Liu (2):
  bpf: mark bpf_d_path() buffer as writeable
  selftests/bpf: fix and consolidate d_path LSM regression test

 kernel/trace/bpf_trace.c                      |  2 +-
 .../testing/selftests/bpf/prog_tests/d_path.c | 64 +++++++++++++++++++
 .../testing/selftests/bpf/progs/test_d_path.c | 33 ++++++++++
 3 files changed, 98 insertions(+), 1 deletion(-)

-- 
2.52.0


^ permalink raw reply

* Re: [PATCH v13 mm-new 07/16] khugepaged: introduce collapse_max_ptes_none helper function
From: Baolin Wang @ 2025-12-02  7:53 UTC (permalink / raw)
  To: Nico Pache, linux-kernel, linux-trace-kernel, linux-mm, linux-doc
  Cc: david, ziy, lorenzo.stoakes, Liam.Howlett, ryan.roberts, dev.jain,
	corbet, rostedt, mhiramat, mathieu.desnoyers, akpm, baohua, willy,
	peterx, wangkefeng.wang, usamaarif642, sunnanyong, vishal.moola,
	thomas.hellstrom, yang, kas, aarcange, raquini, anshuman.khandual,
	catalin.marinas, tiwai, will, dave.hansen, jack, cl, jglisse,
	surenb, zokeefe, hannes, rientjes, mhocko, rdunlap, hughd,
	richard.weiyang, lance.yang, vbabka, rppt, jannh, pfalcato
In-Reply-To: <20251201174627.23295-8-npache@redhat.com>



On 2025/12/2 01:46, Nico Pache wrote:
> The current mechanism for determining mTHP collapse scales the
> khugepaged_max_ptes_none value based on the target order. This
> introduces an undesirable feedback loop, or "creep", when max_ptes_none
> is set to a value greater than HPAGE_PMD_NR / 2.
> 
> With this configuration, a successful collapse to order N will populate
> enough pages to satisfy the collapse condition on order N+1 on the next
> scan. This leads to unnecessary work and memory churn.
> 
> To fix this issue introduce a helper function that will limit mTHP
> collapse support to two max_ptes_none values, 0 and HPAGE_PMD_NR - 1.
> This effectively supports two modes:
> 
> - max_ptes_none=0: never introduce new none-pages for mTHP collapse.
> - max_ptes_none=511 (on 4k pagesz): Always collapse to the highest
>    available mTHP order.
> 
> This removes the possiblilty of "creep", while not modifying any uAPI
> expectations. A warning will be emitted if any non-supported
> max_ptes_none value is configured with mTHP enabled.
> 
> The limits can be ignored by passing full_scan=true, this is useful for
> madvise_collapse (which ignores limits), or in the case of
> collapse_scan_pmd(), allows the full PMD to be scanned when mTHP
> collapse is available.
> 
> Signed-off-by: Nico Pache <npache@redhat.com>
> ---
>   mm/khugepaged.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 8dab49c53128..f425238d5d4f 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -463,6 +463,44 @@ void __khugepaged_enter(struct mm_struct *mm)
>   		wake_up_interruptible(&khugepaged_wait);
>   }
>   
> +/**
> + * collapse_max_ptes_none - Calculate maximum allowed empty PTEs for collapse
> + * @order: The folio order being collapsed to
> + * @full_scan: Whether this is a full scan (ignore limits)
> + *
> + * For madvise-triggered collapses (full_scan=true), all limits are bypassed
> + * and allow up to HPAGE_PMD_NR - 1 empty PTEs.
> + *
> + * For PMD-sized collapses (order == HPAGE_PMD_ORDER), use the configured
> + * khugepaged_max_ptes_none value.
> + *
> + * For mTHP collapses, we currently only support khugepaged_max_pte_none values
> + * of 0 or (HPAGE_PMD_NR - 1). Any other value will emit a warning and no mTHP
> + * collapse will be attempted
> + *
> + * Return: Maximum number of empty PTEs allowed for the collapse operation
> + */
> +static unsigned int collapse_max_ptes_none(unsigned int order, bool full_scan)
> +{
> +	/* ignore max_ptes_none limits */
> +	if (full_scan)
> +		return HPAGE_PMD_NR - 1;
> +
> +	if (!is_mthp_order(order))
> +		return khugepaged_max_ptes_none;
> +
> +	/* Zero/non-present collapse disabled. */
> +	if (!khugepaged_max_ptes_none)
> +		return 0;
> +
> +	if (khugepaged_max_ptes_none == HPAGE_PMD_NR - 1)
> +		return (1 << order) - 1;
> +
> +	pr_warn_once("mTHP collapse only supports max_ptes_none values of 0 or %d\n",
> +		      HPAGE_PMD_NR - 1);
> +	return -EINVAL;
> +}

Thanks. That aligns with what we talked about previously. So
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>

^ permalink raw reply

* Re: [PATCH 1/3] kernel.h: drop STACK_MAGIC macro
From: Andy Shevchenko @ 2025-12-02  7:37 UTC (permalink / raw)
  To: Yury Norov
  Cc: Christophe Leroy (CS GROUP), Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, Randy Dunlap, Ingo Molnar, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Petr Pavlu,
	Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
	Danilo Krummrich, Andrew Morton, linux-kernel, intel-gfx,
	dri-devel, linux-modules, linux-trace-kernel
In-Reply-To: <aS5T9-1z7PK32q9R@yury>

On Mon, Dec 01, 2025 at 09:50:31PM -0500, Yury Norov wrote:
> On Mon, Dec 01, 2025 at 10:38:01AM +0100, Christophe Leroy (CS GROUP) wrote:
> > Le 29/11/2025 à 20:53, Yury Norov (NVIDIA) a écrit :

...

> You can check commit 4914d770dec4 in this project:
> 
> https://archive.org/details/git-history-of-linux

Side note: we have history/history.git tree on kernel.org, and,
if anyone wants to check, it is handy.

Each of the history tree has its own pros and cons:
https://stackoverflow.com/a/51901211/2511795

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v3 0/2] Replace trace_cpu_frequency with trace_policy_frequency
From: Viresh Kumar @ 2025-12-02  6:43 UTC (permalink / raw)
  To: Samuel Wu
  Cc: Huang Rui, Gautham R. Shenoy, Mario Limonciello, Perry Yuan,
	Jonathan Corbet, Rafael J. Wysocki, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Srinivas Pandruvada,
	Len Brown, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Ian Rogers,
	Adrian Hunter, James Clark, christian.loehle, kernel-team,
	linux-pm, linux-doc, linux-kernel, linux-trace-kernel, bpf,
	linux-perf-users
In-Reply-To: <20251201202437.3750901-1-wusamuel@google.com>

On 01-12-25, 12:24, Samuel Wu wrote:
> This series replaces the cpu_frequency trace event with a new trace event,
> policy_frequency. Since by definition all CPUs in a policy are of the same
> frequency, we can emit a frequency change per policy instead of per CPU.
> This saves some compute and memory from the kernel side, while simplifying
> analysis from the post-processing of the trace log side.
> 
> Any process that relied on cpu_frequency trace event needs to switch to the
> new policy_frequency trace event in order to maintain functionality. The
> decision of replacing instead of adding the trace event is intentional. Since
> emitting once per policy instead of once per CPU is anyways a semantics change
> that would require a tooling update, the trace event was also appropriately
> renamed. The presence of the policy_frequency event in a trace log is a clear
> and obvious signal for tooling to determine kernel version and which trace
> event to parse.
> 
> 1/2: Replaces trace_cpu_frequency with trace_policy_frequency
> 2/2: Corresponding documentation patch that updates references to
>      cpu_frequency with policy_frequency
> 
> Changes in v3:
> - Resending v2 properly (accidentally ommited cover letter in v2)
> 
> Changes in v2:
> - Replaced trace_cpu_frequency with trace_policy_frequency (per Christian
>   and Viresh)
> - Updated references to cpu_frequency in documentation with
>   policy_frequency
> - v1 link: https://lore.kernel.org/all/20251112235154.2974902-1-wusamuel@google.com
> 
> Samuel Wu (2):
>   cpufreq: Replace trace_cpu_frequency with trace_policy_frequency
>   cpufreq: Documentation update for trace_policy_frequency
> 
>  Documentation/admin-guide/pm/amd-pstate.rst   | 10 ++++----
>  Documentation/admin-guide/pm/intel_pstate.rst | 14 +++++------
>  Documentation/trace/events-power.rst          |  2 +-
>  drivers/cpufreq/cpufreq.c                     | 14 ++---------
>  drivers/cpufreq/intel_pstate.c                |  6 +++--
>  include/trace/events/power.h                  | 24 ++++++++++++++++---
>  kernel/trace/power-traces.c                   |  2 +-
>  samples/bpf/cpustat_kern.c                    |  8 +++----
>  samples/bpf/cpustat_user.c                    |  6 ++---
>  tools/perf/builtin-timechart.c                | 12 +++++-----
>  10 files changed, 54 insertions(+), 44 deletions(-)

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply

* Re: [PATCH v2 1/2] rv: Convert to use lock guard
From: Gabriele Monaco @ 2025-12-02  6:41 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Nam Cao, Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
	linux-kernel
In-Reply-To: <20251201205132.520eb490@gandalf.local.home>

> On Mon, 1 Dec 2025 20:38:16 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
>
> It's best to always use your latest branch that you did your last pull on
> during a release cycle.
>
> I see you based these changes on v6.18-rc7, but your previous pull was
> based on v6.18-rc5. If I were to pull this in, it gets a bit spaghetti like
> in the merges.
>
>   v6.18-rc5 -> pull1
>   merge <- v6.18-rc7 <- pull2
>
> Where now we have changes between rc5 and rc7.  Was there a reason you
> based on top of rc7 and not use your last pull?
>
> It's fine sending urgent patches this way, as these tags are in Linus's
> tree and it's just new changes being added. But for a subsytem tree, it's
> best not to pull in Linus's tree unless there's a good reason to do that.

Yeah got it, there was no valid reason for that rebase, I'm going to keep it
stable next time or write it explicitly otherwise.

> What I can do is simply pull the patches on top of your last patch
> directly, and keep the history clean for my pull request to Linus.

I'm pushed the tag rebased on -rc5 (actually on the last PR) just in case it
makes your life easier:


The following changes since commit 69d8895cb9a9f6450374577af8584c2e21cb5a9f:

  rv: Add explicit lockdep context for reactors (2025-11-11 13:18:56 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/gmonaco/linux.git rv-6.19-next-2-rc5

for you to fetch changes up to b30f635bb6492f02f2f704b46d898679371015cb:

  rv: Convert to use __free (2025-12-02 07:28:32 +0100)


Thanks,
Gabriele


^ permalink raw reply

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



On 2025/12/2 02:56, 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>
> Signed-off-by: Shivank Garg <shivankg@amd.com>
> ---
>   mm/khugepaged.c | 41 +++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 41 insertions(+)
> 
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index 219dfa2e523c..7a12e9ef30b4 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -22,6 +22,7 @@
>   #include <linux/dax.h>
>   #include <linux/ksm.h>
>   #include <linux/pgalloc.h>
> +#include <linux/backing-dev.h>
>   
>   #include <asm/tlb.h>
>   #include "internal.h"
> @@ -2787,9 +2788,11 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
>   	hend = end & HPAGE_PMD_MASK;
>   
>   	for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
> +		bool retried = false;
>   		int result = SCAN_FAIL;
>   
>   		if (!mmap_locked) {
> +retry:
>   			cond_resched();
>   			mmap_read_lock(mm);
>   			mmap_locked = true;
> @@ -2819,6 +2822,44 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
>   		if (!mmap_locked)
>   			*lock_dropped = true;
>   
> +		/*
> +		 * If the file-backed VMA has dirty pages, the scan triggers
> +		 * async writeback and returns SCAN_PAGE_DIRTY_OR_WRITEBACK.
> +		 * Since MADV_COLLAPSE is sync, we force sync writeback and
> +		 * retry once.
> +		 */
> +		if (result == SCAN_PAGE_DIRTY_OR_WRITEBACK && !retried) {
> +			/*
> +			 * File scan drops the lock. We must re-acquire it to
> +			 * safely inspect the VMA and hold the file reference.
> +			 */
> +			if (!mmap_locked) {
> +				cond_resched();
> +				mmap_read_lock(mm);
> +				mmap_locked = true;
> +				result = hugepage_vma_revalidate(mm, addr, false, &vma, cc);
> +				if (result != SCAN_SUCCEED)
> +					goto handle_result;
> +			}
> +
> +			if (!vma_is_anonymous(vma) && vma->vm_file &&
> +			    mapping_can_writeback(vma->vm_file->f_mapping)) {
> +				struct file *file = get_file(vma->vm_file);
> +				pgoff_t pgoff = linear_page_index(vma, addr);
> +				loff_t lstart = (loff_t)pgoff << PAGE_SHIFT;
> +				loff_t lend = lstart + HPAGE_PMD_SIZE - 1;
> +
> +				mmap_read_unlock(mm);
> +				mmap_locked = false;
> +				*lock_dropped = true;
> +				filemap_write_and_wait_range(file->f_mapping, lstart, lend);
> +				fput(file);
> +				retried = true;
> +				goto retry;
> +			}
> +		}
> +
> +

Nit: spurious blank line.

>   handle_result:
>   		switch (result) {
>   		case SCAN_SUCCEED:


^ permalink raw reply

* Re: [PATCH v2 2/2] cpufreq: Documentation update for trace_policy_frequency
From: Mario Limonciello @ 2025-12-02  2:55 UTC (permalink / raw)
  To: Samuel Wu, Huang Rui, Gautham R. Shenoy, Perry Yuan,
	Jonathan Corbet, Rafael J. Wysocki, Viresh Kumar, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Srinivas Pandruvada,
	Len Brown, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Ian Rogers,
	Adrian Hunter, James Clark
  Cc: christian.loehle, kernel-team, linux-pm, linux-doc, linux-kernel,
	linux-trace-kernel, bpf, linux-perf-users
In-Reply-To: <20251201201340.3746701-1-wusamuel@google.com>



On 12/1/2025 2:13 PM, Samuel Wu wrote:
> Documentation update corresponding to replace the cpu_frequency trace
> event with the policy_frequency trace event.
> 
> Signed-off-by: Samuel Wu <wusamuel@google.com>
> ---
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> # amd-pstate
>   Documentation/admin-guide/pm/amd-pstate.rst   | 10 +++++-----
>   Documentation/admin-guide/pm/intel_pstate.rst | 14 +++++++-------
>   Documentation/trace/events-power.rst          |  2 +-
>   3 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
> index e1771f2225d5..e110854ece88 100644
> --- a/Documentation/admin-guide/pm/amd-pstate.rst
> +++ b/Documentation/admin-guide/pm/amd-pstate.rst
> @@ -503,8 +503,8 @@ Trace Events
>   --------------
>   
>   There are two static trace events that can be used for ``amd-pstate``
> -diagnostics. One of them is the ``cpu_frequency`` trace event generally used
> -by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event
> +diagnostics. One of them is the ``policy_frequency`` trace event generally
> +used by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event
>   specific to ``amd-pstate``.  The following sequence of shell commands can
>   be used to enable them and see their output (if the kernel is
>   configured to support event tracing). ::
> @@ -531,9 +531,9 @@ configured to support event tracing). ::
>             <idle>-0       [003] d.s..  4995.980971: amd_pstate_perf: amd_min_perf=85 amd_des_perf=85 amd_max_perf=166 cpu_id=3 changed=false fast_switch=true
>             <idle>-0       [011] d.s..  4995.980996: amd_pstate_perf: amd_min_perf=85 amd_des_perf=85 amd_max_perf=166 cpu_id=11 changed=false fast_switch=true
>   
> -The ``cpu_frequency`` trace event will be triggered either by the ``schedutil`` scaling
> -governor (for the policies it is attached to), or by the ``CPUFreq`` core (for the
> -policies with other scaling governors).
> +The ``policy_frequency`` trace event will be triggered either by the
> +``schedutil`` scaling governor (for the policies it is attached to), or by the
> +``CPUFreq`` core (for the policies with other scaling governors).
>   
>   
>   Tracer Tool
> diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst
> index fde967b0c2e0..274c9208f342 100644
> --- a/Documentation/admin-guide/pm/intel_pstate.rst
> +++ b/Documentation/admin-guide/pm/intel_pstate.rst
> @@ -822,23 +822,23 @@ Trace Events
>   ------------
>   
>   There are two static trace events that can be used for ``intel_pstate``
> -diagnostics.  One of them is the ``cpu_frequency`` trace event generally used
> -by ``CPUFreq``, and the other one is the ``pstate_sample`` trace event specific
> -to ``intel_pstate``.  Both of them are triggered by ``intel_pstate`` only if
> -it works in the :ref:`active mode <active_mode>`.
> +diagnostics.  One of them is the ``policy_frequency`` trace event generally
> +used by ``CPUFreq``, and the other one is the ``pstate_sample`` trace event
> +specific to ``intel_pstate``.  Both of them are triggered by ``intel_pstate``
> +only if it works in the :ref:`active mode <active_mode>`.
>   
>   The following sequence of shell commands can be used to enable them and see
>   their output (if the kernel is generally configured to support event tracing)::
>   
>    # cd /sys/kernel/tracing/
>    # echo 1 > events/power/pstate_sample/enable
> - # echo 1 > events/power/cpu_frequency/enable
> + # echo 1 > events/power/policy_frequency/enable
>    # cat trace
>    gnome-terminal--4510  [001] ..s.  1177.680733: pstate_sample: core_busy=107 scaled=94 from=26 to=26 mperf=1143818 aperf=1230607 tsc=29838618 freq=2474476
> - cat-5235  [002] ..s.  1177.681723: cpu_frequency: state=2900000 cpu_id=2
> + cat-5235  [002] ..s.  1177.681723: policy_frequency: state=2900000 cpu_id=2 policy_cpus=04
>   
>   If ``intel_pstate`` works in the :ref:`passive mode <passive_mode>`, the
> -``cpu_frequency`` trace event will be triggered either by the ``schedutil``
> +``policy_frequency`` trace event will be triggered either by the ``schedutil``
>   scaling governor (for the policies it is attached to), or by the ``CPUFreq``
>   core (for the policies with other scaling governors).
>   
> diff --git a/Documentation/trace/events-power.rst b/Documentation/trace/events-power.rst
> index f45bf11fa88d..f013c74b932f 100644
> --- a/Documentation/trace/events-power.rst
> +++ b/Documentation/trace/events-power.rst
> @@ -26,8 +26,8 @@ cpufreq.
>   ::
>   
>     cpu_idle		"state=%lu cpu_id=%lu"
> -  cpu_frequency		"state=%lu cpu_id=%lu"
>     cpu_frequency_limits	"min=%lu max=%lu cpu_id=%lu"
> +  policy_frequency	"state=%lu cpu_id=%lu policy_cpus=%*pb"
>   
>   A suspend event is used to indicate the system going in and out of the
>   suspend mode:


^ permalink raw reply

* Re: [PATCH 1/3] kernel.h: drop STACK_MAGIC macro
From: Yury Norov @ 2025-12-02  2:50 UTC (permalink / raw)
  To: Christophe Leroy (CS GROUP)
  Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Andy Shevchenko, Randy Dunlap, Ingo Molnar, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Petr Pavlu,
	Daniel Gomez, Greg Kroah-Hartman, Rafael J. Wysocki,
	Danilo Krummrich, Andrew Morton, linux-kernel, intel-gfx,
	dri-devel, linux-modules, linux-trace-kernel
In-Reply-To: <3e7ddbea-978f-44f7-abdd-7319908fd83c@kernel.org>

On Mon, Dec 01, 2025 at 10:38:01AM +0100, Christophe Leroy (CS GROUP) wrote:
> 
> 
> Le 29/11/2025 à 20:53, Yury Norov (NVIDIA) a écrit :
> > The macro is only used by i915. Move it to a local header and drop from
> > the kernel.h.
> 
> At the begining of the git history we have:
> 
> $ git grep STACK_MAGIC 1da177e4c3f41
> 1da177e4c3f41:arch/h8300/kernel/traps.c:        if (STACK_MAGIC !=
> *(unsigned long *)((unsigned long)current+PAGE_SIZE))
> 1da177e4c3f41:arch/m68k/mac/macints.c:          if (STACK_MAGIC !=
> *(unsigned long *)current->kernel_stack_page)
> 1da177e4c3f41:include/linux/kernel.h:#define STACK_MAGIC        0xdeadbeef
> 
> Would be good to know the history of its usage over time.
> 
> I see:
> - Removed from m68k by 3cd53b14e7c4 ("m68k/mac: Improve NMI handler")
> - Removed from h8300 by 1c4b5ecb7ea1 ("remove the h8300 architecture")
> - Started being used in i915 selftest by 250f8c8140ac ("drm/i915/gtt:
> Read-only pages for insert_entries on bdw+")

STACK_MAGIC was added in 1994 in 1.0.2.  It was indeed used in a couple
of places in core subsystems back then to detect stack corruption. But
since that people invented better ways to guard stacks.

You can check commit 4914d770dec4 in this project:

https://archive.org/details/git-history-of-linux

^ permalink raw reply

* Re: [PATCH] kprobes: avoid crash when rmmod/insmod modules after ftrace_disabled
From: Masami Hiramatsu @ 2025-12-02  2:32 UTC (permalink / raw)
  To: yebin; +Cc: naveen, davem, linux-trace-kernel, yebin10, Steven Rostedt
In-Reply-To: <6929089E.10706@huaweicloud.com>

Cc: Steve,

Since this is caused by ftrace_kill.

On Fri, 28 Nov 2025 10:27:42 +0800
yebin <yebin@huaweicloud.com> wrote:

> 
> 
> On 2025/11/27 12:18, Masami Hiramatsu (Google) wrote:
> > On Thu, 27 Nov 2025 12:52:48 +0900
> > Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:
> >
> >> Hi,
> >>
> >> Thanks for reporting!
> >>
> >>
> >> On Tue, 25 Nov 2025 10:05:36 +0800
> >> Ye Bin <yebin@huaweicloud.com> wrote:
> >>
> >>> From: Ye Bin <yebin10@huawei.com>
> >>>
> >>> There's a issue as follows when rmmod modules after ftrace disabled:
> >>
> >> You may see something like;
> >>
> >> Failed to unregister kprobe-ftrace (error -19)
> >>
> >> or
> >>
> >> Failed to disarm kprobe-ftrace at <function name> (error -19)
> >>
> >> right before this BUG, don't you?
> >> If you reported with that line, it's more easier to understand.
> >>
> Yes, there is indeed a warning generated. I might not have expressed it 
> clearly enough. The issue below is related to the problem that occurs 
> when the second module is unloaded. When the first module was unloaded, 
> some nodes were left in the hash list, causing a use-after-free (UAF) 
> issue when traversing the hash list.
> Therefore, this patch aims to resolve the UAF problem caused by residual 
> nodes in the hash list after unloading a module while ftrace is disabled.

Yes, but I think your patch is redundant. Can you test the code
which I suggested at the last?

BTW, can you explain why that ftrace_disabled was kicked?
That usually means ftrace hits some bug.

> >>
> >>> BUG: unable to handle page fault for address: fffffbfff805000d
> >>> PGD 817fcc067 P4D 817fcc067 PUD 817fc8067 PMD 101555067 PTE 0
> >>> Oops: Oops: 0000 [#1] SMP KASAN PTI
> >>> CPU: 4 UID: 0 PID: 2012 Comm: rmmod Tainted: G        W  OE
> >>> Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
> >>> RIP: 0010:kprobes_module_callback+0x89/0x790
> >>> RSP: 0018:ffff88812e157d30 EFLAGS: 00010a02
> >>> RAX: 1ffffffff805000d RBX: dffffc0000000000 RCX: ffffffff86a8de90
> >>> RDX: ffffed1025c2af9b RSI: 0000000000000008 RDI: ffffffffc0280068
> >>> RBP: 0000000000000000 R08: 0000000000000001 R09: ffffed1025c2af9a
> >>> R10: ffff88812e157cd7 R11: 205d323130325420 R12: 0000000000000002
> >>> R13: ffffffffc0290488 R14: 0000000000000002 R15: ffffffffc0280040
> >>> FS:  00007fbc450dd740(0000) GS:ffff888420331000(0000) knlGS:0000000000000000
> >>> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >>> CR2: fffffbfff805000d CR3: 000000010f624000 CR4: 00000000000006f0
> >>> Call Trace:
> >>>   <TASK>
> >>>   notifier_call_chain+0xc6/0x280
> >>>   blocking_notifier_call_chain+0x60/0x90
> >>>   __do_sys_delete_module.constprop.0+0x32a/0x4e0
> >>>   do_syscall_64+0x5d/0xfa0
> >>>   entry_SYSCALL_64_after_hwframe+0x76/0x7e
> >>>
> >>> The above issue occurs because the kprobe was not removed from the hash
> >>> list after ftrace_disable.
> >>> To prevent the system from restarting unexpectedly after ftrace_disable,
> >>> in such cases, unregister_kprobe() ensures that the probe is removed from
> >>> the hash list, preventing subsequent access to already freed memory.
> >>>
> >>> Fixes: 6f0f1dd71953 ("kprobes: Cleanup disabling and unregistering path")
> >>> Signed-off-by: Ye Bin <yebin10@huawei.com>
> >>> ---
> >>>   kernel/kprobes.c | 26 ++++++++++++++++++++++++--
> >>>   1 file changed, 24 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> >>> index ab8f9fc1f0d1..d735a608b810 100644
> >>> --- a/kernel/kprobes.c
> >>> +++ b/kernel/kprobes.c
> >>> @@ -1731,8 +1731,30 @@ static int __unregister_kprobe_top(struct kprobe *p)
> >>>
> >>>   	/* Disable kprobe. This will disarm it if needed. */
> >>>   	ap = __disable_kprobe(p);
> >>> -	if (IS_ERR(ap))
> >>> -		return PTR_ERR(ap);
> >>> +	if (IS_ERR(ap)) {
> >>> +		int ret = PTR_ERR(ap);
> >>> +
> >>> +		/*
> >>> +		 * If ftrace disabled we need to delete kprobe node from
> >>> +		 * hlist or aggregation list. If nodes are not removed when
> >>> +		 * modules are removed, the already released nodes will
> >>> +		 * remain in the linked list. Subsequent access to the
> >>> +		 * linked list may then trigger exceptions.
> >>> +		 */
> >>> +		if (ret != -ENODEV)
> >>> +			return ret;
> >>> +
> >>> +		ap = __get_valid_kprobe(p);
> >>> +		if (!ap)
> >>> +			return ret;
> >>> +
> >>> +		if (ap == p)
> >>> +			hlist_del_rcu(&ap->hlist);
> >>> +		else
> >>> +			list_del_rcu(&p->list);
> >>
> >> Instead of repeating this process, we should ignore
> >> -ENODEV error from ftrace directly. BTW, ftrace_disabled is set
> >> when ftrace_kill() is called, that means ftrace is no more usable.
> >> So I think we can just ignore ftrace operation in
> >> __disarm_kprobe_ftrace().
> >
> > So, what we need is;
> >
> > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > index ab8f9fc1f0d1..17d451553389 100644
> > --- a/kernel/kprobes.c
> > +++ b/kernel/kprobes.c
> > @@ -1104,6 +1104,10 @@ static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops,
> >   	int ret;
> >
> >   	lockdep_assert_held(&kprobe_mutex);
> > +	if (unlikely(kprobe_ftrace_disabled)) {
> > +		/* Now ftrace is disabled forever, disarm is already done. */
> > +		return 0;
> > +	}
> >
> >   	if (*cnt == 1) {
> >   		ret = unregister_ftrace_function(ops);
> >

This one, it should fix simply.

Thank you,

> >
> 


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

^ permalink raw reply

* Re: [PATCH v2 1/2] rv: Convert to use lock guard
From: Steven Rostedt @ 2025-12-02  1:51 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: Nam Cao, Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
	linux-kernel
In-Reply-To: <20251201203816.5e777f12@gandalf.local.home>

On Mon, 1 Dec 2025 20:38:16 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:

> On Mon, 01 Dec 2025 16:28:21 +0100
> Gabriele Monaco <gmonaco@redhat.com> wrote:
> 
> > I'm stupid, I sent it [1] but the script somehow didn't add you in the To: field
> > and I didn't notice..
> > 
> > I'd say since the merge window is open, this change can wait.
> > 
> > Sorry for that.
> > 
> > Gabriele
> > 
> > [1] - https://lore.kernel.org/lkml/20251126152253.464350-1-gmonaco@redhat.com  
> 
> I can still pull it and run it through my tests tonight and push it later this week.
> 
> It's just clean up code. Linus doesn't get too upset if simple cleanup code
> gets added just before the merge window. It's new features that he doesn't
> like added late in the game.

After pulling it, I take it back ;-)

It's best to always use your latest branch that you did your last pull on
during a release cycle.

I see you based these changes on v6.18-rc7, but your previous pull was
based on v6.18-rc5. If I were to pull this in, it gets a bit spaghetti like
in the merges.

  v6.18-rc5 -> pull1
  merge <- v6.18-rc7 <- pull2

Where now we have changes between rc5 and rc7.  Was there a reason you
based on top of rc7 and not use your last pull?

It's fine sending urgent patches this way, as these tags are in Linus's
tree and it's just new changes being added. But for a subsytem tree, it's
best not to pull in Linus's tree unless there's a good reason to do that.

What I can do is simply pull the patches on top of your last patch
directly, and keep the history clean for my pull request to Linus.

-- Steve


^ permalink raw reply

* Re: [PATCH v2 1/2] rv: Convert to use lock guard
From: Steven Rostedt @ 2025-12-02  1:38 UTC (permalink / raw)
  To: Gabriele Monaco
  Cc: Nam Cao, Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
	linux-kernel
In-Reply-To: <8f98932a8fa9c3e63c9a5cb7ba764e9db968bada.camel@redhat.com>

On Mon, 01 Dec 2025 16:28:21 +0100
Gabriele Monaco <gmonaco@redhat.com> wrote:

> I'm stupid, I sent it [1] but the script somehow didn't add you in the To: field
> and I didn't notice..
> 
> I'd say since the merge window is open, this change can wait.
> 
> Sorry for that.
> 
> Gabriele
> 
> [1] - https://lore.kernel.org/lkml/20251126152253.464350-1-gmonaco@redhat.com

I can still pull it and run it through my tests tonight and push it later this week.

It's just clean up code. Linus doesn't get too upset if simple cleanup code
gets added just before the merge window. It's new features that he doesn't
like added late in the game.

-- Steve

^ permalink raw reply

* Re: [PATCH v3 2/2] cpufreq: Documentation update for trace_policy_frequency
From: Tiffany Yang @ 2025-12-01 23:11 UTC (permalink / raw)
  To: 'Samuel Wu' via kernel-team
  Cc: Huang Rui, Gautham R. Shenoy, Mario Limonciello, Perry Yuan,
	Jonathan Corbet, Rafael J. Wysocki, Viresh Kumar, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Srinivas Pandruvada,
	Len Brown, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Ian Rogers,
	Adrian Hunter, James Clark, Samuel Wu, christian.loehle, linux-pm,
	linux-doc, linux-kernel, linux-trace-kernel, bpf,
	linux-perf-users
In-Reply-To: <20251201202437.3750901-3-wusamuel@google.com>

Hi Sam,

IMO this type of documentation should be in the same patch as the
related change because having a single commit makes it easier to track
(especially if/when these changes are cherry-picked to other
trees). There may be reasons to keep them separate that I'm not thinking
of, so if others disagree, defer to them!


"'Samuel Wu' via kernel-team" <kernel-team@android.com> writes:

> Documentation update corresponding to replace the cpu_frequency trace
> event with the policy_frequency trace event.

> Signed-off-by: Samuel Wu <wusamuel@google.com>
> ---
>   Documentation/admin-guide/pm/amd-pstate.rst   | 10 +++++-----
>   Documentation/admin-guide/pm/intel_pstate.rst | 14 +++++++-------
>   Documentation/trace/events-power.rst          |  2 +-
>   3 files changed, 13 insertions(+), 13 deletions(-)
<snip>

>   A suspend event is used to indicate the system going in and out of the
>   suspend mode:

Otherwise, this change lgtm.

-- 
Tiffany Y. Yang

^ permalink raw reply

* Re: [PATCH] tracing: Add system trigger file to enable triggers for all the system's events
From: Tom Zanussi @ 2025-12-01 22:56 UTC (permalink / raw)
  To: Steven Rostedt, LKML, Linux Trace Kernel
  Cc: Masami Hiramatsu, Mathieu Desnoyers
In-Reply-To: <20251126152404.21a8e3c9@gandalf.local.home>

Hi Steve,

On Wed, 2025-11-26 at 15:24 -0500, Steven Rostedt wrote:
> From: Steven Rostedt <rostedt@goodmis.org>
> 
> Currently a trigger can only be added to individual events. Some triggers
> (like stacktrace) can be useful to add as a bulk trigger for a set of
> system events (like interrupt or scheduling).
> 
> Add a trigger file to the system directories:
> 
>    /sys/kernel/tracing/events/*/trigger
> 
> And allow stacktrace trigger to be enabled for all those events.
> 
> Writing into the system/trigger file acts the same as writing into each of
> the system event's trigger files individually.
> 
> This also allows to remove a trigger from all events in a subsystem (even
> if it's not a subsystem trigger!).
> 

This looks very useful! Just a couple comments below..

> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> ---
> Changes since v2: https://patch.msgid.link/20251125200837.31aae207@gandalf.local.home
> 
> - Removed unneeded NULL initialization of tr (Masami Hiramatsu)
> 
> 
> 

[ ... ]

> +static ssize_t
> +event_system_trigger_write(struct file *filp, const char __user *ubuf,
> +		    size_t cnt, loff_t *ppos)
> +{
> +	struct trace_subsystem_dir *dir = filp->private_data;
> +	struct event_command *p;
> +	char *command, *next;
> +	char *buf __free(kfree) = get_user_buf(ubuf, cnt);

nit: I think you could move this up a couple lines and keep the reverse
Christmas tree.

> +	bool remove = false;
> +	bool found = false;
> +	ssize_t ret;
> +
> +	if (!buf)
> +		return 0;
> +
> +	if (IS_ERR(buf))
> +		return PTR_ERR(buf);
> +
> +	/* system triggers are not allowed to have counters */
> +	if (strchr(buf, ':'))
> +		return -EINVAL;
> +

As mentioned by Masami, I think this would preclude the hist triggers
from having this enabled.

I'm guessing you didn't see the hist commands as one of the triggers
that would be useful as system triggers, but there might be a couple
cases where they could be if using the common fields e.g.

echo hist:keys=common_pid.execname:vals=hitcount > events/syscalls/trigger 

or anywhere just

echo hist:keys=common_stacktrace > trigger

Just about everything else would error out, but these might be worth having.

Maybe you could just change this check to look for :<number> at the end of
the command?

Thanks,

Tom



^ permalink raw reply

* Re: [PATCH v2 2/3] unwind_user/fp: Use dummies instead of ifdef
From: Ingo Molnar @ 2025-12-01 20:30 UTC (permalink / raw)
  To: Jens Remus
  Cc: linux-kernel, linux-trace-kernel, x86, Steven Rostedt,
	Peter Zijlstra, Josh Poimboeuf, Thomas Gleixner, Borislav Petkov,
	Dave Hansen, H. Peter Anvin, Mathieu Desnoyers, Indu Bhagat,
	Jose E. Marchesi, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich
In-Reply-To: <20251201125416.1239568-3-jremus@linux.ibm.com>


* Jens Remus <jremus@linux.ibm.com> wrote:

> -#ifndef ARCH_INIT_USER_FP_FRAME
> - #define ARCH_INIT_USER_FP_FRAME
> +#ifndef CONFIG_HAVE_UNWIND_USER_FP
> +
> +#define ARCH_INIT_USER_FP_FRAME(ws)
> +
> +#endif /* !CONFIG_HAVE_UNWIND_USER_FP */

Just a nit, there's no need for the closing /* !.. */ 
comment for such a short CPP block - just like it's 
done in the next couple of lines:

> +#ifndef ARCH_INIT_USER_FP_ENTRY_FRAME
> +#define ARCH_INIT_USER_FP_ENTRY_FRAME(ws)
> +#endif

Thanks,

	Ingo

^ permalink raw reply

* [PATCH v3 2/2] cpufreq: Documentation update for trace_policy_frequency
From: Samuel Wu @ 2025-12-01 20:24 UTC (permalink / raw)
  To: Huang Rui, Gautham R. Shenoy, Mario Limonciello, Perry Yuan,
	Jonathan Corbet, Rafael J. Wysocki, Viresh Kumar, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Srinivas Pandruvada,
	Len Brown, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Ian Rogers,
	Adrian Hunter, James Clark
  Cc: christian.loehle, Samuel Wu, kernel-team, linux-pm, linux-doc,
	linux-kernel, linux-trace-kernel, bpf, linux-perf-users
In-Reply-To: <20251201202437.3750901-1-wusamuel@google.com>

Documentation update corresponding to replace the cpu_frequency trace
event with the policy_frequency trace event.

Signed-off-by: Samuel Wu <wusamuel@google.com>
---
 Documentation/admin-guide/pm/amd-pstate.rst   | 10 +++++-----
 Documentation/admin-guide/pm/intel_pstate.rst | 14 +++++++-------
 Documentation/trace/events-power.rst          |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/Documentation/admin-guide/pm/amd-pstate.rst b/Documentation/admin-guide/pm/amd-pstate.rst
index e1771f2225d5..e110854ece88 100644
--- a/Documentation/admin-guide/pm/amd-pstate.rst
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
@@ -503,8 +503,8 @@ Trace Events
 --------------
 
 There are two static trace events that can be used for ``amd-pstate``
-diagnostics. One of them is the ``cpu_frequency`` trace event generally used
-by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event
+diagnostics. One of them is the ``policy_frequency`` trace event generally
+used by ``CPUFreq``, and the other one is the ``amd_pstate_perf`` trace event
 specific to ``amd-pstate``.  The following sequence of shell commands can
 be used to enable them and see their output (if the kernel is
 configured to support event tracing). ::
@@ -531,9 +531,9 @@ configured to support event tracing). ::
           <idle>-0       [003] d.s..  4995.980971: amd_pstate_perf: amd_min_perf=85 amd_des_perf=85 amd_max_perf=166 cpu_id=3 changed=false fast_switch=true
           <idle>-0       [011] d.s..  4995.980996: amd_pstate_perf: amd_min_perf=85 amd_des_perf=85 amd_max_perf=166 cpu_id=11 changed=false fast_switch=true
 
-The ``cpu_frequency`` trace event will be triggered either by the ``schedutil`` scaling
-governor (for the policies it is attached to), or by the ``CPUFreq`` core (for the
-policies with other scaling governors).
+The ``policy_frequency`` trace event will be triggered either by the
+``schedutil`` scaling governor (for the policies it is attached to), or by the
+``CPUFreq`` core (for the policies with other scaling governors).
 
 
 Tracer Tool
diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst
index fde967b0c2e0..274c9208f342 100644
--- a/Documentation/admin-guide/pm/intel_pstate.rst
+++ b/Documentation/admin-guide/pm/intel_pstate.rst
@@ -822,23 +822,23 @@ Trace Events
 ------------
 
 There are two static trace events that can be used for ``intel_pstate``
-diagnostics.  One of them is the ``cpu_frequency`` trace event generally used
-by ``CPUFreq``, and the other one is the ``pstate_sample`` trace event specific
-to ``intel_pstate``.  Both of them are triggered by ``intel_pstate`` only if
-it works in the :ref:`active mode <active_mode>`.
+diagnostics.  One of them is the ``policy_frequency`` trace event generally
+used by ``CPUFreq``, and the other one is the ``pstate_sample`` trace event
+specific to ``intel_pstate``.  Both of them are triggered by ``intel_pstate``
+only if it works in the :ref:`active mode <active_mode>`.
 
 The following sequence of shell commands can be used to enable them and see
 their output (if the kernel is generally configured to support event tracing)::
 
  # cd /sys/kernel/tracing/
  # echo 1 > events/power/pstate_sample/enable
- # echo 1 > events/power/cpu_frequency/enable
+ # echo 1 > events/power/policy_frequency/enable
  # cat trace
  gnome-terminal--4510  [001] ..s.  1177.680733: pstate_sample: core_busy=107 scaled=94 from=26 to=26 mperf=1143818 aperf=1230607 tsc=29838618 freq=2474476
- cat-5235  [002] ..s.  1177.681723: cpu_frequency: state=2900000 cpu_id=2
+ cat-5235  [002] ..s.  1177.681723: policy_frequency: state=2900000 cpu_id=2 policy_cpus=04
 
 If ``intel_pstate`` works in the :ref:`passive mode <passive_mode>`, the
-``cpu_frequency`` trace event will be triggered either by the ``schedutil``
+``policy_frequency`` trace event will be triggered either by the ``schedutil``
 scaling governor (for the policies it is attached to), or by the ``CPUFreq``
 core (for the policies with other scaling governors).
 
diff --git a/Documentation/trace/events-power.rst b/Documentation/trace/events-power.rst
index f45bf11fa88d..f013c74b932f 100644
--- a/Documentation/trace/events-power.rst
+++ b/Documentation/trace/events-power.rst
@@ -26,8 +26,8 @@ cpufreq.
 ::
 
   cpu_idle		"state=%lu cpu_id=%lu"
-  cpu_frequency		"state=%lu cpu_id=%lu"
   cpu_frequency_limits	"min=%lu max=%lu cpu_id=%lu"
+  policy_frequency	"state=%lu cpu_id=%lu policy_cpus=%*pb"
 
 A suspend event is used to indicate the system going in and out of the
 suspend mode:
-- 
2.52.0.107.ga0afd4fd5b-goog


^ permalink raw reply related

* [PATCH v3 1/2] cpufreq: Replace trace_cpu_frequency with trace_policy_frequency
From: Samuel Wu @ 2025-12-01 20:24 UTC (permalink / raw)
  To: Huang Rui, Gautham R. Shenoy, Mario Limonciello, Perry Yuan,
	Jonathan Corbet, Rafael J. Wysocki, Viresh Kumar, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Srinivas Pandruvada,
	Len Brown, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Ian Rogers,
	Adrian Hunter, James Clark
  Cc: christian.loehle, Samuel Wu, kernel-team, linux-pm, linux-doc,
	linux-kernel, linux-trace-kernel, bpf, linux-perf-users
In-Reply-To: <20251201202437.3750901-1-wusamuel@google.com>

The existing cpu_frequency trace_event can be verbose, emitting a nearly
identical trace event for every CPU in the policy even when their
frequencies are identical.

This patch replaces the cpu_frequency trace event with policy_frequency
trace event, a more efficient alternative. From the kernel's
perspective, emitting a trace event once per policy instead of once per
cpu saves some memory and is less overhead. From the post-processing
perspective, analysis of the trace log is simplified without any loss of
information.

Signed-off-by: Samuel Wu <wusamuel@google.com>
---
 drivers/cpufreq/cpufreq.c      | 14 ++------------
 drivers/cpufreq/intel_pstate.c |  6 ++++--
 include/trace/events/power.h   | 24 +++++++++++++++++++++---
 kernel/trace/power-traces.c    |  2 +-
 samples/bpf/cpustat_kern.c     |  8 ++++----
 samples/bpf/cpustat_user.c     |  6 +++---
 tools/perf/builtin-timechart.c | 12 ++++++------
 7 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 4472bb1ec83c..dd3f08f3b958 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -309,8 +309,6 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy,
 				      struct cpufreq_freqs *freqs,
 				      unsigned int state)
 {
-	int cpu;
-
 	BUG_ON(irqs_disabled());
 
 	if (cpufreq_disabled())
@@ -344,10 +342,7 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy,
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
 		pr_debug("FREQ: %u - CPUs: %*pbl\n", freqs->new,
 			 cpumask_pr_args(policy->cpus));
-
-		for_each_cpu(cpu, policy->cpus)
-			trace_cpu_frequency(freqs->new, cpu);
-
+		trace_policy_frequency(freqs->new, policy->cpu, policy->cpus);
 		srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
 					 CPUFREQ_POSTCHANGE, freqs);
 
@@ -2201,7 +2196,6 @@ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
 					unsigned int target_freq)
 {
 	unsigned int freq;
-	int cpu;
 
 	target_freq = clamp_val(target_freq, policy->min, policy->max);
 	freq = cpufreq_driver->fast_switch(policy, target_freq);
@@ -2213,11 +2207,7 @@ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
 	arch_set_freq_scale(policy->related_cpus, freq,
 			    arch_scale_freq_ref(policy->cpu));
 	cpufreq_stats_record_transition(policy, freq);
-
-	if (trace_cpu_frequency_enabled()) {
-		for_each_cpu(cpu, policy->cpus)
-			trace_cpu_frequency(freq, cpu);
-	}
+	trace_policy_frequency(freq, policy->cpu, policy->cpus);
 
 	return freq;
 }
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index ec4abe374573..9724b5d19d83 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -2297,7 +2297,8 @@ static int hwp_get_cpu_scaling(int cpu)
 
 static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
 {
-	trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
+	trace_policy_frequency(pstate * cpu->pstate.scaling, cpu->cpu,
+			       cpumask_of(cpu->cpu));
 	cpu->pstate.current_pstate = pstate;
 	/*
 	 * Generally, there is no guarantee that this code will always run on
@@ -2587,7 +2588,8 @@ static void intel_pstate_adjust_pstate(struct cpudata *cpu)
 
 	target_pstate = get_target_pstate(cpu);
 	target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
-	trace_cpu_frequency(target_pstate * cpu->pstate.scaling, cpu->cpu);
+	trace_policy_frequency(target_pstate * cpu->pstate.scaling, cpu->cpu,
+			       cpumask_of(cpu->cpu));
 	intel_pstate_update_pstate(cpu, target_pstate);
 
 	sample = &cpu->sample;
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index 370f8df2fdb4..317098ffdd5f 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -182,11 +182,29 @@ TRACE_EVENT(pstate_sample,
 		{ PM_EVENT_RECOVER, "recover" }, \
 		{ PM_EVENT_POWEROFF, "poweroff" })
 
-DEFINE_EVENT(cpu, cpu_frequency,
+TRACE_EVENT(policy_frequency,
 
-	TP_PROTO(unsigned int frequency, unsigned int cpu_id),
+	TP_PROTO(unsigned int frequency, unsigned int cpu_id,
+		 const struct cpumask *policy_cpus),
 
-	TP_ARGS(frequency, cpu_id)
+	TP_ARGS(frequency, cpu_id, policy_cpus),
+
+	TP_STRUCT__entry(
+		__field(u32, state)
+		__field(u32, cpu_id)
+		__cpumask(cpumask)
+	),
+
+	TP_fast_assign(
+		__entry->state = frequency;
+		__entry->cpu_id = cpu_id;
+		__assign_cpumask(cpumask, policy_cpus);
+	),
+
+	TP_printk("state=%lu cpu_id=%lu policy_cpus=%*pb",
+		  (unsigned long)__entry->state,
+		  (unsigned long)__entry->cpu_id,
+		  cpumask_pr_args((struct cpumask *)__get_dynamic_array(cpumask)))
 );
 
 TRACE_EVENT(cpu_frequency_limits,
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c
index f2fe33573e54..a537e68a6878 100644
--- a/kernel/trace/power-traces.c
+++ b/kernel/trace/power-traces.c
@@ -16,5 +16,5 @@
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(suspend_resume);
 EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle);
-EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_frequency);
+EXPORT_TRACEPOINT_SYMBOL_GPL(policy_frequency);
 
diff --git a/samples/bpf/cpustat_kern.c b/samples/bpf/cpustat_kern.c
index 7ec7143e2757..f485de0f89b2 100644
--- a/samples/bpf/cpustat_kern.c
+++ b/samples/bpf/cpustat_kern.c
@@ -75,9 +75,9 @@ struct {
 } pstate_duration SEC(".maps");
 
 /*
- * The trace events for cpu_idle and cpu_frequency are taken from:
+ * The trace events for cpu_idle and policy_frequency are taken from:
  * /sys/kernel/tracing/events/power/cpu_idle/format
- * /sys/kernel/tracing/events/power/cpu_frequency/format
+ * /sys/kernel/tracing/events/power/policy_frequency/format
  *
  * These two events have same format, so define one common structure.
  */
@@ -162,7 +162,7 @@ int bpf_prog1(struct cpu_args *ctx)
 	 */
 	if (ctx->state != (u32)-1) {
 
-		/* record pstate after have first cpu_frequency event */
+		/* record pstate after have first policy_frequency event */
 		if (!*pts)
 			return 0;
 
@@ -208,7 +208,7 @@ int bpf_prog1(struct cpu_args *ctx)
 	return 0;
 }
 
-SEC("tracepoint/power/cpu_frequency")
+SEC("tracepoint/power/policy_frequency")
 int bpf_prog2(struct cpu_args *ctx)
 {
 	u64 *pts, *cstate, *pstate, cur_ts, delta;
diff --git a/samples/bpf/cpustat_user.c b/samples/bpf/cpustat_user.c
index 356f756cba0d..f7e81f702358 100644
--- a/samples/bpf/cpustat_user.c
+++ b/samples/bpf/cpustat_user.c
@@ -143,12 +143,12 @@ static int cpu_stat_inject_cpu_idle_event(void)
 
 /*
  * It's possible to have no any frequency change for long time and cannot
- * get ftrace event 'trace_cpu_frequency' for long period, this introduces
+ * get ftrace event 'trace_policy_frequency' for long period, this introduces
  * big deviation for pstate statistics.
  *
  * To solve this issue, below code forces to set 'scaling_max_freq' to 208MHz
- * for triggering ftrace event 'trace_cpu_frequency' and then recovery back to
- * the maximum frequency value 1.2GHz.
+ * for triggering ftrace event 'trace_policy_frequency' and then recovery back
+ * to the maximum frequency value 1.2GHz.
  */
 static int cpu_stat_inject_cpu_frequency_event(void)
 {
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 22050c640dfa..3ef1a2fd0493 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -612,10 +612,10 @@ process_sample_cpu_idle(struct timechart *tchart __maybe_unused,
 }
 
 static int
-process_sample_cpu_frequency(struct timechart *tchart,
-			     struct evsel *evsel,
-			     struct perf_sample *sample,
-			     const char *backtrace __maybe_unused)
+process_sample_policy_frequency(struct timechart *tchart,
+				struct evsel *evsel,
+				struct perf_sample *sample,
+				const char *backtrace __maybe_unused)
 {
 	u32 state  = evsel__intval(evsel, sample, "state");
 	u32 cpu_id = evsel__intval(evsel, sample, "cpu_id");
@@ -1541,7 +1541,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
 {
 	const struct evsel_str_handler power_tracepoints[] = {
 		{ "power:cpu_idle",		process_sample_cpu_idle },
-		{ "power:cpu_frequency",	process_sample_cpu_frequency },
+		{ "power:policy_frequency",	process_sample_policy_frequency },
 		{ "sched:sched_wakeup",		process_sample_sched_wakeup },
 		{ "sched:sched_switch",		process_sample_sched_switch },
 #ifdef SUPPORT_OLD_POWER_EVENTS
@@ -1804,7 +1804,7 @@ static int timechart__record(struct timechart *tchart, int argc, const char **ar
 	unsigned int backtrace_args_no = ARRAY_SIZE(backtrace_args);
 
 	const char * const power_args[] = {
-		"-e", "power:cpu_frequency",
+		"-e", "power:policy_frequency",
 		"-e", "power:cpu_idle",
 	};
 	unsigned int power_args_nr = ARRAY_SIZE(power_args);
-- 
2.52.0.107.ga0afd4fd5b-goog


^ permalink raw reply related

* [PATCH v3 0/2] Replace trace_cpu_frequency with trace_policy_frequency
From: Samuel Wu @ 2025-12-01 20:24 UTC (permalink / raw)
  To: Huang Rui, Gautham R. Shenoy, Mario Limonciello, Perry Yuan,
	Jonathan Corbet, Rafael J. Wysocki, Viresh Kumar, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Srinivas Pandruvada,
	Len Brown, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
	Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Ian Rogers,
	Adrian Hunter, James Clark
  Cc: christian.loehle, Samuel Wu, kernel-team, linux-pm, linux-doc,
	linux-kernel, linux-trace-kernel, bpf, linux-perf-users

This series replaces the cpu_frequency trace event with a new trace event,
policy_frequency. Since by definition all CPUs in a policy are of the same
frequency, we can emit a frequency change per policy instead of per CPU.
This saves some compute and memory from the kernel side, while simplifying
analysis from the post-processing of the trace log side.

Any process that relied on cpu_frequency trace event needs to switch to the
new policy_frequency trace event in order to maintain functionality. The
decision of replacing instead of adding the trace event is intentional. Since
emitting once per policy instead of once per CPU is anyways a semantics change
that would require a tooling update, the trace event was also appropriately
renamed. The presence of the policy_frequency event in a trace log is a clear
and obvious signal for tooling to determine kernel version and which trace
event to parse.

1/2: Replaces trace_cpu_frequency with trace_policy_frequency
2/2: Corresponding documentation patch that updates references to
     cpu_frequency with policy_frequency

Changes in v3:
- Resending v2 properly (accidentally ommited cover letter in v2)

Changes in v2:
- Replaced trace_cpu_frequency with trace_policy_frequency (per Christian
  and Viresh)
- Updated references to cpu_frequency in documentation with
  policy_frequency
- v1 link: https://lore.kernel.org/all/20251112235154.2974902-1-wusamuel@google.com

Samuel Wu (2):
  cpufreq: Replace trace_cpu_frequency with trace_policy_frequency
  cpufreq: Documentation update for trace_policy_frequency

 Documentation/admin-guide/pm/amd-pstate.rst   | 10 ++++----
 Documentation/admin-guide/pm/intel_pstate.rst | 14 +++++------
 Documentation/trace/events-power.rst          |  2 +-
 drivers/cpufreq/cpufreq.c                     | 14 ++---------
 drivers/cpufreq/intel_pstate.c                |  6 +++--
 include/trace/events/power.h                  | 24 ++++++++++++++++---
 kernel/trace/power-traces.c                   |  2 +-
 samples/bpf/cpustat_kern.c                    |  8 +++----
 samples/bpf/cpustat_user.c                    |  6 ++---
 tools/perf/builtin-timechart.c                | 12 +++++-----
 10 files changed, 54 insertions(+), 44 deletions(-)

-- 
2.52.0.107.ga0afd4fd5b-goog


^ permalink raw reply


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