public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Mel Gorman <mel@csn.ul.ie>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: werner <w.landgraf@ru.ru>,
	linux-kernel@vger.kernel.org,
	David Rientjes <rientjes@google.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Rafael J. Wysocki" <rjw@sisk.pl>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: kernel problem
Date: Mon, 7 Dec 2009 14:50:11 +0000	[thread overview]
Message-ID: <20091207145011.GA14743@csn.ul.ie> (raw)
In-Reply-To: <20091204154109.GB1716@goodmis.org>

On Fri, Dec 04, 2009 at 10:41:09AM -0500, Steven Rostedt wrote:
> [ Added Cc's of people that may be interested in this ]
> > <SNIP>
> > ------------[ cut here ]------------
> > WARNING: at mm/page_alloc.c:1805
> > __alloc_pages_nodemask+0x127/0x48f()
> > Hardware name: System Product Name
> > Modules linked in:
> > Pid: 1, comm: swapper Not tainted 2.6.32-rc8-git5 #1
> > Call Trace:
> >  [<c103d94b>] warn_slowpath_common+0x65/0x95
> >  [<c103d98d>] warn_slowpath_null+0x12/0x15
> >  [<c109550c>] __alloc_pages_nodemask+0x127/0x48f
> >  [<c10be964>] ? get_slab+0x8/0x50
> >  [<c10b8979>] alloc_page_interleave+0x2e/0x6e
> >  [<c10b8a10>] alloc_pages_current+0x57/0x99
> >  [<c2083a4a>] ? xd_init+0x0/0x482
> >  [<c1094c38>] __get_free_pages+0xd/0x1e
> >  [<c2083a94>] xd_init+0x4a/0x482
> >  [<c2082df0>] ? loop_init+0x104/0x16a
> >  [<c169162d>] ? loop_probe+0x0/0xaf
> >  [<c2083a4a>] ? xd_init+0x0/0x482
> >  [<c1001143>] do_one_initcall+0x51/0x13f
> >  [<c204a307>] kernel_init+0x10b/0x15f
> >  [<c204a1fc>] ? kernel_init+0x0/0x15f
> >  [<c1004347>] kernel_thread_helper+0x7/0x10
> > ---[ end trace 686db6333ade6e7a ]---
> > xd: Out of memory.

First off, it would appear that every block driver under the sun is
being loaded. I seriously doubt this controller really exists in the
machine.

Second, it's a real warning as the driver is trying to allocate a buffer of
size 0 which get_order() chokes on. For bonus points, it tries to allocate
a buffer before it knows what size it should be. This patch should resolve
the problem but because I don't have the hardware to test it on, it could
do with a second set of eyes just to be sure the rejigged logic makes sense.

If this is ok, what is the appropriate submission path for unmaintained
block drivers? Is it the block maintainer or someone else?

==== CUT HERE ====
block,xd: Delay allocation of DMA buffers until device is known

Loading the XD module triggers a warning like

 WARNING: at mm/page_alloc.c:1805
 __alloc_pages_nodemask+0x127/0x48f()
 Hardware name: System Product Name
 Modules linked in:
 Pid: 1, comm: swapper Not tainted 2.6.32-rc8-git5 #1
 Call Trace:
  [<c103d94b>] warn_slowpath_common+0x65/0x95
  [<c103d98d>] warn_slowpath_null+0x12/0x15
  [<c109550c>] __alloc_pages_nodemask+0x127/0x48f
  [<c10be964>] ? get_slab+0x8/0x50
  [<c10b8979>] alloc_page_interleave+0x2e/0x6e
  [<c10b8a10>] alloc_pages_current+0x57/0x99
  [<c2083a4a>] ? xd_init+0x0/0x482
  [<c1094c38>] __get_free_pages+0xd/0x1e
  [<c2083a94>] xd_init+0x4a/0x482
  [<c2082df0>] ? loop_init+0x104/0x16a
  [<c169162d>] ? loop_probe+0x0/0xaf
  [<c2083a4a>] ? xd_init+0x0/0x482
  [<c1001143>] do_one_initcall+0x51/0x13f
  [<c204a307>] kernel_init+0x10b/0x15f
  [<c204a1fc>] ? kernel_init+0x0/0x15f
  [<c1004347>] kernel_thread_helper+0x7/0x10
 ---[ end trace 686db6333ade6e7a ]---
 xd: Out of memory.

The warning is because the alloc_pages is called with an
order >= MAX_ORDER. The simplistic reason is that get_order(0) returns garbage
values when given 0 as a size. The more complex reason is that the XD driver
initialisation is broken.

It's not clear why this ever worked. XD allocates a buffer for DMA based
on the value of xd_maxsectors. This value is determined by the exact
type of controller in use but the value is determined *after* an attempt
has been made to allocate the buffer. i.e. the requested size of the DMA
buffer will always be 0.

This patch alters how XD is initialised slightly by allocating the
buffer when and if a device has actually been detected. The error paths
are updated to suit the new logic.

Signed-off-by: Mel Gorman <mel@csn.ul.ie>
---
 drivers/block/xd.c |   30 +++++++++++++++++++-----------
 1 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 0877d36..d1fd032 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -169,13 +169,6 @@ static int __init xd_init(void)
 
 	init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
 
-	if (!xd_dma_buffer)
-		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
-	if (!xd_dma_buffer) {
-		printk(KERN_ERR "xd: Out of memory.\n");
-		return -ENOMEM;
-	}
-
 	err = -EBUSY;
 	if (register_blkdev(XT_DISK_MAJOR, "xd"))
 		goto out1;
@@ -202,6 +195,19 @@ static int __init xd_init(void)
 			xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
 	}
 
