Thread (10 messages) flat view 10 messages, 3 authors, 2011-03-24

Hit BUG_ON in dma-mapping.c:425

From: Nicolas Ferre <hidden>
Date: 2011-01-06 10:38:43
Also in: lkml

(I include MTD mailing-list now)

Le 05/01/2011 17:55, Russell King - ARM Linux :
On Wed, Jan 05, 2011 at 05:49:12PM +0100, Nicolas Ferre wrote:
quoted
Hi,

While running mtd_stresstest on a dataflash (atmel_spi 
+ mtd_dataflash drivers) I hit the BUG_ON directive that 
is at the beginning of ___dma_single_cpu_to_dev() function.
This function is called from the SPI driver that do a 
dma_map_single() before DMA operations on the buffer 
transmitted from upper layers.

It seems that this address is above "high_memory" limit because 
it is allocated by vmalloc (in mtd_stresstest.c:285)...
Well, its telling you is that you're not allowed to DMA to vmalloc
addresses.  Whether that's the fault of the map driver or not is a
question for mtd folk.
So you mean that those vmalloc calls should be changed to kmalloc in MTD like this:
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -26,7 +26,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <linux/vmalloc.h>
 
 #define PRINT_PREF KERN_INFO "mtd_stresstest: "
 
@@ -281,8 +280,8 @@ static int __init mtd_stresstest_init(void)
        bufsize = mtd->erasesize * 2;
 
        err = -ENOMEM;
-       readbuf = vmalloc(bufsize);
-       writebuf = vmalloc(bufsize);
+       readbuf = kmalloc(bufsize, GFP_KERNEL);
+       writebuf = kmalloc(bufsize, GFP_KERNEL);
        offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL);
        if (!readbuf || !writebuf || !offsets) {
                printk(PRINT_PREF "error: cannot allocate memory\n");
@@ -313,8 +312,8 @@ static int __init mtd_stresstest_init(void)
 out:
        kfree(offsets);
        kfree(bbt);
-       vfree(writebuf);
-       vfree(readbuf);
+       kfree(writebuf);
+       kfree(readbuf);
        put_mtd_device(mtd);
        if (err)
                printk(PRINT_PREF "error %d occurred\n", err);

I also discovered the same issue while trying to write with "dd" on /dev/mtdblockx

Same vmalloc'ed memory seems to be used in mtdblock_writesect():
mtdblk->cache_data = vmalloc(mtdblk->mbd.mtd->erasesize);

I know that using "dd" on a block device is not the common case but it should work instead of not being able to transmit buffer with DMA... So what it implies to switch this to kmalloc? Is it regression-free to do this?

Best regards,
-- 
Nicolas Ferre
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help