From patchwork Thu Jan 25 10:14:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ganapathi Bhat X-Patchwork-Id: 10183847 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 799B0601D5 for ; Thu, 25 Jan 2018 10:19:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6830D28924 for ; Thu, 25 Jan 2018 10:19:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5CBE628A70; Thu, 25 Jan 2018 10:19:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD6F328924 for ; Thu, 25 Jan 2018 10:19:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751161AbeAYKTN (ORCPT ); Thu, 25 Jan 2018 05:19:13 -0500 Received: from mx0b-0016f401.pphosted.com ([67.231.156.173]:51738 "EHLO mx0b-0016f401.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750769AbeAYKTJ (ORCPT ); Thu, 25 Jan 2018 05:19:09 -0500 Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w0PAEgl9031519; Thu, 25 Jan 2018 02:19:08 -0800 Received: from sc-exch02.marvell.com ([199.233.58.182]) by mx0b-0016f401.pphosted.com with ESMTP id 2fnycv6p3k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Thu, 25 Jan 2018 02:19:08 -0800 Received: from SC-EXCH02.marvell.com (10.93.176.82) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Thu, 25 Jan 2018 02:19:06 -0800 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server id 15.0.1210.3 via Frontend Transport; Thu, 25 Jan 2018 02:19:06 -0800 Received: from localhost (gbhat-thinkpad-t430.marvell.com [10.31.130.81]) by maili.marvell.com (Postfix) with ESMTP id 746F63F703F; Thu, 25 Jan 2018 02:19:06 -0800 (PST) Received: from localhost.marvell.com (localhost [127.0.0.1]) by localhost (8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id w0PAEe7k012217; Thu, 25 Jan 2018 15:44:40 +0530 Received: (from root@localhost) by localhost.marvell.com (8.14.4/8.14.4/Submit) id w0PAEem5012216; Thu, 25 Jan 2018 15:44:40 +0530 From: Ganapathi Bhat To: CC: Brian Norris , Cathy Luo , Xinming Hu , Zhiyuan Yang , James Cao , Mangesh Malusare , Shrenik Shikhare , Ganapathi Bhat Subject: [PATCH v2 2/2] mwifiex: use more_rx_task_flag to avoid USB RX stall Date: Thu, 25 Jan 2018 15:44:36 +0530 Message-ID: <1516875276-12171-3-git-send-email-gbhat@marvell.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1516875276-12171-1-git-send-email-gbhat@marvell.com> References: <1516875276-12171-1-git-send-email-gbhat@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-01-25_03:, , signatures=0 X-Proofpoint-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=830 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1801250141 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Shrenik Shikhare There is a race condition for acquiring rx_proc_lock between rx worker thread and USB RX data interrupt (mwifiex_usb_rx_complete): 1. USB receives an RX data interrupt, queues rx_work 2. rx_work empties rx_data_q, tries to acquire rx_proc_lock (to clear rx_processing flag) 3. While #2 is yet to acquire rx_proc_lock, driver receives continuous RX data interupts(mwifiex_usb_rx_complete) 3. For each interrupt at #3, driver acquires rx_proc_lock(it gets the lock since it is in interrupt context), tries to queue rx_work, but fails to do so since rx_processing is still set(#2) 4. When rx_pending exceeds HIGH_RX_PENDING, driver stops submitting URBs back to USB subsystem and thus firmware stops uploading RX data to driver 5. Now finally #2 will acquire rx_proc_lock, but because of #4, there are no further triggers to schedule rx_work again The above scenario occurs in some platforms where the RX processing is comparitively slower. This results in RX stall in driver, command/TX timeouts in firmware. The above scenario is introduced after commit c7dbdcb2a4e1 ("mwifiex: schedule rx_work on RX interrupt for USB") To fix this set a new more_rx_task_flag whenever RX data callback is trying to schedule rx_work but rx_processing is not yet cleared. This will let the current rx_work(which was waiting for rx_proc_lock) to loopback and process newly arrived RX packets. Fixes: c7dbdcb2a4e1 ("mwifiex: schedule rx_work on RX interrupt for USB") Signed-off-by: Cathy Luo Signed-off-by: Ganapathi Bhat --- v2: added 'Fixes' label in commit message --- drivers/net/wireless/marvell/mwifiex/main.c | 10 +++++++++- drivers/net/wireless/marvell/mwifiex/main.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 6e6e1a7..ea87c7c 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -163,6 +163,7 @@ void mwifiex_queue_main_work(struct mwifiex_adapter *adapter) spin_lock_irqsave(&adapter->main_proc_lock, flags); if (adapter->mwifiex_processing) { adapter->more_task_flag = true; + adapter->more_rx_task_flag = true; spin_unlock_irqrestore(&adapter->main_proc_lock, flags); } else { spin_unlock_irqrestore(&adapter->main_proc_lock, flags); @@ -177,6 +178,7 @@ void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter) spin_lock_irqsave(&adapter->rx_proc_lock, flags); if (adapter->rx_processing) { + adapter->more_rx_task_flag = true; spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); } else { spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); @@ -193,13 +195,14 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter) spin_lock_irqsave(&adapter->rx_proc_lock, flags); if (adapter->rx_processing || adapter->rx_locked) { + adapter->more_rx_task_flag = true; spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); goto exit_rx_proc; } else { adapter->rx_processing = true; spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); } - +rx_process_start: /* Check for Rx data */ while ((skb = skb_dequeue(&adapter->rx_data_q))) { atomic_dec(&adapter->rx_pending); @@ -221,6 +224,11 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter) } } spin_lock_irqsave(&adapter->rx_proc_lock, flags); + if (adapter->more_rx_task_flag) { + adapter->more_rx_task_flag = false; + spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); + goto rx_process_start; + } adapter->rx_processing = false; spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 66ba95c..242e05e 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -891,6 +891,7 @@ struct mwifiex_adapter { spinlock_t main_proc_lock; u32 mwifiex_processing; u8 more_task_flag; + u8 more_rx_task_flag; u16 tx_buf_size; u16 curr_tx_buf_size; /* sdio single port rx aggregation capability */