linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] slub: reduce total stack usage of slab_err & object_err
@ 2008-09-30 15:15 Richard Kennedy
  2008-09-30 15:32 ` Matt Mackall
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Richard Kennedy @ 2008-09-30 15:15 UTC (permalink / raw)
  To: Christoph Lameter, penberg, mpm; +Cc: linux-mm, lkml

reduce the total stack usage of slab_err & object_err.

Introduce a new function to display a simple slab bug message, and call
this when vprintk is not needed.

before: (stack size as reported by checkstack on x86_64)
	slab_err/object_err -> slab_bug(328)->printk
after:
	slab_err/object_err -> slab_bug_message(8) -> printk

Signed-off-by: Richard Kennedy <richard@rsk.demon.co.uk>

----
I've been trying to build a tool to estimate the maximum stack usage in
the kernel, & noticed that most of the biggest stack users are the error
handling routines.
This simple change will reduced the stack used handling some slub errors
on both 64 & 32 bit platforms, although I haven't measured it on 32 bit
it will save at least 100 bytes. 
I haven't spotted anywhere that overflows the stack but this change
should reduce the chance of it happening.

It boots & run successfully on my AMD x86_64 desktop -- but I haven't
seen any slub errors so the new code hasn't been run.

regards
Richard


diff --git a/mm/slub.c b/mm/slub.c
index 0c83e6a..0646452 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -419,6 +419,15 @@ static void print_page_info(struct page *page)
 
 }
 
+static void slab_bug_message(struct kmem_cache *s, char *msg)
+{
+	printk(KERN_ERR "========================================"
+			"=====================================\n");
+	printk(KERN_ERR "BUG %s: %s\n", s->name, msg);
+	printk(KERN_ERR "----------------------------------------"
+			"-------------------------------------\n\n");
+}
+
 static void slab_bug(struct kmem_cache *s, char *fmt, ...)
 {
 	va_list args;
@@ -427,11 +436,7 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...)
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
-	printk(KERN_ERR "========================================"
-			"=====================================\n");
-	printk(KERN_ERR "BUG %s: %s\n", s->name, buf);
-	printk(KERN_ERR "----------------------------------------"
-			"-------------------------------------\n\n");
+	slab_bug_message(s, buf);
 }
 
 static void slab_fix(struct kmem_cache *s, char *fmt, ...)
@@ -484,7 +489,7 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
 static void object_err(struct kmem_cache *s, struct page *page,
 			u8 *object, char *reason)
 {
-	slab_bug(s, "%s", reason);
+	slab_bug_message(s, reason);
 	print_trailer(s, page, object);
 }
 
@@ -496,7 +501,7 @@ static void slab_err(struct kmem_cache *s, struct page *page, char *fmt, ...)
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
-	slab_bug(s, "%s", buf);
+	slab_bug_message(s, buf);
 	print_page_info(page);
 	dump_stack();
 }



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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 15:15 [PATCH] slub: reduce total stack usage of slab_err & object_err Richard Kennedy
@ 2008-09-30 15:32 ` Matt Mackall
  2008-09-30 15:38 ` Christoph Lameter
  2008-09-30 19:33 ` Jörn Engel
  2 siblings, 0 replies; 14+ messages in thread
From: Matt Mackall @ 2008-09-30 15:32 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, linux-mm, lkml


On Tue, 2008-09-30 at 16:15 +0100, Richard Kennedy wrote:
> reduce the total stack usage of slab_err & object_err.

I've got a better idea: use vprintk.

-- 
Mathematics is the supreme nostalgia of our time.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 15:15 [PATCH] slub: reduce total stack usage of slab_err & object_err Richard Kennedy
  2008-09-30 15:32 ` Matt Mackall
@ 2008-09-30 15:38 ` Christoph Lameter
  2008-09-30 15:49   ` Matt Mackall
  2008-09-30 16:20   ` Richard Kennedy
  2008-09-30 19:33 ` Jörn Engel
  2 siblings, 2 replies; 14+ messages in thread
From: Christoph Lameter @ 2008-09-30 15:38 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: penberg, mpm, linux-mm, lkml

Richard Kennedy wrote:
> reduce the total stack usage of slab_err & object_err.
> 
> Introduce a new function to display a simple slab bug message, and call
> this when vprintk is not needed.

You could simply get rid of the 100 byte buffer by using vprintk? Same method
could be used elsewhere in the kernel and does not require additional
functions. Compiles, untestted.




Subject: Slub reduce slab_bug stack usage by using vprintk

Signed-off-by: Christoph Lameter <cl@linux-foundation.org>

Index: linux-2.6/mm/slub.c
===================================================================
--- linux-2.6.orig/mm/slub.c	2008-09-30 10:34:40.000000000 -0500
+++ linux-2.6/mm/slub.c	2008-09-30 10:36:10.000000000 -0500
@@ -422,15 +422,14 @@
 static void slab_bug(struct kmem_cache *s, char *fmt, ...)
 {
 	va_list args;
-	char buf[100];

 	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
-	va_end(args);
 	printk(KERN_ERR "========================================"
 			"=====================================\n");
-	printk(KERN_ERR "BUG %s: %s\n", s->name, buf);
-	printk(KERN_ERR "----------------------------------------"
+	printk(KERN_ERR "BUG %s: ", s->name);
+	vprintk(fmt, args);
+	va_end(args);
+	printk(KERN_ERR "\n----------------------------------------"
 			"-------------------------------------\n\n");
 }


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 15:38 ` Christoph Lameter
@ 2008-09-30 15:49   ` Matt Mackall
  2008-09-30 16:20   ` Richard Kennedy
  1 sibling, 0 replies; 14+ messages in thread
From: Matt Mackall @ 2008-09-30 15:49 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Richard Kennedy, penberg, linux-mm, lkml


