Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755160AbaAHGWm (ORCPT ); Wed, 8 Jan 2014 01:22:42 -0500 Received: from mail.windriver.com ([147.11.1.11]:48942 "EHLO mail.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752932AbaAHGWd (ORCPT ); Wed, 8 Jan 2014 01:22:33 -0500 From: "wenlin.kang" To: , CC: , Subject: [PATCH 1/2] usb/gadget: fix printer deadlock Date: Wed, 8 Jan 2014 14:22:11 +0800 Message-ID: <1389162132-17857-1-git-send-email-wenlin.kang@windriver.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "wenlin.kang" The problem occurs in follow path. printer_read() | +---setup_rx_reqs() | +---usb_ep_queue() | +---... | +---rx_complete() Although it is clear from code, we can't get it normally. only when we enable some spin_lock debug config option, we can find it. eg: BUG: spinlock lockup on CPU#0, g_printer_test_/584 lock: bf05e158, .magic: dead4ead, .owner: g_printer_test_/584, .owner_cpu: 0 [] (unwind_backtrace+0x0/0x104) from [] (dump_stack+0x20/0x24) [] (dump_stack+0x20/0x24) from [] (spin_dump+0x8c/0x94) [] (spin_dump+0x8c/0x94) from [] (do_raw_spin_lock+0x128/0x154) [] (do_raw_spin_lock+0x128/0x154) from [] (_raw_spin_lock_irqsave+0x64/0x70) [] (_raw_spin_lock_irqsave+0x64/0x70) from [] (rx_complete+0x54/0x10c [g_printer]) [] (rx_complete+0x54/0x10c [g_printer]) from [] (musb_g_giveback+0x78/0x88) [] (musb_g_giveback+0x78/0x88) from [] (rxstate+0xa0/0x10c) [] (rxstate+0xa0/0x10c) from [] (musb_ep_restart+0x44/0x70) [] (musb_ep_restart+0x44/0x70) from [] (musb_gadget_queue+0xe8/0xf8) [] (musb_gadget_queue+0xe8/0xf8) from [] (setup_rx_reqs+0xa4/0x178 [g_printer]) [] (setup_rx_reqs+0xa4/0x178 [g_printer]) from [] (printer_read+0x9c/0x3f4 [g_printer]) [] (printer_read+0x9c/0x3f4 [g_printer]) from [] (vfs_read+0xb4/0x144) [] (vfs_read+0xb4/0x144) from [] (sys_read+0x50/0x124) [] (sys_read+0x50/0x124) from [] (ret_fast_syscall+0x0/0x3c) The root cause is that we use the same lock two time in a path, so to avoid the deadlock, we need to unlock in setup_rx_reqs(), and only unlock. Signed-off-by: wenlin.kang --- drivers/usb/gadget/printer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 4e4dc1f..f4b4fa8 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -526,7 +526,10 @@ setup_rx_reqs(struct printer_dev *dev) req->length = USB_BUFSIZE; req->complete = rx_complete; + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); error = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); if (error) { DBG(dev, "rx submit --> %d\n", error); list_add(&req->list, &dev->rx_reqs); -- 1.7.9.5 -- 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/