linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Support resetting WARN*_ONCE
@ 2016-08-02 20:40 Andi Kleen
  2016-08-03  4:12 ` kbuild test robot
  0 siblings, 1 reply; 8+ messages in thread
From: Andi Kleen @ 2016-08-02 20:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

WARN*_ONCE warnings only appear once.

During testing I find it useful to reset the state of the once warnings,
so that I can rerun tests and see if they trigger again, or can
guarantee that a test run always hits the same warnings.

This patch adds a debugfs interface to reset all the _ONCE
warnings so that they appear again:

echo 1 > /sys/kernel/debug/clear_warn_once

This is implemented by putting all the warning flags into
a special section, and clearing it.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/asm-generic/bug.h         |  6 +++---
 include/asm-generic/sections.h    |  1 +
 include/asm-generic/vmlinux.lds.h |  3 +++
 kernel/panic.c                    | 24 ++++++++++++++++++++++++
 4 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 6f96247226a4..4dae133b51c9 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -113,7 +113,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
 })
 
 #define WARN_ON_ONCE(condition)	({				\
-	static bool __section(.data.unlikely) __warned;		\
+	static bool __section(.data.once) __warned;		\
 	int __ret_warn_once = !!(condition);			\
 								\
 	if (unlikely(__ret_warn_once && !__warned)) {		\
@@ -124,7 +124,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
 })
 
 #define WARN_ONCE(condition, format...)	({			\
-	static bool __section(.data.unlikely) __warned;		\
+	static bool __section(.data.once) __warned;		\
 	int __ret_warn_once = !!(condition);			\
 								\
 	if (unlikely(__ret_warn_once && !__warned)) {		\
@@ -135,7 +135,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
 })
 
 #define WARN_TAINT_ONCE(condition, taint, format...)	({	\
-	static bool __section(.data.unlikely) __warned;		\
+	static bool __section(.data.once) __warned;		\
 	int __ret_warn_once = !!(condition);			\
 								\
 	if (unlikely(__ret_warn_once && !__warned)) {		\
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index af0254c09424..0e9826a4acab 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -36,6 +36,7 @@ extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
 extern char __kprobes_text_start[], __kprobes_text_end[];
 extern char __entry_text_start[], __entry_text_end[];
 extern char __start_rodata[], __end_rodata[];
+extern char __start_once[], __end_once[];
 
 /* Start and end of .ctors section - used for constructor calls. */
 extern char __ctors_start[], __ctors_end[];
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6a67ab94b553..4b8d43b7c07f 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -204,6 +204,9 @@
 	MEM_KEEP(init.data)						\
 	MEM_KEEP(exit.data)						\
 	*(.data.unlikely)						\
+	VMLINUX_SYMBOL(__start_once) = .;				\
+	*(.data.once)							\
+	VMLINUX_SYMBOL(__end_once) = .;					\
 	STRUCT_ALIGN();							\
 	*(__tracepoints)						\
 	/* implement dynamic printk debug */				\
diff --git a/kernel/panic.c b/kernel/panic.c
index 8aa74497cc5a..4f52356f1562 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -25,6 +25,7 @@
 #include <linux/nmi.h>
 #include <linux/console.h>
 #include <linux/bug.h>
+#include <linux/debugfs.h>
 
 #define PANIC_TIMER_STEP 100
 #define PANIC_BLINK_SPD 18
@@ -553,6 +554,29 @@ void warn_slowpath_null(const char *file, int line)
 EXPORT_SYMBOL(warn_slowpath_null);
 #endif
 
+/* Support resetting WARN*_ONCE state */
+
+static int clear_warn_once_set(void *data, u64 val)
+{
+	memset(__start_once, 0, __end_once - __start_once);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clear_warn_once_fops,
+			NULL,
+                        clear_warn_once_set,
+		        "%lld\n");
+
+static __init int register_warn_debugfs(void)
+{
+	/* Don't care about failure */
+	debugfs_create_file("clear_warn_once", 0644, NULL,
+			    NULL, &clear_warn_once_fops);
+	return 0;
+}
+
+__initcall(register_warn_debugfs);
+
 #ifdef CONFIG_CC_STACKPROTECTOR
 
 /*
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support resetting WARN*_ONCE
  2016-08-02 20:40 [PATCH] Support resetting WARN*_ONCE Andi Kleen
@ 2016-08-03  4:12 ` kbuild test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kbuild test robot @ 2016-08-03  4:12 UTC (permalink / raw)
  To: Andi Kleen; +Cc: kbuild-all, akpm, linux-kernel, Andi Kleen

