From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from wolverine01.qualcomm.com ([199.106.114.254]:47162 "EHLO wolverine01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752394Ab0LGMYk (ORCPT ); Tue, 7 Dec 2010 07:24:40 -0500 From: Pavankumar Kondeti Subject: [PATCH V3 06/11] USB: gadget: Fix "scheduling while atomic" bugs in ci13xxx_udc Date: Tue, 7 Dec 2010 17:54:00 +0530 Message-Id: <1291724645-26074-7-git-send-email-pkondeti@codeaurora.org> In-Reply-To: <1291724645-26074-1-git-send-email-pkondeti@codeaurora.org> References: <1291724645-26074-1-git-send-email-pkondeti@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org List-ID: To: linux-usb@vger.kernel.org, greg@kroah.com Cc: linux-arm-msm@vger.kernel.org, swetland@google.com, arve@google.com, benoitgoby@google.com, lockwood@android.com, dima@android.com, Pavankumar Kondeti dma_pool_alloc() require sleeping context when called with GFP_KERNEL argument. Hence release the spin lock before calling dma_pool_alloc(). usb_ep_alloc_request can also be called with non-atomic GFP flags. Hence get rid off spin lock while allocation request memory. Use GFP_ATOMIC flag for allocating request for ep0 in interrupt handler. Signed-off-by: Pavankumar Kondeti --- drivers/usb/gadget/ci13xxx_udc.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 4e9ec7d..d19537a 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -1626,7 +1626,7 @@ __acquires(udc->lock) spin_unlock(udc->lock); retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); if (!retval) { - mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_KERNEL); + mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC); if (mEp->status == NULL) { usb_ep_disable(&mEp->ep); retval = -ENOMEM; @@ -2055,7 +2055,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); struct ci13xxx_req *mReq = NULL; - unsigned long flags; trace("%p, %i", ep, gfp_flags); @@ -2064,8 +2063,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) return NULL; } - spin_lock_irqsave(mEp->lock, flags); - mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); if (mReq != NULL) { INIT_LIST_HEAD(&mReq->queue); @@ -2080,8 +2077,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); - spin_unlock_irqrestore(mEp->lock, flags); - return (mReq == NULL) ? NULL : &mReq->req; } @@ -2404,9 +2399,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, /* this allocation cannot be random */ for (k = RX; k <= TX; k++) { INIT_LIST_HEAD(&mEp->qh[k].queue); + spin_unlock_irqrestore(udc->lock, flags); mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL, &mEp->qh[k].dma); + spin_lock_irqsave(udc->lock, flags); if (mEp->qh[k].ptr == NULL) retval = -ENOMEM; else -- 1.7.1 -- Sent by a consultant of the Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.