All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: 2.6 /proc/interrupts fails on systems with many CPUs
@ 2003-11-11 18:15 Manfred Spraul
  0 siblings, 0 replies; 19+ messages in thread
From: Manfred Spraul @ 2003-11-11 18:15 UTC (permalink / raw)
  To: Erik Jacobson, linux-kernel

Erik wrote:

>	/* don't ask for more than the kmalloc() max size, currently 128 KB */
> 	if (size > 128 * 1024)
> 		size = 128 * 1024;
>-	buf = kmalloc(size, GFP_KERNEL);
>+	buf = __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
>  
>
kmalloc needs a contiguous memory block. Thus after a long runtime, 
large kmalloc calls can fail due to fragmentation. I'd prefer if you 
switch to vmalloc after 2*PAGE_SIZE.

Or switch to a line based seq file iterator, then you wouldn't need the 
huge buffer.
--
    Manfred


^ permalink raw reply	[flat|nested] 19+ messages in thread
* 2.6 /proc/interrupts fails on systems with many CPUs
@ 2003-11-11 17:21 Erik Jacobson
  2003-11-11 17:29 ` Randy.Dunlap
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Erik Jacobson @ 2003-11-11 17:21 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 696 bytes --]

Howdy.

On systems with lots of processors (512 for example), catting /proc/interrupts
fails with a "not enough memory" error.

This was observed in 2.6.0-test8

I tracked this down to this in proc_misc.c:

static int interrupts_open(struct inode *inode, struct file *file)
{
   unsigned size = 4096 * (1 + num_online_cpus() / 8);
   char *buf = kmalloc(size, GFP_KERNEL);

The kmalloc fails here.

I'm looking for suggestions on how to fix this.  I came up with one fix
that seems to work OK for ia64.  I have attached it to this message.
I'm looking for advice on what should be proposed for the real fix.

Thanks!

--
Erik Jacobson - Linux System Software - Silicon Graphics - Eagan, Minnesota

[-- Attachment #2: Type: TEXT/PLAIN, Size: 3252 bytes --]


===========================================================================
linux/fs/proc/proc_misc.c
===========================================================================

--- /usr/tmp/TmpDir.18901-0/linux/fs/proc/proc_misc.c_1.52	Tue Nov 11 09:55:19 2003
+++ linux/fs/proc/proc_misc.c	Tue Nov 11 09:43:32 2003
@@ -445,7 +445,7 @@
 	/* don't ask for more than the kmalloc() max size, currently 128 KB */
 	if (size > 128 * 1024)
 		size = 128 * 1024;
-	buf = kmalloc(size, GFP_KERNEL);
+	buf = __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -476,20 +476,21 @@
 extern int show_interrupts(struct seq_file *p, void *v);
 static int interrupts_open(struct inode *inode, struct file *file)
 {
-	unsigned size = 4096 * (1 + num_online_cpus() / 8);
-	char *buf = kmalloc(size, GFP_KERNEL);
+	unsigned size = 4096 * (1 + num_online_cpus() / 8); 
+	char *buf = __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
 	struct seq_file *m;
 	int res;
 
-	if (!buf)
+	if (!buf) 
 		return -ENOMEM;
+	
 	res = single_open(file, show_interrupts, NULL);
 	if (!res) {
 		m = file->private_data;
 		m->buf = buf;
 		m->size = size;
 	} else
-		kfree(buf);
+		vfree(buf);
 	return res;
 }
 static struct file_operations proc_interrupts_operations = {

===========================================================================
linux/fs/seq_file.c
===========================================================================

--- /usr/tmp/TmpDir.18901-0/linux/fs/seq_file.c_1.8	Tue Nov 11 09:55:19 2003
+++ linux/fs/seq_file.c	Tue Nov 11 09:18:06 2003
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -29,6 +30,7 @@
 int seq_open(struct file *file, struct seq_operations *op)
 {
 	struct seq_file *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
 	if (!p)
 		return -ENOMEM;
 	memset(p, 0, sizeof(*p));
@@ -61,7 +63,7 @@
 	down(&m->sem);
 	/* grab buffer if we didn't have one */
 	if (!m->buf) {
-		m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
+		m->buf = __vmalloc(m->size = PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
 		if (!m->buf)
 			goto Enomem;
 	}
@@ -94,8 +96,8 @@
 		if (m->count < m->size)
 			goto Fill;
 		m->op->stop(m, p);
-		kfree(m->buf);
-		m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
+		vfree(m->buf);
+		m->buf = __vmalloc(m->size <<= 1, GFP_KERNEL, PAGE_KERNEL);
 		if (!m->buf)
 			goto Enomem;
 		m->count = 0;
@@ -160,7 +162,7 @@
 	if (!offset)
 		return 0;
 	if (!m->buf) {
-		m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
+		m->buf = __vmalloc(m->size = PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
 		if (!m->buf)
 			return -ENOMEM;
 	}
@@ -192,8 +194,8 @@
 
 Eoverflow:
 	m->op->stop(m, p);
-	kfree(m->buf);
-	m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
+	vfree(m->buf);
+	m->buf = __vmalloc(m->size <<= 1, GFP_KERNEL, PAGE_KERNEL);
 	return !m->buf ? -ENOMEM : -EAGAIN;
 }
 
@@ -246,7 +248,7 @@
 int seq_release(struct inode *inode, struct file *file)
 {
 	struct seq_file *m = (struct seq_file *)file->private_data;
-	kfree(m->buf);
+	vfree(m->buf);
 	kfree(m);
 	return 0;
 }

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

end of thread, other threads:[~2003-11-12  2:09 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <BF1FE1855350A0479097B3A0D2A80EE0013B1188@hdsmsx402.hd.intel.com>
2003-11-11 19:55 ` 2.6 /proc/interrupts fails on systems with many CPUs Len Brown
2003-11-11 23:37   ` Erlend Aasland
2003-11-12  2:35     ` Martin J. Bligh
2003-11-11 18:15 Manfred Spraul
  -- strict thread matches above, loose matches on Subject: below --
2003-11-11 17:21 Erik Jacobson
2003-11-11 17:29 ` Randy.Dunlap
2003-11-11 17:51 ` Robert Love
2003-11-11 18:02 ` Martin J. Bligh
2003-11-11 18:24   ` Linus Torvalds
2003-11-11 18:57     ` Martin J. Bligh
2003-11-11 18:36       ` Linus Torvalds
2003-11-11 20:14     ` Anton Blanchard
2003-11-11 22:41       ` Martin J. Bligh
2003-11-11 22:32         ` Zwane Mwaikambo
2003-11-11 18:17 ` Linus Torvalds
2003-11-11 18:22   ` viro
2003-11-11 20:15     ` Jonathan Corbet
2003-11-11 18:32   ` Randy.Dunlap
2003-11-11 19:19 ` Anton Blanchard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.