On Tue, 2008-09-30 at 10:38 -0500, Christoph Lameter wrote:
> Richard Kennedy wrote:
> > reduce the total stack usage of slab_err & object_err.
> > 
> > Introduce a new function to display a simple slab bug message, and call
> > this when vprintk is not needed.
> 
> You could simply get rid of the 100 byte buffer by using vprintk? Same method
> could be used elsewhere in the kernel and does not require additional
> functions. Compiles, untestted.

I'm fixing a bunch of these in the kernel right now.

-- 
Mathematics is the supreme nostalgia of our time.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 15:38 ` Christoph Lameter
  2008-09-30 15:49   ` Matt Mackall
@ 2008-09-30 16:20   ` Richard Kennedy
  2008-09-30 16:43     ` Matt Mackall
                       ` (3 more replies)
  1 sibling, 4 replies; 14+ messages in thread
From: Richard Kennedy @ 2008-09-30 16:20 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: penberg, mpm, linux-mm, lkml

On Tue, 2008-09-30 at 10:38 -0500, Christoph Lameter wrote:
> Richard Kennedy wrote:
> > reduce the total stack usage of slab_err & object_err.
> > 
> > Introduce a new function to display a simple slab bug message, and call
> > this when vprintk is not needed.
> 
> You could simply get rid of the 100 byte buffer by using vprintk? Same method
> could be used elsewhere in the kernel and does not require additional
> functions. Compiles, untestted.
> 
> 
> 
> 
> Subject: Slub reduce slab_bug stack usage by using vprintk
> 
> Signed-off-by: Christoph Lameter <cl@linux-foundation.org>
> 
> Index: linux-2.6/mm/slub.c
> ===================================================================
> --- linux-2.6.orig/mm/slub.c	2008-09-30 10:34:40.000000000 -0500
> +++ linux-2.6/mm/slub.c	2008-09-30 10:36:10.000000000 -0500
> @@ -422,15 +422,14 @@
>  static void slab_bug(struct kmem_cache *s, char *fmt, ...)
>  {
>  	va_list args;
> -	char buf[100];
> 
>  	va_start(args, fmt);
> -	vsnprintf(buf, sizeof(buf), fmt, args);
> -	va_end(args);
>  	printk(KERN_ERR "========================================"
>  			"=====================================\n");
> -	printk(KERN_ERR "BUG %s: %s\n", s->name, buf);
> -	printk(KERN_ERR "----------------------------------------"
> +	printk(KERN_ERR "BUG %s: ", s->name);
> +	vprintk(fmt, args);
> +	va_end(args);
> +	printk(KERN_ERR "\n----------------------------------------"
>  			"-------------------------------------\n\n");
>  }
> 
Yes, using vprintk is better but you still have this path :
( with your patch applied)

	object_err -> slab_bug(208) -> printk(216)
instead of 
	object_err -> slab_bug_message(8) -> printk(216)

unfortunately the overhead for having var_args is pretty big, at least
on x86_64. I haven't measured it on 32 bit yet.

Richard



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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 16:20   ` Richard Kennedy
@ 2008-09-30 16:43     ` Matt Mackall
  2008-09-30 17:36     ` Christoph Lameter
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Matt Mackall @ 2008-09-30 16:43 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, linux-mm, lkml, Andrew Morton


On Tue, 2008-09-30 at 17:20 +0100, Richard Kennedy wrote:
> On Tue, 2008-09-30 at 10:38 -0500, Christoph Lameter wrote:
> > Richard Kennedy wrote:
> > > reduce the total stack usage of slab_err & object_err.
> > > 
> > > Introduce a new function to display a simple slab bug message, and call
> > > this when vprintk is not needed.
> > 
> > You could simply get rid of the 100 byte buffer by using vprintk? Same method
> > could be used elsewhere in the kernel and does not require additional
> > functions.

(Funny, I added vprintk precisely to fix the extra buffer issue in
ext2/3 years ago, but never hit the rest of the kernel..)

Use vprintk rather that vsnprintf where possible

This does away with lots of large static and on-stack buffers as well
as a few associated locks.

Signed-off-by: Matt Mackall <mpm@selenic.com>

diff -r 6841f3ce32be -r 9ac0727d59d8 drivers/cpufreq/cpufreq.c
--- a/drivers/cpufreq/cpufreq.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/drivers/cpufreq/cpufreq.c	Tue Sep 30 11:37:30 2008 -0500
@@ -220,9 +220,7 @@
 void cpufreq_debug_printk(unsigned int type, const char *prefix,
 			const char *fmt, ...)
 {
-	char s[256];
 	va_list args;
-	unsigned int len;
 	unsigned long flags;
 
 	WARN_ON(!prefix);
@@ -235,15 +233,10 @@
 		}
 		spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
 
-		len = snprintf(s, 256, KERN_DEBUG "%s: ", prefix);
-
 		va_start(args, fmt);
-		len += vsnprintf(&s[len], (256 - len), fmt, args);
+		printk(KERN_DEBUG "%s: ", prefix);
+		vprintk(fmt, args);
 		va_end(args);
-
-		printk(s);
-
-		WARN_ON(len < 5);
 	}
 }
 EXPORT_SYMBOL(cpufreq_debug_printk);
