Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp860489pxf; Wed, 7 Apr 2021 13:30:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxs5+Za6/QPE0oibA5uMACX1jQ691ZirXkjKXfPIBfJ08Hy3+ILIJ5P44OU6EUmA6tWvDza X-Received: by 2002:aa7:c64b:: with SMTP id z11mr6867885edr.8.1617827434999; Wed, 07 Apr 2021 13:30:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617827434; cv=none; d=google.com; s=arc-20160816; b=YW99u9eYvVzdnoXM0UWMbyL60DfbwdreHnX23c0Fj01C3AkhylM962SsSxKnLqwFxi fB1o+qrEXHmdrgmG2fSDzUZ1oGgdf0iH1g33JKPtm+lZmJYusFb7tE3V0B0LWfnLOVcj 3Jlbs/E8UqTWDl8oJLD8P2EJFw1Zj4LFTBGYwXPf3w0TVE4c5JJZQYzvLZ0gIdHDK1Nh ksYXYgO5GrEWqJqq2jcqU81Sf1SU7m98DFj3wPoc9KsRnt2/VWax7iYv5BKEAN6rpboa uNPLn6dOgVyxM+HT7zrcc6YIHzvnDbxcRX1tdYTnlTroEFCsMJfCEU6+T/q4DbFF9WKt EEOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:to:from:dkim-signature; bh=bV6kxVVTqjRAhD5Hf0TFvesDFNLy5ggRKT+CWxVJ1rU=; b=XeIs08cLUZ64P03aTmAyWidCBoJuRl5uDeuWw9nZDKUHfyPs5UI6ZqBKz7yP5sEbF5 Nd8LpV2cD+WE+e84AP0w5kof1gXB+pPqWIBHCh6MkXuCXqA55BiHhJKlm9cU5FUZ/9i9 ecz7I/3/QFtFzRjxMM5VIPK+kIrcS8zMkuWTTta+Q3B2DuzYB4bN2DLBLAmcRuouwdZf 2T/WXCl2Q2GMgQ07DroRxEfPdOgnTR2xMvgEeF0A1yCIP7VvZHzSTKXDHtxPzfdIVt1x c66FicnwcQGqdUeGyN9Q0GsKtzsaVlyZUXTTEfekN1BLjvqxOMcsN4x5xQZopIEF9sg4 Fifw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@nbd.name header.s=20160729 header.b=felGIiJU; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w22si9645747edx.93.2021.04.07.13.30.12; Wed, 07 Apr 2021 13:30:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@nbd.name header.s=20160729 header.b=felGIiJU; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244678AbhDGINV (ORCPT + 99 others); Wed, 7 Apr 2021 04:13:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233700AbhDGINV (ORCPT ); Wed, 7 Apr 2021 04:13:21 -0400 Received: from nbd.name (nbd.name [IPv6:2a01:4f8:221:3d45::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DBBCC06174A for ; Wed, 7 Apr 2021 01:13:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject :To:From:Sender:Reply-To:Cc:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=bV6kxVVTqjRAhD5Hf0TFvesDFNLy5ggRKT+CWxVJ1rU=; b=felGIiJUJ8JElkgpGpxxAYmykK 9IjoEqXIr6e/qnIdCmQMG60+thLkFDugQi2VuXLhDHvfS/WDdvufMogso+YWDqmxRc4/ejfxgOnDE 6KQvLp3Q+DxJu8QiZmG29I+jpAuiw5sjPPx6lp3dAWE74vQc+hZ7PlQSdO6ESzyyGmVs=; Received: from p4ff13c8d.dip0.t-ipconnect.de ([79.241.60.141] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1lU3JG-0002NN-3G for linux-wireless@vger.kernel.org; Wed, 07 Apr 2021 10:13:10 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Subject: [PATCH v2] mt76: fix rx amsdu subframe processing Date: Wed, 7 Apr 2021 10:13:03 +0200 Message-Id: <20210407081303.59647-1-nbd@nbd.name> X-Mailer: git-send-email 2.30.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When receiving an A-MSDU containing only a single subframe, status->last_amsdu is set, but no previous head is present in the rx A-MSDU queue. In this case, the A-MSDU subframe will be held until the next one is received, potentially causing significant extra latency. Rework the code to make it easier to read and less convoluted, and release the newly created head if status->last_amsdu is set. Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 7684a8cf00fb..ef31026ac9d7 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -508,44 +508,37 @@ void mt76_free_device(struct mt76_dev *dev) } EXPORT_SYMBOL_GPL(mt76_free_device); +static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q) +{ + struct sk_buff *skb = phy->rx_amsdu[q].head; + struct mt76_dev *dev = phy->dev; + + phy->rx_amsdu[q].head = NULL; + phy->rx_amsdu[q].tail = NULL; + __skb_queue_tail(&dev->rx_skb[q], skb); +} + static void mt76_rx_release_burst(struct mt76_phy *phy, enum mt76_rxq_id q, struct sk_buff *skb) { struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - struct sk_buff *nskb = phy->rx_amsdu[q].head; - struct mt76_dev *dev = phy->dev; - /* first amsdu subframe */ - if (status->amsdu && !phy->rx_amsdu[q].head) { + if (phy->rx_amsdu[q].head && + (!status->amsdu || status->first_amsdu || + status->seqno != phy->rx_amsdu[q].seqno)) + mt76_rx_release_amsdu(phy, q); + + if (!phy->rx_amsdu[q].head) { phy->rx_amsdu[q].tail = &skb_shinfo(skb)->frag_list; phy->rx_amsdu[q].seqno = status->seqno; phy->rx_amsdu[q].head = skb; - goto enqueue; - } - - /* ampdu or out-of-order amsdu subframes */ - if (!status->amsdu || status->seqno != phy->rx_amsdu[q].seqno) { - /* release pending frames */ - if (phy->rx_amsdu[q].head) - __skb_queue_tail(&dev->rx_skb[q], - phy->rx_amsdu[q].head); - nskb = skb; - goto reset_burst; - } - - /* trailing amsdu subframes */ - *phy->rx_amsdu[q].tail = skb; - if (!status->last_amsdu) { + } else { + *phy->rx_amsdu[q].tail = skb; phy->rx_amsdu[q].tail = &skb->next; - return; } -reset_burst: - phy->rx_amsdu[q].head = NULL; - phy->rx_amsdu[q].tail = NULL; -enqueue: - if (nskb) - __skb_queue_tail(&dev->rx_skb[q], nskb); + if (!status->amsdu || status->last_amsdu) + mt76_rx_release_amsdu(phy, q); } void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) -- 2.30.1