+	/*
+	 * With the drive detected, xd_maxsectors should now be known.
+	 * If xd_maxsectors is 0, nothing was detected and we fall through
+	 * to return -ENODEV
+	 */
+	if (!xd_dma_buffer && xd_maxsectors) {
+		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
+		if (!xd_dma_buffer) {
+			printk(KERN_ERR "xd: Out of memory.\n");
+			goto out3;
+		}
+	}
+
 	err = -ENODEV;
 	if (!xd_drives)
 		goto out3;
@@ -249,15 +255,17 @@ out4:
 	for (i = 0; i < xd_drives; i++)
 		put_disk(xd_gendisk[i]);
 out3:
-	release_region(xd_iobase,4);
+	if (xd_maxsectors)
+		release_region(xd_iobase,4);
+
+	if (xd_dma_buffer)
+		xd_dma_mem_free((unsigned long)xd_dma_buffer,
+				xd_maxsectors * 0x200);
 out2:
 	blk_cleanup_queue(xd_queue);
 out1a:
 	unregister_blkdev(XT_DISK_MAJOR, "xd");
 out1:
-	if (xd_dma_buffer)
-		xd_dma_mem_free((unsigned long)xd_dma_buffer,
-				xd_maxsectors * 0x200);
 	return err;
 Enomem:
 	err = -ENOMEM;

  reply	other threads:[~2009-12-07 14:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-03  7:40 kernel problem werner
2009-12-04 15:41 ` Steven Rostedt
2009-12-07 14:50   ` Mel Gorman [this message]
2009-12-07 20:48     ` Andrew Morton
2009-12-07 21:09     ` Jens Axboe
  -- strict thread matches above, loose matches on Subject: below --
2009-12-09  7:01 werner
2009-12-09  7:01 werner
2009-12-04 19:48 werner
2009-12-04 19:47 werner
2004-06-22 16:54 Kernel problem Juhani Pirttilahti
2004-06-22 17:18 ` William Lee Irwin III
2004-06-22 19:47   ` Juhani Pirttilahti
2004-06-22 22:43     ` Juhani Pirttilahti
2004-06-23  8:33 ` Geert Uytterhoeven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091207145011.GA14743@csn.ul.ie \
    --to=mel@csn.ul.ie \
    --cc=acme@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rientjes@google.com \
    --cc=rjw@sisk.pl \
    --cc=rostedt@goodmis.org \
    --cc=w.landgraf@ru.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox