dma: fix sleep in atomic bug
author黄涛 <huangtao@rock-chips.com>
Tue, 12 Oct 2010 09:30:48 +0000 (17:30 +0800)
committer黄涛 <huangtao@rock-chips.com>
Tue, 12 Oct 2010 09:30:48 +0000 (17:30 +0800)
dma_alloc_coherent use GFP_ATOMIC, fix this bug:
BUG: sleeping function called from invalid context at mm/page_alloc.c:1939
in_atomic(): 1, irqs_disabled(): 0, pid: 44, name: mmcqd
2 locks held by mmcqd/44:
 #0:  (&host->lock){......}, at: [<c0631fec>] rk2818_sdmmc_request+0x38/0x7c
 #1:  (&rk2818_dma[i].lock){......}, at: [<c04574e4>] rk28_dma_request+0x28/0x108
[<c044f108>] (unwind_backtrace+0x0/0xdc) from [<c06f3ac0>] (dump_stack+0x18/0x1c)
[<c06f3ac0>] (dump_stack+0x18/0x1c) from [<c045cc8c>] (__might_sleep+0x124/0x144)
[<c045cc8c>] (__might_sleep+0x124/0x144) from [<c04a8174>] (__alloc_pages_nodemask+0xb8/0x5ac)
[<c04a8174>] (__alloc_pages_nodemask+0xb8/0x5ac) from [<c044fc70>] (__dma_alloc+0x150/0x3e0)
[<c044fc70>] (__dma_alloc+0x150/0x3e0) from [<c044ff8c>] (dma_alloc_coherent+0x58/0x64)
[<c044ff8c>] (dma_alloc_coherent+0x58/0x64) from [<c0457534>] (rk28_dma_request+0x78/0x108)
[<c0457534>] (rk28_dma_request+0x78/0x108) from [<c044e3b4>] (request_dma+0x7c/0xa8)
[<c044e3b4>] (request_dma+0x7c/0xa8) from [<c0631d70>] (rk2818_sdmmc_start_request+0x25c/0x38c)
[<c0631d70>] (rk2818_sdmmc_start_request+0x25c/0x38c) from [<c063200c>] (rk2818_sdmmc_request+0x58/0x7c)
[<c063200c>] (rk2818_sdmmc_request+0x58/0x7c) from [<c0629fa8>] (mmc_wait_for_req+0x150/0x16c)
[<c0629fa8>] (mmc_wait_for_req+0x150/0x16c) from [<c06307b0>] (mmc_blk_issue_rq+0x234/0x4b8)
[<c06307b0>] (mmc_blk_issue_rq+0x234/0x4b8) from [<c06313b4>] (mmc_queue_thread+0x100/0x104)
[<c06313b4>] (mmc_queue_thread+0x100/0x104) from [<c047a868>] (kthread+0x84/0x8c)
[<c047a868>] (kthread+0x84/0x8c) from [<c044a8fc>] (kernel_thread_exit+0x0/0x8)

arch/arm/mach-rk2818/dma.c

index 81b945c03c4c0995d67aa57481c35090b2af3266..ca05cfc770005f03c588a512523172b18a17a69b 100644 (file)
@@ -506,7 +506,7 @@ static int rk28_dma_request(unsigned int dma_ch, dma_t *dma_t)
     
        /*channel 0 and 1 support llp, but others does not*/    
        if (dma_ch < RK28_DMA_CH2) { 
-        rk28dma->dma_llp_vir = (struct rk28_dma_llp *)dma_alloc_coherent(NULL, RK28_MAX_DMA_LLPS*sizeof(struct rk28_dma_llp), &rk28dma->dma_llp_phy, GFP_KERNEL);
+        rk28dma->dma_llp_vir = (struct rk28_dma_llp *)dma_alloc_coherent(NULL, RK28_MAX_DMA_LLPS*sizeof(struct rk28_dma_llp), &rk28dma->dma_llp_phy, GFP_ATOMIC);
         if (!rk28dma->dma_llp_vir) {
             printk(KERN_ERR "dma_request: no dma space can be allocated for llp by virtual channel %d\n", dma_ch); 
             return -ENOMEM;