[PATCH 1/2] powerpc: Use seq_buf to avoid pr_cont() in __die()

Subsystems: linux for powerpc (32-bit and 64-bit), the rest

STALE2829d

7 messages, 2 authors, 2019-01-10 · open the first message on its own page

[PATCH 1/2] powerpc: Use seq_buf to avoid pr_cont() in __die()

From: Michael Ellerman <mpe@ellerman.id.au>
Date: 2019-01-08 12:07:10

Using pr_cont() risks having our output interleaved with other output
from other CPUs. Instead use a seq_buf to construct the line and then
print it as a whole.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/traps.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 64936b60d521..431a86d3f772 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -38,6 +38,7 @@
 #include <linux/kdebug.h>
 #include <linux/ratelimit.h>
 #include <linux/context_tracking.h>
+#include <linux/seq_buf.h>
 #include <linux/smp.h>
 #include <linux/console.h>
 #include <linux/kmsg_dump.h>
@@ -255,26 +256,34 @@ NOKPROBE_SYMBOL(oops_end);
 
 static int __die(const char *str, struct pt_regs *regs, long err)
 {
+	char buf[128]; /* enough for all flags and a long platform name */
+	struct seq_buf s;
+
+	seq_buf_init(&s, buf, sizeof(buf));
+
 	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
 
 	if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
-		printk("LE ");
+		seq_buf_puts(&s, "LE ");
 	else
-		printk("BE ");
+		seq_buf_puts(&s, "BE ");
 
 	if (IS_ENABLED(CONFIG_PREEMPT))
-		pr_cont("PREEMPT ");
+		seq_buf_puts(&s, "PREEMPT ");
 
 	if (IS_ENABLED(CONFIG_SMP))
-		pr_cont("SMP NR_CPUS=%d ", NR_CPUS);
+		seq_buf_printf(&s, "SMP NR_CPUS=%d ", NR_CPUS);
 
 	if (debug_pagealloc_enabled())
-		pr_cont("DEBUG_PAGEALLOC ");
+		seq_buf_puts(&s, "DEBUG_PAGEALLOC ");
 
 	if (IS_ENABLED(CONFIG_NUMA))
-		pr_cont("NUMA ");
+		seq_buf_puts(&s, "NUMA ");
+
+	if (ppc_md.name)
+		seq_buf_puts(&s, ppc_md.name);
 
-	pr_cont("%s\n", ppc_md.name ? ppc_md.name : "");
+	printk("%s\n", buf);
 
 	if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP)
 		return 1;
-- 
2.20.1

[PATCH 2/2] powerpc: Show PAGE_SIZE in __die() output

From: Michael Ellerman <mpe@ellerman.id.au>
Date: 2019-01-08 12:09:24

The page size the kernel is built with is useful info when debugging a
crash, so add it to the output in __die().

