From 633dc92a28fc3fea6f08ef34de0b353ff5f9bf08 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 30 Jan 2013 23:55:35 +0000 Subject: ARM: DMA mapping: fix bad atomic test Realview fails to boot with this warning: BUG: spinlock lockup suspected on CPU#0, init/1 lock: 0xcf8bde10, .magic: dead4ead, .owner: init/1, .owner_cpu: 0 Backtrace: [] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c) r6:cf8bde10 r5:cf83d1c0 r4:cf8bde10 r3:cf83d1c0 [] (dump_stack+0x0/0x1c) from [] (spin_dump+0x84/0x98) [] (spin_dump+0x0/0x98) from [] (do_raw_spin_lock+0x100/0x198) [] (do_raw_spin_lock+0x0/0x198) from [] (_raw_spin_lock+0x3c/0x44) [] (_raw_spin_lock+0x0/0x44) from [] (pl011_console_write+0xe8/0x11c) [] (pl011_console_write+0x0/0x11c) from [] (call_console_drivers.clone.7+0xdc/0x104) [] (call_console_drivers.clone.7+0x0/0x104) from [] (console_unlock+0x2e8/0x454) [] (console_unlock+0x0/0x454) from [] (vprintk_emit+0x2d8/0x594) [] (vprintk_emit+0x0/0x594) from [] (printk+0x3c/0x44) [] (printk+0x0/0x44) from [] (warn_slowpath_common+0x28/0x6c) [] (warn_slowpath_common+0x0/0x6c) from [] (warn_slowpath_null+0x24/0x2c) [] (warn_slowpath_null+0x0/0x2c) from [] (lockdep_trace_alloc+0xd8/0xf0) [] (lockdep_trace_alloc+0x0/0xf0) from [] (kmem_cache_alloc+0x24/0x11c) [] (kmem_cache_alloc+0x0/0x11c) from [] (__get_vm_area_node.clone.24+0x7c/0x16c) [] (__get_vm_area_node.clone.24+0x0/0x16c) from [] (get_vm_area_caller+0x48/0x54) [] (get_vm_area_caller+0x0/0x54) from [] (__alloc_remap_buffer.clone.15+0x38/0xb8) [] (__alloc_remap_buffer.clone.15+0x0/0xb8) from [] (__dma_alloc+0x160/0x2c8) [] (__dma_alloc+0x0/0x2c8) from [] (arm_dma_alloc+0x88/0xa0)[] (arm_dma_alloc+0x0/0xa0) from [] (dma_pool_alloc+0xcc/0x1a8) [] (dma_pool_alloc+0x0/0x1a8) from [] (pl08x_fill_llis_for_desc+0x28/0x568) [] (pl08x_fill_llis_for_desc+0x0/0x568) from [] (pl08x_prep_slave_sg+0x258/0x3b0) [] (pl08x_prep_slave_sg+0x0/0x3b0) from [] (pl011_dma_tx_refill+0x140/0x288) [] (pl011_dma_tx_refill+0x0/0x288) from [] (pl011_start_tx+0xe4/0x120) [] (pl011_start_tx+0x0/0x120) from [] (__uart_start+0x48/0x4c) [] (__uart_start+0x0/0x4c) from [] (uart_start+0x2c/0x3c) [] (uart_start+0x0/0x3c) from [] (uart_write+0xcc/0xf4) [] (uart_write+0x0/0xf4) from [] (n_tty_write+0x1c0/0x3e4) [] (n_tty_write+0x0/0x3e4) from [] (tty_write+0x144/0x240) [] (tty_write+0x0/0x240) from [] (redirected_tty_write+0x98/0xac) [] (redirected_tty_write+0x0/0xac) from [] (vfs_write+0xbc/0x150) [] (vfs_write+0x0/0x150) from [] (sys_write+0x4c/0x78) [] (sys_write+0x0/0x78) from [] (ret_fast_syscall+0x0/0x3c) This happens because the DMA allocation code is not respecting atomic allocations correctly. GFP flags should not be tested for GFP_ATOMIC to determine if an atomic allocation is being requested. GFP_ATOMIC is not a flag but a value. The GFP bitmask flags are all prefixed with __GFP_. The rest of the kernel tests for __GFP_WAIT not being set to indicate an atomic allocation. We need to do the same. Signed-off-by: Russell King --- arch/arm/mm/dma-mapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 076c26d4386..dda3904dc64 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -640,7 +640,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, if (is_coherent || nommu()) addr = __alloc_simple_buffer(dev, size, gfp, &page); - else if (gfp & GFP_ATOMIC) + else if (!(gfp & __GFP_WAIT)) addr = __alloc_from_pool(size, &page); else if (!IS_ENABLED(CONFIG_CMA)) addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller); -- cgit v1.2.3