Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757002Ab2HULWw (ORCPT ); Tue, 21 Aug 2012 07:22:52 -0400 Received: from hqemgate04.nvidia.com ([216.228.121.35]:2957 "EHLO hqemgate04.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756938Ab2HULWt (ORCPT ); Tue, 21 Aug 2012 07:22:49 -0400 X-PGP-Universal: processed; by hqnvupgp06.nvidia.com on Tue, 21 Aug 2012 04:22:38 -0700 Date: Tue, 21 Aug 2012 14:22:35 +0300 From: Hiroshi Doyu To: Marek Szyprowski CC: "linux-arm-kernel@lists.infradead.org" , "linaro-mm-sig@lists.linaro.org" , "linux-mm@kvack.org" , "linux-kernel@vger.kernel.org" , Kyungmin Park , Arnd Bergmann , Russell King - ARM Linux , Chunsang Jeong , Krishna Reddy , Konrad Rzeszutek Wilk , Subash Patel , Minchan Kim Subject: Re: [PATCHv6 2/2] ARM: dma-mapping: remove custom consistent dma region Message-ID: <20120821142235.97984abc9ad98d01015a3338@nvidia.com> In-Reply-To: <1343636899-19508-3-git-send-email-m.szyprowski@samsung.com> References: <1343636899-19508-1-git-send-email-m.szyprowski@samsung.com> <1343636899-19508-3-git-send-email-m.szyprowski@samsung.com> X-Mailer: Sylpheed 3.2.0beta3 (GTK+ 2.24.6; x86_64-pc-linux-gnu) X-NVConfidentiality: public MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7638 Lines: 131 Hi, On Mon, 30 Jul 2012 10:28:19 +0200 Marek Szyprowski wrote: > This patch changes dma-mapping subsystem to use generic vmalloc areas > for all consistent dma allocations. This increases the total size limit > of the consistent allocations and removes platform hacks and a lot of > duplicated code. > > Atomic allocations are served from special pool preallocated on boot, > because vmalloc areas cannot be reliably created in atomic context. > > Signed-off-by: Marek Szyprowski > Reviewed-by: Kyungmin Park > --- > Documentation/kernel-parameters.txt | 2 +- > arch/arm/include/asm/dma-mapping.h | 2 +- > arch/arm/mm/dma-mapping.c | 486 ++++++++++++----------------------- > arch/arm/mm/mm.h | 3 + > include/linux/vmalloc.h | 1 + > mm/vmalloc.c | 10 +- > 6 files changed, 181 insertions(+), 323 deletions(-) > ... > @@ -1117,61 +984,32 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t s > * Create a CPU mapping for a specified pages > */ > static void * > -__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot) > +__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot, > + const void *caller) > { > - struct arm_vmregion *c; > - size_t align; > - size_t count = size >> PAGE_SHIFT; > - int bit; > + unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; > + struct vm_struct *area; > + unsigned long p; > > - if (!consistent_pte[0]) { > - pr_err("%s: not initialised\n", __func__); > - dump_stack(); > + area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, > + caller); > + if (!area) This patch replaced the custom "consistent_pte" with get_vm_area_caller()", which breaks the compatibility with the existing driver. This causes the following kernel oops(*1). That driver has called dma_pool_alloc() to allocate memory from the interrupt context, and it hits BUG_ON(in_interrpt()) in "get_vm_area_caller()"(*2). Regardless of the badness of allocation from interrupt handler in the driver, I have the following question. The following "__get_vm_area_node()" can take gfp_mask, it means that this function is expected to be called from atomic context, but why it's _NOT_ allowed _ONLY_ from interrupt context? According to the following definitions, "in_interrupt()" is in "in_atomic()". #define in_interrupt() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK | NMI_MASK)) #define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) Does anyone know why BUG_ON(in_interrupt()) is set in __get_vm_area_node(*3)? *2: static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long align, unsigned long flags, unsigned long start, unsigned long end, int node, gfp_t gfp_mask, const void *caller) { struct vmap_area *va; struct vm_struct *area; BUG_ON(in_interrupt()); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^*3: *1: [ 8.321343] ------------[ cut here ]------------ [ 8.325971] kernel BUG at /home/hdoyu/mydroid-k340-cardhu/kernel/mm/vmalloc.c:1322! [ 8.333615] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM [ 8.339436] Modules linked in: [ 8.342496] CPU: 0 Tainted: G W (3.4.6-00067-g5d485f7 #67) [ 8.349192] PC is at __get_vm_area_node.isra.29+0x164/0x16c [ 8.354758] LR is at get_vm_area_caller+0x4c/0x54 [ 8.359454] pc : [] lr : [] psr: 20000193 [ 8.359458] sp : c09edca0 ip : c09ec000 fp : ae278000 [ 8.370922] r10: f0000000 r9 : c011aa54 r8 : c0a26cb8 [ 8.376136] r7 : 00000001 r6 : 000000d0 r5 : 20000008 r4 : c09edca0 [ 8.382651] r3 : 00010000 r2 : 20000008 r1 : 00000001 r0 : 00001000 [ 8.389166] Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel [ 8.396549] Control: 10c5387d Table: ad98c04a DAC: 00000015 .... [ 9.169162] dfa0: 412fc099 c09ec000 00000000 c000fdd8 c06df1e4 c0a1b080 00000000 00000000 [ 9.177329] dfc0: c0a235cc 8000406a 00000000 c0986818 ffffffff ffffffff c0986404 00000000 [ 9.185497] dfe0: 00000000 c09bb070 10c5387d c0a19c58 c09bb064 80008044 00000000 00000000 [ 9.193673] [] (__get_vm_area_node.isra.29+0x164/0x16c) from [] (get_vm_area_caller+0x4c/0x54) [ 9.204022] [] (get_vm_area_caller+0x4c/0x54) from [] (__iommu_alloc_remap.isra.14+0x2c/0xfc) [ 9.214276] [] (__iommu_alloc_remap.isra.14+0x2c/0xfc) from [] (arm_iommu_alloc_attrs+0xc4/0xf8) [ 9.224795] [] (arm_iommu_alloc_attrs+0xc4/0xf8) from [] (pool_alloc_page.constprop.5+0x6c/0xf8) [ 9.235309] [] (pool_alloc_page.constprop.5+0x6c/0xf8) from [] (dma_pool_alloc+0x80/0x170) [ 9.245304] [] (dma_pool_alloc+0x80/0x170) from [] (tegra_build_dtd+0x48/0x14c) [ 9.254344] [] (tegra_build_dtd+0x48/0x14c) from [] (tegra_req_to_dtd+0x7c/0xa8) [ 9.263467] [] (tegra_req_to_dtd+0x7c/0xa8) from [] (tegra_ep_queue+0x154/0x33c) [ 9.272592] [] (tegra_ep_queue+0x154/0x33c) from [] (composite_setup+0x364/0x6d4) [ 9.281804] [] (composite_setup+0x364/0x6d4) from [] (android_setup+0xb8/0x14c) [ 9.290843] [] (android_setup+0xb8/0x14c) from [] (setup_received_irq+0xbc/0x270) [ 9.300053] [] (setup_received_irq+0xbc/0x270) from [] (tegra_udc_irq+0x2ac/0x2c4) [ 9.309353] [] (tegra_udc_irq+0x2ac/0x2c4) from [] (handle_irq_event_percpu+0x78/0x2e0) [ 9.319087] [] (handle_irq_event_percpu+0x78/0x2e0) from [] (handle_irq_event+0x44/0x64) [ 9.328907] [] (handle_irq_event+0x44/0x64) from [] (handle_fasteoi_irq+0xc4/0x16c) [ 9.338294] [] (handle_fasteoi_irq+0xc4/0x16c) from [] (generic_handle_irq+0x34/0x48) [ 9.347858] [] (generic_handle_irq+0x34/0x48) from [] (handle_IRQ+0x54/0xb4) [ 9.356637] [] (handle_IRQ+0x54/0xb4) from [] (gic_handle_irq+0x2c/0x60) [ 9.365068] [] (gic_handle_irq+0x2c/0x60) from [] (__irq_svc+0x40/0x70) [ 9.373405] Exception stack(0xc09edf10 to 0xc09edf58) [ 9.378447] df00: 00000000 000f4240 00000003 00000000 [ 9.386615] df20: 00000000 e55bbc00 ef66f3ca 00000001 00000000 412fc099 c0abb9c8 00000000 [ 9.394781] df40: 3b9ac9ff c09edf58 c027a9bc c0042880 20000113 ffffffff [ 9.401396] [] (__irq_svc+0x40/0x70) from [] (tegra_idle_enter_lp3+0x68/0x78) [ 9.410272] [] (tegra_idle_enter_lp3+0x68/0x78) from [] (cpuidle_idle_call+0xdc/0x3a4) [ 9.419922] [] (cpuidle_idle_call+0xdc/0x3a4) from [] (cpu_idle+0xd8/0x134) [ 9.428612] [] (cpu_idle+0xd8/0x134) from [] (start_kernel+0x27c/0x2cc) [ 9.436952] Code: e1a00004 e3a04000 eb002265 eaffffe0 (e7f001f2) [ 9.443038] ---[ end trace 1b75b31a2719ed24 ]--- [ 9.447645] Kernel panic - not syncing: Fatal exception in interrupt -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/