Result looks like eg:

  kernel BUG at drivers/misc/lkdtm/bugs.c:63!
  Oops: Exception in kernel mode, sig: 5 [#1]
  LE PAGE_SIZE=64K SMP NR_CPUS=2048 NUMA pSeries
  Modules linked in: vmx_crypto kvm binfmt_misc ip_tables

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/traps.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 431a86d3f772..fc972e4eee5f 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -268,6 +268,18 @@ static int __die(const char *str, struct pt_regs *regs, long err)
 	else
 		seq_buf_puts(&s, "BE ");
 
+	seq_buf_puts(&s, "PAGE_SIZE=");
+	if (IS_ENABLED(CONFIG_PPC_4K_PAGES))
+		seq_buf_puts(&s, "4K ");
+	else if (IS_ENABLED(CONFIG_PPC_16K_PAGES))
+		seq_buf_puts(&s, "16K ");
+	else if (IS_ENABLED(CONFIG_PPC_64K_PAGES))
+		seq_buf_puts(&s, "64K ");
+	else if (IS_ENABLED(CONFIG_PPC_256K_PAGES))
+		seq_buf_puts(&s, "256K ");
+	else
+		BUILD_BUG_ON(1);
+
 	if (IS_ENABLED(CONFIG_PREEMPT))
 		seq_buf_puts(&s, "PREEMPT ");
 
-- 
2.20.1

Re: [PATCH 1/2] powerpc: Use seq_buf to avoid pr_cont() in __die()

From: Christophe Leroy <hidden>
Date: 2019-01-08 12:20:38


Le 08/01/2019 à 13:04, Michael Ellerman a écrit :
Using pr_cont() risks having our output interleaved with other output
from other CPUs. Instead use a seq_buf to construct the line and then
print it as a whole.
Why not simply doing a single printk() or similar on the same model as X86 for instance ? (https://elixir.bootlin.com/linux/v5.0-rc1/source/arch/x86/kernel/dumpstack.c#L368)

Christophe
quoted hunk
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
  arch/powerpc/kernel/traps.c | 23 ++++++++++++++++-------
  1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 64936b60d521..431a86d3f772 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -38,6 +38,7 @@
  #include <linux/kdebug.h>
  #include <linux/ratelimit.h>
  #include <linux/context_tracking.h>
+#include <linux/seq_buf.h>
  #include <linux/smp.h>
  #include <linux/console.h>
  #include <linux/kmsg_dump.h>
@@ -255,26 +256,34 @@ NOKPROBE_SYMBOL(oops_end);
  
  static int __die(const char *str, struct pt_regs *regs, long err)
  {
+	char buf[128]; /* enough for all flags and a long platform name */
+	struct seq_buf s;
+
+	seq_buf_init(&s, buf, sizeof(buf));
+
  	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
  
  	if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))
-		printk("LE ");
+		seq_buf_puts(&s, "LE ");
  	else
-		printk("BE ");
+		seq_buf_puts(&s, "BE ");
  
  	if (IS_ENABLED(CONFIG_PREEMPT))
-		pr_cont("PREEMPT ");
+		seq_buf_puts(&s, "PREEMPT ");
  
  	if (IS_ENABLED(CONFIG_SMP))
-		pr_cont("SMP NR_CPUS=%d ", NR_CPUS);
+		seq_buf_printf(&s, "SMP NR_CPUS=%d ", NR_CPUS);
  
  	if (debug_pagealloc_enabled())
-		pr_cont("DEBUG_PAGEALLOC ");
+		seq_buf_puts(&s, "DEBUG_PAGEALLOC ");
  
  	if (IS_ENABLED(CONFIG_NUMA))
-		pr_cont("NUMA ");
+		seq_buf_puts(&s, "NUMA ");
+
+	if (ppc_md.name)
+		seq_buf_puts(&s, ppc_md.name);
  
-	pr_cont("%s\n", ppc_md.name ? ppc_md.name : "");
+	printk("%s\n", buf);
  
  	if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP)
  		return 1;

Re: [PATCH 2/2] powerpc: Show PAGE_SIZE in __die() output

From: Christophe Leroy <hidden>
Date: 2019-01-08 12:23:18


Le 08/01/2019 à 13:05, Michael Ellerman a écrit :
quoted hunk
The page size the kernel is built with is useful info when debugging a
crash, so add it to the output in __die().