diff -r 6841f3ce32be -r 9ac0727d59d8 drivers/scsi/arm/fas216.c
--- a/drivers/scsi/arm/fas216.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/drivers/scsi/arm/fas216.c	Tue Sep 30 11:37:30 2008 -0500
@@ -290,10 +290,8 @@
 static void
 fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
 {
-	static char buf[1024];
-
-	vsnprintf(buf, sizeof(buf), fmt, ap);
-	printk("scsi%d.%c: %s", info->host->host_no, target, buf);
+	printk("scsi%d.%c: ", info->host->host_no, target, buf);
+	vprintk(fmt, ap);
 }
 
 static void fas216_log_command(FAS216_Info *info, int level,
diff -r 6841f3ce32be -r 9ac0727d59d8 drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/drivers/scsi/nsp32.c	Tue Sep 30 11:37:30 2008 -0500
@@ -323,36 +323,31 @@
 #define NSP32_DEBUG_INIT		BIT(17)
 #define NSP32_SPECIAL_PRINT_REGISTER	BIT(20)
 
-#define NSP32_DEBUG_BUF_LEN		100
-
 static void nsp32_message(const char *func, int line, char *type, char *fmt, ...)
 {
 	va_list args;
-	char buf[NSP32_DEBUG_BUF_LEN];
-
 	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
+#ifndef NSP32_DEBUG
+	printk("%snsp32: ", type);
+#else
+	printk("%snsp32: %s (%d): ", type, func, line);
+#endif
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-
-#ifndef NSP32_DEBUG
-	printk("%snsp32: %s\n", type, buf);
-#else
-	printk("%snsp32: %s (%d): %s\n", type, func, line, buf);
-#endif
 }
 
 #ifdef NSP32_DEBUG
 static void nsp32_dmessage(const char *func, int line, int mask, char *fmt, ...)
 {
 	va_list args;
-	char buf[NSP32_DEBUG_BUF_LEN];
-
-	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
-	va_end(args);
 
 	if (mask & NSP32_DEBUG_MASK) {
-		printk("nsp32-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
+		va_start(args, fmt);
+		printk("nsp32-debug: 0x%x %s (%d): ", mask, func, line);
+		vprintk(fmt, args);
+		printk("\n");
+		va_end(args);
 	}
 }
 #endif
diff -r 6841f3ce32be -r 9ac0727d59d8 drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Tue Sep 30 11:37:30 2008 -0500
@@ -132,8 +132,6 @@
 #define NSP_DEBUG_DATA_IO      		BIT(18)
 #define NSP_SPECIAL_PRINT_REGISTER	BIT(20)
 
-#define NSP_DEBUG_BUF_LEN		150
-
 static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
 {
 	scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
@@ -142,31 +140,28 @@
 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
 {
 	va_list args;
-	char buf[NSP_DEBUG_BUF_LEN];
 
 	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
+#ifndef NSP_DEBUG
+	printk("%snsp_cs: ", type);
+#else
+	printk("%snsp_cs: %s (%d): ", type, func);
+#endif
+	vprintk(fmt, args);
 	va_end(args);
-
-#ifndef NSP_DEBUG
-	printk("%snsp_cs: %s\n", type, buf);
-#else
-	printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
-#endif
 }
 
 #ifdef NSP_DEBUG
 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
 {
 	va_list args;
-	char buf[NSP_DEBUG_BUF_LEN];
-
-	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
-	va_end(args);
 
 	if (mask & NSP_DEBUG_MASK) {
-		printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
+		va_start(args, fmt);
+		printk("nsp_cs-debug: 0x%x %s (%d): ", mask, func, line);
+		vprintk(fmt, args);
+		printk("\n");
+		va_end(args);
 	}
 }
 #endif
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/adfs/super.c
--- a/fs/adfs/super.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/adfs/super.c	Tue Sep 30 11:37:30 2008 -0500
@@ -37,16 +37,14 @@
 
 void __adfs_error(struct super_block *sb, const char *function, const char *fmt, ...)
 {
-	char error_buf[128];
 	va_list args;
-
 	va_start(args, fmt);
-	vsnprintf(error_buf, sizeof(error_buf), fmt, args);
+	printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: ",
+		sb->s_id, function ? ": " : "",
+		function ? function : "");
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-
-	printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %s\n",
-		sb->s_id, function ? ": " : "",
-		function ? function : "", error_buf);
 }
 
 static int adfs_checkdiscrecord(struct adfs_discrecord *dr)
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/affs/amigaffs.c
--- a/fs/affs/amigaffs.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/affs/amigaffs.c	Tue Sep 30 11:37:30 2008 -0500
@@ -11,8 +11,6 @@
 #include "affs.h"
 
 extern struct timezone sys_tz;
-
-static char ErrorBuffer[256];
 
 /*
  * Functions for accessing Amiga-FFS structures.
@@ -444,14 +442,13 @@
 void
 affs_error(struct super_block *sb, const char *function, const char *fmt, ...)
 {
-	va_list	 args;
-
+	va_list	args;
 	va_start(args,fmt);
-	vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args);
+	printk(KERN_CRIT "AFFS error (device %s): %s(): ", sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
 
-	printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id,
-		function,ErrorBuffer);
 	if (!(sb->s_flags & MS_RDONLY))
 		printk(KERN_WARNING "AFFS: Remounting filesystem read-only\n");
 	sb->s_flags |= MS_RDONLY;
@@ -460,14 +457,13 @@
 void
 affs_warning(struct super_block *sb, const char *function, const char *fmt, ...)
 {
-	va_list	 args;
-
+	va_list	args;
 	va_start(args,fmt);
-	vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args);
+	printk(KERN_WARNING "AFFS warning (device %s): %s(): ", sb->s_id,
+		function);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-
-	printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id,
-		function,ErrorBuffer);
 }
 
 /* Check if the name is valid for a affs object. */
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/befs/debug.c
--- a/fs/befs/debug.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/befs/debug.c	Tue Sep 30 11:37:30 2008 -0500
@@ -22,70 +22,41 @@
 
 #include "befs.h"
 
-#define ERRBUFSIZE 1024
-
 void
 befs_error(const struct super_block *sb, const char *fmt, ...)
 {
 	va_list args;
-	char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
-	if (err_buf == NULL) {
-		printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE);
-		return;
-	}
-
 	va_start(args, fmt);
-	vsnprintf(err_buf, ERRBUFSIZE, fmt, args);
+	printk(KERN_ERR "BeFS(%s): ", sb->s_id);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-
-	printk(KERN_ERR "BeFS(%s): %s\n", sb->s_id, err_buf);
-	kfree(err_buf);
 }
 
 void
 befs_warning(const struct super_block *sb, const char *fmt, ...)
 {
 	va_list args;
-	char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
-	if (err_buf == NULL) {
-		printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE);
-		return;
-	}
-
 	va_start(args, fmt);
