* Re: [PATCH v3 0/7] kallsyms: Prevent invalid access when showing module buildid
From: Petr Mladek @ 2025-12-16 14:00 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Alexei Starovoitov, Andrew Morton,
Kees Cook
Cc: Aaron Tomlin, Daniel Borkmann, John Fastabend, Masami Hiramatsu,
Mark Rutland, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
linux-kernel, bpf, linux-modules, linux-trace-kernel
In-Reply-To: <20251128135920.217303-1-pmladek@suse.com>
Hi,
I wonder who could take this patchset.
IMHO, the failed test report is bogus. The system went out of memory.
Anyway, the info provided by the mail is not enough for debugging.
IMHO. this patchset is ready for linux-next. Unfortunately, kallsyms
do not have any dedicated maintainer. I though about Kees (hardening)
or Andrew (core stuff). Or I could take it via printk tree.
Best Regards,
Petr
On Fri 2025-11-28 14:59:13, Petr Mladek wrote:
> This patchset is cleaning up kallsyms code related to module buildid.
> It is fixing an invalid access when printing backtraces, see [v1] for
> more details:
>
> + 1st..4th patches are preparatory.
>
> + 5th and 6th patches are fixing bpf and ftrace related APIs.
>
> + 7th patch prevents a potential race.
>
>
> Changes against [v2]:
>
> + Fixed typos in commit message [Alexei]
>
> + Added Acks [Alexei]
>
>
> Changes against [v1]:
>
> + Added existing Reviewed-by tags.
>
> + Shuffled patches to update the kallsyms_lookup_buildid() initialization
> code 1st.
>
> + Initialized also *modname and *modbuildid in kallsyms_lookup_buildid().
>
> + Renamed __bpf_address_lookup() to bpf_address_lookup() and used it
> in kallsyms_lookup_buildid(). Did this instead of passing @modbuildid
> parameter just to clear it.
>
>
> [v1] https://lore.kernel.org/r/20251105142319.1139183-1-pmladek@suse.com
> [v2] https://lore.kernel.org/r/20251112142003.182062-1-pmladek@suse.com
>
>
> Petr Mladek (7):
> kallsyms: Clean up @namebuf initialization in
> kallsyms_lookup_buildid()
> kallsyms: Clean up modname and modbuildid initialization in
> kallsyms_lookup_buildid()
> module: Add helper function for reading module_buildid()
> kallsyms: Cleanup code for appending the module buildid
> kallsyms/bpf: Rename __bpf_address_lookup() to bpf_address_lookup()
> kallsyms/ftrace: Set module buildid in ftrace_mod_address_lookup()
> kallsyms: Prevent module removal when printing module name and buildid
>
> arch/arm64/net/bpf_jit_comp.c | 2 +-
> arch/powerpc/net/bpf_jit_comp.c | 2 +-
> include/linux/filter.h | 26 ++----------
> include/linux/ftrace.h | 6 ++-
> include/linux/module.h | 9 ++++
> kernel/bpf/core.c | 4 +-
> kernel/kallsyms.c | 73 ++++++++++++++++++++++++---------
> kernel/module/kallsyms.c | 9 +---
> kernel/trace/ftrace.c | 5 ++-
> 9 files changed, 81 insertions(+), 55 deletions(-)
>
> --
> 2.52.0
^ permalink raw reply
* [PATCH 3/3] mm/khugepaged: make khugepaged_collapse_control static
From: Shivank Garg @ 2025-12-16 11:11 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, linux-mm, linux-kernel,
linux-trace-kernel, shivankg
In-Reply-To: <20251216111139.95438-2-shivankg@amd.com>
The global variable 'khugepaged_collapse_control' is not used outside of
mm/khugepaged.c. Make it static to limit its scope.
Signed-off-by: Shivank Garg <shivankg@amd.com>
---
mm/khugepaged.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 65b1b778378a..d130357a2d88 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -829,7 +829,7 @@ static void khugepaged_alloc_sleep(void)
remove_wait_queue(&khugepaged_wait, &wait);
}
-struct collapse_control khugepaged_collapse_control = {
+static struct collapse_control khugepaged_collapse_control = {
.is_khugepaged = true,
};
--
2.43.0
^ permalink raw reply related
* [PATCH 2/3] mm/khugepaged: use enum scan_result for result variables
From: Shivank Garg @ 2025-12-16 11:11 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, linux-mm, linux-kernel,
linux-trace-kernel, shivankg
In-Reply-To: <20251216111139.95438-2-shivankg@amd.com>
Use enum scan_result for local variables and the result pointer in
khugepaged_scan_mm_slot(), instead of plain int. This improves code
readability and clarifies intent,
No functional change.
Signed-off-by: Shivank Garg <shivankg@amd.com>
---
mm/khugepaged.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 107146f012b1..65b1b778378a 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -547,7 +547,8 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
struct folio *folio = NULL;
unsigned long addr = start_addr;
pte_t *_pte;
- int none_or_zero = 0, shared = 0, result = SCAN_FAIL, referenced = 0;
+ int none_or_zero = 0, shared = 0, referenced = 0;
+ enum scan_result result = SCAN_FAIL;
for (_pte = pte; _pte < pte + HPAGE_PMD_NR;
_pte++, addr += PAGE_SIZE) {
@@ -786,7 +787,7 @@ static int __collapse_huge_page_copy(pte_t *pte, struct folio *folio,
struct list_head *compound_pagelist)
{
unsigned int i;
- int result = SCAN_SUCCEED;
+ enum scan_result result = SCAN_SUCCEED;
/*
* Copying pages' contents is subject to memory poison at any iteration.
@@ -969,7 +970,7 @@ static int check_pmd_still_valid(struct mm_struct *mm,
pmd_t *pmd)
{
pmd_t *new_pmd;
- int result = find_pmd_or_thp_or_none(mm, address, &new_pmd);
+ enum scan_result result = find_pmd_or_thp_or_none(mm, address, &new_pmd);
if (result != SCAN_SUCCEED)
return result;
@@ -993,7 +994,7 @@ static int __collapse_huge_page_swapin(struct mm_struct *mm,
int swapped_in = 0;
vm_fault_t ret = 0;
unsigned long addr, end = start_addr + (HPAGE_PMD_NR * PAGE_SIZE);
- int result;
+ enum scan_result result;
pte_t *pte = NULL;
spinlock_t *ptl;
@@ -1100,7 +1101,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
pgtable_t pgtable;
struct folio *folio;
spinlock_t *pmd_ptl, *pte_ptl;
- int result = SCAN_FAIL;
+ enum scan_result result = SCAN_FAIL;
struct vm_area_struct *vma;
struct mmu_notifier_range range;
@@ -1253,8 +1254,8 @@ static int hpage_collapse_scan_pmd(struct mm_struct *mm,
{
pmd_t *pmd;
pte_t *pte, *_pte;
- int result = SCAN_FAIL, referenced = 0;
- int none_or_zero = 0, shared = 0;
+ int none_or_zero = 0, shared = 0, referenced = 0;
+ enum scan_result result = SCAN_FAIL;
struct page *page = NULL;
struct folio *folio = NULL;
unsigned long addr;
@@ -1492,7 +1493,8 @@ static int set_huge_pmd(struct vm_area_struct *vma, unsigned long addr,
int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
bool install_pmd)
{
- int nr_mapped_ptes = 0, result = SCAN_FAIL;
+ enum scan_result result = SCAN_FAIL;
+ int nr_mapped_ptes = 0;
unsigned int nr_batch_ptes;
struct mmu_notifier_range range;
bool notified = false;
@@ -1866,7 +1868,8 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr,
pgoff_t index = 0, end = start + HPAGE_PMD_NR;
LIST_HEAD(pagelist);
XA_STATE_ORDER(xas, &mapping->i_pages, start, HPAGE_PMD_ORDER);
- int nr_none = 0, result = SCAN_SUCCEED;
+ enum scan_result result = SCAN_SUCCEED;
+ int nr_none = 0;
bool is_shmem = shmem_file(file);
VM_BUG_ON(!IS_ENABLED(CONFIG_READ_ONLY_THP_FOR_FS) && !is_shmem);
@@ -2296,7 +2299,7 @@ static int hpage_collapse_scan_file(struct mm_struct *mm, unsigned long addr,
XA_STATE(xas, &mapping->i_pages, start);
int present, swap;
int node = NUMA_NO_NODE;
- int result = SCAN_SUCCEED;
+ enum scan_result result = SCAN_SUCCEED;
present = 0;
swap = 0;
@@ -2394,7 +2397,7 @@ static int hpage_collapse_scan_file(struct mm_struct *mm, unsigned long addr,
return result;
}
-static unsigned int khugepaged_scan_mm_slot(unsigned int pages, int *result,
+static unsigned int khugepaged_scan_mm_slot(unsigned int pages, enum scan_result *result,
struct collapse_control *cc)
__releases(&khugepaged_mm_lock)
__acquires(&khugepaged_mm_lock)
@@ -2555,7 +2558,7 @@ static void khugepaged_do_scan(struct collapse_control *cc)
unsigned int progress = 0, pass_through_head = 0;
unsigned int pages = READ_ONCE(khugepaged_pages_to_scan);
bool wait = true;
- int result = SCAN_SUCCEED;
+ enum scan_result result = SCAN_SUCCEED;
lru_add_drain_all();
@@ -2790,7 +2793,7 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start,
for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
bool retried = false;
- int result = SCAN_FAIL;
+ enum scan_result result = SCAN_FAIL;
if (!mmap_locked) {
retry:
--
2.43.0
^ permalink raw reply related
* [PATCH 1/3] mm/khugepaged: remove unnecessary goto 'skip' label
From: Shivank Garg @ 2025-12-16 11:11 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, linux-mm, linux-kernel,
linux-trace-kernel, shivankg
In-Reply-To: <20251216111139.95438-2-shivankg@amd.com>
Replace 'goto skip' with actual logic for better code readability.
No functional change.
Signed-off-by: Shivank Garg <shivankg@amd.com>
---
mm/khugepaged.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 6c8c35d3e0c9..107146f012b1 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2442,14 +2442,15 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, int *result,
break;
}
if (!thp_vma_allowable_order(vma, vma->vm_flags, TVA_KHUGEPAGED, PMD_ORDER)) {
-skip:
progress++;
continue;
}
hstart = round_up(vma->vm_start, HPAGE_PMD_SIZE);
hend = round_down(vma->vm_end, HPAGE_PMD_SIZE);
- if (khugepaged_scan.address > hend)
- goto skip;
+ if (khugepaged_scan.address > hend) {
+ progress++;
+ continue;
+ }
if (khugepaged_scan.address < hstart)
khugepaged_scan.address = hstart;
VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);
--
2.43.0
^ permalink raw reply related
* [PATCH 0/3] mm/khugepaged: minor cleanups
From: Shivank Garg @ 2025-12-16 11:11 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes
Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Lance Yang, linux-mm, linux-kernel,
linux-trace-kernel, shivankg
This small series contains minor cleanups in mm/khugepaged and
no functional changes are intended.
Thanks,
Shivank Garg (3):
mm/khugepaged: remove unnecessary goto 'skip' label
mm/khugepaged: use enum scan_result for result variables
mm/khugepaged: make khugepaged_collapse_control static
mm/khugepaged.c | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)
base-commit: c642ecda5b136882e518d8303863473c0d21ab2f
--
2.43.0
^ permalink raw reply
* Re: [PATCH v2 2/2] mm: Remove tlb_flush_reason::NR_TLB_FLUSH_REASONS
From: Lorenzo Stoakes @ 2025-12-16 10:32 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: Tal Zussman, Steven Rostedt, Masami Hiramatsu, Ingo Molnar,
Rik van Riel, Andrew Morton, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, x86, Will Deacon,
Aneesh Kumar K.V, Nick Piggin, Peter Zijlstra, David Hildenbrand,
linux-kernel, linux-trace-kernel, linux-mm, linux-arch
In-Reply-To: <c754c406-2816-4b70-a4a8-7a11b9ec45d3@efficios.com>
On Mon, Dec 15, 2025 at 08:35:58AM -0500, Mathieu Desnoyers wrote:
> On 2025-12-15 07:40, Lorenzo Stoakes wrote:
> > On Fri, Dec 12, 2025 at 04:08:08AM -0500, Tal Zussman wrote:
> > > This has been unused since it was added 11 years ago in commit
> > > d17d8f9dedb9 ("x86/mm: Add tracepoints for TLB flushes").
> > >
> > > Acked-by: David Hildenbrand <david@redhat.com>
> > > Reviewed-by: Rik van Riel <riel@surriel.com>
> > > Signed-off-by: Tal Zussman <tz2294@columbia.edu>
> >
> > Hmm, guess just a way of counting the number of reasons, but if nobody's using
> > it that's silly. So:
>
> If TRACE_DEFINE_ENUM was implemented differently [1,2], then we could use
> NR_TLB_FLUSH_REASONS in a static assert to validate that the number of
> exported enum labels matches the enum tlb_flush_reason.
>
> This would catch this kind of discrepancy at compile-time.
Sure, but for the time being this isn't being used, so dead code -> yoink!
We can obviously come back to this as necessary.
>
> Thanks,
>
> Mathieu
>
> [1] https://github.com/lttng/lttng-modules/blob/master/include/instrumentation/events/sched.h#L132
> [2] https://github.com/lttng/lttng-modules/blob/master/include/lttng/tracepoint-event-impl.h#L176
>
> >
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> https://www.efficios.com
Cheers, Lorenzo
^ permalink raw reply
* [PATCH v3 4/4] LoongArch: ftrace: Adjust register stack restore order in direct call trampolines
From: Chenghao Duan @ 2025-12-16 9:47 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel, Youling Tang
In-Reply-To: <20251216094753.1317231-1-duanchenghao@kylinos.cn>
Ensure that in the ftrace direct call logic, the CPU register state
(with ra = parent return address) is restored to the correct state
after the execution of the custom trampoline function and before
returning to the traced function. Additionally, guarantee the
correctness of the jump logic for jr t0 (traced function address).
Reported-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
samples/ftrace/ftrace-direct-modify.c | 8 ++++----
samples/ftrace/ftrace-direct-multi-modify.c | 8 ++++----
samples/ftrace/ftrace-direct-multi.c | 4 ++--
samples/ftrace/ftrace-direct-too.c | 4 ++--
samples/ftrace/ftrace-direct.c | 4 ++--
5 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-direct-modify.c
index da3a9f2091f5..1ba1927b548e 100644
--- a/samples/ftrace/ftrace-direct-modify.c
+++ b/samples/ftrace/ftrace-direct-modify.c
@@ -176,8 +176,8 @@ asm (
" st.d $t0, $sp, 0\n"
" st.d $ra, $sp, 8\n"
" bl my_direct_func1\n"
-" ld.d $t0, $sp, 0\n"
-" ld.d $ra, $sp, 8\n"
+" ld.d $ra, $sp, 0\n"
+" ld.d $t0, $sp, 8\n"
" addi.d $sp, $sp, 16\n"
" jr $t0\n"
" .size my_tramp1, .-my_tramp1\n"
@@ -189,8 +189,8 @@ asm (
" st.d $t0, $sp, 0\n"
" st.d $ra, $sp, 8\n"
" bl my_direct_func2\n"
-" ld.d $t0, $sp, 0\n"
-" ld.d $ra, $sp, 8\n"
+" ld.d $ra, $sp, 0\n"
+" ld.d $t0, $sp, 8\n"
" addi.d $sp, $sp, 16\n"
" jr $t0\n"
" .size my_tramp2, .-my_tramp2\n"
diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/ftrace-direct-multi-modify.c
index 8f7986d698d8..7a7822dfeb50 100644
--- a/samples/ftrace/ftrace-direct-multi-modify.c
+++ b/samples/ftrace/ftrace-direct-multi-modify.c
@@ -199,8 +199,8 @@ asm (
" move $a0, $t0\n"
" bl my_direct_func1\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp1, .-my_tramp1\n"
@@ -215,8 +215,8 @@ asm (
" move $a0, $t0\n"
" bl my_direct_func2\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp2, .-my_tramp2\n"
diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-direct-multi.c
index db326c81a27d..3fe6ddaf0b69 100644
--- a/samples/ftrace/ftrace-direct-multi.c
+++ b/samples/ftrace/ftrace-direct-multi.c
@@ -131,8 +131,8 @@ asm (
" move $a0, $t0\n"
" bl my_direct_func\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp, .-my_tramp\n"
diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-direct-too.c
index 3d0fa260332d..bf2411aa6fd7 100644
--- a/samples/ftrace/ftrace-direct-too.c
+++ b/samples/ftrace/ftrace-direct-too.c
@@ -143,8 +143,8 @@ asm (
" ld.d $a0, $sp, 0\n"
" ld.d $a1, $sp, 8\n"
" ld.d $a2, $sp, 16\n"
-" ld.d $t0, $sp, 24\n"
-" ld.d $ra, $sp, 32\n"
+" ld.d $ra, $sp, 24\n"
+" ld.d $t0, $sp, 32\n"
" addi.d $sp, $sp, 48\n"
" jr $t0\n"
" .size my_tramp, .-my_tramp\n"
diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c
index 956834b0d19a..5368c8c39cbb 100644
--- a/samples/ftrace/ftrace-direct.c
+++ b/samples/ftrace/ftrace-direct.c
@@ -124,8 +124,8 @@ asm (
" st.d $ra, $sp, 16\n"
" bl my_direct_func\n"
" ld.d $a0, $sp, 0\n"
-" ld.d $t0, $sp, 8\n"
-" ld.d $ra, $sp, 16\n"
+" ld.d $ra, $sp, 8\n"
+" ld.d $t0, $sp, 16\n"
" addi.d $sp, $sp, 32\n"
" jr $t0\n"
" .size my_tramp, .-my_tramp\n"
--
2.25.1
^ permalink raw reply related
* [PATCH v3 3/4] LoongArch: BPF: Enhance trampoline support for kernel and module tracing
From: Chenghao Duan @ 2025-12-16 9:47 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251216094753.1317231-1-duanchenghao@kylinos.cn>
This patch addresses two main issues in the LoongArch BPF trampoline
implementation:
1. BPF-to-BPF call handling:
- Modify the build_prologue function to ensure that the value of the
return address register ra is saved to t0 before entering the
trampoline operation.
- This ensures that the return address handling logic is accurate and
error-free when a BPF program calls another BPF program.
2. Enable Module Function Tracing Support:
- Remove the previous restrictions that blocked the tracing of kernel
module functions.
- Fix the issue that previously caused kernel lockups when attempting
to trace module functions
3. Related Function Optimizations:
- Adjust the jump offset of tail calls to ensure correct instruction
alignment.
- Enhance the bpf_arch_text_poke() function to enable accurate location
of BPF program entry points.
- Refine the trampoline return logic to ensure that the register data
is correct when returning to both the traced function and the parent
function.
After applying the current patch series, the following selftests/bpf
test cases all pass:
./test_progs -t module_attach
./test_progs -t module_fentry_shadow
./test_progs -t subprogs
./test_progs -t subprogs_extable
./test_progs -t tailcalls
./test_progs -t struct_ops -d struct_ops_multi_pages
./test_progs -t fexit_bpf2bpf
./test_progs -t fexit_stress
./test_progs -t fentry_test/fentry
./test_progs -t fexit_test/fexit
./test_progs -t fentry_fexit
./test_progs -t modify_return
./test_progs -t fexit_sleep
./test_progs -t trampoline_count
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/net/bpf_jit.c | 38 +++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 8dc58781b8eb..0c16a1b18e8f 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -139,6 +139,7 @@ static void build_prologue(struct jit_ctx *ctx)
stack_adjust = round_up(stack_adjust, 16);
stack_adjust += bpf_stack_adjust;
+ move_reg(ctx, LOONGARCH_GPR_T0, LOONGARCH_GPR_RA);
/* Reserve space for the move_imm + jirl instruction */
for (i = 0; i < LOONGARCH_LONG_JUMP_NINSNS; i++)
emit_insn(ctx, nop);
@@ -238,7 +239,7 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)
* Call the next bpf prog and skip the first instruction
* of TCC initialization.
*/
- emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 6);
+ emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 7);
}
}
@@ -1265,7 +1266,7 @@ static int emit_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call)
return 0;
}
- return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_T0 : LOONGARCH_GPR_ZERO, (u64)target);
+ return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_RA : LOONGARCH_GPR_ZERO, (u64)target);
}
static int emit_call(struct jit_ctx *ctx, u64 addr)
@@ -1289,6 +1290,10 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
void *new_addr)
{
int ret;
+ unsigned long size = 0;
+ unsigned long offset = 0;
+ char namebuf[KSYM_NAME_LEN];
+ void *image = NULL;
bool is_call;
u32 old_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP};
u32 new_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP};
@@ -1296,9 +1301,18 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
/* Only poking bpf text is supported. Since kernel function entry
* is set up by ftrace, we rely on ftrace to poke kernel functions.
*/
- if (!is_bpf_text_address((unsigned long)ip))
+ if (!__bpf_address_lookup((unsigned long)ip, &size, &offset, namebuf))
return -ENOTSUPP;
+ image = ip - offset;
+ /* zero offset means we're poking bpf prog entry */
+ if (offset == 0)
+ /* skip to the nop instruction in bpf prog entry:
+ * move t0, ra
+ * nop
+ */
+ ip = image + LOONGARCH_INSN_SIZE;
+
is_call = old_t == BPF_MOD_CALL;
ret = emit_jump_or_nops(old_addr, ip, old_insns, is_call);
if (ret)
@@ -1622,14 +1636,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
/* To traced function */
/* Ftrace jump skips 2 NOP instructions */
- if (is_kernel_text((unsigned long)orig_call))
+ if (is_kernel_text((unsigned long)orig_call) ||
+ is_module_text_address((unsigned long)orig_call))
orig_call += LOONGARCH_FENTRY_NBYTES;
/* Direct jump skips 5 NOP instructions */
else if (is_bpf_text_address((unsigned long)orig_call))
orig_call += LOONGARCH_BPF_FENTRY_NBYTES;
- /* Module tracing not supported - cause kernel lockups */
- else if (is_module_text_address((unsigned long)orig_call))
- return -ENOTSUPP;
if (flags & BPF_TRAMP_F_CALL_ORIG) {
move_addr(ctx, LOONGARCH_GPR_A0, (const u64)im);
@@ -1722,12 +1734,16 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0);
emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, 16);
- if (flags & BPF_TRAMP_F_SKIP_FRAME)
+ if (flags & BPF_TRAMP_F_SKIP_FRAME) {
/* return to parent function */
- emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
- else
- /* return to traced function */
+ move_reg(ctx, LOONGARCH_GPR_RA, LOONGARCH_GPR_T0);
emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T0, 0);
+ } else {
+ /* return to traced function */
+ move_reg(ctx, LOONGARCH_GPR_T1, LOONGARCH_GPR_RA);
+ move_reg(ctx, LOONGARCH_GPR_RA, LOONGARCH_GPR_T0);
+ emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T1, 0);
+ }
}
ret = ctx->idx;
--
2.25.1
^ permalink raw reply related
* [PATCH v3 2/4] LoongArch: Enable exception fixup for specific ADE subcode
From: Chenghao Duan @ 2025-12-16 9:47 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251216094753.1317231-1-duanchenghao@kylinos.cn>
This patch allows the LoongArch BPF JIT to handle recoverable memory
access errors generated by BPF_PROBE_MEM* instructions.
When a BPF program performs memory access operations, the instructions
it executes may trigger ADEM exceptions. The kernel’s built-in BPF
exception table mechanism (EX_TYPE_BPF) will generate corresponding
exception fixup entries in the JIT compilation phase; however, the
architecture-specific trap handling function needs to proactively call
the common fixup routine to achieve exception recovery.
do_ade(): fix EX_TYPE_BPF memory access exceptions for BPF programs,
ensure safe execution.
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/kernel/traps.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index 004b8ebf0051..201c9a5532f4 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -534,11 +534,18 @@ asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr)
asmlinkage void noinstr do_ade(struct pt_regs *regs)
{
- irqentry_state_t state = irqentry_enter(regs);
+ irqentry_state_t state;
+ unsigned int esubcode = FIELD_GET(CSR_ESTAT_ESUBCODE, regs->csr_estat);
+
+ state = irqentry_enter(regs);
+
+ if ((esubcode == EXSUBCODE_ADEM) && fixup_exception(regs))
+ goto out;
die_if_kernel("Kernel ade access", regs);
force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)regs->csr_badvaddr);
+out:
irqentry_exit(regs, state);
}
--
2.25.1
^ permalink raw reply related
* [PATCH v3 1/4] LoongArch: ftrace: Refactor register restoration in ftrace_common_return
From: Chenghao Duan @ 2025-12-16 9:47 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
In-Reply-To: <20251216094753.1317231-1-duanchenghao@kylinos.cn>
Refactor the register restoration sequence in the ftrace_common_return
function to clearly distinguish between the logic of normal returns and
direct call returns in function tracing scenarios. The logic is as
follows:
1. In the case of a normal return, the execution flow returns to the
traced function, and ftrace must ensure that the register data is
consistent with the state when the function was entered.
ra = parent return address; t0 = traced function return address.
2. In the case of a direct call return, the execution flow jumps to the
custom trampoline function, and ftrace must ensure that the register
data is consistent with the state when ftrace was entered.
ra = traced function return address; t0 = parent return address.
Fixes: 9cdc3b6a299c ("LoongArch: ftrace: Add direct call support")
Signed-off-by: Chenghao Duan <duanchenghao@kylinos.cn>
---
arch/loongarch/kernel/mcount_dyn.S | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/loongarch/kernel/mcount_dyn.S b/arch/loongarch/kernel/mcount_dyn.S
index d6b474ad1d5e..5729c20e5b8b 100644
--- a/arch/loongarch/kernel/mcount_dyn.S
+++ b/arch/loongarch/kernel/mcount_dyn.S
@@ -94,7 +94,6 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
* at the callsite, so there is no need to restore the T series regs.
*/
ftrace_common_return:
- PTR_L ra, sp, PT_R1
PTR_L a0, sp, PT_R4
PTR_L a1, sp, PT_R5
PTR_L a2, sp, PT_R6
@@ -104,12 +103,17 @@ ftrace_common_return:
PTR_L a6, sp, PT_R10
PTR_L a7, sp, PT_R11
PTR_L fp, sp, PT_R22
- PTR_L t0, sp, PT_ERA
PTR_L t1, sp, PT_R13
- PTR_ADDI sp, sp, PT_SIZE
bnez t1, .Ldirect
+
+ PTR_L ra, sp, PT_R1
+ PTR_L t0, sp, PT_ERA
+ PTR_ADDI sp, sp, PT_SIZE
jr t0
.Ldirect:
+ PTR_L t0, sp, PT_R1
+ PTR_L ra, sp, PT_ERA
+ PTR_ADDI sp, sp, PT_SIZE
jr t1
SYM_CODE_END(ftrace_common)
@@ -161,6 +165,8 @@ SYM_CODE_END(return_to_handler)
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
SYM_CODE_START(ftrace_stub_direct_tramp)
UNWIND_HINT_UNDEFINED
- jr t0
+ move t1, ra
+ move ra, t0
+ jr t1
SYM_CODE_END(ftrace_stub_direct_tramp)
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
--
2.25.1
^ permalink raw reply related
* [PATCH v3 0/4] Fix the failure issue of the module_attach test case
From: Chenghao Duan @ 2025-12-16 9:47 UTC (permalink / raw)
To: yangtiezhu, rostedt, mhiramat, mark.rutland, hengqi.chen,
chenhuacai
Cc: kernel, zhangtianyang, masahiroy, linux-kernel, loongarch, bpf,
duanchenghao, youling.tang, jianghaoran, vincent.mc.li,
linux-trace-kernel
v3:
1. Adjust the position of fixup_exception() in the patch "LoongArch:
Enable exception fixup for specific ADE": move its invocation to within
the code block wrapped by irqentry_enter()/irqentry_exit().
2. Add the relevant test items to the patch commit log.
3. Adjust the sequence of patches
With the exception of the patch "LoongArch: Enable exception fixup for
specific ADE", no source code changes have been made in the other
patches.
--------------------------Changelog------------------------------------
v2:
links: https://lore.kernel.org/all/20251212091103.1247753-1-duanchenghao@kylinos.cn/
Referring to Tiezhu's suggestion, split the v1 patch titled
"LoongArch: Modify the jump logic of the trampoline" into three parts:
(1) ftrace code
(2) sample test
(3) bpf code
The code logic and implementation remain unchanged.
v1:
links: https://lore.kernel.org/all/20251209093405.1309253-1-duanchenghao@kylinos.cn/
The following test cases under the tools/testing/selftests/bpf/
directory have passed the test:
./test_progs -t module_attach
./test_progs -t module_fentry_shadow
./test_progs -t subprogs
./test_progs -t subprogs_extable
./test_progs -t tailcalls
./test_progs -t struct_ops -d struct_ops_multi_pages
./test_progs -t fexit_bpf2bpf
./test_progs -t fexit_stress
./test_progs -t module_fentry_shadow
./test_progs -t fentry_test/fentry
./test_progs -t fexit_test/fexit
./test_progs -t fentry_fexit
./test_progs -t modify_return
./test_progs -t fexit_sleep
./test_progs -t test_overhead
./test_progs -t trampoline_count
Chenghao Duan (4):
LoongArch: ftrace: Refactor register restoration in
ftrace_common_return
LoongArch: Enable exception fixup for specific ADE subcode
LoongArch: BPF: Enhance trampoline support for kernel and module
tracing
LoongArch: ftrace: Adjust register stack restore order in direct call
trampolines
arch/loongarch/kernel/mcount_dyn.S | 14 +++++---
arch/loongarch/kernel/traps.c | 9 ++++-
arch/loongarch/net/bpf_jit.c | 38 +++++++++++++++------
samples/ftrace/ftrace-direct-modify.c | 8 ++---
samples/ftrace/ftrace-direct-multi-modify.c | 8 ++---
samples/ftrace/ftrace-direct-multi.c | 4 +--
samples/ftrace/ftrace-direct-too.c | 4 +--
samples/ftrace/ftrace-direct.c | 4 +--
8 files changed, 59 insertions(+), 30 deletions(-)
--
2.25.1
^ permalink raw reply
* Re: [PATCH v6 4/6] perf script: Display PERF_RECORD_CALLCHAIN_DEFERRED
From: Jens Remus @ 2025-12-16 9:29 UTC (permalink / raw)
To: Namhyung Kim
Cc: Arnaldo Carvalho de Melo, Ian Rogers, James Clark, Jiri Olsa,
Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML,
linux-perf-users, Steven Rostedt, Josh Poimboeuf, Indu Bhagat,
Mathieu Desnoyers, linux-trace-kernel, bpf, Heiko Carstens,
Vasily Gorbik
In-Reply-To: <aUDkpsW-WH3IPIhh@google.com>
Hello Namhyung!
On 12/16/2025 5:48 AM, Namhyung Kim wrote:
> On Fri, Dec 12, 2025 at 01:11:38PM +0100, Jens Remus wrote:
>> following is an observation from my attempt to enable unwind user fp on
>> s390 using s390 back chain instead of frame pointer and relaxing the
>> s390-specific IP validation check.
>>
>> When capturing call graphs of a Java application the list of "unwound"
>> user space IPs may contain invalid entries, such as 0x0, 0xdeaddeaf,
>> and 0xffffffffffffff. IPs that exceed PERF_CONTEXT_MAX, such as the
>> latter, cause perf not to display any deferred (or merged) call chain.
>> Note that this is not caused by your patch series.
>
> Right, it's not a real IP so perf ABI treats them as a magic context.
>
>>
>> While re-adding the s390-specific IP checks would "hide" those, I found
>> that the call graphs look good otherwise. That is the back chain seems
>> to be intact. It is just the user space application (e.g. Java JRE) not
>> correctly adhering to the ABI and saving the return address to the
>> specified location on the stack, causing bogus IPs to be reported.
>>
>> Could perf be improved to handle those user space IPs that exceed
>> PERF_CONTEXT_MAX?
>
> Ideally we should not have them in the first place. Is it a JRE issue
> or your s390 unwinder issue? Is it possible to ignore them in the
> unwinder?
Stack tracing using frame pointer is virtually impossible on s390, as
the ABI does not designate a specific register as FP register, does not
specify a fixed register save area layout, nor does mandate a FP to be
setup early. Compilers usually setup a FP late, that is after static
stack allocation.
An alternative is the s390-specific back chain, which is basically a
frame pointer on stack. The ABI specifics that *(SP+0) has the pointer
to the previous frame and *(BC-48) has the return address (RA), if a
back chain is used (e.g. compiler option -mbackchain is used). This is
why I implemented unwind user fp on s390 using back chain. Note that
the back chain can be correctly followed, even if the saved RAs are
bogus. That is what can be observed in case of this specific Java JRE.
Apparently it correctly maintains the back chain stack slot, but does
not correctly maintain the RA stack slot. So the RA stack save slot may
contain any random value.
The s390-implementation of unwind user fp could check whether the return
address is a valid IP. This is how it is implemented in the existing
stack tracer in arch/s390/kernel/stacktrace.c:
static inline bool ip_invalid(unsigned long ip)
{
/* ABI requires IPs to be 2-byte aligned */
if (ip & 1)
return true;
if (ip < mmap_min_addr)
return true;
if (ip >= current->mm->context.asce_limit)
return true;
return false;
}
It could then either stop or return some magic value
(e.g. PERF_CONTEXT_MAX - 1) to indicate that the IP is invalid and
continue. Actually I would prefer to continue so that a user an see
that there is something odd with the stack trace.
Alternatively such a check could possibly also be implemented in the
common undwind user, if the address space limits are known in common
code, or as an architecture-specific hook. In general I tend to at
least add a check whether the IP is zero, as this is used on several
architectures as indication for outermost frames (usually in
combination with a FP of zero).
>>
>> Is there otherwise guidance how unwind user and/or the s390
>> implementation should deal with such IPs? Should it stop taking the
>> deferred calltrace? Should it substitute those with e.g 0, so that
>> perf can display them?
>> Sample for IP == ffffffffffffff (perf does not display any call chain):
...
>> # perf report -D
>> ...
>> 44004346257 0x17718 [0x40]: PERF_RECORD_SAMPLE(IP, 0x2): 1082/1084: 0x3ffa3e413aa period: 1001001 addr: 0
>> ... FP chain: nr:2
>> ..... 0: fffffffffffffd80
>> ..... 1: 0000000400000079
>> ...... (deferred)
>> ... thread: java:1084
>> ...... dso: /tmp/perf-1082.map
>>
>> 0x17758@perf.data [0xd0]: event: 22
>> .
>> . ... raw event: size 208 bytes
...
>>
>> 44004348864 0x17758 [0xd0]: PERF_RECORD_CALLCHAIN_DEFERRED(IP, 0x2): 1082/1084: 0x400000079
>> ... FP chain: nr:21
>> ..... 0: 000003ffa3e413aa
>> ..... 1: 000003ff3809e2d0
>> ..... 2: 000003ff3809e130
>> ..... 3: 000003ffb95fdf68
>> ..... 4: 0000000000000000
>> ..... 5: 000003ffb95fe128
>> ..... 6: 000003ffb95fe1d0
>> ..... 7: 005780888e7647a5
>> ..... 8: 000003ffa3e437f2
>> ..... 9: ffffffffffffffff <-- !
>> ..... 10: 000003ffa3e4a1fc
>> ..... 11: 0000000000000000
>> ..... 12: 000003ffa3e37900
>> ..... 13: 000003ffa3e41080
>> ..... 14: 000003ffb9dd11de
>> ..... 15: 000003ffb9e8df92
>> ..... 16: 000003ffb9e90e86
>> ..... 17: 000003ffbab8b07e
>> ..... 18: 000003ffbab8e040
>> ..... 19: 000003ffba8abbd8
>> ..... 20: 000003ffba92b950
>> : unhandled!
>>
>> ...
>> [next entry]
>>
>>
>> On 11/21/2025 12:48 AM, Namhyung Kim wrote:
>>> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
>>
>>> +static int process_deferred_sample_event(const struct perf_tool *tool,
>>> + union perf_event *event,
>>> + struct perf_sample *sample,
>>> + struct evsel *evsel,
>>> + struct machine *machine)
>>> +{
>>
>>> + perf_sample__fprintf_start(scr, sample, al.thread, evsel,
>>> + PERF_RECORD_CALLCHAIN_DEFERRED, fp);
>>> + fprintf(fp, "DEFERRED CALLCHAIN [cookie: %llx]",
>>> + (unsigned long long)event->callchain_deferred.cookie);
>>> +
>>> + if (PRINT_FIELD(IP)) {
>>> + struct callchain_cursor *cursor = NULL;
>>> +
>>> + if (symbol_conf.use_callchain && sample->callchain) {
>>> + cursor = get_tls_callchain_cursor();
>>> + if (thread__resolve_callchain(al.thread, cursor, evsel,
>>> + sample, NULL, NULL,
>>> + scripting_max_stack)) {
>>
>> thread__resolve_callchain()
>> calls __thread__resolve_callchain()
>> calls thread__resolve_callchain_sample():
>>
>> for (i = first_call, nr_entries = 0;
>> i < chain_nr && nr_entries < max_stack; i++) {
>> ...
>> ip = chain->ips[j];
>> if (ip < PERF_CONTEXT_MAX) <-- IP=ff..ff is greater than PERF_CONTEXT_MAX
>> ++nr_entries;
>
> Right.
>
>> ...
>> err = add_callchain_ip(thread, cursor, parent,
>> root_al, &cpumode, ip,
>> false, NULL, NULL, 0, symbols);
>>
>> if (err)
>> return (err < 0) ? err : 0;
>>
>> calls add_callchain_ip:
>>
>> if (ip >= PERF_CONTEXT_MAX) {
>> switch (ip) {
>> case PERF_CONTEXT_HV:
>> *cpumode = PERF_RECORD_MISC_HYPERVISOR;
>> break;
>> case PERF_CONTEXT_KERNEL:
>> *cpumode = PERF_RECORD_MISC_KERNEL;
>> break;
>> case PERF_CONTEXT_USER:
>> case PERF_CONTEXT_USER_DEFERRED:
>> *cpumode = PERF_RECORD_MISC_USER;
>> break;
>> default:
>> pr_debug("invalid callchain context: " <-- IP=ff..ff reaches default case
>> "%"PRId64"\n", (s64) ip);
>
> We may skip -1 if it's Java and *cpumode is already USER and it's s390.
> But I'd like to understand the situation first.
Let's better not add any weird architecture-specific handling. This is
also not limited to -1 (and 0), as Java may have used the stack save
area in any way, so it may be any random value.
>> /*
>> * It seems the callchain is corrupted.
>> * Discard all.
>> */
>> callchain_cursor_reset(cursor);
>> err = 1;
>> goto out;
>> }
>>
>>> + pr_info("cannot resolve deferred callchains\n");
>>> + cursor = NULL;
>>> + }
>>> + }
>>> +
>>> + fputc(cursor ? '\n' : ' ', fp);
>>> + sample__fprintf_sym(sample, &al, 0, output[type].print_ip_opts,
>>> + cursor, symbol_conf.bt_stop_list, fp);
>>> + }
Thanks and regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
+49-7031-16-1128 Office
jremus@de.ibm.com
IBM
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
^ permalink raw reply
* Re: [PATCH v6] dma-buf: add some tracepoints to debug.
From: Barry Song @ 2025-12-16 9:05 UTC (permalink / raw)
To: Christian König
Cc: Xiang Gao, sumit.semwal, rostedt, mhiramat, linux-media,
dri-devel, linux-kernel, mathieu.desnoyers, dhowells, kuba,
brauner, akpm, linux-trace-kernel, gaoxiang17
In-Reply-To: <7a41abc8-df47-459a-ab3e-ba7943fdd0ff@amd.com>
On Tue, Dec 16, 2025 at 4:44 PM Christian König
<christian.koenig@amd.com> wrote:
>
> On 12/16/25 07:39, Xiang Gao wrote:
> > From: gaoxiang17 <gaoxiang17@xiaomi.com>
> >
> > Since we can only inspect dmabuf by iterating over process FDs or the
> > dmabuf_list, we need to add our own tracepoints to track its status in
> > real time in production.
> >
> > For example:
> > binder:3016_1-3102 [006] ...1. 255.126521: dma_buf_export: exp_name=qcom,system size=12685312 ino=2738
> > binder:3016_1-3102 [006] ...1. 255.126528: dma_buf_fd: exp_name=qcom,system size=12685312 ino=2738 fd=8
> > binder:3016_1-3102 [006] ...1. 255.126642: dma_buf_mmap_internal: exp_name=qcom,system size=28672 ino=2739
> > kworker/6:1-86 [006] ...1. 255.127194: dma_buf_put: exp_name=qcom,system size=12685312 ino=2738
> > RenderThread-9293 [006] ...1. 316.618179: dma_buf_get: exp_name=qcom,system size=12771328 ino=2762 fd=176
> > RenderThread-9293 [006] ...1. 316.618195: dma_buf_dynamic_attach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
> > RenderThread-9293 [006] ...1. 318.878220: dma_buf_detach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
> >
> > Signed-off-by: Xiang Gao <gaoxiang17@xiaomi.com>
>
> Reviewed-by: Christian König <christian.koenig@amd.com>
>
> Going to push this to drm-misc-next today unless somebody has some last minute objections.
No objection, but I would strongly suggest Xiang include a
diff description next time, after the changelog for each new
version.
I recall clearly commenting on both changelog refinement and
the DMA_BUF_TRACE() macro [1]. It would be better to mention
similar things for each new version next time :-)
[1] https://lore.kernel.org/lkml/CAGsJ_4y0zc_nh2q=w4uR04vtveCf6L7+hgafznHuL8ByWbyNOQ@mail.gmail.com/
Thanks
Barry
^ permalink raw reply
* Re: [PATCH v6] dma-buf: add some tracepoints to debug.
From: Christian König @ 2025-12-16 8:43 UTC (permalink / raw)
To: Xiang Gao, sumit.semwal, rostedt, mhiramat
Cc: linux-media, dri-devel, linux-kernel, mathieu.desnoyers, dhowells,
kuba, brauner, akpm, linux-trace-kernel, gaoxiang17
In-Reply-To: <20251216063952.516364-1-gxxa03070307@gmail.com>
On 12/16/25 07:39, Xiang Gao wrote:
> From: gaoxiang17 <gaoxiang17@xiaomi.com>
>
> Since we can only inspect dmabuf by iterating over process FDs or the
> dmabuf_list, we need to add our own tracepoints to track its status in
> real time in production.
>
> For example:
> binder:3016_1-3102 [006] ...1. 255.126521: dma_buf_export: exp_name=qcom,system size=12685312 ino=2738
> binder:3016_1-3102 [006] ...1. 255.126528: dma_buf_fd: exp_name=qcom,system size=12685312 ino=2738 fd=8
> binder:3016_1-3102 [006] ...1. 255.126642: dma_buf_mmap_internal: exp_name=qcom,system size=28672 ino=2739
> kworker/6:1-86 [006] ...1. 255.127194: dma_buf_put: exp_name=qcom,system size=12685312 ino=2738
> RenderThread-9293 [006] ...1. 316.618179: dma_buf_get: exp_name=qcom,system size=12771328 ino=2762 fd=176
> RenderThread-9293 [006] ...1. 316.618195: dma_buf_dynamic_attach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
> RenderThread-9293 [006] ...1. 318.878220: dma_buf_detach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
>
> Signed-off-by: Xiang Gao <gaoxiang17@xiaomi.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Going to push this to drm-misc-next today unless somebody has some last minute objections.
Regards,
Christian.
> ---
> drivers/dma-buf/dma-buf.c | 42 ++++++++-
> include/trace/events/dma_buf.h | 154 +++++++++++++++++++++++++++++++++
> 2 files changed, 195 insertions(+), 1 deletion(-)
> create mode 100644 include/trace/events/dma_buf.h
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 2bcf9ceca997..831973de76c4 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -35,6 +35,25 @@
>
> #include "dma-buf-sysfs-stats.h"
>
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/dma_buf.h>
> +
> +/*
> + * dmabuf->name must be accessed with holding dmabuf->name_lock.
> + * we need to take the lock around the tracepoint call itself where
> + * it is called in the code.
> + *
> + * Note: FUNC##_enabled() is a static branch that will only
> + * be set when the trace event is enabled.
> + */
> +#define DMA_BUF_TRACE(FUNC, ...) \
> + do { \
> + if (FUNC##_enabled()) { \
> + guard(spinlock)(&dmabuf->name_lock); \
> + FUNC(__VA_ARGS__); \
> + } \
> + } while (0)
> +
> static inline int is_dma_buf_file(struct file *);
>
> static DEFINE_MUTEX(dmabuf_list_mutex);
> @@ -220,6 +239,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
> dmabuf->size >> PAGE_SHIFT)
> return -EINVAL;
>
> + DMA_BUF_TRACE(trace_dma_buf_mmap_internal, dmabuf);
> +
> return dmabuf->ops->mmap(dmabuf, vma);
> }
>
> @@ -745,6 +766,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
>
> __dma_buf_list_add(dmabuf);
>
> + DMA_BUF_TRACE(trace_dma_buf_export, dmabuf);
> +
> return dmabuf;
>
> err_dmabuf:
> @@ -779,6 +802,8 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags)
>
> fd_install(fd, dmabuf->file);
>
> + DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd);
> +
> return fd;
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
> @@ -794,6 +819,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
> struct dma_buf *dma_buf_get(int fd)
> {
> struct file *file;
> + struct dma_buf *dmabuf;
>
> file = fget(fd);
>
> @@ -805,7 +831,11 @@ struct dma_buf *dma_buf_get(int fd)
> return ERR_PTR(-EINVAL);
> }
>
> - return file->private_data;
> + dmabuf = file->private_data;
> +
> + DMA_BUF_TRACE(trace_dma_buf_get, dmabuf, fd);
> +
> + return dmabuf;
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF");
>
> @@ -825,6 +855,8 @@ void dma_buf_put(struct dma_buf *dmabuf)
> return;
>
> fput(dmabuf->file);
> +
> + DMA_BUF_TRACE(trace_dma_buf_put, dmabuf);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
>
> @@ -979,6 +1011,9 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
> list_add(&attach->node, &dmabuf->attachments);
> dma_resv_unlock(dmabuf->resv);
>
> + DMA_BUF_TRACE(trace_dma_buf_dynamic_attach, dmabuf, attach,
> + dma_buf_attachment_is_dynamic(attach), dev);
> +
> return attach;
>
> err_attach:
> @@ -1023,6 +1058,9 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
> if (dmabuf->ops->detach)
> dmabuf->ops->detach(dmabuf, attach);
>
> + DMA_BUF_TRACE(trace_dma_buf_detach, dmabuf, attach,
> + dma_buf_attachment_is_dynamic(attach), attach->dev);
> +
> kfree(attach);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
> @@ -1488,6 +1526,8 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
> vma_set_file(vma, dmabuf->file);
> vma->vm_pgoff = pgoff;
>
> + DMA_BUF_TRACE(trace_dma_buf_mmap, dmabuf);
> +
> return dmabuf->ops->mmap(dmabuf, vma);
> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF");
> diff --git a/include/trace/events/dma_buf.h b/include/trace/events/dma_buf.h
> new file mode 100644
> index 000000000000..81ee4d05979c
> --- /dev/null
> +++ b/include/trace/events/dma_buf.h
> @@ -0,0 +1,154 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM dma_buf
> +
> +#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_DMA_BUF_H
> +
> +#include <linux/dma-buf.h>
> +#include <linux/tracepoint.h>
> +
> +DECLARE_EVENT_CLASS(dma_buf,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + ),
> +
> + TP_printk("exp_name=%s size=%zu ino=%lu",
> + __get_str(exp_name),
> + __entry->size,
> + __entry->ino)
> +);
> +
> +DECLARE_EVENT_CLASS(dma_buf_attach_dev,
> +
> + TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
> +
> + TP_ARGS(dmabuf, attach, is_dynamic, dev),
> +
> + TP_STRUCT__entry(
> + __string(dev_name, dev_name(dev))
> + __string(exp_name, dmabuf->exp_name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + __field(struct dma_buf_attachment *, attach)
> + __field(bool, is_dynamic)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(dev_name);
> + __assign_str(exp_name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + __entry->is_dynamic = is_dynamic;
> + __entry->attach = attach;
> + ),
> +
> + TP_printk("exp_name=%s size=%zu ino=%lu attachment:%p is_dynamic=%d dev_name=%s",
> + __get_str(exp_name),
> + __entry->size,
> + __entry->ino,
> + __entry->attach,
> + __entry->is_dynamic,
> + __get_str(dev_name))
> +);
> +
> +DECLARE_EVENT_CLASS(dma_buf_fd,
> +
> + TP_PROTO(struct dma_buf *dmabuf, int fd),
> +
> + TP_ARGS(dmabuf, fd),
> +
> + TP_STRUCT__entry(
> + __string(exp_name, dmabuf->exp_name)
> + __field(size_t, size)
> + __field(ino_t, ino)
> + __field(int, fd)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(exp_name);
> + __entry->size = dmabuf->size;
> + __entry->ino = dmabuf->file->f_inode->i_ino;
> + __entry->fd = fd;
> + ),
> +
> + TP_printk("exp_name=%s size=%zu ino=%lu fd=%d",
> + __get_str(exp_name),
> + __entry->size,
> + __entry->ino,
> + __entry->fd)
> +);
> +
> +DEFINE_EVENT(dma_buf, dma_buf_export,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf)
> +);
> +
> +DEFINE_EVENT(dma_buf, dma_buf_mmap_internal,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf)
> +);
> +
> +DEFINE_EVENT(dma_buf, dma_buf_mmap,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf)
> +);
> +
> +DEFINE_EVENT(dma_buf, dma_buf_put,
> +
> + TP_PROTO(struct dma_buf *dmabuf),
> +
> + TP_ARGS(dmabuf)
> +);
> +
> +DEFINE_EVENT(dma_buf_attach_dev, dma_buf_dynamic_attach,
> +
> + TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
> +
> + TP_ARGS(dmabuf, attach, is_dynamic, dev)
> +);
> +
> +DEFINE_EVENT(dma_buf_attach_dev, dma_buf_detach,
> +
> + TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
> +
> + TP_ARGS(dmabuf, attach, is_dynamic, dev)
> +);
> +
> +DEFINE_EVENT(dma_buf_fd, dma_buf_fd,
> +
> + TP_PROTO(struct dma_buf *dmabuf, int fd),
> +
> + TP_ARGS(dmabuf, fd)
> +);
> +
> +DEFINE_EVENT(dma_buf_fd, dma_buf_get,
> +
> + TP_PROTO(struct dma_buf *dmabuf, int fd),
> +
> + TP_ARGS(dmabuf, fd)
> +);
> +
> +#endif /* _TRACE_DMA_BUF_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>
^ permalink raw reply
* Re: [PATCH v13 mm-new 07/16] khugepaged: introduce collapse_max_ptes_none helper function
From: Baolin Wang @ 2025-12-16 8:12 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>
Hi Nico,
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;
> +}
> +
> void khugepaged_enter_vma(struct vm_area_struct *vma,
> vm_flags_t vm_flags)
> {
> @@ -550,7 +588,10 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
> pte_t *_pte;
> int none_or_zero = 0, shared = 0, result = SCAN_FAIL, referenced = 0;
> const unsigned long nr_pages = 1UL << order;
> - int max_ptes_none = khugepaged_max_ptes_none >> (HPAGE_PMD_ORDER - order);
> + int max_ptes_none = collapse_max_ptes_none(order, !cc->is_khugepaged);
> +
> + if (max_ptes_none == -EINVAL)
> + goto out;
After testing your patchset, I hit the following crash. The reason is
that when 'max_ptes_none' is -EINVAL here, it shouldn't goto out to call
release_pte_pages(), because the '_pte' hasn't been initialized at this
point, and there's no need to release folios either.
After applying the fix below, the crash issue is resolved. I'm not sure
whether Andrew will help fix this or if you will send a new version to
address this issue.
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 8cffaf59ced8..2e8171a6d7df 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -646,7 +646,7 @@ static int __collapse_huge_page_isolate(struct
vm_area_struct *vma,
int max_ptes_none = collapse_max_ptes_none(order,
!cc->is_khugepaged);
if (max_ptes_none == -EINVAL)
- goto out;
+ return result;
for (_pte = pte; _pte < pte + nr_pages;
_pte++, addr += PAGE_SIZE) {
"
[ 565.319345] Unable to handle kernel paging request at virtual address
fffffffffffffffa
.......
[ 565.319409] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000001f8549a000
[ 565.319416] [fffffffffffffffa] pgd=0000001f85f2a403,
p4d=0000001f85f2a403, pud=0000001f85f2b403, pmd=0000000000000000
[ 565.319427] Internal error: Oops: 0000000096000006 [#1] SMP
.......
[ 565.326733] pc : release_pte_pages+0x68/0x178
[ 565.326960] lr : __collapse_huge_page_isolate+0xc0/0x748
[ 565.327232] sp : ffff800083593910
.......
[ 565.331476] Call trace:
[ 565.331664] release_pte_pages+0x68/0x178 (P)
[ 565.331940] __collapse_huge_page_isolate+0xc0/0x748
[ 565.332249] collapse_huge_page+0x4cc/0xa70
[ 565.332510] mthp_collapse+0x254/0x2a8
[ 565.332754] collapse_scan_pmd+0x5a0/0x6d8
[ 565.333010] collapse_single_pmd+0x214/0x288
[ 565.333275] collapse_scan_mm_slot.constprop.0+0x2ac/0x460
[ 565.333617] khugepaged+0x204/0x2c8
[ 565.333992] kthread+0xf8/0x110
[ 565.334368] ret_from_fork+0x10/0x20
"
>
> for (_pte = pte; _pte < pte + nr_pages;
> _pte++, addr += PAGE_SIZE) {
^ permalink raw reply related
* [PATCH 12/12] mm/damon/core: add trace point for damos stat per apply interval
From: SeongJae Park @ 2025-12-16 8:01 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, Masami Hiramatsu, Mathieu Desnoyers,
Steven Rostedt, damon, linux-kernel, linux-mm, linux-trace-kernel
In-Reply-To: <20251216080128.42991-1-sj@kernel.org>
DAMON users can read DAMOS stats via DAMON sysfs interface. It enables
efficient, simple and flexible usages of the stats. Especially for
systems not having advanced tools like perf or bpftrace, that can be
useful. But if the advanced tools are available, exposing the stats via
tracepoint can reduce unnecessary reimplementation of the wheels. Add a
new tracepoint for DAMOS stats, namely damos_stat_after_apply_interval.
The tracepoint is triggered for each scheme's apply interval and exposes
the whole stat values. If the user needs sub-apply interval information
for any chance, damos_before_apply tracepoint could be used.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
include/trace/events/damon.h | 41 ++++++++++++++++++++++++++++++++++++
mm/damon/core.c | 17 +++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/include/trace/events/damon.h b/include/trace/events/damon.h
index 852d725afea2..24fc402ab3c8 100644
--- a/include/trace/events/damon.h
+++ b/include/trace/events/damon.h
@@ -9,6 +9,47 @@
#include <linux/types.h>
#include <linux/tracepoint.h>
+TRACE_EVENT(damos_stat_after_apply_interval,
+
+ TP_PROTO(unsigned int context_idx, unsigned int scheme_idx,
+ struct damos_stat *stat),
+
+ TP_ARGS(context_idx, scheme_idx, stat),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, context_idx)
+ __field(unsigned int, scheme_idx)
+ __field(unsigned long, nr_tried)
+ __field(unsigned long, sz_tried)
+ __field(unsigned long, nr_applied)
+ __field(unsigned long, sz_applied)
+ __field(unsigned long, sz_ops_filter_passed)
+ __field(unsigned long, qt_exceeds)
+ __field(unsigned long, nr_snapshots)
+ ),
+
+ TP_fast_assign(
+ __entry->context_idx = context_idx;
+ __entry->scheme_idx = scheme_idx;
+ __entry->nr_tried = stat->nr_tried;
+ __entry->sz_tried = stat->sz_tried;
+ __entry->nr_applied = stat->nr_applied;
+ __entry->sz_applied = stat->sz_applied;
+ __entry->sz_ops_filter_passed = stat->sz_ops_filter_passed;
+ __entry->qt_exceeds = stat->qt_exceeds;
+ __entry->nr_snapshots = stat->nr_snapshots;
+ ),
+
+ TP_printk("ctx_idx=%u scheme_idx=%u nr_tried=%lu sz_tried=%lu "
+ "nr_applied=%lu sz_tried=%lu sz_ops_filter_passed=%lu "
+ "qt_exceeds=%lu nr_snapshots=%lu",
+ __entry->context_idx, __entry->scheme_idx,
+ __entry->nr_tried, __entry->sz_tried,
+ __entry->nr_applied, __entry->sz_applied,
+ __entry->sz_ops_filter_passed, __entry->qt_exceeds,
+ __entry->nr_snapshots)
+);
+
TRACE_EVENT(damos_esz,
TP_PROTO(unsigned int context_idx, unsigned int scheme_idx,
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 8908aec6670f..68dd2f7acba2 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -2256,6 +2256,22 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
quota->min_score = score;
}
+static void damos_trace_stat(struct damon_ctx *c, struct damos *s)
+{
+ unsigned int cidx = 0, sidx = 0;
+ struct damos *siter;
+
+ if (!trace_damos_stat_after_apply_interval_enabled())
+ return;
+
+ damon_for_each_scheme(siter, c) {
+ if (siter == s)
+ break;
+ sidx++;
+ }
+ trace_damos_stat_after_apply_interval(cidx, sidx, &s->stat);
+}
+
static void kdamond_apply_schemes(struct damon_ctx *c)
{
struct damon_target *t;
@@ -2297,6 +2313,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
(s->apply_interval_us ? s->apply_interval_us :
c->attrs.aggr_interval) / sample_interval;
s->last_applied = NULL;
+ damos_trace_stat(c, s);
}
mutex_unlock(&c->walk_control_lock);
}
--
2.47.3
^ permalink raw reply related
* [PATCH 00/12] mm/damon: introduce {,max_}nr_snapshots and tracepoint for damos stats
From: SeongJae Park @ 2025-12-16 8:01 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, Liam R. Howlett, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Masami Hiramatsu,
Mathieu Desnoyers, Michal Hocko, Mike Rapoport, Steven Rostedt,
Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm, linux-trace-kernel
Introduce three changes for improving DAMOS stat's provided information,
deterministic control, and reading usability.
DAMOS provides stats that are important for understanding its behavior.
It lacks information about how many DAMON-generated monitoring output
snapshots it has worked on. Add a new stat, nr_snapshots, to show the
information.
Users can control DAMOS schemes in multiple ways. Using the online
parameters commit feature, they can install and uninstall DAMOS schemes
whenever they want while keeping DAMON runs. DAMOS quotas and
watermarks can be used for manually or automatically turning on/off or
adjusting the aggressiveness of the scheme. DAMOS filters can be used
for applying the scheme to specific memory entities based on their types
and locations. Some users want their DAMOS scheme to be applied to only
specific number of DAMON snapshots, for more deterministic control. One
example use case is tracepoint based snapshot reading. Add a new knob,
max_nr_snapshots, to support this. If the nr_snapshots parameter
becomes same to or greater than the value of this parameter, the scheme
is deactivated.
Users can read DAMOS stats via DAMON's sysfs interface. For deep level
investigations on environments having advanced tools like perf and
bpftrace, exposing the stats via a tracepoint can be useful. Implement
a new tracepoint, namely damon:damos_stat_after_apply_interval.
First five patches (patches 1-5) of this series implement the new stat,
nr_snapshots, on the core layer (patch 1), expose on DAMON sysfs user
interface (patch 2), and update documents (patches 3-5).
Following six patches (patches 6-11) are for the new stat based DAMOS
deactivation (max_nr_snapshots). The first one (patch 6) of this group
updates a kernel-doc comment before making further changes. Then an
implementation of it on the core layer (patch 7), an introduction of a
new DAMON sysfs interface file for users of the feature (patch 8), and
three updates of the documents (patches 9-11) follow.
The final one (patch 12) introduces the new tracepoint that exposes the
DAMOS stat values for each scheme apply interval.
Revision History
----------------
Changes from RFC
(https://lore.kernel.org/20251123184329.85287-1-sj@kernel.org)
- Check damos_stat tracepoint enablement inside the trace function.
- Update ABI document's 'Date:' fields.
- Slightly change series subject.
SeongJae Park (12):
mm/damon/core: introduce nr_snapshots damos stat
mm/damon/sysfs-schemes: introduce nr_snapshots damos stat file
Docs/mm/damon/design: update for nr_snapshots damos stat
Docs/admin-guide/mm/damon/usage: update for nr_snapshots damos stat
Docs/ABI/damon: update for nr_snapshots damos stat
mm/damon: update damos kerneldoc for stat field
mm/damon/core: implement max_nr_snapshots
mm/damon/sysfs-schemes: implement max_nr_snapshots file
Docs/mm/damon/design: update for max_nr_snapshots
Docs/admin-guide/mm/damon/usage: update for max_nr_snapshots
Docs/ABI/damon: update for max_nr_snapshots
mm/damon/core: add trace point for damos stat per apply interval
.../ABI/testing/sysfs-kernel-mm-damon | 13 ++++++
Documentation/admin-guide/mm/damon/usage.rst | 11 ++---
Documentation/mm/damon/design.rst | 7 +++
include/linux/damon.h | 12 ++++--
include/trace/events/damon.h | 41 ++++++++++++++++++
mm/damon/core.c | 39 +++++++++++++++--
mm/damon/sysfs-schemes.c | 43 +++++++++++++++++++
7 files changed, 155 insertions(+), 11 deletions(-)
base-commit: 37164b8fc049b9a72b3f0fa9bf3241e8852931a9
--
2.47.3
^ permalink raw reply
* [PATCH v6] dma-buf: add some tracepoints to debug.
From: Xiang Gao @ 2025-12-16 6:39 UTC (permalink / raw)
To: sumit.semwal, christian.koenig, rostedt, mhiramat
Cc: linux-media, dri-devel, linux-kernel, mathieu.desnoyers, dhowells,
kuba, brauner, akpm, linux-trace-kernel, gaoxiang17
From: gaoxiang17 <gaoxiang17@xiaomi.com>
Since we can only inspect dmabuf by iterating over process FDs or the
dmabuf_list, we need to add our own tracepoints to track its status in
real time in production.
For example:
binder:3016_1-3102 [006] ...1. 255.126521: dma_buf_export: exp_name=qcom,system size=12685312 ino=2738
binder:3016_1-3102 [006] ...1. 255.126528: dma_buf_fd: exp_name=qcom,system size=12685312 ino=2738 fd=8
binder:3016_1-3102 [006] ...1. 255.126642: dma_buf_mmap_internal: exp_name=qcom,system size=28672 ino=2739
kworker/6:1-86 [006] ...1. 255.127194: dma_buf_put: exp_name=qcom,system size=12685312 ino=2738
RenderThread-9293 [006] ...1. 316.618179: dma_buf_get: exp_name=qcom,system size=12771328 ino=2762 fd=176
RenderThread-9293 [006] ...1. 316.618195: dma_buf_dynamic_attach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
RenderThread-9293 [006] ...1. 318.878220: dma_buf_detach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0
Signed-off-by: Xiang Gao <gaoxiang17@xiaomi.com>
---
drivers/dma-buf/dma-buf.c | 42 ++++++++-
include/trace/events/dma_buf.h | 154 +++++++++++++++++++++++++++++++++
2 files changed, 195 insertions(+), 1 deletion(-)
create mode 100644 include/trace/events/dma_buf.h
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 2bcf9ceca997..831973de76c4 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -35,6 +35,25 @@
#include "dma-buf-sysfs-stats.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/dma_buf.h>
+
+/*
+ * dmabuf->name must be accessed with holding dmabuf->name_lock.
+ * we need to take the lock around the tracepoint call itself where
+ * it is called in the code.
+ *
+ * Note: FUNC##_enabled() is a static branch that will only
+ * be set when the trace event is enabled.
+ */
+#define DMA_BUF_TRACE(FUNC, ...) \
+ do { \
+ if (FUNC##_enabled()) { \
+ guard(spinlock)(&dmabuf->name_lock); \
+ FUNC(__VA_ARGS__); \
+ } \
+ } while (0)
+
static inline int is_dma_buf_file(struct file *);
static DEFINE_MUTEX(dmabuf_list_mutex);
@@ -220,6 +239,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
dmabuf->size >> PAGE_SHIFT)
return -EINVAL;
+ DMA_BUF_TRACE(trace_dma_buf_mmap_internal, dmabuf);
+
return dmabuf->ops->mmap(dmabuf, vma);
}
@@ -745,6 +766,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
__dma_buf_list_add(dmabuf);
+ DMA_BUF_TRACE(trace_dma_buf_export, dmabuf);
+
return dmabuf;
err_dmabuf:
@@ -779,6 +802,8 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags)
fd_install(fd, dmabuf->file);
+ DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd);
+
return fd;
}
EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
@@ -794,6 +819,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
struct dma_buf *dma_buf_get(int fd)
{
struct file *file;
+ struct dma_buf *dmabuf;
file = fget(fd);
@@ -805,7 +831,11 @@ struct dma_buf *dma_buf_get(int fd)
return ERR_PTR(-EINVAL);
}
- return file->private_data;
+ dmabuf = file->private_data;
+
+ DMA_BUF_TRACE(trace_dma_buf_get, dmabuf, fd);
+
+ return dmabuf;
}
EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF");
@@ -825,6 +855,8 @@ void dma_buf_put(struct dma_buf *dmabuf)
return;
fput(dmabuf->file);
+
+ DMA_BUF_TRACE(trace_dma_buf_put, dmabuf);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
@@ -979,6 +1011,9 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
list_add(&attach->node, &dmabuf->attachments);
dma_resv_unlock(dmabuf->resv);
+ DMA_BUF_TRACE(trace_dma_buf_dynamic_attach, dmabuf, attach,
+ dma_buf_attachment_is_dynamic(attach), dev);
+
return attach;
err_attach:
@@ -1023,6 +1058,9 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
if (dmabuf->ops->detach)
dmabuf->ops->detach(dmabuf, attach);
+ DMA_BUF_TRACE(trace_dma_buf_detach, dmabuf, attach,
+ dma_buf_attachment_is_dynamic(attach), attach->dev);
+
kfree(attach);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
@@ -1488,6 +1526,8 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
vma_set_file(vma, dmabuf->file);
vma->vm_pgoff = pgoff;
+ DMA_BUF_TRACE(trace_dma_buf_mmap, dmabuf);
+
return dmabuf->ops->mmap(dmabuf, vma);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF");
diff --git a/include/trace/events/dma_buf.h b/include/trace/events/dma_buf.h
new file mode 100644
index 000000000000..81ee4d05979c
--- /dev/null
+++ b/include/trace/events/dma_buf.h
@@ -0,0 +1,154 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dma_buf
+
+#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DMA_BUF_H
+
+#include <linux/dma-buf.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(dma_buf,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ ),
+
+ TP_printk("exp_name=%s size=%zu ino=%lu",
+ __get_str(exp_name),
+ __entry->size,
+ __entry->ino)
+);
+
+DECLARE_EVENT_CLASS(dma_buf_attach_dev,
+
+ TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
+
+ TP_ARGS(dmabuf, attach, is_dynamic, dev),
+
+ TP_STRUCT__entry(
+ __string(dev_name, dev_name(dev))
+ __string(exp_name, dmabuf->exp_name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ __field(struct dma_buf_attachment *, attach)
+ __field(bool, is_dynamic)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev_name);
+ __assign_str(exp_name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ __entry->is_dynamic = is_dynamic;
+ __entry->attach = attach;
+ ),
+
+ TP_printk("exp_name=%s size=%zu ino=%lu attachment:%p is_dynamic=%d dev_name=%s",
+ __get_str(exp_name),
+ __entry->size,
+ __entry->ino,
+ __entry->attach,
+ __entry->is_dynamic,
+ __get_str(dev_name))
+);
+
+DECLARE_EVENT_CLASS(dma_buf_fd,
+
+ TP_PROTO(struct dma_buf *dmabuf, int fd),
+
+ TP_ARGS(dmabuf, fd),
+
+ TP_STRUCT__entry(
+ __string(exp_name, dmabuf->exp_name)
+ __field(size_t, size)
+ __field(ino_t, ino)
+ __field(int, fd)
+ ),
+
+ TP_fast_assign(
+ __assign_str(exp_name);
+ __entry->size = dmabuf->size;
+ __entry->ino = dmabuf->file->f_inode->i_ino;
+ __entry->fd = fd;
+ ),
+
+ TP_printk("exp_name=%s size=%zu ino=%lu fd=%d",
+ __get_str(exp_name),
+ __entry->size,
+ __entry->ino,
+ __entry->fd)
+);
+
+DEFINE_EVENT(dma_buf, dma_buf_export,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf)
+);
+
+DEFINE_EVENT(dma_buf, dma_buf_mmap_internal,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf)
+);
+
+DEFINE_EVENT(dma_buf, dma_buf_mmap,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf)
+);
+
+DEFINE_EVENT(dma_buf, dma_buf_put,
+
+ TP_PROTO(struct dma_buf *dmabuf),
+
+ TP_ARGS(dmabuf)
+);
+
+DEFINE_EVENT(dma_buf_attach_dev, dma_buf_dynamic_attach,
+
+ TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
+
+ TP_ARGS(dmabuf, attach, is_dynamic, dev)
+);
+
+DEFINE_EVENT(dma_buf_attach_dev, dma_buf_detach,
+
+ TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach, bool is_dynamic, struct device *dev),
+
+ TP_ARGS(dmabuf, attach, is_dynamic, dev)
+);
+
+DEFINE_EVENT(dma_buf_fd, dma_buf_fd,
+
+ TP_PROTO(struct dma_buf *dmabuf, int fd),
+
+ TP_ARGS(dmabuf, fd)
+);
+
+DEFINE_EVENT(dma_buf_fd, dma_buf_get,
+
+ TP_PROTO(struct dma_buf *dmabuf, int fd),
+
+ TP_ARGS(dmabuf, fd)
+);
+
+#endif /* _TRACE_DMA_BUF_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v6 4/6] perf script: Display PERF_RECORD_CALLCHAIN_DEFERRED
From: Namhyung Kim @ 2025-12-16 4:48 UTC (permalink / raw)
To: Jens Remus
Cc: Arnaldo Carvalho de Melo, Ian Rogers, James Clark, Jiri Olsa,
Adrian Hunter, Peter Zijlstra, Ingo Molnar, LKML,
linux-perf-users, Steven Rostedt, Josh Poimboeuf, Indu Bhagat,
Mathieu Desnoyers, linux-trace-kernel, bpf, Heiko Carstens,
Vasily Gorbik
In-Reply-To: <9fe12698-2fd5-41fe-8505-735d73eae0a2@linux.ibm.com>
Hello!
On Fri, Dec 12, 2025 at 01:11:38PM +0100, Jens Remus wrote:
> Hello Namhyung,
>
> following is an observation from my attempt to enable unwind user fp on
> s390 using s390 back chain instead of frame pointer and relaxing the
> s390-specific IP validation check.
>
> When capturing call graphs of a Java application the list of "unwound"
> user space IPs may contain invalid entries, such as 0x0, 0xdeaddeaf,
> and 0xffffffffffffff. IPs that exceed PERF_CONTEXT_MAX, such as the
> latter, cause perf not to display any deferred (or merged) call chain.
> Note that this is not caused by your patch series.
Right, it's not a real IP so perf ABI treats them as a magic context.
>
> While re-adding the s390-specific IP checks would "hide" those, I found
> that the call graphs look good otherwise. That is the back chain seems
> to be intact. It is just the user space application (e.g. Java JRE) not
> correctly adhering to the ABI and saving the return address to the
> specified location on the stack, causing bogus IPs to be reported.
>
> Could perf be improved to handle those user space IPs that exceed
> PERF_CONTEXT_MAX?
Ideally we should not have them in the first place. Is it a JRE issue
or your s390 unwinder issue? Is it possible to ignore them in the
unwinder?
>
> Is there otherwise guidance how unwind user and/or the s390
> implementation should deal with such IPs? Should it stop taking the
> deferred calltrace? Should it substitute those with e.g 0, so that
> perf can display them?
>
>
> Sample for IP == deaddeaf (perf displays this correctly):
>
> java 1084 33.086790: DEFERRED CALLCHAIN [cookie: 2000001f9]
> 3ff983f071c java.lang.String CryptoBench.crypt(java.lang.String)+0x89c (/tmp/perf-1082.map)
> 3ff983ff894 void CryptoBench.execute()+0x94 (/tmp/perf-1082.map)
> ! --> deaddeaf [unknown] ([unknown])
> 3ff97e37900 StubRoutines (initial stubs)+0x80 (/tmp/perf-1082.map)
> 3ff97e41080 Interpreter+0x3300 (/tmp/perf-1082.map)
> 3ffae2d11de JavaCalls::call(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x3e (/usr/lib/jvm/.../libjvm.so)
> 3ffae38df92 jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*) [clone .constprop.1]+0x242 (/usr/lib/jvm/.../libjvm.so)
> 3ffae390e86 jni_CallStaticVoidMethod+0x116 (/usr/lib/jvm/.../libjvm.so)
> 3ffaf08b07e JavaMain+0x113e (/usr/lib/jvm/.../libjli.so)
> 3ffaf08e040 ThreadJavaMain+0x20 (/usr/lib/jvm/.../libjli.so)
> 3ffaedabbd8 start_thread+0x198 (/usr/lib64/libc.so.6)
> 3ffaee2b950 thread_start+0x10 (/usr/lib64/libc.so.6)
>
>
> Sample for IP == 0 (perf displays this correctly):
>
> java 1084 33.021987: DEFERRED CALLCHAIN [cookie: 20000017b]
> 3ff983f067c java.lang.String CryptoBench.crypt(java.lang.String)+0x7fc (/tmp/perf-1082.map)
> 3ff9098aa88 void CryptoBench.execute()+0x748 (/tmp/perf-1082.map)
> ! --> 0 [unknown] ([unknown])
> 3ff97e37900 StubRoutines (initial stubs)+0x80 (/tmp/perf-1082.map)
> 3ff97e41080 Interpreter+0x3300 (/tmp/perf-1082.map)
> 3ffae2d11de JavaCalls::call(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x3e (/usr/lib/jvm/.../libjvm.so)
> 3ffae38df92 jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*) [clone .constprop.1]+0x242 (/usr/lib/jvm/.../libjvm.so)
> 3ffae390e86 jni_CallStaticVoidMethod+0x116 (/usr/lib/jvm/.../libjvm.so)
> 3ffaf08b07e JavaMain+0x113e (/usr/lib/jvm/.../libjli.so)
> 3ffaf08e040 ThreadJavaMain+0x20 (/usr/lib/jvm/.../libjli.so)
> 3ffaedabbd8 start_thread+0x198 (/usr/lib64/libc.so.6)
> 3ffaee2b950 thread_start+0x10 (/usr/lib64/libc.so.6)
>
> Note that for the IP==0 case I am thinking about adding a common unwind
> user check, to stop taking the deferred calltrace.
>
>
> Sample for IP == ffffffffffffff (perf does not display any call chain):
>
> # perf script
> ...
> java 1084 44.004346: 1001001 task-clock:ppp:
>
> ...
> [next entry]
>
> # perf script --no-merge-callchain
> ...
> java 1084 44.004346: 1001001 task-clock:ppp:
> 400000079 (cookie) ([unknown])
>
> java 1084 44.004348: DEFERRED CALLCHAIN [cookie: 400000079]
>
> ...
> [next entry]
>
> # perf report -D
> ...
> 44004346257 0x17718 [0x40]: PERF_RECORD_SAMPLE(IP, 0x2): 1082/1084: 0x3ffa3e413aa period: 1001001 addr: 0
> ... FP chain: nr:2
> ..... 0: fffffffffffffd80
> ..... 1: 0000000400000079
> ...... (deferred)
> ... thread: java:1084
> ...... dso: /tmp/perf-1082.map
>
> 0x17758@perf.data [0xd0]: event: 22
> .
> . ... raw event: size 208 bytes
> . 0000: 00 00 00 16 00 02 00 d0 00 00 00 04 00 00 00 79 ...............y
> . 0010: 00 00 00 00 00 00 00 15 00 00 03 ff a3 e4 13 aa ................
> . 0020: 00 00 03 ff 38 09 e2 d0 00 00 03 ff 38 09 e1 30 ....8.......8..0
> . 0030: 00 00 03 ff b9 5f df 68 00 00 00 00 00 00 00 00 ....._.h........
> . 0040: 00 00 03 ff b9 5f e1 28 00 00 03 ff b9 5f e1 d0 ....._.(....._..
> . 0050: 00 57 80 88 8e 76 47 a5 00 00 03 ff a3 e4 37 f2 .W...vG.......7.
> . 0060: ff ff ff ff ff ff ff ff 00 00 03 ff a3 e4 a1 fc ................
> . 0070: 00 00 00 00 00 00 00 00 00 00 03 ff a3 e3 79 00 ..............y.
> . 0080: 00 00 03 ff a3 e4 10 80 00 00 03 ff b9 dd 11 de ................
> . 0090: 00 00 03 ff b9 e8 df 92 00 00 03 ff b9 e9 0e 86 ................
> . 00a0: 00 00 03 ff ba b8 b0 7e 00 00 03 ff ba b8 e0 40 .......~.......@
> . 00b0: 00 00 03 ff ba 8a bb d8 00 00 03 ff ba 92 b9 50 ...............P
> . 00c0: 00 00 04 3a 00 00 04 3c 00 00 00 0a 3e dd 13 c0 ...:...<....>...
>
> 44004348864 0x17758 [0xd0]: PERF_RECORD_CALLCHAIN_DEFERRED(IP, 0x2): 1082/1084: 0x400000079
> ... FP chain: nr:21
> ..... 0: 000003ffa3e413aa
> ..... 1: 000003ff3809e2d0
> ..... 2: 000003ff3809e130
> ..... 3: 000003ffb95fdf68
> ..... 4: 0000000000000000
> ..... 5: 000003ffb95fe128
> ..... 6: 000003ffb95fe1d0
> ..... 7: 005780888e7647a5
> ..... 8: 000003ffa3e437f2
> ..... 9: ffffffffffffffff <-- !
> ..... 10: 000003ffa3e4a1fc
> ..... 11: 0000000000000000
> ..... 12: 000003ffa3e37900
> ..... 13: 000003ffa3e41080
> ..... 14: 000003ffb9dd11de
> ..... 15: 000003ffb9e8df92
> ..... 16: 000003ffb9e90e86
> ..... 17: 000003ffbab8b07e
> ..... 18: 000003ffbab8e040
> ..... 19: 000003ffba8abbd8
> ..... 20: 000003ffba92b950
> : unhandled!
>
> ...
> [next entry]
>
>
> On 11/21/2025 12:48 AM, Namhyung Kim wrote:
> > Handle the deferred callchains in the script output.
> >
> > $ perf script
> > ...
> > pwd 2312 121.163435: 249113 cpu/cycles/P:
> > ffffffff845b78d8 __build_id_parse.isra.0+0x218 ([kernel.kallsyms])
> > ffffffff83bb5bf6 perf_event_mmap+0x2e6 ([kernel.kallsyms])
> > ffffffff83c31959 mprotect_fixup+0x1e9 ([kernel.kallsyms])
> > ffffffff83c31dc5 do_mprotect_pkey+0x2b5 ([kernel.kallsyms])
> > ffffffff83c3206f __x64_sys_mprotect+0x1f ([kernel.kallsyms])
> > ffffffff845e6692 do_syscall_64+0x62 ([kernel.kallsyms])
> > ffffffff8360012f entry_SYSCALL_64_after_hwframe+0x76 ([kernel.kallsyms])
> > b00000006 (cookie) ([unknown])
> >
> > pwd 2312 121.163447: DEFERRED CALLCHAIN [cookie: b00000006]
> > 7f18fe337fa7 mprotect+0x7 (/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
> > 7f18fe330e0f _dl_sysdep_start+0x7f (/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
> > 7f18fe331448 _dl_start_user+0x0 (/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
>
> > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
>
> > +static int process_deferred_sample_event(const struct perf_tool *tool,
> > + union perf_event *event,
> > + struct perf_sample *sample,
> > + struct evsel *evsel,
> > + struct machine *machine)
> > +{
>
> > + perf_sample__fprintf_start(scr, sample, al.thread, evsel,
> > + PERF_RECORD_CALLCHAIN_DEFERRED, fp);
> > + fprintf(fp, "DEFERRED CALLCHAIN [cookie: %llx]",
> > + (unsigned long long)event->callchain_deferred.cookie);
> > +
> > + if (PRINT_FIELD(IP)) {
> > + struct callchain_cursor *cursor = NULL;
> > +
> > + if (symbol_conf.use_callchain && sample->callchain) {
> > + cursor = get_tls_callchain_cursor();
> > + if (thread__resolve_callchain(al.thread, cursor, evsel,
> > + sample, NULL, NULL,
> > + scripting_max_stack)) {
>
> thread__resolve_callchain()
> calls __thread__resolve_callchain()
> calls thread__resolve_callchain_sample():
>
> for (i = first_call, nr_entries = 0;
> i < chain_nr && nr_entries < max_stack; i++) {
> ...
> ip = chain->ips[j];
> if (ip < PERF_CONTEXT_MAX) <-- IP=ff..ff is greater than PERF_CONTEXT_MAX
> ++nr_entries;
Right.
> ...
> err = add_callchain_ip(thread, cursor, parent,
> root_al, &cpumode, ip,
> false, NULL, NULL, 0, symbols);
>
> if (err)
> return (err < 0) ? err : 0;
>
> calls add_callchain_ip:
>
> if (ip >= PERF_CONTEXT_MAX) {
> switch (ip) {
> case PERF_CONTEXT_HV:
> *cpumode = PERF_RECORD_MISC_HYPERVISOR;
> break;
> case PERF_CONTEXT_KERNEL:
> *cpumode = PERF_RECORD_MISC_KERNEL;
> break;
> case PERF_CONTEXT_USER:
> case PERF_CONTEXT_USER_DEFERRED:
> *cpumode = PERF_RECORD_MISC_USER;
> break;
> default:
> pr_debug("invalid callchain context: " <-- IP=ff..ff reaches default case
> "%"PRId64"\n", (s64) ip);
We may skip -1 if it's Java and *cpumode is already USER and it's s390.
But I'd like to understand the situation first.
Thanks,
Namhyung
> /*
> * It seems the callchain is corrupted.
> * Discard all.
> */
> callchain_cursor_reset(cursor);
> err = 1;
> goto out;
> }
>
> > + pr_info("cannot resolve deferred callchains\n");
> > + cursor = NULL;
> > + }
> > + }
> > +
> > + fputc(cursor ? '\n' : ' ', fp);
> > + sample__fprintf_sym(sample, &al, 0, output[type].print_ip_opts,
> > + cursor, symbol_conf.bt_stop_list, fp);
> > + }
> Thanks and regards,
> Jens
> --
> Jens Remus
> Linux on Z Development (D3303)
> +49-7031-16-1128 Office
> jremus@de.ibm.com
>
> IBM
>
> IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
> IBM Data Privacy Statement: https://www.ibm.com/privacy/
>
^ permalink raw reply
* [PATCH] ftrace: fix address for jmp mode in t_show
From: Menglong Dong @ 2025-12-16 3:45 UTC (permalink / raw)
To: rostedt
Cc: mhiramat, mark.rutland, mathieu.desnoyers, menglong8.dong, ast,
jiang.biao, linux-kernel, linux-trace-kernel
The address from ftrace_find_rec_direct() is printed directly in t_show().
This can mislead symbol offsets if it has the "jmp" bit in the last bit.
Fix this by printing the address that returned by ftrace_jmp_get().
Fixes: 25e4e3565d45 ("ftrace: Introduce FTRACE_OPS_FL_JMP")
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
kernel/trace/ftrace.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index bbb37c0f8c6c..d4c41fb76a25 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4492,8 +4492,12 @@ static int t_show(struct seq_file *m, void *v)
unsigned long direct;
direct = ftrace_find_rec_direct(rec->ip);
- if (direct)
- seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
+ if (direct) {
+ seq_printf(m, ftrace_is_jmp(direct) ?
+ "\n\tdirect(jmp)-->%pS" :
+ "\n\tdirect-->%pS",
+ (void *)ftrace_jmp_get(direct));
+ }
}
}
--
2.52.0
^ permalink raw reply related
* Re: [PATCH v3 1/4] kernel.h: drop STACK_MAGIC macro
From: Aaron Tomlin @ 2025-12-16 3:05 UTC (permalink / raw)
To: Yury Norov (NVIDIA)
Cc: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Andy Shevchenko, Christophe Leroy, Randy Dunlap, Ingo Molnar,
Jani Nikula, Joonas Lahtinen, David Laight, Petr Pavlu,
Andi Shyti, Rodrigo Vivi, Tvrtko Ursulin, Daniel Gomez,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Andrew Morton, linux-kernel, intel-gfx, dri-devel, linux-modules,
linux-trace-kernel, Jani Nikula
In-Reply-To: <20251205175237.242022-2-yury.norov@gmail.com>
On Fri, Dec 05, 2025 at 12:52:32PM -0500, Yury Norov (NVIDIA) wrote:
> The macro was introduced in 1994, v1.0.4, for stacks protection. Since
> that, people found better ways to protect stacks, and now the macro is
> only used by i915 selftests. Move it to a local header and drop from
> the kernel.h.
>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Acked-by: Randy Dunlap <rdunlap@infradead.org>
> Acked-by: Jani Nikula <jani.nikula@intel.com>
> Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
> Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
> ---
> drivers/gpu/drm/i915/gt/selftest_ring_submission.c | 1 +
> drivers/gpu/drm/i915/i915_selftest.h | 2 ++
> include/linux/kernel.h | 2 --
> 3 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/selftest_ring_submission.c b/drivers/gpu/drm/i915/gt/selftest_ring_submission.c
> index 87ceb0f374b6..600333ae6c8c 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_ring_submission.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_ring_submission.c
> @@ -3,6 +3,7 @@
> * Copyright © 2020 Intel Corporation
> */
>
> +#include "i915_selftest.h"
> #include "intel_engine_pm.h"
> #include "selftests/igt_flush_test.h"
>
> diff --git a/drivers/gpu/drm/i915/i915_selftest.h b/drivers/gpu/drm/i915/i915_selftest.h
> index bdf3e22c0a34..72922028f4ba 100644
> --- a/drivers/gpu/drm/i915/i915_selftest.h
> +++ b/drivers/gpu/drm/i915/i915_selftest.h
> @@ -26,6 +26,8 @@
>
> #include <linux/types.h>
>
> +#define STACK_MAGIC 0xdeadbeef
> +
> struct pci_dev;
> struct drm_i915_private;
>
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 5b46924fdff5..61d63c57bc2d 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -40,8 +40,6 @@
>
> #include <uapi/linux/kernel.h>
>
> -#define STACK_MAGIC 0xdeadbeef
> -
> struct completion;
> struct user;
>
> --
> 2.43.0
>
>
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
--
Aaron Tomlin
^ permalink raw reply
* Re: [PATCHv5 bpf-next 1/9] ftrace,bpf: Remove FTRACE_OPS_FL_JMP ftrace_ops flag
From: Menglong Dong @ 2025-12-16 1:27 UTC (permalink / raw)
To: jolsa, rostedt, revest, mark.rutland, bot+bpf-ci
Cc: bpf, linux-kernel, linux-trace-kernel, linux-arm-kernel, ast,
daniel, andrii, menglong8.dong, song, ast, andrii, daniel,
martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai
In-Reply-To: <95c13c0b793604796037ca67c191e1bfce22770dd020107c7179a698c5d49b91@mail.kernel.org>
On 2025/12/16 05:31 bot+bpf-ci@kernel.org write:
> > diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> > index 015dd1049bea..505b7d3f5641 100644
> > --- a/include/linux/ftrace.h
> > +++ b/include/linux/ftrace.h
>
> [ ... ]
>
> > diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> > index 976d89011b15..b9a358d7a78f 100644
> > --- a/kernel/bpf/trampoline.c
> > +++ b/kernel/bpf/trampoline.c
> > @@ -214,10 +214,15 @@ static int modify_fentry(struct bpf_trampoline *tr, u32 orig_flags,
> > int ret;
> >
> > if (tr->func.ftrace_managed) {
> > + unsigned long addr = (unsigned long) new_addr;
> > +
> > + if (bpf_trampoline_use_jmp(tr->flags))
> > + addr = ftrace_jmp_set(addr);
> > +
> > if (lock_direct_mutex)
> > - ret = modify_ftrace_direct(tr->fops, (long)new_addr);
> > + ret = modify_ftrace_direct(tr->fops, addr);
> > else
> > - ret = modify_ftrace_direct_nolock(tr->fops, (long)new_addr);
> > + ret = modify_ftrace_direct_nolock(tr->fops, addr);
> > } else {
> > ret = bpf_trampoline_update_fentry(tr, orig_flags, old_addr,
> > new_addr);
> > @@ -240,10 +245,15 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
> > }
> >
> > if (tr->func.ftrace_managed) {
> > + unsigned long addr = (unsigned long) new_addr;
> > +
> > + if (bpf_trampoline_use_jmp(tr->flags))
> > + addr = ftrace_jmp_set(addr);
> > +
> > ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1);
> > if (ret)
> > return ret;
> > - ret = register_ftrace_direct(tr->fops, (long)new_addr);
> > + ret = register_ftrace_direct(tr->fops, addr);
> > } else {
> > ret = bpf_trampoline_update_fentry(tr, 0, NULL, new_addr);
> > }
>
> After this change, register_ftrace_direct() receives an address with
> the LSB bit already set (via ftrace_jmp_set) and stores it as-is in
> entry->direct. This address then flows through to ftrace_find_rec_direct()
> which returns entry->direct unchanged.
>
> In available_filter_functions_show():
>
> direct = ftrace_find_rec_direct(rec->ip);
> if (direct)
> seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
>
> Can the debug output show misleading symbol offsets? When the LSB is
> set, %pS will resolve addresses like "function+0x1" instead of just
> "function". This makes ftrace debug output harder to read for users
> trying to understand direct call attachments.
>
> The fix would be to strip the LSB bit before printing:
> seq_printf(m, "\n\tdirect-->%pS", (void *)ftrace_jmp_get(direct));
Ah, this is a good point. However, it's totally another problem, and
I'll follow up it.
Thanks!
Menglong Dong
>
> [ ... ]
>
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index bbb37c0f8c6c..b0dc911411f1 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
> > @@ -6017,15 +6017,8 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> > if (ftrace_hash_empty(hash))
> > return -EINVAL;
> >
> > - /* This is a "raw" address, and this should never happen. */
> > - if (WARN_ON_ONCE(ftrace_is_jmp(addr)))
> > - return -EINVAL;
> > -
> > mutex_lock(&direct_mutex);
> >
> > - if (ops->flags & FTRACE_OPS_FL_JMP)
> > - addr = ftrace_jmp_set(addr);
> > -
> > /* Make sure requested entries are not already registered.. */
> > size = 1 << hash->size_bits;
> > for (i = 0; i < size; i++) {
>
> [ ... ]
>
> > @@ -6146,13 +6139,6 @@ __modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
> >
> > lockdep_assert_held_once(&direct_mutex);
> >
> > - /* This is a "raw" address, and this should never happen. */
> > - if (WARN_ON_ONCE(ftrace_is_jmp(addr)))
> > - return -EINVAL;
> > -
> > - if (ops->flags & FTRACE_OPS_FL_JMP)
> > - addr = ftrace_jmp_set(addr);
> > -
> > /* Enable the tmp_ops to have the same functions as the direct ops */
> > ftrace_ops_init(&tmp_ops);
> > tmp_ops.func_hash = ops->func_hash;
>
> [ ... ]
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/20247816064
>
^ permalink raw reply
* Re: [PATCH v1 1/1] bpf: Disable -Wsuggest-attribute=format
From: Ihor Solodrai @ 2025-12-16 0:53 UTC (permalink / raw)
To: Andy Shevchenko, Alexei Starovoitov, Steven Rostedt, bpf,
linux-kernel, linux-trace-kernel, Andrii Nakryiko
Cc: Daniel Borkmann, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, Jiri Olsa, Masami Hiramatsu, Mathieu Desnoyers,
kernel test robot
In-Reply-To: <982ded3a-a973-4c2e-ae7e-af01d346d582@linux.dev>
On 12/15/25 4:11 PM, Ihor Solodrai wrote:
> On 12/10/25 5:12 AM, Andy Shevchenko wrote:
>> [...]
>> -obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o log.o token.o liveness.o
>> +obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o tnum.o log.o token.o liveness.o
>> +
>> +obj-$(CONFIG_BPF_SYSCALL) += helpers.o stream.o
>> +# The ____bpf_snprintf() uses the format string that triggers a compiler warning.
>> +CFLAGS_helpers.o += -Wno-suggest-attribute=format
>> +# The bpf_stream_vprintk_impl() uses the format string that triggers a compiler warning.
>> +CFLAGS_stream.o += -Wno-suggest-attribute=format
>
> Hi Andy,
>
> This flag does not exist in clang:
>
> $ LLVM=1 make -j$(nproc)
> [...]
> $ LLVM=1 make
> CALL scripts/checksyscalls.sh
> DESCEND objtool
> INSTALL libsubcmd_headers
> DESCEND bpf/resolve_btfids
> INSTALL libsubcmd_headers
> CC kernel/trace/bpf_trace.o
> error: unknown warning option '-Wno-suggest-attribute=format'; did you mean '-Wno-property-attribute-mismatch'? [-Werror,-Wunknown-warning-option]
> make[4]: *** [scripts/Makefile.build:287: kernel/trace/bpf_trace.o] Error 1
> make[3]: *** [scripts/Makefile.build:556: kernel/trace] Error 2
> make[2]: *** [scripts/Makefile.build:556: kernel] Error 2
> make[1]: *** [/home/isolodrai/kernels/bpf-next/Makefile:2030: .] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
>
> We should probably conditionalize the flag addition in the makefile.
Just confirmed that the patch below fixes LLVM=1 build:
From 842b31ff3384df65bb6f13763464daa03ba4f025 Mon Sep 17 00:00:00 2001
From: Ihor Solodrai <isolodrai@meta.com>
Date: Mon, 15 Dec 2025 16:45:19 -0800
Subject: [PATCH] bpf: Ensure CC is set to GCC for
-Wno-suggest-attribute=format
LLVM=1 kernel build got broken because clang does not have
-Wno-suggest-attribute=format option.
Check for CONFIG_CC_IS_GCC before setting this option.
Fixes: ba34388912b5 ("bpf: Disable false positive -Wsuggest-attribute=format warning")
Closes: https://lore.kernel.org/bpf/20251210131234.3185985-1-andriy.shevchenko@linux.intel.com/
Signed-off-by: Ihor Solodrai <isolodrai@meta.com>
---
kernel/bpf/Makefile | 2 ++
kernel/trace/Makefile | 2 ++
2 files changed, 4 insertions(+)
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index d7bcdb1fd35a..7a33c701e5fb 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -17,8 +17,10 @@ obj-$(CONFIG_BPF_JIT) += trampoline.o
obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.o rqspinlock.o stream.o
# Disable incorrect warning. bpf printf-like helpers cannot use
# gnu_printf attribute.
+ifeq ($(CONFIG_CC_IS_GCC),y)
CFLAGS_helpers.o += -Wno-suggest-attribute=format
CFLAGS_stream.o += -Wno-suggest-attribute=format
+endif
ifeq ($(CONFIG_MMU)$(CONFIG_64BIT),yy)
obj-$(CONFIG_BPF_SYSCALL) += arena.o range_tree.o
endif
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 5869c1f1af89..06705d6fed2c 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -90,7 +90,9 @@ obj-$(CONFIG_USER_EVENTS) += trace_events_user.o
obj-$(CONFIG_BPF_EVENTS) += bpf_trace.o
# Disable incorrect warning. bpf printf-like helpers cannot use
# gnu_printf attribute.
+ifeq ($(CONFIG_CC_IS_GCC),y)
CFLAGS_bpf_trace.o += -Wno-suggest-attribute=format
+endif
obj-$(CONFIG_KPROBE_EVENTS) += trace_kprobe.o
obj-$(CONFIG_TRACEPOINTS) += error_report-traces.o
obj-$(CONFIG_TRACEPOINTS) += power-traces.o
--
2.47.3
>
> Or better yet, address the root cause as suggested in the thread.
>
> BPF CI is red on bpf branch at the moment:
> https://github.com/kernel-patches/bpf/actions/runs/20243520506/job/58144348281
>
>>
>> [...]
>
^ permalink raw reply related
* Re: [PATCH v1 1/1] bpf: Disable -Wsuggest-attribute=format
From: Ihor Solodrai @ 2025-12-16 0:11 UTC (permalink / raw)
To: Andy Shevchenko, Alexei Starovoitov, Steven Rostedt, bpf,
linux-kernel, linux-trace-kernel, Andrii Nakryiko
Cc: Daniel Borkmann, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, Jiri Olsa, Masami Hiramatsu, Mathieu Desnoyers,
kernel test robot
In-Reply-To: <20251210131234.3185985-1-andriy.shevchenko@linux.intel.com>
On 12/10/25 5:12 AM, Andy Shevchenko wrote:
> The printing functions in BPF code are using printf() type of format,
> and compiler is not happy about them as is:
>
> kernel/bpf/helpers.c:1069:9: error: function ‘____bpf_snprintf’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format]
> 1069 | err = bstr_printf(str, str_size, fmt, data.bin_args);
> | ^~~
>
> kernel/bpf/stream.c:241:9: error: function ‘bpf_stream_vprintk_impl’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format]
> 241 | ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt__str, data.bin_args);
> | ^~~
>
> kernel/trace/bpf_trace.c:377:9: error: function ‘____bpf_trace_printk’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format]
> 377 | ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args);
> | ^~~
>
> kernel/trace/bpf_trace.c:433:9: error: function ‘____bpf_trace_vprintk’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format]
> 433 | ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args);
> | ^~~
>
> kernel/trace/bpf_trace.c:475:9: error: function ‘____bpf_seq_printf’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format]
> 475 | seq_bprintf(m, fmt, data.bin_args);
> | ^~~~~~~~~~~
>
> Fix the compilation errors by disabling that warning since the code is
> generated and warning is not so useful in this case — it can't check
> the parameters for now.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202512061425.x0qTt9ww-lkp@intel.com/
> Closes: https://lore.kernel.org/oe-kbuild-all/202512061640.9hKTnB8p-lkp@intel.com/
> Closes: https://lore.kernel.org/oe-kbuild-all/202512081321.2h9ThWTg-lkp@intel.com/
> Fixes: 5ab154f1463a ("bpf: Introduce BPF standard streams")
> Fixes: 10aceb629e19 ("bpf: Add bpf_trace_vprintk helper")
> Fixes: 7b15523a989b ("bpf: Add a bpf_snprintf helper")
> Fixes: 492e639f0c22 ("bpf: Add bpf_seq_printf and bpf_seq_write helpers")
> Fixes: f3694e001238 ("bpf: add BPF_CALL_x macros for declaring helpers")
> Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> kernel/bpf/Makefile | 11 +++++++++--
> kernel/trace/Makefile | 6 ++++++
> 2 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
> index 232cbc97434d..cf7e8a972f98 100644
> --- a/kernel/bpf/Makefile
> +++ b/kernel/bpf/Makefile
> @@ -6,7 +6,14 @@ cflags-nogcse-$(CONFIG_X86)$(CONFIG_CC_IS_GCC) := -fno-gcse
> endif
> CFLAGS_core.o += -Wno-override-init $(cflags-nogcse-yy)
>
> -obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o log.o token.o liveness.o
> +obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o tnum.o log.o token.o liveness.o
> +
> +obj-$(CONFIG_BPF_SYSCALL) += helpers.o stream.o
> +# The ____bpf_snprintf() uses the format string that triggers a compiler warning.
> +CFLAGS_helpers.o += -Wno-suggest-attribute=format
> +# The bpf_stream_vprintk_impl() uses the format string that triggers a compiler warning.
> +CFLAGS_stream.o += -Wno-suggest-attribute=format
Hi Andy,
This flag does not exist in clang:
$ LLVM=1 make -j$(nproc)
[...]
$ LLVM=1 make
CALL scripts/checksyscalls.sh
DESCEND objtool
INSTALL libsubcmd_headers
DESCEND bpf/resolve_btfids
INSTALL libsubcmd_headers
CC kernel/trace/bpf_trace.o
error: unknown warning option '-Wno-suggest-attribute=format'; did you mean '-Wno-property-attribute-mismatch'? [-Werror,-Wunknown-warning-option]
make[4]: *** [scripts/Makefile.build:287: kernel/trace/bpf_trace.o] Error 1
make[3]: *** [scripts/Makefile.build:556: kernel/trace] Error 2
make[2]: *** [scripts/Makefile.build:556: kernel] Error 2
make[1]: *** [/home/isolodrai/kernels/bpf-next/Makefile:2030: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
We should probably conditionalize the flag addition in the makefile.
Or better yet, address the root cause as suggested in the thread.
BPF CI is red on bpf branch at the moment:
https://github.com/kernel-patches/bpf/actions/runs/20243520506/job/58144348281
> +
> obj-$(CONFIG_BPF_SYSCALL) += bpf_iter.o map_iter.o task_iter.o prog_iter.o link_iter.o
> obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o bloom_filter.o
> obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o bpf_insn_array.o
> @@ -14,7 +21,7 @@ obj-$(CONFIG_BPF_SYSCALL) += bpf_local_storage.o bpf_task_storage.o
> obj-${CONFIG_BPF_LSM} += bpf_inode_storage.o
> obj-$(CONFIG_BPF_SYSCALL) += disasm.o mprog.o
> obj-$(CONFIG_BPF_JIT) += trampoline.o
> -obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.o rqspinlock.o stream.o
> +obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.o rqspinlock.o
> ifeq ($(CONFIG_MMU)$(CONFIG_64BIT),yy)
> obj-$(CONFIG_BPF_SYSCALL) += arena.o range_tree.o
> endif
> diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
> index fc5dcc888e13..1673b395c14c 100644
> --- a/kernel/trace/Makefile
> +++ b/kernel/trace/Makefile
> @@ -104,7 +104,13 @@ obj-$(CONFIG_TRACE_EVENT_INJECT) += trace_events_inject.o
> obj-$(CONFIG_SYNTH_EVENTS) += trace_events_synth.o
> obj-$(CONFIG_HIST_TRIGGERS) += trace_events_hist.o
> obj-$(CONFIG_USER_EVENTS) += trace_events_user.o
> +
> obj-$(CONFIG_BPF_EVENTS) += bpf_trace.o
> +# The BPF printing functions use the format string that triggers a compiler warning.
> +# Since the code is generated and warning is not so useful in this case (it can't
> +# check the parameters for now) disable the warning.
> +CFLAGS_bpf_trace.o += -Wno-suggest-attribute=format
> +
> obj-$(CONFIG_KPROBE_EVENTS) += trace_kprobe.o
> obj-$(CONFIG_TRACEPOINTS) += error_report-traces.o
> obj-$(CONFIG_TRACEPOINTS) += power-traces.o
^ permalink raw reply
* Re: [PATCH v1 1/1] bpf: Disable -Wsuggest-attribute=format
From: Steven Rostedt @ 2025-12-15 22:18 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Andrii Nakryiko, Andy Shevchenko, Alexei Starovoitov, bpf, LKML,
linux-trace-kernel, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Masami Hiramatsu, Mathieu Desnoyers, kernel test robot
In-Reply-To: <CAADnVQLZPYc0HWqQw7ma=G-t9UMXXo+aXomVkYAzoQt=0ZrQ=Q@mail.gmail.com>
On Mon, 15 Dec 2025 10:40:16 -0800
Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> > But I think instead of Makefile changes we should fix the root cause
> > here. And that seems to be just wrong __printf annotations for
> > seq_bprintf and bstr_printf. They are not printf-like, they should not
> > be marked as such, and then the compiler won't be wrongly suggesting
> > bpf_stream_vprintk_impl (and others that make use of either
> > bstr_printf or seq_bprintf) to be marked with __printf.
>
> yeah. commit 7bf819aa992f ("vsnprintf: Mark binary printing functions
> with __printf() attribute")
> should be reverted,
> but that somebody else problem and the revert would need to silence
> that incorrect warning in lib/vsprintf.c too.
From what I understand, the __printf(X, 0) simply quiets the warning, which
is why those two are:
__printf(3, 0) int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
__printf(3, 0) int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
Hence, it's not a big deal to have that. Actually, it does document that
the printf format is different than a normal printf, and that the arguments
are not the same as a normal printf.
I complained about this at first too (and never gave an acked-by), but
because it does quiet a warning, I also didn't nack it.
-- Steve
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox