From patchwork Thu Aug 30 08:05:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arend van Spriel X-Patchwork-Id: 1386991 Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 04A23DF215 for ; Thu, 30 Aug 2012 08:06:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752375Ab2H3IGA (ORCPT ); Thu, 30 Aug 2012 04:06:00 -0400 Received: from mms3.broadcom.com ([216.31.210.19]:4997 "EHLO mms3.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752052Ab2H3IF4 (ORCPT ); Thu, 30 Aug 2012 04:05:56 -0400 Received: from [10.9.200.131] by mms3.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.5)); Thu, 30 Aug 2012 01:03:38 -0700 X-Server-Uuid: B86B6450-0931-4310-942E-F00ED04CA7AF Received: from mail-irva-13.broadcom.com (10.11.16.103) by IRVEXCHHUB01.corp.ad.broadcom.com (10.9.200.131) with Microsoft SMTP Server id 8.2.247.2; Thu, 30 Aug 2012 01:05:42 -0700 Received: from mail-sj1-12.sj.broadcom.com (mail-sj1-12.sj.broadcom.com [10.17.16.106]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 237069F9F5; Thu, 30 Aug 2012 01:05:42 -0700 (PDT) Received: from arend-vb-pepper (unknown [10.176.68.25]) by mail-sj1-12.sj.broadcom.com (Postfix) with ESMTP id 784BB207C0; Thu, 30 Aug 2012 01:05:41 -0700 (PDT) Received: from arend by arend-vb-pepper with local (Exim 4.76) ( envelope-from ) id 1T6zky-0000wt-Am; Thu, 30 Aug 2012 10:05:40 +0200 From: "Arend van Spriel" To: "John W. Linville" cc: "Linux Wireless List" , "Hante Meuleman" , "Arend van Spriel" Subject: [PATCH 3/4] brcmfmac: fix race condition for rx and tx data. Date: Thu, 30 Aug 2012 10:05:36 +0200 Message-ID: <1346313937-3605-4-git-send-email-arend@broadcom.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1346313937-3605-1-git-send-email-arend@broadcom.com> References: <1346313937-3605-1-git-send-email-arend@broadcom.com> MIME-Version: 1.0 X-WSS-ID: 7C21C1D049825109994-01-01 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Hante Meuleman On both rx and tx there is was a race condition on the queueing of usb requests. When for example frame gets submitted it is possible that complete function gets called even before usb_submit_urb() returns. As a result it is possible that usb requests get losts, which was noticed on OMAP4 pandaboard platform. This patch fixes the race condition. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel --- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 8ea2db7..58f89fa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -550,6 +550,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { brcmf_dbg(ERROR, "rx protocol error\n"); brcmu_pkt_buf_free_skb(skb); + brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); devinfo->bus_pub.bus->dstats.rx_errors++; } else { brcmf_rx_packet(devinfo->dev, ifidx, skb); @@ -557,6 +558,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) } } else { brcmu_pkt_buf_free_skb(skb); + brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); } return; @@ -582,11 +584,11 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, req); req->devinfo = devinfo; + brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); ret = usb_submit_urb(req->urb, GFP_ATOMIC); - if (ret == 0) { - brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); - } else { + if (ret) { + brcmf_usb_del_fromq(devinfo, req); brcmu_pkt_buf_free_skb(req->skb); req->skb = NULL; brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); @@ -682,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); if (!req) { + brcmu_pkt_buf_free_skb(skb); brcmf_dbg(ERROR, "no req to send\n"); return -ENOMEM; } - if (!req->urb) { - brcmf_dbg(ERROR, "no urb for req %p\n", req); - return -ENOBUFS; - } req->skb = skb; req->devinfo = devinfo; usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, skb->data, skb->len, brcmf_usb_tx_complete, req); req->urb->transfer_flags |= URB_ZERO_PACKET; + brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); ret = usb_submit_urb(req->urb, GFP_ATOMIC); - if (!ret) { - brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); - } else { + if (ret) { + brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); + brcmf_usb_del_fromq(devinfo, req); + brcmu_pkt_buf_free_skb(req->skb); req->skb = NULL; brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); }