From patchwork Fri Aug 31 07:26:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshihiro Shimoda X-Patchwork-Id: 1391321 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 8F6753FDF6 for ; Fri, 31 Aug 2012 07:27:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751671Ab2HaH1H (ORCPT ); Fri, 31 Aug 2012 03:27:07 -0400 Received: from relmlor3.renesas.com ([210.160.252.173]:52272 "EHLO relmlor3.renesas.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751781Ab2HaH04 (ORCPT ); Fri, 31 Aug 2012 03:26:56 -0400 Received: from relmlir2.idc.renesas.com ([10.200.68.152]) by relmlor3.idc.renesas.com ( SJSMS) with ESMTP id <0M9L0057YZCVV1E0@relmlor3.idc.renesas.com> for linux-sh@vger.kernel.org; Fri, 31 Aug 2012 16:26:55 +0900 (JST) Received: from relmlac1.idc.renesas.com ([10.200.69.21]) by relmlir2.idc.renesas.com ( SJSMS) with ESMTP id <0M9L008H2ZCV3Y00@relmlir2.idc.renesas.com> for linux-sh@vger.kernel.org; Fri, 31 Aug 2012 16:26:55 +0900 (JST) Received: by relmlac1.idc.renesas.com (Postfix, from userid 0) id F32B880195; Fri, 31 Aug 2012 16:26:53 +0900 (JST) Received: from relmlac1.idc.renesas.com (localhost [127.0.0.1]) by relmlac1.idc.renesas.com (Postfix) with ESMTP id EDAF48015D; Fri, 31 Aug 2012 16:26:53 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac1.idc.renesas.com with ESMTP id SAA24696; Fri, 31 Aug 2012 16:26:53 +0900 X-IronPort-AV: E=Sophos; i="4.80,346,1344178800"; d="scan'208"; a="96198573" Received: from unknown (HELO [172.30.8.157]) ([172.30.8.157]) by relmlii1.idc.renesas.com with ESMTP; Fri, 31 Aug 2012 16:26:52 +0900 Message-id: <5040673C.3000207@renesas.com> Date: Fri, 31 Aug 2012 16:26:52 +0900 From: "Shimoda, Yoshihiro" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:15.0) Gecko/20120824 Thunderbird/15.0 MIME-version: 1.0 To: Paul Mundt Cc: SH-Linux Subject: [RFC][PATCH] sh: fix dma_generic_alloc_coherent for 32-bit mode Content-type: text/plain; charset=ISO-8859-1 Content-transfer-encoding: 7bit Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org Hi Paul, I found an issue when I used the following environment: - linux-3.6-rc3 - SH7785 32-bit mode - EHCI PCI card - USBNIC When I ran ifconfig for USBNIC, the panic happened: ======= ~ # ifconfig usb0 up kernel BUG at /linux.git/mm/vmalloc.c:1330! Kernel BUG: 003e [#1] Modules linked in: Pid : 525, Comm: ifconfig CPU : 0 Not tainted (3.6.0-rc3-00037-g2d809dc #6) PC is at __get_vm_area_node+0x1a0/0x220 PR is at get_vm_area_caller+0x20/0x40 PC : 800a0940 SP : 9f69dacc SR : 400081f0 TEA : c0012324 R0 : 800a07a0 R1 : 07ffff00 R2 : 00000103 R3 : 00000000 R4 : 00001000 R5 : 00000001 R6 : 00000001 R7 : c0000000 R8 : 5f695000 R9 : 00001000 R10 : 00000001 R11 : 00000001 R12 : 00003810 R13 : c0000000 R14 : 9f69dacc MACH: 0000000b MACL: 00000000 GBR : 29799440 PR : 800a09e0 Call trace: [<800a09e0>] get_vm_area_caller+0x20/0x40 [<800a7754>] dma_pool_alloc+0xb4/0x240 [<800a7754>] dma_pool_alloc+0xb4/0x240 [<80436816>] __ioremap_caller+0x76/0x120 [<800115d2>] dma_generic_alloc_coherent+0x92/0x140 [<800a7754>] dma_pool_alloc+0xb4/0x240 [<800a7754>] dma_pool_alloc+0xb4/0x240 [<800a7754>] dma_pool_alloc+0xb4/0x240 [<800080ec>] ret_from_exception+0x0/0x8 [<800080ec>] ret_from_exception+0x0/0x8 [<802cbf56>] ehci_qtd_alloc+0x16/0x60 [<802cca1a>] qh_urb_transaction+0x13a/0x3e0 [<802cc902>] qh_urb_transaction+0x22/0x3e0 [<802c8300>] qtd_fill+0x0/0xc0 [<8044dac0>] _raw_spin_unlock+0x20/0x40 [<802ccd7a>] ehci_urb_enqueue+0xba/0xec0 [<802ccd1c>] ehci_urb_enqueue+0x5c/0xec0 [<8007ecde>] get_page_from_freelist+0x45e/0x5e0 [<800031fc>] nommu_map_page+0x3c/0x80 [<802b9ed8>] usb_hcd_map_urb_for_dma+0x378/0x3e0 [<8007f202>] __alloc_pages_nodemask+0xa2/0x620 [<802b9fae>] usb_hcd_submit_urb+0x6e/0x8e0 [<802003e0>] debug_smp_processor_id+0x0/0xe0 [<8044dbc0>] _raw_spin_lock+0x0/0x40 [<8044daa0>] _raw_spin_unlock+0x0/0x40 [<8044dbd6>] _raw_spin_lock+0x16/0x40 [<8044dac0>] _raw_spin_unlock+0x20/0x40 [<800ad36c>] kmem_cache_alloc+0x2c/0x140 [<800ad442>] kmem_cache_alloc+0x102/0x140 [<8038cd26>] build_skb+0x26/0xc0 [<8038f226>] __netdev_alloc_skb+0x86/0x100 [<802bad34>] usb_submit_urb+0xd4/0x340 [<802af1e6>] rx_submit+0xe6/0x260 [<802af3bc>] rx_alloc_submit+0x5c/0xc0 [<802bb3c0>] usb_alloc_urb+0x0/0x60 [<802b0246>] usbnet_bh+0x1e6/0x2a0 [<8038c980>] consume_skb+0x0/0x60 [<8038ba00>] skb_dequeue+0x0/0x80 [<8002059c>] tasklet_action+0x5c/0xc0 [<80003a20>] arch_local_irq_restore+0x0/0x40 [<80020cb0>] __do_softirq+0xb0/0x1c0 [<80021046>] do_softirq+0x66/0xa0 [<803964e0>] dev_set_rx_mode+0x0/0x40 [<80003a20>] arch_local_irq_restore+0x0/0x40 [<80021258>] local_bh_enable_ip+0x78/0xe0 [<80043d40>] sub_preempt_count+0x0/0xa0 [<8044d9da>] _raw_spin_unlock_bh+0x1a/0x40 [<80396502>] dev_set_rx_mode+0x22/0x40 [<80396502>] dev_set_rx_mode+0x22/0x40 [<80399920>] __dev_open+0xe0/0x160 [<80396746>] __dev_change_flags+0xe6/0x1a0 [<803997da>] dev_change_flags+0x1a/0x80 [<803ed688>] devinet_ioctl+0x748/0x800 [<803ee7fe>] inet_ioctl+0x1e/0x160 [<80383e14>] sock_ioctl+0xf4/0x2e0 [<800c6f0c>] do_vfs_ioctl+0x6c/0x640 [<8044daaa>] _raw_spin_unlock+0xa/0x40 [<8044dab0>] _raw_spin_unlock+0x10/0x40 [<800b207c>] fd_install+0x3c/0x80 [<80383c44>] sock_map_fd+0x24/0x40 [<80384cc0>] sys_socket+0x60/0xa0 [<800c7512>] sys_ioctl+0x32/0xa0 [<8000826a>] syscall_call+0xc/0x10 [<800c74e0>] sys_ioctl+0x0/0xa0 ======= If I used the following patch, the panic didn't happen. But, I don't know whether this modification is right. --- Some drivers call dma_pool_alloc() in atomic context. When mmu mode of sh4 is 32bit, get_vm_area_caller() is called finally. Then, the BUG_ON() in __get_vm_area_node() will call panic(). This patch fixes this issue using ioremap_fixed(). Signed-off-by: Yoshihiro Shimoda --- arch/sh/mm/consistent.c | 7 ++++++- arch/sh/mm/ioremap_fixed.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index b81d9db..06164ac 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -51,7 +51,12 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, */ dma_cache_sync(dev, ret, size, DMA_BIDIRECTIONAL); - ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size); + if (!__in_29bit_mode() && (gfp & GFP_ATOMIC)) + ret_nocache = (void __force *)ioremap_fixed(virt_to_phys(ret), + size, PAGE_KERNEL_NOCACHE); + else + ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), + size); if (!ret_nocache) { free_pages((unsigned long)ret, order); return NULL; diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index efbe84a..ffae5c2 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -43,7 +43,7 @@ void __init ioremap_fixed_init(void) } } -void __init __iomem * +void __iomem * ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot) { enum fixed_addresses idx0, idx;