From patchwork Tue Mar 22 11:52:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajkumar Manoharan X-Patchwork-Id: 8641511 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1A795C0553 for ; Tue, 22 Mar 2016 11:53:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 194B92035B for ; Tue, 22 Mar 2016 11:53:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F029F202B8 for ; Tue, 22 Mar 2016 11:53:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758887AbcCVLxh (ORCPT ); Tue, 22 Mar 2016 07:53:37 -0400 Received: from wolverine02.qualcomm.com ([199.106.114.251]:15926 "EHLO wolverine02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758858AbcCVLxf (ORCPT ); Tue, 22 Mar 2016 07:53:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=qti.qualcomm.com; i=@qti.qualcomm.com; q=dns/txt; s=qcdkim; t=1458647615; x=1490183615; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=F+/9ouhCF4JtUGTB3ltzWIppuVkibvTSyTIBOUgwy5g=; b=hY6nmh7+44ZhpPV4oMmkclH5Kyx5W9Bf2o4F3W2pbN3MPrhdlixBYJ2G KSaGxBM5s0YKNwt07DraVVooU2R3wd3njhz0HEyAOWRwwC0Lskj17ZiFH XQ2wCpFxk9JRFJKET+74twwiwJ06W6fNKozCJYFCMT3gsGp9vTo4E0WQu w=; X-IronPort-AV: E=Sophos;i="5.24,376,1455004800"; d="scan'208";a="273525092" Received: from unknown (HELO Ironmsg03-L.qualcomm.com) ([10.53.140.110]) by wolverine02.qualcomm.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 22 Mar 2016 04:53:34 -0700 X-IronPort-AV: E=McAfee;i="5700,7163,8111"; a="1115433284" Received: from nasanexm02b.na.qualcomm.com ([10.85.0.42]) by Ironmsg03-L.qualcomm.com with ESMTP/TLS/RC4-SHA; 22 Mar 2016 04:53:34 -0700 Received: from aphydexm01b.ap.qualcomm.com (10.252.127.11) by nasanexm02b.na.qualcomm.com (10.85.0.42) with Microsoft SMTP Server (TLS) id 15.0.1130.7; Tue, 22 Mar 2016 04:53:33 -0700 Received: from qcmail1.qualcomm.com (10.80.80.8) by aphydexm01b.ap.qualcomm.com (10.252.127.11) with Microsoft SMTP Server (TLS) id 15.0.1130.7; Tue, 22 Mar 2016 17:23:25 +0530 Received: by qcmail1.qualcomm.com (sSMTP sendmail emulation); Tue, 22 Mar 2016 17:23:18 +0530 From: Rajkumar Manoharan To: CC: , , "Rajkumar Manoharan" Subject: [PATCH 4/9] ath10k: cleanup amsdu processing for rx indication Date: Tue, 22 Mar 2016 17:22:14 +0530 Message-ID: <1458647539-17213-5-git-send-email-rmanohar@qti.qualcomm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1458647539-17213-1-git-send-email-rmanohar@qti.qualcomm.com> References: <1458647539-17213-1-git-send-email-rmanohar@qti.qualcomm.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanexm01a.na.qualcomm.com (10.85.0.81) To aphydexm01b.ap.qualcomm.com (10.252.127.11) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Make amsdu handlers (i.e amsdu_pop and rx_h_handler) common to both rx_ind and frag_ind htt events. It is sufficient to hold rx_ring lock for amsdu_pop alone and no need to hold it until the packets are delivered to mac80211. This helps to reduce rx_lock contention as well. Signed-off-by: Rajkumar Manoharan --- drivers/net/wireless/ath/ath10k/htt_rx.c | 100 +++++++++++++------------------ 1 file changed, 41 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index abb712f..3fdbfee 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1528,20 +1528,49 @@ static void ath10k_htt_rx_h_filter(struct ath10k *ar, __skb_queue_purge(amsdu); } +static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) +{ + struct ath10k *ar = htt->ar; + static struct ieee80211_rx_status rx_status; + struct sk_buff_head amsdu; + int ret; + + __skb_queue_head_init(&amsdu); + + spin_lock_bh(&htt->rx_ring.lock); + if (htt->rx_confused) { + spin_unlock_bh(&htt->rx_ring.lock); + return -EIO; + } + ret = ath10k_htt_rx_amsdu_pop(htt, &amsdu); + spin_unlock_bh(&htt->rx_ring.lock); + + if (ret < 0) { + ath10k_warn(ar, "rx ring became corrupted: %d\n", ret); + __skb_queue_purge(&amsdu); + /* FIXME: It's probably a good idea to reboot the + * device instead of leaving it inoperable. + */ + htt->rx_confused = true; + return ret; + } + + ath10k_htt_rx_h_ppdu(ar, &amsdu, &rx_status, 0xffff); + ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); + ath10k_htt_rx_h_filter(ar, &amsdu, &rx_status); + ath10k_htt_rx_h_mpdu(ar, &amsdu, &rx_status); + ath10k_htt_rx_h_deliver(ar, &amsdu, &rx_status); + + return 0; +} + static void ath10k_htt_rx_handler(struct ath10k_htt *htt, struct htt_rx_indication *rx) { struct ath10k *ar = htt->ar; - struct ieee80211_rx_status *rx_status = &htt->rx_status; struct htt_rx_indication_mpdu_range *mpdu_ranges; - struct sk_buff_head amsdu; int num_mpdu_ranges; - int i, ret, mpdu_count = 0; - - lockdep_assert_held(&htt->rx_ring.lock); - - if (htt->rx_confused) - return; + int i, mpdu_count = 0; num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1), HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); @@ -1556,63 +1585,18 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, mpdu_count += mpdu_ranges[i].mpdu_count; while (mpdu_count--) { - __skb_queue_head_init(&amsdu); - ret = ath10k_htt_rx_amsdu_pop(htt, &amsdu); - if (ret < 0) { - ath10k_warn(ar, "rx ring became corrupted: %d\n", ret); - __skb_queue_purge(&amsdu); - /* FIXME: It's probably a good idea to reboot the - * device instead of leaving it inoperable. - */ - htt->rx_confused = true; + if (ath10k_htt_rx_handle_amsdu(htt) < 0) break; - } - - ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); - ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); - ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); - ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); - ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); } tasklet_schedule(&htt->rx_replenish_task); } -static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, - struct htt_rx_fragment_indication *frag) +static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt) { - struct ath10k *ar = htt->ar; - struct ieee80211_rx_status *rx_status = &htt->rx_status; - struct sk_buff_head amsdu; - int ret; - - __skb_queue_head_init(&amsdu); - - spin_lock_bh(&htt->rx_ring.lock); - ret = ath10k_htt_rx_amsdu_pop(htt, &amsdu); - spin_unlock_bh(&htt->rx_ring.lock); + ath10k_htt_rx_handle_amsdu(htt); tasklet_schedule(&htt->rx_replenish_task); - - ath10k_dbg(ar, ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); - - if (ret) { - ath10k_warn(ar, "failed to pop amsdu from httr rx ring for fragmented rx %d\n", - ret); - __skb_queue_purge(&amsdu); - return; - } - - if (skb_queue_len(&amsdu) != 1) { - ath10k_warn(ar, "failed to pop frag amsdu: too many msdus\n"); - __skb_queue_purge(&amsdu); - return; - } - - ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); - ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); - ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); - ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); } static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, @@ -2331,7 +2315,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) case HTT_T2H_MSG_TYPE_RX_FRAG_IND: { ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", skb->data, skb->len); - ath10k_htt_rx_frag_handler(htt, &resp->rx_frag_ind); + ath10k_htt_rx_frag_handler(htt); break; } case HTT_T2H_MSG_TYPE_TEST: @@ -2473,9 +2457,7 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr) while ((skb = __skb_dequeue(&rx_q))) { resp = (struct htt_resp *)skb->data; - spin_lock_bh(&htt->rx_ring.lock); ath10k_htt_rx_handler(htt, &resp->rx_ind); - spin_unlock_bh(&htt->rx_ring.lock); dev_kfree_skb_any(skb); }