-	vsnprintf(err_buf, ERRBUFSIZE, fmt, args);
+	printk(KERN_WARNING "BeFS(%s): %s\n", sb->s_id);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-
-	printk(KERN_WARNING "BeFS(%s): %s\n", sb->s_id, err_buf);
-
-	kfree(err_buf);
 }
 
 void
 befs_debug(const struct super_block *sb, const char *fmt, ...)
 {
 #ifdef CONFIG_BEFS_DEBUG
-
 	va_list args;
-	char *err_buf = NULL;
 
 	if (BEFS_SB(sb)->mount_opts.debug) {
-		err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
-		if (err_buf == NULL) {
-			printk(KERN_ERR "could not allocate %d bytes\n",
-				ERRBUFSIZE);
-			return;
-		}
-
 		va_start(args, fmt);
-		vsnprintf(err_buf, ERRBUFSIZE, fmt, args);
+		printk(KERN_DEBUG "BeFS(%s): ", sb->s_id);
+		vprintk(fmt, args);
+		printk("\n");
 		va_end(args);
-
-		printk(KERN_DEBUG "BeFS(%s): %s\n", sb->s_id, err_buf);
-
-		kfree(err_buf);
 	}
-
 #endif				//CONFIG_BEFS_DEBUG
 }
 
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/hpfs/super.c
--- a/fs/hpfs/super.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/hpfs/super.c	Tue Sep 30 11:37:30 2008 -0500
@@ -46,18 +46,15 @@
 	}
 }
 