[-- Attachment #1: Type: text/plain, Size: 1712 bytes --]

Hi Andi,

[auto build test ERROR on asm-generic/master]
[also build test ERROR on v4.7 next-20160802]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Andi-Kleen/Support-resetting-WARN-_ONCE/20160803-112312
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All errors (new ones prefixed by >>):

   kernel/panic.c: In function 'clear_warn_once_set':
>> kernel/panic.c:557:9: error: '__start_once' undeclared (first use in this function)
     memset(__start_once, 0, __end_once - __start_once);
            ^
   kernel/panic.c:557:9: note: each undeclared identifier is reported only once for each function it appears in
>> kernel/panic.c:557:26: error: '__end_once' undeclared (first use in this function)
     memset(__start_once, 0, __end_once - __start_once);
                             ^

vim +/__start_once +557 kernel/panic.c

   551	#endif
   552	
   553	/* Support resetting WARN*_ONCE state */
   554	
   555	static int clear_warn_once_set(void *data, u64 val)
   556	{
 > 557		memset(__start_once, 0, __end_once - __start_once);
   558		return 0;
   559	}
   560	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 44813 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support resetting WARN*_ONCE
  2017-10-17 21:40 Andi Kleen
  2017-10-17 21:54 ` Andrew Morton
  2017-10-18  5:35 ` Michael Ellerman
@ 2017-11-03  9:39 ` Michael Ellerman
  2 siblings, 0 replies; 8+ messages in thread
From: Michael Ellerman @ 2017-11-03  9:39 UTC (permalink / raw)
  To: Andi Kleen, akpm; +Cc: linux-kernel, Andi Kleen

Andi Kleen <andi@firstfloor.org> writes:

> diff --git a/kernel/panic.c b/kernel/panic.c
> index bdd18afa19a4..b2d872fa16de 100644
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -587,6 +588,32 @@ void warn_slowpath_null(const char *file, int line)
>  EXPORT_SYMBOL(warn_slowpath_null);
>  #endif
>  
> +#ifdef CONFIG_BUG
> +
> +/* Support resetting WARN*_ONCE state */
> +
> +static int clear_warn_once_set(void *data, u64 val)
> +{
> +	memset(__start_once, 0, __end_once - __start_once);
> +	return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(clear_warn_once_fops,
> +			NULL,
> +                        clear_warn_once_set,
> +		        "%lld\n");
> +
> +static __init int register_warn_debugfs(void)
> +{
> +	/* Don't care about failure */
> +	debugfs_create_file("clear_warn_once", 0644, NULL,
                                               ^

Wouldn't 0200 be more appropriate if it's only writable?

Otherwise it appears readable, but cat'ing it gives you an error.

cheers

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support resetting WARN*_ONCE
  2017-10-18  5:35 ` Michael Ellerman
@ 2017-10-19 20:47   ` Andi Kleen
  0 siblings, 0 replies; 8+ messages in thread
From: Andi Kleen @ 2017-10-19 20:47 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: Andi Kleen, akpm, linux-kernel

On Wed, Oct 18, 2017 at 04:35:14PM +1100, Michael Ellerman wrote:
> Andi Kleen <andi@firstfloor.org> writes:
> 
> > From: Andi Kleen <ak@linux.intel.com>
> >
> > I like _ONCE warnings because it's guaranteed that they don't
> > flood the log.
> >
> > During testing I find it useful to reset the state of the once warnings,
> > so that I can rerun tests and see if they trigger again, or can
> > guarantee that a test run always hits the same warnings.
> >
> > This patch adds a debugfs interface to reset all the _ONCE
> > warnings so that they appear again:
> >
> > echo 1 > /sys/kernel/debug/clear_warn_once
> >
> > This is implemented by putting all the warning booleans into
> > a special section, and clearing it.
> 
> That won't work for arches that do the ONCE logic with a flag will it?
> ie. arm64, parisc, powerpc, s390, sh, x86.

Thanks. I sent an incremential patch that fixes this.

-Andi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support resetting WARN*_ONCE
  2017-10-17 21:40 Andi Kleen
  2017-10-17 21:54 ` Andrew Morton
@ 2017-10-18  5:35 ` Michael Ellerman
  2017-10-19 20:47   ` Andi Kleen
  2017-11-03  9:39 ` Michael Ellerman
  2 siblings, 1 reply; 8+ messages in thread
From: Michael Ellerman @ 2017-10-18  5:35 UTC (permalink / raw)
  To: Andi Kleen, akpm; +Cc: linux-kernel, Andi Kleen

Andi Kleen <andi@firstfloor.org> writes:

> From: Andi Kleen <ak@linux.intel.com>
>
> I like _ONCE warnings because it's guaranteed that they don't
> flood the log.
>
> During testing I find it useful to reset the state of the once warnings,
> so that I can rerun tests and see if they trigger again, or can
> guarantee that a test run always hits the same warnings.
>
> This patch adds a debugfs interface to reset all the _ONCE
> warnings so that they appear again:
>
> echo 1 > /sys/kernel/debug/clear_warn_once
>
> This is implemented by putting all the warning booleans into
> a special section, and clearing it.

That won't work for arches that do the ONCE logic with a flag will it?
ie. arm64, parisc, powerpc, s390, sh, x86.

They use the version of WARN_ON_ONCE at line ~64 of bug.h

#define __WARN_ONCE_TAINT(taint)	__WARN_FLAGS(BUGFLAG_ONCE|BUGFLAG_TAINT(taint))

#define WARN_ON_ONCE(condition) ({				\
	int __ret_warn_on = !!(condition);			\
	if (unlikely(__ret_warn_on))				\
		__WARN_ONCE_TAINT(TAINT_WARN);			\
	unlikely(__ret_warn_on);				\
})


cheers

> diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
> index 87191357d303..68c2f08b7914 100644
> --- a/include/asm-generic/bug.h
> +++ b/include/asm-generic/bug.h
> @@ -129,7 +129,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
>  
>  #ifndef WARN_ON_ONCE
>  #define WARN_ON_ONCE(condition)	({				\
> -	static bool __section(.data.unlikely) __warned;		\
> +	static bool __section(.data.once) __warned;		\
>  	int __ret_warn_once = !!(condition);			\
>  								\
>  	if (unlikely(__ret_warn_once && !__warned)) {		\
> @@ -141,7 +141,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
>  #endif
>  
>  #define WARN_ONCE(condition, format...)	({			\
> -	static bool __section(.data.unlikely) __warned;		\
> +	static bool __section(.data.once) __warned;		\
>  	int __ret_warn_once = !!(condition);			\
>  								\
>  	if (unlikely(__ret_warn_once && !__warned)) {		\
> @@ -152,7 +152,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
>  })
>  
>  #define WARN_TAINT_ONCE(condition, taint, format...)	({	\
> -	static bool __section(.data.unlikely) __warned;		\
> +	static bool __section(.data.once) __warned;		\
>  	int __ret_warn_once = !!(condition);			\
>  								\
>  	if (unlikely(__ret_warn_once && !__warned)) {		\

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support resetting WARN*_ONCE
  2017-10-17 21:54 ` Andrew Morton
@ 2017-10-17 22:11   ` Andi Kleen
  0 siblings, 0 replies; 8+ messages in thread
From: Andi Kleen @ 2017-10-17 22:11 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Andi Kleen, linux-kernel, Andi Kleen

> Seems useful.  Can we document the new interface please?
> 
> I'm not sure where :( If it was in /proc/sys/kernel then we'd have a
> Documentation file.  But debugfs?

I added a new file Documentation/clearing-warn-once.txt

But longer term would be good to document all the debugfs
entries systematically. Won't tackle that for this patchkit
though.

-Andi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Support resetting WARN*_ONCE
  2017-10-17 21:40 Andi Kleen
@ 2017-10-17 21:54 ` Andrew Morton
  2017-10-17 22:11   ` Andi Kleen
  2017-10-18  5:35 ` Michael Ellerman
  2017-11-03  9:39 ` Michael Ellerman
  2 siblings, 1 reply; 8+ messages in thread
From: Andrew Morton @ 2017-10-17 21:54 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, Andi Kleen

On Tue, 17 Oct 2017 14:40:17 -0700 Andi Kleen <andi@firstfloor.org> wrote:

> From: Andi Kleen <ak@linux.intel.com>
> 
> I like _ONCE warnings because it's guaranteed that they don't
> flood the log.
> 
> During testing I find it useful to reset the state of the once warnings,
> so that I can rerun tests and see if they trigger again, or can
> guarantee that a test run always hits the same warnings.
> 
> This patch adds a debugfs interface to reset all the _ONCE
> warnings so that they appear again:
> 
> echo 1 > /sys/kernel/debug/clear_warn_once
> 
> This is implemented by putting all the warning booleans into
> a special section, and clearing it.

Seems useful.  Can we document the new interface please?

I'm not sure where :( If it was in /proc/sys/kernel then we'd have a
Documentation file.  But debugfs?

> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -27,6 +27,7 @@
>  #include <linux/console.h>
>  #include <linux/bug.h>
>  #include <linux/ratelimit.h>
> +#include <linux/debugfs.h>
>  
>  #define PANIC_TIMER_STEP 100
>  #define PANIC_BLINK_SPD 18
> @@ -587,6 +588,32 @@ void warn_slowpath_null(const char *file, int line)
>  EXPORT_SYMBOL(warn_slowpath_null);
>  #endif
>  
> +#ifdef CONFIG_BUG
> +
> +/* Support resetting WARN*_ONCE state */
> +
> +static int clear_warn_once_set(void *data, u64 val)
> +{
> +	memset(__start_once, 0, __end_once - __start_once);

Suggest we include asm/sections.h explicitly, rather than by luck.

> +	return 0;
> +}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] Support resetting WARN*_ONCE
@ 2017-10-17 21:40 Andi Kleen
  2017-10-17 21:54 ` Andrew Morton
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Andi Kleen @ 2017-10-17 21:40 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

I like _ONCE warnings because it's guaranteed that they don't
flood the log.

During testing I find it useful to reset the state of the once warnings,
so that I can rerun tests and see if they trigger again, or can
guarantee that a test run always hits the same warnings.

This patch adds a debugfs interface to reset all the _ONCE
warnings so that they appear again:

echo 1 > /sys/kernel/debug/clear_warn_once

This is implemented by putting all the warning booleans into
a special section, and clearing it.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/asm-generic/bug.h         |  6 +++---
 include/asm-generic/sections.h    |  1 +
 include/asm-generic/vmlinux.lds.h |  3 +++
 kernel/panic.c                    | 27 +++++++++++++++++++++++++++
 4 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 87191357d303..68c2f08b7914 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -129,7 +129,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
 
 #ifndef WARN_ON_ONCE
 #define WARN_ON_ONCE(condition)	({				\
-	static bool __section(.data.unlikely) __warned;		\
+	static bool __section(.data.once) __warned;		\
 	int __ret_warn_once = !!(condition);			\
 								\
 	if (unlikely(__ret_warn_once && !__warned)) {		\
@@ -141,7 +141,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
 #endif
 
 #define WARN_ONCE(condition, format...)	({			\
-	static bool __section(.data.unlikely) __warned;		\
+	static bool __section(.data.once) __warned;		\
 	int __ret_warn_once = !!(condition);			\
 								\
 	if (unlikely(__ret_warn_once && !__warned)) {		\
@@ -152,7 +152,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint,
 })
 
 #define WARN_TAINT_ONCE(condition, taint, format...)	({	\
-	static bool __section(.data.unlikely) __warned;		\
+	static bool __section(.data.once) __warned;		\
 	int __ret_warn_once = !!(condition);			\
 								\
 	if (unlikely(__ret_warn_once && !__warned)) {		\
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index e5da44eddd2f..611c01bc5d21 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -43,6 +43,7 @@ extern char __entry_text_start[], __entry_text_end[];
 extern char __start_rodata[], __end_rodata[];
 extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __softirqentry_text_start[], __softirqentry_text_end[];
+extern char __start_once[], __end_once[];
 
 /* Start and end of .ctors section - used for constructor calls. */
 extern char __ctors_start[], __ctors_end[];
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8acfc1e099e1..ac511e24ea4a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -223,6 +223,9 @@
 	MEM_KEEP(init.data)						\
 	MEM_KEEP(exit.data)						\
 	*(.data.unlikely)						\
+	VMLINUX_SYMBOL(__start_once) = .;				\
+	*(.data.once)							\
+	VMLINUX_SYMBOL(__end_once) = .;					\
 	STRUCT_ALIGN();							\
 	*(__tracepoints)						\
 	/* implement dynamic printk debug */				\
diff --git a/kernel/panic.c b/kernel/panic.c
index bdd18afa19a4..b2d872fa16de 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -27,6 +27,7 @@
 #include <linux/console.h>
 #include <linux/bug.h>
 #include <linux/ratelimit.h>
+#include <linux/debugfs.h>
 
 #define PANIC_TIMER_STEP 100
 #define PANIC_BLINK_SPD 18
@@ -587,6 +588,32 @@ void warn_slowpath_null(const char *file, int line)
 EXPORT_SYMBOL(warn_slowpath_null);
 #endif
 
+#ifdef CONFIG_BUG
+
+/* Support resetting WARN*_ONCE state */
+
+static int clear_warn_once_set(void *data, u64 val)
+{
+	memset(__start_once, 0, __end_once - __start_once);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clear_warn_once_fops,
+			NULL,
+                        clear_warn_once_set,
+		        "%lld\n");
+
+static __init int register_warn_debugfs(void)
+{
+	/* Don't care about failure */
+	debugfs_create_file("clear_warn_once", 0644, NULL,
+			    NULL, &clear_warn_once_fops);
+	return 0;
+}
+
+__initcall(register_warn_debugfs);
+#endif
+
 #ifdef CONFIG_CC_STACKPROTECTOR
 
 /*
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-11-03  9:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-02 20:40 [PATCH] Support resetting WARN*_ONCE Andi Kleen
2016-08-03  4:12 ` kbuild test robot
2017-10-17 21:40 Andi Kleen
2017-10-17 21:54 ` Andrew Morton
2017-10-17 22:11   ` Andi Kleen
2017-10-18  5:35 ` Michael Ellerman
2017-10-19 20:47   ` Andi Kleen
2017-11-03  9:39 ` Michael Ellerman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).