[PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings

Andy Shevchenko posted 6 patches 5 months, 1 week ago
There is a newer version of this series
[PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings
Posted by Andy Shevchenko 5 months, 1 week ago
There is no need to keep a custom structure just for the need of
a plain array of strings. Replace struct sys_info_name with plain
array of strings.

With that done, simplify the code, in particular, naturally use
for_each_set_bit() when iterating over si_bits_global bitmap.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/sys_info.c | 48 +++++++++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/lib/sys_info.c b/lib/sys_info.c
index 6b0188b30227..5aecf4b6025f 100644
--- a/lib/sys_info.c
+++ b/lib/sys_info.c
@@ -1,30 +1,29 @@
 // SPDX-License-Identifier: GPL-2.0-only
-#include <linux/sched/debug.h>
+#include <linux/bitops.h>
 #include <linux/console.h>
+#include <linux/log2.h>
 #include <linux/kernel.h>
 #include <linux/ftrace.h>
-#include <linux/sysctl.h>
 #include <linux/nmi.h>
+#include <linux/sched/debug.h>
+#include <linux/string.h>
+#include <linux/sysctl.h>
 
 #include <linux/sys_info.h>
 
-struct sys_info_name {
-	unsigned long bit;
-	const char *name;
-};
-
 /*
  * When 'si_names' gets updated,  please make sure the 'sys_info_avail'
  * below is updated accordingly.
  */
-static const struct sys_info_name  si_names[] = {
-	{ SYS_INFO_TASKS,		"tasks" },
-	{ SYS_INFO_MEM,			"mem" },
-	{ SYS_INFO_TIMERS,		"timers" },
-	{ SYS_INFO_LOCKS,		"locks" },
-	{ SYS_INFO_FTRACE,		"ftrace" },
-	{ SYS_INFO_ALL_BT,		"all_bt" },
-	{ SYS_INFO_BLOCKED_TASKS,	"blocked_tasks" },
+static const char * const si_names[] = {
+	[ilog2(SYS_INFO_TASKS)]			= "tasks",
+	[ilog2(SYS_INFO_MEM)]			= "mem",
+	[ilog2(SYS_INFO_TIMERS)]		= "timers",
+	[ilog2(SYS_INFO_LOCKS)]			= "locks",
+	[ilog2(SYS_INFO_FTRACE)]		= "ftrace",
+	[ilog2(SYS_INFO_PANIC_CONSOLE_REPLAY)]	= "",
+	[ilog2(SYS_INFO_ALL_BT)]		= "all_bt",
+	[ilog2(SYS_INFO_BLOCKED_TASKS)]		= "blocked_tasks",
 };
 
 /* Expecting string like "xxx_sys_info=tasks,mem,timers,locks,ftrace,..." */
@@ -36,12 +35,9 @@ unsigned long sys_info_parse_param(char *str)
 
 	s = str;
 	while ((name = strsep(&s, ",")) && *name) {
-		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
-			if (!strcmp(name, si_names[i].name)) {
-				si_bits |= si_names[i].bit;
-				break;
-			}
-		}
+		i = match_string(si_names, ARRAY_SIZE(si_names), name);
+		if (i >= 0)
+			__set_bit(i, &si_bits);
 	}
 
 	return si_bits;
@@ -85,12 +81,10 @@ int sysctl_sys_info_handler(const struct ctl_table *ro_table, int write,
 		si_bits = READ_ONCE(*si_bits_global);
 
 		names[0] = '\0';
-		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
-			if (si_bits & si_names[i].bit) {
-				len += scnprintf(names + len, sizeof(names) - len,
-					"%s%s", delim, si_names[i].name);
-				delim = ",";
-			}
+		for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) {
+			len += scnprintf(names + len, sizeof(names) - len,
+					 "%s%s", delim, si_names[i]);
+			delim = ",";
 		}
 
 		table = *ro_table;
-- 
2.50.1
Re: [PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings
Posted by Feng Tang 5 months, 1 week ago
On Wed, Oct 29, 2025 at 12:07:38PM +0100, Andy Shevchenko wrote:
> There is no need to keep a custom structure just for the need of
> a plain array of strings. Replace struct sys_info_name with plain
> array of strings.
> 
> With that done, simplify the code, in particular, naturally use
> for_each_set_bit() when iterating over si_bits_global bitmap.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  lib/sys_info.c | 48 +++++++++++++++++++++---------------------------
>  1 file changed, 21 insertions(+), 27 deletions(-)
> 
> diff --git a/lib/sys_info.c b/lib/sys_info.c
> index 6b0188b30227..5aecf4b6025f 100644
> --- a/lib/sys_info.c
> +++ b/lib/sys_info.c
> @@ -1,30 +1,29 @@
>  // SPDX-License-Identifier: GPL-2.0-only
> -#include <linux/sched/debug.h>
> +#include <linux/bitops.h>
>  #include <linux/console.h>
> +#include <linux/log2.h>
>  #include <linux/kernel.h>
>  #include <linux/ftrace.h>
> -#include <linux/sysctl.h>
>  #include <linux/nmi.h>
> +#include <linux/sched/debug.h>
> +#include <linux/string.h>
> +#include <linux/sysctl.h>
>  
>  #include <linux/sys_info.h>
>  
> -struct sys_info_name {
> -	unsigned long bit;
> -	const char *name;
> -};
> -
>  /*
>   * When 'si_names' gets updated,  please make sure the 'sys_info_avail'
>   * below is updated accordingly.
>   */
> -static const struct sys_info_name  si_names[] = {
> -	{ SYS_INFO_TASKS,		"tasks" },
> -	{ SYS_INFO_MEM,			"mem" },
> -	{ SYS_INFO_TIMERS,		"timers" },
> -	{ SYS_INFO_LOCKS,		"locks" },
> -	{ SYS_INFO_FTRACE,		"ftrace" },
> -	{ SYS_INFO_ALL_BT,		"all_bt" },
> -	{ SYS_INFO_BLOCKED_TASKS,	"blocked_tasks" },
> +static const char * const si_names[] = {
> +	[ilog2(SYS_INFO_TASKS)]			= "tasks",
> +	[ilog2(SYS_INFO_MEM)]			= "mem",
> +	[ilog2(SYS_INFO_TIMERS)]		= "timers",
> +	[ilog2(SYS_INFO_LOCKS)]			= "locks",
> +	[ilog2(SYS_INFO_FTRACE)]		= "ftrace",
> +	[ilog2(SYS_INFO_PANIC_CONSOLE_REPLAY)]	= "",
> +	[ilog2(SYS_INFO_ALL_BT)]		= "all_bt",
> +	[ilog2(SYS_INFO_BLOCKED_TASKS)]		= "blocked_tasks",
>  };
>  
>  /* Expecting string like "xxx_sys_info=tasks,mem,timers,locks,ftrace,..." */
> @@ -36,12 +35,9 @@ unsigned long sys_info_parse_param(char *str)
>  
>  	s = str;
>  	while ((name = strsep(&s, ",")) && *name) {
> -		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
> -			if (!strcmp(name, si_names[i].name)) {
> -				si_bits |= si_names[i].bit;
> -				break;
> -			}
> -		}
> +		i = match_string(si_names, ARRAY_SIZE(si_names), name);
> +		if (i >= 0)
> +			__set_bit(i, &si_bits);
>  	}
>  
>  	return si_bits;
> @@ -85,12 +81,10 @@ int sysctl_sys_info_handler(const struct ctl_table *ro_table, int write,
>  		si_bits = READ_ONCE(*si_bits_global);
>  
>  		names[0] = '\0';
> -		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
> -			if (si_bits & si_names[i].bit) {
> -				len += scnprintf(names + len, sizeof(names) - len,
> -					"%s%s", delim, si_names[i].name);
> -				delim = ",";
> -			}
> +		for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) {
> +			len += scnprintf(names + len, sizeof(names) - len,
> +					 "%s%s", delim, si_names[i]);
> +			delim = ",";

For SYS_INFO_PANIC_CONSOLE_REPLAY bit, it is a NULL string, no need for
an extra ','?

Thanks,
Feng
Re: [PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings
Posted by Andy Shevchenko 5 months, 1 week ago
On Thu, Oct 30, 2025 at 10:01:49AM +0800, Feng Tang wrote:
> On Wed, Oct 29, 2025 at 12:07:38PM +0100, Andy Shevchenko wrote:
> > There is no need to keep a custom structure just for the need of
> > a plain array of strings. Replace struct sys_info_name with plain
> > array of strings.
> > 
> > With that done, simplify the code, in particular, naturally use
> > for_each_set_bit() when iterating over si_bits_global bitmap.

...

> >  		names[0] = '\0';
> > -		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
> > -			if (si_bits & si_names[i].bit) {
> > -				len += scnprintf(names + len, sizeof(names) - len,
> > -					"%s%s", delim, si_names[i].name);
> > -				delim = ",";
> > -			}
> > +		for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) {
> > +			len += scnprintf(names + len, sizeof(names) - len,
> > +					 "%s%s", delim, si_names[i]);
> > +			delim = ",";
> 
> For SYS_INFO_PANIC_CONSOLE_REPLAY bit, it is a NULL string, no need for
> an extra ','?

If you look closer to the original code, the behaviour is the same. Feel free
to update behaviour separately as I tried to keep the functionality to be not
changed with my series (with the exceptions of the fetching issue).

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings
Posted by Feng Tang 5 months, 1 week ago
On Thu, Oct 30, 2025 at 09:36:42AM +0200, Andy Shevchenko wrote:
> On Thu, Oct 30, 2025 at 10:01:49AM +0800, Feng Tang wrote:
> > On Wed, Oct 29, 2025 at 12:07:38PM +0100, Andy Shevchenko wrote:
> > > There is no need to keep a custom structure just for the need of
> > > a plain array of strings. Replace struct sys_info_name with plain
> > > array of strings.
> > > 
> > > With that done, simplify the code, in particular, naturally use
> > > for_each_set_bit() when iterating over si_bits_global bitmap.
> 
> ...
> 
> > >  		names[0] = '\0';
> > > -		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
> > > -			if (si_bits & si_names[i].bit) {
> > > -				len += scnprintf(names + len, sizeof(names) - len,
> > > -					"%s%s", delim, si_names[i].name);
> > > -				delim = ",";
> > > -			}
> > > +		for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) {
> > > +			len += scnprintf(names + len, sizeof(names) - len,
> > > +					 "%s%s", delim, si_names[i]);
> > > +			delim = ",";
> > 
> > For SYS_INFO_PANIC_CONSOLE_REPLAY bit, it is a NULL string, no need for
> > an extra ','?
> 
> If you look closer to the original code, the behaviour is the same. Feel free
> to update behaviour separately as I tried to keep the functionality to be not
> changed with my series (with the exceptions of the fetching issue).

I gave the comment by code-reading.

And to double check it, I just run a simple test by adding "panic_print=0xff"
to cmdline, with the current kernel, by running "sysctl  kernel.panic_sys_info"
on current kernel, it will get:

	'kernel.panic_sys_info = tasks,mem,timers,locks,ftrace,all_bt,blocked_tasks'

And after applying your first 3 patches, it will show:
	
	'kernel.panic_sys_info = tasks,mem,timers,locks,ftrace,,all_bt,blocked_task'

Thanks,
Feng
Re: [PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings
Posted by Andy Shevchenko 5 months, 1 week ago
On Thu, Oct 30, 2025 at 04:45:24PM +0800, Feng Tang wrote:
> On Thu, Oct 30, 2025 at 09:36:42AM +0200, Andy Shevchenko wrote:
> > On Thu, Oct 30, 2025 at 10:01:49AM +0800, Feng Tang wrote:
> > > On Wed, Oct 29, 2025 at 12:07:38PM +0100, Andy Shevchenko wrote:
> > > > There is no need to keep a custom structure just for the need of
> > > > a plain array of strings. Replace struct sys_info_name with plain
> > > > array of strings.
> > > > 
> > > > With that done, simplify the code, in particular, naturally use
> > > > for_each_set_bit() when iterating over si_bits_global bitmap.

...

> > > >  		names[0] = '\0';
> > > > -		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
> > > > -			if (si_bits & si_names[i].bit) {
> > > > -				len += scnprintf(names + len, sizeof(names) - len,
> > > > -					"%s%s", delim, si_names[i].name);
> > > > -				delim = ",";
> > > > -			}
> > > > +		for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) {
> > > > +			len += scnprintf(names + len, sizeof(names) - len,
> > > > +					 "%s%s", delim, si_names[i]);
> > > > +			delim = ",";
> > > 
> > > For SYS_INFO_PANIC_CONSOLE_REPLAY bit, it is a NULL string, no need for
> > > an extra ','?
> > 
> > If you look closer to the original code, the behaviour is the same. Feel free
> > to update behaviour separately as I tried to keep the functionality to be not
> > changed with my series (with the exceptions of the fetching issue).
> 
> I gave the comment by code-reading.
> 
> And to double check it, I just run a simple test by adding "panic_print=0xff"
> to cmdline, with the current kernel, by running "sysctl  kernel.panic_sys_info"
> on current kernel, it will get:
> 
> 	'kernel.panic_sys_info = tasks,mem,timers,locks,ftrace,all_bt,blocked_tasks'
> 
> And after applying your first 3 patches, it will show:
> 	
> 	'kernel.panic_sys_info = tasks,mem,timers,locks,ftrace,,all_bt,blocked_task'

Thanks for the test, now I see the issue! Before si_names has no entry for that bit.
I will address this in next version. Sorry for the confusion.

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 3/6] panic: sys_info: Replace struct sys_info_name with plain array of strings
Posted by Feng Tang 5 months, 1 week ago
On Thu, Oct 30, 2025 at 11:05:59AM +0200, Andy Shevchenko wrote:
> On Thu, Oct 30, 2025 at 04:45:24PM +0800, Feng Tang wrote:
> > On Thu, Oct 30, 2025 at 09:36:42AM +0200, Andy Shevchenko wrote:
> > > On Thu, Oct 30, 2025 at 10:01:49AM +0800, Feng Tang wrote:
> > > > On Wed, Oct 29, 2025 at 12:07:38PM +0100, Andy Shevchenko wrote:
> > > > > There is no need to keep a custom structure just for the need of
> > > > > a plain array of strings. Replace struct sys_info_name with plain
> > > > > array of strings.
> > > > > 
> > > > > With that done, simplify the code, in particular, naturally use
> > > > > for_each_set_bit() when iterating over si_bits_global bitmap.
> 
> ...
> 
> > > > >  		names[0] = '\0';
> > > > > -		for (i = 0; i < ARRAY_SIZE(si_names); i++) {
> > > > > -			if (si_bits & si_names[i].bit) {
> > > > > -				len += scnprintf(names + len, sizeof(names) - len,
> > > > > -					"%s%s", delim, si_names[i].name);
> > > > > -				delim = ",";
> > > > > -			}
> > > > > +		for_each_set_bit(i, &si_bits, ARRAY_SIZE(si_names)) {
> > > > > +			len += scnprintf(names + len, sizeof(names) - len,
> > > > > +					 "%s%s", delim, si_names[i]);
> > > > > +			delim = ",";
> > > > 
> > > > For SYS_INFO_PANIC_CONSOLE_REPLAY bit, it is a NULL string, no need for
> > > > an extra ','?
> > > 
> > > If you look closer to the original code, the behaviour is the same. Feel free
> > > to update behaviour separately as I tried to keep the functionality to be not
> > > changed with my series (with the exceptions of the fetching issue).
> > 
> > I gave the comment by code-reading.
> > 
> > And to double check it, I just run a simple test by adding "panic_print=0xff"
> > to cmdline, with the current kernel, by running "sysctl  kernel.panic_sys_info"
> > on current kernel, it will get:
> > 
> > 	'kernel.panic_sys_info = tasks,mem,timers,locks,ftrace,all_bt,blocked_tasks'
> > 
> > And after applying your first 3 patches, it will show:
> > 	
> > 	'kernel.panic_sys_info = tasks,mem,timers,locks,ftrace,,all_bt,blocked_task'
> 
> Thanks for the test, now I see the issue! Before si_names has no entry for that bit.
> I will address this in next version. Sorry for the confusion.

No problem. Thanks for helping to improve the code!

- Feng