On Tue 2026-06-23 15:34:58, Bradley Morgan wrote:
> Some callers handle SYS_INFO_ALL_BT themselves before calling sys_info().
> Add a helper that strips that bit without turning an all_bt only mask into
> a kernel_sys_info fallback.
> 
> Signed-off-by: Bradley Morgan <[email protected]>
> ---
> Changes since v1:
> - New patch for the shared helper suggested by Petr.
> 
>  include/linux/sys_info.h |  1 +
>  lib/sys_info.c           | 15 +++++++++++++++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/include/linux/sys_info.h b/include/linux/sys_info.h
> index a5bc3ea3d44b..87a841ec7b6a 100644
> --- a/include/linux/sys_info.h
> +++ b/include/linux/sys_info.h
> @@ -18,6 +18,7 @@
>  #define SYS_INFO_BLOCKED_TASKS               0x00000080
>  
>  void sys_info(unsigned long si_mask);
> +void sys_info_without_all_bt(unsigned long si_mask);
>  unsigned long sys_info_parse_param(char *str);
>  
>  #ifdef CONFIG_SYSCTL
> diff --git a/lib/sys_info.c b/lib/sys_info.c
> index f32a06ec9ed4..6afd4c697633 100644
> --- a/lib/sys_info.c
> +++ b/lib/sys_info.c
> @@ -164,3 +164,18 @@ void sys_info(unsigned long si_mask)
>  {
>       __sys_info(si_mask ? : kernel_si_mask);
>  }
> +
> +void sys_info_without_all_bt(unsigned long si_mask)
> +{
> +     unsigned long dump_mask = si_mask & ~SYS_INFO_ALL_BT;
> +
> +     /*
> +      * Do not call sys_info() when the caller context required only
> +      * backtraces from all CPUs. Otherwise sys_info() would fall back
> +      * to the generic kernel_si_mask.
> +      */
> +     if (si_mask && !dump_mask)
> +             return;
> +
> +     sys_info(dump_mask);
> +}

Sashiko AI pointed out that this function still migth trigger printing
duplicate backtraces when (si_mask == 0). It calls sys_info(0)
which falls back to kernel_si_mask which might have SYS_INFO_ALL_BT
bit set, see 
https://sashiko.dev/#/patchset/9b8c96e291696815d3c7de5d3e199298dee0279d.1782228656.git.include%40grrlz.net

=> we need to eventually disable the SYS_INFO_ALL_BT bit also
   in kernel_si_mask.

I think about creating a generic API which would allow to apply
a filter mask, something like:

>From 02fc810a801adc0fc4d1fd14318415719bdfc656 Mon Sep 17 00:00:00 2001
From: Bradley Morgan <[email protected]>
Date: Tue, 23 Jun 2026 15:34:58 +0000
Subject: [PATCH 1/4] sys_info: add helper for callers that print some
sys_info on their own

Some callers print some sys_info on their own before calling sys_info().
Add a helper which would allow to prevent a duplicated output.

It is a bit tricky because kernel_si_mask should be used only
when the call-specific si_mask is empty. But the duplicated
output must be prevented there as well.

Signed-off-by: Bradley Morgan <[email protected]>
Fixes: a9af76a78760 ("watchdog: add sys_info sysctls to dump sys info on system 
lockup") ?
Fixes: a9af76a78760 ("watchdog: add sys_info sysctls to dump sys info on system 
lockup")
---
 include/linux/sys_info.h |  1 +
 lib/sys_info.c           | 20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/linux/sys_info.h b/include/linux/sys_info.h
index a5bc3ea3d44b..f1c2552ca3d1 100644
--- a/include/linux/sys_info.h
+++ b/include/linux/sys_info.h
@@ -18,6 +18,7 @@
 #define SYS_INFO_BLOCKED_TASKS         0x00000080
 
 void sys_info(unsigned long si_mask);
+void sys_info_with_filter(unsigned long si_mask, unsigned long si_ignore_mask);
 unsigned long sys_info_parse_param(char *str);
 
 #ifdef CONFIG_SYSCTL
diff --git a/lib/sys_info.c b/lib/sys_info.c
index f32a06ec9ed4..d411fee10415 100644
--- a/lib/sys_info.c
+++ b/lib/sys_info.c
@@ -136,8 +136,10 @@ static int __init sys_info_sysctl_init(void)
 subsys_initcall(sys_info_sysctl_init);
 #endif
 
-static void __sys_info(unsigned long si_mask)
+static void __sys_info(unsigned long si_mask, unsigned long si_ignore_mask)
 {
+       si_mask &= ~si_ignore_mask;
+
        if (si_mask & SYS_INFO_TASKS)
                show_state();
 
@@ -160,7 +162,21 @@ static void __sys_info(unsigned long si_mask)
                show_state_filter(TASK_UNINTERRUPTIBLE);
 }
 
+void sys_info_with_filter(unsigned long si_mask, unsigned long si_ignore_mask)
+{
+       unsigned long dump_mask = si_mask & ~si_ignore_mask;
+
+       /*
+        * Do not fall back to kernel_si_mask when the caller context
+        * required only the ignored information.
+        */
+       if (si_mask && !dump_mask)
+               return;
+
+       __sys_info(dump_mask ? : kernel_si_mask, si_ignore_mask);
+}
+
 void sys_info(unsigned long si_mask)
 {
-       __sys_info(si_mask ? : kernel_si_mask);
+       sys_info_with_filter(si_mask, 0);
 }

The next patches might use sys_info_with_filter(si_mask,
SYS_INFO_ALL_BT) instead of sys_info_without_all_bt(si_mask).

Feel free to bike shed about the function name. Also I am not
sure whether to pass the filter as bits to filter or already
the complement (~mask).

Best Regards,
Petr


Reply via email to