-/* Filesystem error... */
-static char err_buf[1024];
-
 void hpfs_error(struct super_block *s, const char *fmt, ...)
 {
 	va_list args;
 
 	va_start(args, fmt);
-	vsnprintf(err_buf, sizeof(err_buf), fmt, args);
+	printk("HPFS: filesystem error: ");
+	vprintk(fmt, args);
 	va_end(args);
 
-	printk("HPFS: filesystem error: %s", err_buf);
 	if (!hpfs_sb(s)->sb_was_error) {
 		if (hpfs_sb(s)->sb_err == 2) {
 			printk("; crashing the system because you wanted it\n");
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/jfs/super.c
--- a/fs/jfs/super.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/jfs/super.c	Tue Sep 30 11:37:30 2008 -0500
@@ -91,14 +91,13 @@
 
 void jfs_error(struct super_block *sb, const char * function, ...)
 {
-	static char error_buf[256];
 	va_list args;
 
 	va_start(args, function);
-	vsnprintf(error_buf, sizeof(error_buf), function, args);
+	printk(KERN_ERR "ERROR: (device %s): ", sb->s_id);
+	vprintk(function, args);
+	printk("\n");
 	va_end(args);
-
-	printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf);
 
 	jfs_handle_error(sb);
 }
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/ntfs/debug.c
--- a/fs/ntfs/debug.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/ntfs/debug.c	Tue Sep 30 11:37:30 2008 -0500
@@ -20,13 +20,6 @@
  */
 
 #include "debug.h"
-
-/*
- * A static buffer to hold the error string being displayed and a spinlock
- * to protect concurrent accesses to it.
- */
-static char err_buf[1024];
-static DEFINE_SPINLOCK(err_buf_lock);
 
 /**
  * __ntfs_warning - output a warning to the syslog
@@ -59,17 +52,16 @@
 #endif
 	if (function)
 		flen = strlen(function);
-	spin_lock(&err_buf_lock);
 	va_start(args, fmt);
-	vsnprintf(err_buf, sizeof(err_buf), fmt, args);
+	if (sb)
+		printk(KERN_ERR "NTFS-fs warning (device %s): %s(): ",
+				sb->s_id, flen ? function : "");
+	else
+		printk(KERN_ERR "NTFS-fs warning: %s(): ",
+				flen ? function : "");
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-	if (sb)
-		printk(KERN_ERR "NTFS-fs warning (device %s): %s(): %s\n",
-				sb->s_id, flen ? function : "", err_buf);
-	else
-		printk(KERN_ERR "NTFS-fs warning: %s(): %s\n",
-				flen ? function : "", err_buf);
-	spin_unlock(&err_buf_lock);
 }
 
 /**
@@ -103,17 +95,16 @@
 #endif
 	if (function)
 		flen = strlen(function);
-	spin_lock(&err_buf_lock);
 	va_start(args, fmt);
-	vsnprintf(err_buf, sizeof(err_buf), fmt, args);
+	if (sb)
+		printk(KERN_ERR "NTFS-fs error (device %s): %s(): ",
+				sb->s_id, flen ? function : "");
+	else
+		printk(KERN_ERR "NTFS-fs error: %s(): ",
+				flen ? function : "");
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-	if (sb)
-		printk(KERN_ERR "NTFS-fs error (device %s): %s(): %s\n",
-				sb->s_id, flen ? function : "", err_buf);
-	else
-		printk(KERN_ERR "NTFS-fs error: %s(): %s\n",
-				flen ? function : "", err_buf);
-	spin_unlock(&err_buf_lock);
 }
 
 #ifdef DEBUG
@@ -131,13 +122,12 @@
 		return;
 	if (function)
 		flen = strlen(function);
-	spin_lock(&err_buf_lock);
 	va_start(args, fmt);
-	vsnprintf(err_buf, sizeof(err_buf), fmt, args);
+	printk(KERN_DEBUG "NTFS-fs DEBUG (%s, %d): %s(): ", file, line,
+			flen ? function : "");
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-	printk(KERN_DEBUG "NTFS-fs DEBUG (%s, %d): %s(): %s\n", file, line,
-			flen ? function : "", err_buf);
-	spin_unlock(&err_buf_lock);
 }
 
 /* Dump a runlist. Caller has to provide synchronisation for @rl. */
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/ocfs2/super.c
--- a/fs/ocfs2/super.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/ocfs2/super.c	Tue Sep 30 11:37:30 2008 -0500
@@ -1817,22 +1817,20 @@
 	ocfs2_set_ro_flag(osb, 0);
 }
 
-static char error_buf[1024];
-
 void __ocfs2_error(struct super_block *sb,
 		   const char *function,
 		   const char *fmt, ...)
 {
 	va_list args;
 
-	va_start(args, fmt);
-	vsnprintf(error_buf, sizeof(error_buf), fmt, args);
-	va_end(args);
-
 	/* Not using mlog here because we want to show the actual
 	 * function the error came from. */
-	printk(KERN_CRIT "OCFS2: ERROR (device %s): %s: %s\n",
-	       sb->s_id, function, error_buf);
+	va_start(args, fmt);
+	printk(KERN_CRIT "OCFS2: ERROR (device %s): %s: ",
+	       sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
 
 	ocfs2_handle_error(sb);
 }
@@ -1847,11 +1845,11 @@
 	va_list args;
 
 	va_start(args, fmt);
-	vsnprintf(error_buf, sizeof(error_buf), fmt, args);
+	printk(KERN_CRIT "OCFS2: abort (device %s): %s: ",
+	       sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-
-	printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n",
-	       sb->s_id, function, error_buf);
 
 	/* We don't have the cluster support yet to go straight to
 	 * hard readonly in here. Until then, we want to keep
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/partitions/ldm.c
--- a/fs/partitions/ldm.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/partitions/ldm.c	Tue Sep 30 11:37:30 2008 -0500
@@ -52,14 +52,13 @@
 static void _ldm_printk (const char *level, const char *function,
 			 const char *fmt, ...)
 {
-	static char buf[128];
 	va_list args;
 
 	va_start (args, fmt);
-	vsnprintf (buf, sizeof (buf), fmt, args);
+	printk("%s%s(): ", level, function, buf);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end (args);
-
-	printk ("%s%s(): %s\n", level, function, buf);
 }
 
 /**
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/udf/super.c
--- a/fs/udf/super.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/udf/super.c	Tue Sep 30 11:37:30 2008 -0500
@@ -75,8 +75,6 @@
 #define VDS_POS_LENGTH			7
 
 #define UDF_DEFAULT_BLOCKSIZE 2048
-
-static char error_buf[1024];
 
 /* These are the "meat" - everything else is stuffing */
 static int udf_fill_super(struct super_block *, void *, int);
@@ -2040,10 +2038,11 @@
 		sb->s_dirt = 1;
 	}
 	va_start(args, fmt);
-	vsnprintf(error_buf, sizeof(error_buf), fmt, args);
+	printk(KERN_CRIT "UDF-fs error (device %s): %s: ",
+		sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-	printk(KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
-		sb->s_id, function, error_buf);
 }
 
 void udf_warning(struct super_block *sb, const char *function,
@@ -2052,10 +2051,11 @@
 	va_list args;
 
 	va_start(args, fmt);
-	vsnprintf(error_buf, sizeof(error_buf), fmt, args);
+	printk(KERN_WARNING "UDF-fs warning (device %s): %s: ",
+	       sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-	printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n",
-	       sb->s_id, function, error_buf);
 }
 
 static void udf_put_super(struct super_block *sb)
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/ufs/super.c
--- a/fs/ufs/super.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/ufs/super.c	Tue Sep 30 11:37:30 2008 -0500
@@ -222,8 +222,6 @@
 
 static const struct super_operations ufs_super_ops;
 
-static char error_buf[1024];
-
 void ufs_error (struct super_block * sb, const char * function,
 	const char * fmt, ...)
 {
@@ -233,27 +231,28 @@
 
 	uspi = UFS_SB(sb)->s_uspi;
 	usb1 = ubh_get_usb_first(uspi);
-	
+
 	if (!(sb->s_flags & MS_RDONLY)) {
 		usb1->fs_clean = UFS_FSBAD;
 		ubh_mark_buffer_dirty(USPI_UBH(uspi));
 		sb->s_dirt = 1;
 		sb->s_flags |= MS_RDONLY;
 	}
-	va_start (args, fmt);
-	vsnprintf (error_buf, sizeof(error_buf), fmt, args);
-	va_end (args);
 	switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) {
 	case UFS_MOUNT_ONERROR_PANIC:
-		panic ("UFS-fs panic (device %s): %s: %s\n", 
-			sb->s_id, function, error_buf);
+		panic ("UFS-fs panic (device %s): %s: ",
+			sb->s_id, function);
 
 	case UFS_MOUNT_ONERROR_LOCK:
 	case UFS_MOUNT_ONERROR_UMOUNT:
 	case UFS_MOUNT_ONERROR_REPAIR:
-		printk (KERN_CRIT "UFS-fs error (device %s): %s: %s\n",
-			sb->s_id, function, error_buf);
-	}		
+		printk (KERN_CRIT "UFS-fs error (device %s): %s: ",
+			sb->s_id, function);
+	}
+	va_start(args, fmt);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
 }
 
 void ufs_panic (struct super_block * sb, const char * function,
@@ -262,21 +261,22 @@
 	struct ufs_sb_private_info * uspi;
 	struct ufs_super_block_first * usb1;
 	va_list args;
-	
+
 	uspi = UFS_SB(sb)->s_uspi;
 	usb1 = ubh_get_usb_first(uspi);
-	
+
 	if (!(sb->s_flags & MS_RDONLY)) {
 		usb1->fs_clean = UFS_FSBAD;
 		ubh_mark_buffer_dirty(USPI_UBH(uspi));
 		sb->s_dirt = 1;
 	}
-	va_start (args, fmt);
-	vsnprintf (error_buf, sizeof(error_buf), fmt, args);
-	va_end (args);
+	va_start(args, fmt);
+	printk(KERN_CRIT "UFS-fs panic (device %s): %s: ",
+		sb->s_id, function);
+	vprintk(fmt, args);
+	printk("\n");
+	va_end(args);
 	sb->s_flags |= MS_RDONLY;
-	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n",
-		sb->s_id, function, error_buf);
 }
 
 void ufs_warning (struct super_block * sb, const char * function,
@@ -284,11 +284,11 @@
 {
 	va_list args;
 
-	va_start (args, fmt);
-	vsnprintf (error_buf, sizeof(error_buf), fmt, args);
-	va_end (args);
-	printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n",
-		sb->s_id, function, error_buf);
+	va_start(args, fmt);
+	printk(KERN_WARNING "UFS-fs warning (device %s): %s: ",
+		sb->s_id, function);
+	vprintk(fmt, args);
+	va_end(args);
 }
 
 enum {
diff -r 6841f3ce32be -r 9ac0727d59d8 fs/xfs/support/debug.c
--- a/fs/xfs/support/debug.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/fs/xfs/support/debug.c	Tue Sep 30 11:37:30 2008 -0500
@@ -18,9 +18,6 @@
 #include <xfs.h>
 #include "debug.h"
 
-static char		message[1024];	/* keep it off the stack */
-static DEFINE_SPINLOCK(xfs_err_lock);
-
 /* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
 #define XFS_MAX_ERR_LEVEL	7
 #define XFS_ERR_MASK		((1 << 3) - 1)
@@ -40,17 +37,13 @@
 	level &= XFS_ERR_MASK;
 	if (level > XFS_MAX_ERR_LEVEL)
 		level = XFS_MAX_ERR_LEVEL;
-	spin_lock_irqsave(&xfs_err_lock,flags);
+
 	va_start(ap, fmt);
 	if (*fmt == '!') fp++;
-	len = vsnprintf(message, sizeof(message), fp, ap);
-	if (len >= sizeof(message))
-		len = sizeof(message) - 1;
-	if (message[len-1] == '\n')
-		message[len-1] = 0;
-	printk("%s%s\n", err_level[level], message);
+	printk("%s", err_level[level]);
+	vprintk(fp, ap);
+	printk("\n");
 	va_end(ap);
-	spin_unlock_irqrestore(&xfs_err_lock,flags);
 	BUG_ON(level == CE_PANIC);
 }
 
@@ -63,14 +56,9 @@
 	level &= XFS_ERR_MASK;
 	if(level > XFS_MAX_ERR_LEVEL)
 		level = XFS_MAX_ERR_LEVEL;
-	spin_lock_irqsave(&xfs_err_lock,flags);
-	len = vsnprintf(message, sizeof(message), fmt, ap);
-	if (len >= sizeof(message))
-		len = sizeof(message) - 1;
-	if (message[len-1] == '\n')
-		message[len-1] = 0;
-	printk("%s%s\n", err_level[level], message);
-	spin_unlock_irqrestore(&xfs_err_lock,flags);
+	printk("%s", err_level[level]);
+	vprintk(fmt, ap);
+	printk("\n");
 	BUG_ON(level == CE_PANIC);
 }
 
diff -r 6841f3ce32be -r 9ac0727d59d8 kernel/panic.c
--- a/kernel/panic.c	Mon Sep 29 17:28:44 2008 -0500
+++ b/kernel/panic.c	Tue Sep 30 11:37:30 2008 -0500
@@ -62,7 +62,6 @@
 NORET_TYPE void panic(const char * fmt, ...)
 {
 	long i;
-	static char buf[1024];
 	va_list args;
 #if defined(CONFIG_S390)
 	unsigned long caller = (unsigned long) __builtin_return_address(0);
@@ -77,9 +76,10 @@
 
 	bust_spinlocks(1);
 	va_start(args, fmt);
-	vsnprintf(buf, sizeof(buf), fmt, args);
+	printk(KERN_EMERG "Kernel panic - not syncing: ");
+	vprintk(fmt, args);
+	printk("\n");
 	va_end(args);
-	printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
 	bust_spinlocks(0);
 
 	/*


-- 
Mathematics is the supreme nostalgia of our time.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 16:20   ` Richard Kennedy
  2008-09-30 16:43     ` Matt Mackall
@ 2008-09-30 17:36     ` Christoph Lameter
  2008-09-30 17:37     ` Matt Mackall
  2008-10-01  0:02     ` Matt Mackall
  3 siblings, 0 replies; 14+ messages in thread
From: Christoph Lameter @ 2008-09-30 17:36 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: penberg, mpm, linux-mm, lkml

Richard Kennedy wrote:

> Yes, using vprintk is better but you still have this path :
> ( with your patch applied)
> 
> 	object_err -> slab_bug(208) -> printk(216)
> instead of 
> 	object_err -> slab_bug_message(8) -> printk(216)
> 
> unfortunately the overhead for having var_args is pretty big, at least
> on x86_64. I haven't measured it on 32 bit yet.

Really 208 bytes for a va arg parameter declaration? I expected it to be
simply a null terminated pointer list.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 16:20   ` Richard Kennedy
  2008-09-30 16:43     ` Matt Mackall
  2008-09-30 17:36     ` Christoph Lameter
@ 2008-09-30 17:37     ` Matt Mackall
  2008-09-30 18:33       ` Matt Mackall
  2008-10-01  0:02     ` Matt Mackall
  3 siblings, 1 reply; 14+ messages in thread
From: Matt Mackall @ 2008-09-30 17:37 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, linux-mm, lkml, Ingo Molnar


On Tue, 2008-09-30 at 17:20 +0100, Richard Kennedy wrote:
> Yes, using vprintk is better but you still have this path :
> ( with your patch applied)
> 
> 	object_err -> slab_bug(208) -> printk(216)
> instead of 
> 	object_err -> slab_bug_message(8) -> printk(216)
> 
> unfortunately the overhead for having var_args is pretty big, at least
> on x86_64. I haven't measured it on 32 bit yet.

That's fascinating. I tried a simple test case in userspace:

#include <stdarg.h>
#include <stdio.h>

void p(char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	vprintf(fmt, args);
	va_end(args);
}

On 32-bit, I'm seeing 32 bytes of stack vs 216 on 64-bit. Disassembly
suggests it's connected to va_list fiddling with XMM registers, which
seems quite odd.

-- 
Mathematics is the supreme nostalgia of our time.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 17:37     ` Matt Mackall
@ 2008-09-30 18:33       ` Matt Mackall
  2008-10-01  9:50         ` Richard Kennedy
  0 siblings, 1 reply; 14+ messages in thread
From: Matt Mackall @ 2008-09-30 18:33 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, linux-mm, lkml, Ingo Molnar


On Tue, 2008-09-30 at 12:37 -0500, Matt Mackall wrote:
> On Tue, 2008-09-30 at 17:20 +0100, Richard Kennedy wrote:
> > Yes, using vprintk is better but you still have this path :
> > ( with your patch applied)
> > 
> > 	object_err -> slab_bug(208) -> printk(216)
> > instead of 
> > 	object_err -> slab_bug_message(8) -> printk(216)
> > 
> > unfortunately the overhead for having var_args is pretty big, at least
> > on x86_64. I haven't measured it on 32 bit yet.
> 
> That's fascinating. I tried a simple test case in userspace:
> 
> #include <stdarg.h>
> #include <stdio.h>
> 
> void p(char *fmt, ...)
> {
> 	va_list args;
> 
> 	va_start(args, fmt);
> 	vprintf(fmt, args);
> 	va_end(args);
> }
> 
> On 32-bit, I'm seeing 32 bytes of stack vs 216 on 64-bit. Disassembly
> suggests it's connected to va_list fiddling with XMM registers, which
> seems quite odd.

Ok, on closer inspection, this is part of the x86_64 calling convention.
When calling a varargs function, the caller passes the number of
floating point SSE regs used in rax. The callee then has to save these
away for va_list use. The GCC prologue apparently sets aside space for
xmm0-xmm7 (16 bytes each) all the time (plus rdi, rsi, rdx, rcx, r8, and
r9).

Obviously, we're never passing floating point args in the kernel, so
we're taking about a 40+ byte hit in code size and 128 byte hit in stack
size for every varargs call.

Looks like the gcc people have a patch in progress:

http://gcc.gnu.org/ml/gcc-patches/2008-08/msg02165.html

So I think we should assume that x86_64 will sort this out eventually.

-- 
Mathematics is the supreme nostalgia of our time.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 15:15 [PATCH] slub: reduce total stack usage of slab_err & object_err Richard Kennedy
  2008-09-30 15:32 ` Matt Mackall
  2008-09-30 15:38 ` Christoph Lameter
@ 2008-09-30 19:33 ` Jörn Engel
  2008-10-01 10:06   ` Richard Kennedy
  2 siblings, 1 reply; 14+ messages in thread
From: Jörn Engel @ 2008-09-30 19:33 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, mpm, linux-mm, lkml

On Tue, 30 September 2008 16:15:36 +0100, Richard Kennedy wrote:
> 
> I've been trying to build a tool to estimate the maximum stack usage in
> the kernel, & noticed that most of the biggest stack users are the error
> handling routines.

Cool!  I once did the same, although the code has severely bitrotted by
now.  Is the code available somewhere?

Jörn

-- 
"Error protection by error detection and correction."
-- from a university class

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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 16:20   ` Richard Kennedy
                       ` (2 preceding siblings ...)
  2008-09-30 17:37     ` Matt Mackall
@ 2008-10-01  0:02     ` Matt Mackall
  3 siblings, 0 replies; 14+ messages in thread
From: Matt Mackall @ 2008-10-01  0:02 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, linux-mm, lkml


On Tue, 2008-09-30 at 17:20 +0100, Richard Kennedy wrote:
> Yes, using vprintk is better but you still have this path :
> ( with your patch applied)
> 
> 	object_err -> slab_bug(208) -> printk(216)
> instead of 
> 	object_err -> slab_bug_message(8) -> printk(216)
> 
> unfortunately the overhead for having var_args is pretty big, at least
> on x86_64. I haven't measured it on 32 bit yet.

Looks like this got fixed for x86_64 in gcc 4.4. For most other arches,
the overhead should be reasonable.

-- 
Mathematics is the supreme nostalgia of our time.


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 18:33       ` Matt Mackall
@ 2008-10-01  9:50         ` Richard Kennedy
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Kennedy @ 2008-10-01  9:50 UTC (permalink / raw)
  To: Matt Mackall; +Cc: Christoph Lameter, penberg, linux-mm, lkml, Ingo Molnar

On Tue, 2008-09-30 at 13:33 -0500, Matt Mackall wrote:
> On Tue, 2008-09-30 at 12:37 -0500, Matt Mackall wrote:
> > On Tue, 2008-09-30 at 17:20 +0100, Richard Kennedy wrote:
> > > Yes, using vprintk is better but you still have this path :
> > > ( with your patch applied)
> > > 
> > > 	object_err -> slab_bug(208) -> printk(216)
> > > instead of 
> > > 	object_err -> slab_bug_message(8) -> printk(216)
> > > 
> > > unfortunately the overhead for having var_args is pretty big, at least
> > > on x86_64. I haven't measured it on 32 bit yet.
> > 
> > That's fascinating. I tried a simple test case in userspace:
> > 
> > #include <stdarg.h>
> > #include <stdio.h>
> > 
> > void p(char *fmt, ...)
> > {
> > 	va_list args;
> > 
> > 	va_start(args, fmt);
> > 	vprintf(fmt, args);
> > 	va_end(args);
> > }
> > 
> > On 32-bit, I'm seeing 32 bytes of stack vs 216 on 64-bit. Disassembly
> > suggests it's connected to va_list fiddling with XMM registers, which
> > seems quite odd.
> 
> Ok, on closer inspection, this is part of the x86_64 calling convention.
> When calling a varargs function, the caller passes the number of
> floating point SSE regs used in rax. The callee then has to save these
> away for va_list use. The GCC prologue apparently sets aside space for
> xmm0-xmm7 (16 bytes each) all the time (plus rdi, rsi, rdx, rcx, r8, and
> r9).
> 
> Obviously, we're never passing floating point args in the kernel, so
> we're taking about a 40+ byte hit in code size and 128 byte hit in stack
> size for every varargs call.
> 
> Looks like the gcc people have a patch in progress:
> 
> http://gcc.gnu.org/ml/gcc-patches/2008-08/msg02165.html
> 
> So I think we should assume that x86_64 will sort this out eventually.
> 
thanks for the info. 

so vprintk _is_ the best solution. I did think it a bit strange to have
to add code to remove varargs to save stack space, but I didn't even
consider that it might be a gcc issue. 

 




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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-09-30 19:33 ` Jörn Engel
@ 2008-10-01 10:06   ` Richard Kennedy
  2008-10-01 10:32     ` Jörn Engel
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Kennedy @ 2008-10-01 10:06 UTC (permalink / raw)
  To: Jörn Engel; +Cc: Christoph Lameter, penberg, mpm, linux-mm, lkml

On Tue, 2008-09-30 at 21:33 +0200, Jörn Engel wrote:
> On Tue, 30 September 2008 16:15:36 +0100, Richard Kennedy wrote:
> > 
> > I've been trying to build a tool to estimate the maximum stack usage in
> > the kernel, & noticed that most of the biggest stack users are the error
> > handling routines.
> 
> Cool!  I once did the same, although the code has severely bitrotted by
> now.  Is the code available somewhere?
> 
> Jörn

No I haven't made it available as it's really only a proof of concept,
and I still don't have any sensible ideas how to deal with pointers to
functions. Plus I'm still testing it to see if the results are anything
like reasonable.
Also it's finding lots of potentially recursive code paths and my
heuristic to deal with them is very basic. I'm just adding a feature so
that I can ignore some code paths, so maybe that will help.

Richard


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

* Re: [PATCH] slub: reduce total stack usage of slab_err & object_err
  2008-10-01 10:06   ` Richard Kennedy
@ 2008-10-01 10:32     ` Jörn Engel
  0 siblings, 0 replies; 14+ messages in thread
From: Jörn Engel @ 2008-10-01 10:32 UTC (permalink / raw)
  To: Richard Kennedy; +Cc: Christoph Lameter, penberg, mpm, linux-mm, lkml

On Wed, 1 October 2008 11:06:07 +0100, Richard Kennedy wrote:
> 
> No I haven't made it available as it's really only a proof of concept,
> and I still don't have any sensible ideas how to deal with pointers to
> functions. Plus I'm still testing it to see if the results are anything
> like reasonable.
> Also it's finding lots of potentially recursive code paths and my
> heuristic to deal with them is very basic. I'm just adding a feature so
> that I can ignore some code paths, so maybe that will help.

Sounds very familiar. ;)

Function pointers are fairly easy.  When a function pointer is part of a
structure, simply consider that pointer to be a pseudo-function that
doesn't consume any stack space.  Whenever that pointer is written to,
that value can be "called" from the pseudo-function.  Callback functions
that are passed as function parameters can be handles similarly.

Getting this information wasn't too hard with smatch, but smatch depends
on gcc 3.1, which has *ahem* matured a bit.

Recursions essentially consume an infinite amount of stack unless you
know the upper bound for them.  I handled this two-fold.  First, every
single recursion is reported.  Secondly, every recursion is assumed to
be taken exactly once when calculating stack consumption.  This is the
minimal sane value.  Feel free to pick two or three if you prefer.

The main function code was done in two stages, iirc.  First stage simply
creates the call graph in memory.  Somewhere in the range of a million
objects.  Then I collapsed the graph from the leaves.  If function A
calls functions B, C and D, you first throw away two of the called
functions and keep the one with the biggest stack footprint.  Then A is
turned into a function A' that has the combined stack footprint of A and
B (assuming C and D are lighter) and is a leaf function.  Add some
annotation that B is called, along with anything B itself called before
it was collapsed.

If you use this method, recursions will sooner or later turn into a
pattern where A calls A.  Trivial to detect.

Maybe my thesis has a few more details:
http://wh.fh-wedel.de/~joern/quality.pdf

Jörn

-- 
Joern's library part 13:
http://www.chip-architect.com/

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

end of thread, other threads:[~2008-10-01 10:32 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-30 15:15 [PATCH] slub: reduce total stack usage of slab_err & object_err Richard Kennedy
2008-09-30 15:32 ` Matt Mackall
2008-09-30 15:38 ` Christoph Lameter
2008-09-30 15:49   ` Matt Mackall
2008-09-30 16:20   ` Richard Kennedy
2008-09-30 16:43     ` Matt Mackall
2008-09-30 17:36     ` Christoph Lameter
2008-09-30 17:37     ` Matt Mackall
2008-09-30 18:33       ` Matt Mackall
2008-10-01  9:50         ` Richard Kennedy
2008-10-01  0:02     ` Matt Mackall
2008-09-30 19:33 ` Jörn Engel
2008-10-01 10:06   ` Richard Kennedy
2008-10-01 10:32     ` Jörn Engel

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).