Result looks like eg:

   kernel BUG at drivers/misc/lkdtm/bugs.c:63!
   Oops: Exception in kernel mode, sig: 5 [#1]
   LE PAGE_SIZE=64K SMP NR_CPUS=2048 NUMA pSeries
   Modules linked in: vmx_crypto kvm binfmt_misc ip_tables

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
  arch/powerpc/kernel/traps.c | 12 ++++++++++++
  1 file changed, 12 insertions(+)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 431a86d3f772..fc972e4eee5f 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -268,6 +268,18 @@ static int __die(const char *str, struct pt_regs *regs, long err)
  	else
  		seq_buf_puts(&s, "BE ");
  
+	seq_buf_puts(&s, "PAGE_SIZE=");
+	if (IS_ENABLED(CONFIG_PPC_4K_PAGES))
+		seq_buf_puts(&s, "4K ");
+	else if (IS_ENABLED(CONFIG_PPC_16K_PAGES))
+		seq_buf_puts(&s, "16K ");
+	else if (IS_ENABLED(CONFIG_PPC_64K_PAGES))
+		seq_buf_puts(&s, "64K ");
+	else if (IS_ENABLED(CONFIG_PPC_256K_PAGES))
+		seq_buf_puts(&s, "256K ");
Can't we build all the above at once using PAGE_SHIFT ?

Something like (untested):

"%dK ", 1 << (PAGE_SHIFT - 10)

Christophe
quoted hunk
+	else
+		BUILD_BUG_ON(1);
+
  	if (IS_ENABLED(CONFIG_PREEMPT))
  		seq_buf_puts(&s, "PREEMPT ");
  

Re: [PATCH 2/2] powerpc: Show PAGE_SIZE in __die() output

From: Christophe Leroy <hidden>
Date: 2019-01-09 07:48:41


Le 08/01/2019 à 13:21, Christophe Leroy a écrit :

Le 08/01/2019 à 13:05, Michael Ellerman a écrit :
quoted
The page size the kernel is built with is useful info when debugging a
crash, so add it to the output in __die().

Result looks like eg:

   kernel BUG at drivers/misc/lkdtm/bugs.c:63!
   Oops: Exception in kernel mode, sig: 5 [#1]
   LE PAGE_SIZE=64K SMP NR_CPUS=2048 NUMA pSeries
   Modules linked in: vmx_crypto kvm binfmt_misc ip_tables

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
  arch/powerpc/kernel/traps.c | 12 ++++++++++++
  1 file changed, 12 insertions(+)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 431a86d3f772..fc972e4eee5f 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -268,6 +268,18 @@ static int __die(const char *str, struct pt_regs *regs, long err)
      else
          seq_buf_puts(&s, "BE ");
+    seq_buf_puts(&s, "PAGE_SIZE=");
+    if (IS_ENABLED(CONFIG_PPC_4K_PAGES))
+        seq_buf_puts(&s, "4K ");
+    else if (IS_ENABLED(CONFIG_PPC_16K_PAGES))
+        seq_buf_puts(&s, "16K ");
+    else if (IS_ENABLED(CONFIG_PPC_64K_PAGES))
+        seq_buf_puts(&s, "64K ");
+    else if (IS_ENABLED(CONFIG_PPC_256K_PAGES))
+        seq_buf_puts(&s, "256K ");
Can't we build all the above at once using PAGE_SHIFT ?

Something like (untested):

"%dK ", 1 << (PAGE_SHIFT - 10)
Or even simplier:

"%dK ", PAGE_SIZE / 1024

Christophe

Christophe
quoted
+    else
+        BUILD_BUG_ON(1);
+
      if (IS_ENABLED(CONFIG_PREEMPT))
          seq_buf_puts(&s, "PREEMPT ");

Re: [PATCH 2/2] powerpc: Show PAGE_SIZE in __die() output

From: Michael Ellerman <mpe@ellerman.id.au>
Date: 2019-01-10 01:04:27

Christophe Leroy [off-list ref] writes:
Le 08/01/2019 à 13:21, Christophe Leroy a écrit :
quoted
Le 08/01/2019 à 13:05, Michael Ellerman a écrit :
quoted
The page size the kernel is built with is useful info when debugging a
crash, so add it to the output in __die().

Result looks like eg:

   kernel BUG at drivers/misc/lkdtm/bugs.c:63!
   Oops: Exception in kernel mode, sig: 5 [#1]
   LE PAGE_SIZE=64K SMP NR_CPUS=2048 NUMA pSeries
   Modules linked in: vmx_crypto kvm binfmt_misc ip_tables

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
  arch/powerpc/kernel/traps.c | 12 ++++++++++++
  1 file changed, 12 insertions(+)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 431a86d3f772..fc972e4eee5f 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -268,6 +268,18 @@ static int __die(const char *str, struct pt_regs 
*regs, long err)
      else
          seq_buf_puts(&s, "BE ");
+    seq_buf_puts(&s, "PAGE_SIZE=");
+    if (IS_ENABLED(CONFIG_PPC_4K_PAGES))
+        seq_buf_puts(&s, "4K ");
+    else if (IS_ENABLED(CONFIG_PPC_16K_PAGES))
+        seq_buf_puts(&s, "16K ");
+    else if (IS_ENABLED(CONFIG_PPC_64K_PAGES))
+        seq_buf_puts(&s, "64K ");
+    else if (IS_ENABLED(CONFIG_PPC_256K_PAGES))
+        seq_buf_puts(&s, "256K ");
Can't we build all the above at once using PAGE_SHIFT ?

Something like (untested):

"%dK ", 1 << (PAGE_SHIFT - 10)
Or even simplier:

"%dK ", PAGE_SIZE / 1024
Yep, good point.

Clearly I have forgotten how to program over the break (if I ever knew).

cheers

Re: [PATCH 1/2] powerpc: Use seq_buf to avoid pr_cont() in __die()

From: Michael Ellerman <mpe@ellerman.id.au>
Date: 2019-01-10 10:56:13

Christophe Leroy [off-list ref] writes:
Le 08/01/2019 à 13:04, Michael Ellerman a écrit :
quoted
Using pr_cont() risks having our output interleaved with other output
from other CPUs. Instead use a seq_buf to construct the line and then
print it as a whole.
Why not simply doing a single printk() or similar on the same model as 
X86 for instance ? 
(https://elixir.bootlin.com/linux/v5.0-rc1/source/arch/x86/kernel/dumpstack.c#L368)
Yeah we could do it that way, though it can become a bit of a mess.

In this case I guess it's not *too* bad:

	printk("%s PAGE_SIZE=%luK%s%s%s%s%s %s\n",
	       IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE",
	       PAGE_SIZE / 1024,
	       IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "",
	       IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
	       IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "",
	       debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
	       IS_ENABLED(CONFIG_NUMA) ? " NUMA" : "",
	       ppc_md.name ? ppc_md.name : "");

And the generated code is obviously a lot smaller.

So yeah I'll go with that. Thanks for the review.

cheers
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help