From patchwork Tue Oct 15 17:18:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 11191305 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4299814ED for ; Tue, 15 Oct 2019 17:19:26 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A34E020854 for ; Tue, 15 Oct 2019 17:19:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="SImhzj1z"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PmbyUusq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A34E020854 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:To:From:Subject:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1nk4deRBRez/G/dafyUNi3f3SfNw1tcpXV/exOuouP4=; b=SImhzj1z69geKn WUr2PRwrd0u4qTe1HlVDNp8zQA5shel4YXretxBBx09rXBUi163g5wGVaP7+6se/I1Lngu0cabqyv I8oR6Ri92YIa3Nh60RTIBYOaFotqecMWHdz8zvpohVWOoThi08ko/nSLJvEsGPlC+GAfP2oc5EQWs +C70KmJZ8EsNOHYxmjlYrpbUGwBkRiSFvlKqw3gGONbKC+HjADHqk61ZKT0J4pYEoKD4Yt6WEEmfc HD8Hktclm9VYxzfPJWA5+BCQUSbFPIO0XUJKMf0KvAB/me7WTMhxcbGKJH54mCn3yJZf6uQpScp1C i9KAz/5Atb/mjVO9yVHA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTg-0007CR-Ri; Tue, 15 Oct 2019 17:19:20 +0000 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120] helo=us-smtp-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTW-0006yZ-Sk for ath10k@lists.infradead.org; Tue, 15 Oct 2019 17:19:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571159945; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2qf8HGaC9XYB4yCBmVPA2/e9VNoQoe0I/AoOfC2m9mE=; b=PmbyUusqO+MO2cLHtjGNc1bFvYNZiR+PZGGpc/ps0/DFpWL/F6CzEdGMgJfBmwFT2wI56V hRG0/2pxNOhjIhqTF9T4V0X7U6cU5Q7whzkTlqwfB49VvTYdjiZ6U9q4N33ZsrbH5oVSkG Ql2qQBGCYXfGboEmaHQX64zDopZOIb8= Received: from mail-lj1-f197.google.com (mail-lj1-f197.google.com [209.85.208.197]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-382-e1033LQYPjywFM3tZbgYGg-1; Tue, 15 Oct 2019 13:19:03 -0400 Received: by mail-lj1-f197.google.com with SMTP id y28so4049781ljn.2 for ; Tue, 15 Oct 2019 10:19:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=Xz0DFDu36TCFLND3BKlsyYv/TX/+u1NMntE7P/QH1z8=; b=j1dGkH2sJz85FR5+RyPP/ferxJTtao9u4krqqfCLTB1QBd5aT9qyKOiGCOZAr8SO0b Ix8UgIazCQ84mLZNlAYQuYuV4+rg1YaHRM4QIjPLgbSL8gH0w+Ne+FfF+ZWz8M4LfXGC S/Gk/VdzLJ9mHSNn3qvpcRBk99apMvj1DCro8NCeWg8GR3UmEYz04GOMUYw1uPPLZEvP dDmf/Mm9L4MUecQfOvnuBLz9f6YgHe6UcW4nzU2pnpbAo8k1TTf3MNc9slT28aKM1ECN 8wSyGVMBLOTTmA4bgO4RjsNQOlMmbdwMJS2pxHzBr4zja4++iU5ykJ1+DDlVoMO+9NWs gu7w== X-Gm-Message-State: APjAAAVdIyG80ewn1tYtvorw/DfCG14tLQGsjgU5o3Fbt48EaCjc7suE 4eKyUzsViy2jVRIJ5z8vv5C7Rnpij2SpFcDswaSByXmiABiiuVBXar+P+KqHz/g7Ge3dFwvC07y rkxkybG4CnzImTdTcbYerwQ== X-Received: by 2002:a19:dc14:: with SMTP id t20mr3205378lfg.21.1571159940384; Tue, 15 Oct 2019 10:19:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqzjLO6aCJGIyJgLbMmJuwRaVWDfTwy3zvUgeePNCzfGgSDv/H65WMQjzv2MbphmgGo+wiStTQ== X-Received: by 2002:a19:dc14:: with SMTP id t20mr3205368lfg.21.1571159940122; Tue, 15 Oct 2019 10:19:00 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id z72sm5664042ljb.98.2019.10.15.10.18.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Oct 2019 10:18:59 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id B680A1803A9; Tue, 15 Oct 2019 19:18:58 +0200 (CEST) Subject: [PATCH v2 1/4] mac80211: Rearrange ieee80211_tx_info to make room for tx_time_est From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Johannes Berg Date: Tue, 15 Oct 2019 19:18:58 +0200 Message-ID: <157115993866.2500430.13989567853855880476.stgit@toke.dk> In-Reply-To: <157115993755.2500430.12214017471129215800.stgit@toke.dk> References: <157115993755.2500430.12214017471129215800.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: e1033LQYPjywFM3tZbgYGg-1 X-Mimecast-Spam-Score: 0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191015_101911_044561_D3186EF3 X-CRM114-Status: GOOD ( 13.56 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [205.139.110.120 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kan Yan , Rajkumar Manoharan , Kevin Hayes , make-wifi-fast@lists.bufferbloat.net, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org From: Toke Høiland-Jørgensen To implement airtime queue limiting, we need to keep a running account of the estimated airtime of all skbs queued into the device. Do to this correctly, we need to store the airtime estimate into the skb so we can decrease the outstanding balance when the skb is freed. This means that the time estimate must be stored somewhere that will survive for the lifetime of the skb. Fortunately, we had a couple of bytes left in the 'status' field in the ieee80211_tx_info; and since we only plan to calculate the airtime estimate after the skb is dequeued from the FQ structure, on the control side we can share the space with the codel enqueue time. And by rearranging the order of elements it is possible to have the position of the new tx_time_est line up between the control and status structs, so the value will survive from when mac80211 hands the packet to the driver, and until the driver either frees it, or hands it back through TX status. Signed-off-by: Toke Høiland-Jørgensen --- include/net/mac80211.h | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d69081c38788..49f8ea0af5f8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -975,20 +975,23 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate) * @control.short_preamble: use short preamble (CCK only) * @control.skip_table: skip externally configured rate table * @control.jiffies: timestamp for expiry on powersave clients + * @control.enqueue_time: enqueue time (for iTXQs) + * @control.tx_time_est: estimated airtime usage (shared with @status) + * @control.reserved: unused field to ensure alignment of data structure + * @control.flags: control flags, see &enum mac80211_tx_control_flags * @control.vif: virtual interface (may be NULL) * @control.hw_key: key to encrypt with (may be NULL) - * @control.flags: control flags, see &enum mac80211_tx_control_flags - * @control.enqueue_time: enqueue time (for iTXQs) * @driver_rates: alias to @control.rates to reserve space * @pad: padding * @rate_driver_data: driver use area if driver needs @control.rates * @status: union part for status data * @status.rates: attempted rates * @status.ack_signal: ACK signal + * @status.tx_time_est: estimated airtime of skb (shared with @control) + * @status.tx_time: actual airtime consumed for transmission * @status.ampdu_ack_len: AMPDU ack length * @status.ampdu_len: AMPDU length * @status.antenna: (legacy, kept only for iwlegacy) - * @status.tx_time: airtime consumed for transmission * @status.is_valid_ack_signal: ACK signal is valid * @status.status_driver_data: driver use area * @ack: union part for pure ACK data @@ -1026,11 +1029,17 @@ struct ieee80211_tx_info { /* only needed before rate control */ unsigned long jiffies; }; + union { + codel_time_t enqueue_time; + struct { + u16 tx_time_est; /* shared with status */ + u16 reserved; /* padding for alignment */ + }; + }; + u32 flags; /* NB: vif can be NULL for injected frames */ struct ieee80211_vif *vif; struct ieee80211_key_conf *hw_key; - u32 flags; - codel_time_t enqueue_time; } control; struct { u64 cookie; @@ -1038,12 +1047,13 @@ struct ieee80211_tx_info { struct { struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; s32 ack_signal; + u16 tx_time_est; /* shared with control */ + u16 tx_time; u8 ampdu_ack_len; u8 ampdu_len; u8 antenna; - u16 tx_time; bool is_valid_ack_signal; - void *status_driver_data[19 / sizeof(void *)]; + void *status_driver_data[16 / sizeof(void *)]; } status; struct { struct ieee80211_tx_rate driver_rates[ @@ -1126,6 +1136,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) offsetof(struct ieee80211_tx_info, control.rates)); BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) != offsetof(struct ieee80211_tx_info, driver_rates)); + BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, control.tx_time_est) != + offsetof(struct ieee80211_tx_info, status.tx_time_est)); BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) != 8); /* clear the rate counts */ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) From patchwork Tue Oct 15 17:18:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 11191303 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3B59A14ED for ; Tue, 15 Oct 2019 17:19:19 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 15C0C20854 for ; Tue, 15 Oct 2019 17:19:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="tEyQCgRr"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Z5ukk7J6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 15C0C20854 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:To:From:Subject:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=XmtUhail0PTUxlQPz7MZnHQhq2EQ1llgt4cipGqQ8go=; b=tEyQCgRrh9kTHF U5/4CLipj2lSONA+YxJHISSIAEafoaDeu2Mh6I3h9l2HjEgcwgaj5QtkA4me/p5Nzr1gbK2ZDKVuY J3xRWQsrXEyCGPbrj1Uf4M7DaH9qgL9hRdLp/1OBUlCVKW/79R16GsSbD9M0VuuenuHlxp08Sjn5d NjrcTz5ONcEseGberWmoaKzxIIOmkamFU2CaghR3agpSp03U8IYelZRZy+KYSKkDnilVRCtHZOx6S 8e/G4UaqnR2hqK+f35K9eyxTwDhgDIutL9B+AaswvsdFof0vwWI/fhjG3IUgtmdwpWDacQxYuhmAd S2Ph7zaoWnfO5+ZBZzbg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTd-00078s-Ti; Tue, 15 Oct 2019 17:19:17 +0000 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120] helo=us-smtp-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTU-0006zR-Oi for ath10k@lists.infradead.org; Tue, 15 Oct 2019 17:19:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571159947; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=U2B+RQcc+GBcfes1Irvb9PkgSokPNhyOEN8//bJUpHA=; b=Z5ukk7J60jtLvF2XMamr0fmFG8gPfCfIFwn9LIw1k/liLbK7Ex93KsNExt6R/iFJIitqqJ wzU0qp6JbwcuRe3pToW9B9Q22Yp6C8/D+mrjcsJTy5+Ps1YEyb7Rcjb1XN4dzAg/svwici iJJE5pbNPwgm+tz0CaD06e6hsxxOcKs= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-51-Xii4aWjvMG69PrdHVtwOlQ-1; Tue, 15 Oct 2019 13:19:03 -0400 Received: by mail-lf1-f70.google.com with SMTP id e1so3914670lfb.12 for ; Tue, 15 Oct 2019 10:19:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=T6qHqaS13xJ+wOnFKPV4Xv6wH5SCpjGm2KAC5stfSZA=; b=tM8B3ofQ6+a78AiH9Db1TpQNZFcTZZRQ1wUt3cy/HYJTiY+sQ1r1tChGcaNWJLVMSy fJBwGJ3YnZfZKUtfqQq6mV//BlmizD8YOmyyPCRmD50Q+y2+++PbADYhWYNOtLwaf1Ck OqW9tto5mOlXcjWgscbi+E9Fp0qYEplSMuGEWg04kkrRzE9mW4gm7kCmiLAsMLbu8yUi 5z/rEmV37dxYYk8JH56Zk3mq8zM9jsbjWVTrPccHxyh2FQeYRK+kI/Z3VUS50lF0Uvcp EmKRfgJa8j3SSe+WJnrKsiu1ZFmncFY+yQ8S60NgQhzI63D8TGFnQs/Q1TZFMUttfkH9 3uug== X-Gm-Message-State: APjAAAUqj0me/yic07u+ur5WEB7fV4vjgBhK/fN1SKil3GXDm3zj6Omg R0XDHsrc/J7YPCX6bCEJPfFFOCiHO3Sl1DTemcZf42/ZTchpui5WpoEVyrD28QZct9Z7nhqBoWr nPTPRsMqQNASFiqqy8nJvbA== X-Received: by 2002:a2e:8684:: with SMTP id l4mr22699958lji.53.1571159941985; Tue, 15 Oct 2019 10:19:01 -0700 (PDT) X-Google-Smtp-Source: APXvYqwxh5NICgmbnRnEbvnnS4YCs2kIeYMu3ff45ye0NEfbHFfVfZPldYNfM6grnvEWjoIqn+QSsg== X-Received: by 2002:a2e:8684:: with SMTP id l4mr22699907lji.53.1571159941081; Tue, 15 Oct 2019 10:19:01 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id u26sm5233078lfd.19.2019.10.15.10.19.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Oct 2019 10:19:00 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id CBD6A1803A8; Tue, 15 Oct 2019 19:18:59 +0200 (CEST) Subject: [PATCH v2 2/4] mac80211: Import airtime calculation code from mt76 From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Johannes Berg Date: Tue, 15 Oct 2019 19:18:59 +0200 Message-ID: <157115993975.2500430.3838554513349536280.stgit@toke.dk> In-Reply-To: <157115993755.2500430.12214017471129215800.stgit@toke.dk> References: <157115993755.2500430.12214017471129215800.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: Xii4aWjvMG69PrdHVtwOlQ-1 X-Mimecast-Spam-Score: 0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191015_101908_961230_DA0F2FFC X-CRM114-Status: GOOD ( 16.01 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [207.211.31.120 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kan Yan , Rajkumar Manoharan , Kevin Hayes , make-wifi-fast@lists.bufferbloat.net, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org From: Toke Høiland-Jørgensen Felix recently added code to calculate airtime of packets to the mt76 driver. Import this into mac80211 so we can use it for airtime queue limit calculations later. The airtime.c file is copied verbatim from the mt76 driver, and adjusted to use mac80211 data structures instead (which is fairly straight forward). The per-rate TX rate calculation is split out to its own function (ieee80211_calc_tx_airtime_rate()) so it can be used directly for the AQL calculations added in a subsequent patch. The only thing that it was not possible to port directly was the bit that read the internal driver flags of struct ieee80211_rate to determine whether a rate is using CCK or OFDM encoding. Instead, just look at the rate index, since at least mt76 and ath10k both seem to have the same number of CCK rates (4) in their tables. Signed-off-by: Toke Høiland-Jørgensen --- include/net/mac80211.h | 14 ++ net/mac80211/Makefile | 3 net/mac80211/airtime.c | 375 ++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 4 4 files changed, 395 insertions(+), 1 deletion(-) create mode 100644 net/mac80211/airtime.c diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 49f8ea0af5f8..7619eb74d612 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -6434,4 +6434,18 @@ void ieee80211_nan_func_match(struct ieee80211_vif *vif, struct cfg80211_nan_match_params *match, gfp_t gfp); +/** + * ieee80211_calc_tx_airtime - calculate estimated transmission airtime. + * + * This function calculates the estimated airtime usage of a frame based on the + * rate information in the TX info struct and the frame length. + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @info: &struct ieee80211_tx_info of the frame. + * @len: frame length in bytes + */ +u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info, + int len); + #endif /* MAC80211_H */ diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 4f03ebe732fa..6cbb1286d6c0 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -32,7 +32,8 @@ mac80211-y := \ chan.o \ trace.o mlme.o \ tdls.o \ - ocb.o + ocb.o \ + airtime.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c new file mode 100644 index 000000000000..7a18d5405756 --- /dev/null +++ b/net/mac80211/airtime.c @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2019 Felix Fietkau + */ + +#include +#include "ieee80211_i.h" +#include "sta_info.h" + +#define AVG_PKT_SIZE 1024 + +/* Number of bits for an average sized packet */ +#define MCS_NBITS (AVG_PKT_SIZE << 3) + +/* Number of symbols for a packet with (bps) bits per symbol */ +#define MCS_NSYMS(bps) DIV_ROUND_UP(MCS_NBITS, (bps)) + +/* Transmission time (1024 usec) for a packet containing (syms) * symbols */ +#define MCS_SYMBOL_TIME(sgi, syms) \ + (sgi ? \ + ((syms) * 18 * 1024 + 4 * 1024) / 5 : /* syms * 3.6 us */ \ + ((syms) * 1024) << 2 /* syms * 4 us */ \ + ) + +/* Transmit duration for the raw data part of an average sized packet */ +#define MCS_DURATION(streams, sgi, bps) \ + MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) + +#define BW_20 0 +#define BW_40 1 +#define BW_80 2 + +/* + * Define group sort order: HT40 -> SGI -> #streams + */ +#define IEEE80211_MAX_STREAMS 4 +#define IEEE80211_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ +#define IEEE80211_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ + +#define IEEE80211_HT_GROUPS_NB (IEEE80211_MAX_STREAMS * \ + IEEE80211_HT_STREAM_GROUPS) +#define IEEE80211_VHT_GROUPS_NB (IEEE80211_MAX_STREAMS * \ + IEEE80211_VHT_STREAM_GROUPS) +#define IEEE80211_GROUPS_NB (IEEE80211_HT_GROUPS_NB + \ + IEEE80211_VHT_GROUPS_NB) + +#define IEEE80211_HT_GROUP_0 0 +#define IEEE80211_VHT_GROUP_0 (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB) + +#define MCS_GROUP_RATES 10 +#define CCK_NUM_RATES 4 + +#define HT_GROUP_IDX(_streams, _sgi, _ht40) \ + IEEE80211_HT_GROUP_0 + \ + IEEE80211_MAX_STREAMS * 2 * _ht40 + \ + IEEE80211_MAX_STREAMS * _sgi + \ + _streams - 1 + +#define _MAX(a, b) (((a)>(b))?(a):(b)) + +#define GROUP_SHIFT(duration) \ + _MAX(0, 16 - __builtin_clz(duration)) + +/* MCS rate information for an MCS group */ +#define __MCS_GROUP(_streams, _sgi, _ht40, _s) \ + [HT_GROUP_IDX(_streams, _sgi, _ht40)] = { \ + .shift = _s, \ + .duration = { \ + MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \ + MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \ + } \ +} + +#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40) \ + GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26)) + +#define MCS_GROUP(_streams, _sgi, _ht40) \ + __MCS_GROUP(_streams, _sgi, _ht40, \ + MCS_GROUP_SHIFT(_streams, _sgi, _ht40)) + +#define VHT_GROUP_IDX(_streams, _sgi, _bw) \ + (IEEE80211_VHT_GROUP_0 + \ + IEEE80211_MAX_STREAMS * 2 * (_bw) + \ + IEEE80211_MAX_STREAMS * (_sgi) + \ + (_streams) - 1) + +#define BW2VBPS(_bw, r3, r2, r1) \ + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) + +#define __VHT_GROUP(_streams, _sgi, _bw, _s) \ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .shift = _s, \ + .duration = { \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 117, 54, 26)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 234, 108, 52)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 351, 162, 78)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 468, 216, 104)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 702, 324, 156)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 936, 432, 208)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1053, 486, 234)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1170, 540, 260)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1404, 648, 312)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 1560, 720, 346)) >> _s \ + } \ +} + +#define VHT_GROUP_SHIFT(_streams, _sgi, _bw) \ + GROUP_SHIFT(MCS_DURATION(_streams, _sgi, \ + BW2VBPS(_bw, 117, 54, 26))) + +#define VHT_GROUP(_streams, _sgi, _bw) \ + __VHT_GROUP(_streams, _sgi, _bw, \ + VHT_GROUP_SHIFT(_streams, _sgi, _bw)) + +struct mcs_group { + u8 shift; + u16 duration[MCS_GROUP_RATES]; +}; + +static const struct mcs_group airtime_mcs_groups[] = { + MCS_GROUP(1, 0, BW_20), + MCS_GROUP(2, 0, BW_20), + MCS_GROUP(3, 0, BW_20), + MCS_GROUP(4, 0, BW_20), + + MCS_GROUP(1, 1, BW_20), + MCS_GROUP(2, 1, BW_20), + MCS_GROUP(3, 1, BW_20), + MCS_GROUP(4, 1, BW_20), + + MCS_GROUP(1, 0, BW_40), + MCS_GROUP(2, 0, BW_40), + MCS_GROUP(3, 0, BW_40), + MCS_GROUP(4, 0, BW_40), + + MCS_GROUP(1, 1, BW_40), + MCS_GROUP(2, 1, BW_40), + MCS_GROUP(3, 1, BW_40), + MCS_GROUP(4, 1, BW_40), + + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), + VHT_GROUP(3, 0, BW_20), + VHT_GROUP(4, 0, BW_20), + + VHT_GROUP(1, 1, BW_20), + VHT_GROUP(2, 1, BW_20), + VHT_GROUP(3, 1, BW_20), + VHT_GROUP(4, 1, BW_20), + + VHT_GROUP(1, 0, BW_40), + VHT_GROUP(2, 0, BW_40), + VHT_GROUP(3, 0, BW_40), + VHT_GROUP(4, 0, BW_40), + + VHT_GROUP(1, 1, BW_40), + VHT_GROUP(2, 1, BW_40), + VHT_GROUP(3, 1, BW_40), + VHT_GROUP(4, 1, BW_40), + + VHT_GROUP(1, 0, BW_80), + VHT_GROUP(2, 0, BW_80), + VHT_GROUP(3, 0, BW_80), + VHT_GROUP(4, 0, BW_80), + + VHT_GROUP(1, 1, BW_80), + VHT_GROUP(2, 1, BW_80), + VHT_GROUP(3, 1, BW_80), + VHT_GROUP(4, 1, BW_80), +}; + +static u32 +ieee80211_calc_legacy_rate_duration(const struct ieee80211_rate *rate, + bool short_pre, bool cck, + int len) +{ + u32 duration; + + if (cck) { + duration = 144 + 48; /* preamble + PLCP */ + if (short_pre) + duration >>= 1; + + duration += 10; /* SIFS */ + } else { + duration = 20 + 16; /* premable + SIFS */ + } + + len <<= 3; + duration += (len * 10) / rate->bitrate; + + return duration; +} + +u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw, + struct ieee80211_rx_status *status, + int len) +{ + struct ieee80211_supported_band *sband; + const struct ieee80211_rate *rate; + bool sgi = status->enc_flags & RX_ENC_FLAG_SHORT_GI; + bool sp = status->enc_flags & RX_ENC_FLAG_SHORTPRE; + int bw, streams; + u32 duration; + int group, idx; + bool cck; + + switch (status->bw) { + case RATE_INFO_BW_20: + bw = BW_20; + break; + case RATE_INFO_BW_40: + bw = BW_40; + break; + case RATE_INFO_BW_80: + bw = BW_80; + break; + default: + WARN_ON_ONCE(1); + return 0; + } + + switch (status->encoding) { + case RX_ENC_LEGACY: + if (WARN_ON_ONCE(status->band > NL80211_BAND_5GHZ)) + return 0; + + sband = hw->wiphy->bands[status->band]; + if (!sband || status->rate_idx > sband->n_bitrates) + return 0; + + rate = &sband->bitrates[status->rate_idx]; + cck = (status->rate_idx < CCK_NUM_RATES); + + return ieee80211_calc_legacy_rate_duration(rate, sp, cck, len); + + case RX_ENC_VHT: + streams = status->nss; + idx = status->rate_idx; + group = VHT_GROUP_IDX(streams, sgi, bw); + break; + case RX_ENC_HT: + streams = ((status->rate_idx >> 3) & 3) + 1; + idx = status->rate_idx & 7; + group = HT_GROUP_IDX(streams, sgi, bw); + break; + default: + WARN_ON_ONCE(1); + return 0; + } + + if (WARN_ON_ONCE(streams > 4)) + return 0; + + duration = airtime_mcs_groups[group].duration[idx]; + duration <<= airtime_mcs_groups[group].shift; + duration *= len; + duration /= AVG_PKT_SIZE; + duration /= 1024; + + duration += 36 + (streams << 2); + + return duration; +} + +u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw, + struct ieee80211_tx_rate *rate, + u8 band, int len) +{ + struct ieee80211_rx_status stat = { + .band = band, + }; + + if (rate->idx < 0 || !rate->count) + return 0; + + if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH) + stat.bw = RATE_INFO_BW_80; + else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + stat.bw = RATE_INFO_BW_40; + else + stat.bw = RATE_INFO_BW_20; + + stat.enc_flags = 0; + if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + stat.enc_flags |= RX_ENC_FLAG_SHORTPRE; + if (rate->flags & IEEE80211_TX_RC_SHORT_GI) + stat.enc_flags |= RX_ENC_FLAG_SHORT_GI; + + stat.rate_idx = rate->idx; + if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + stat.encoding = RX_ENC_VHT; + stat.rate_idx = ieee80211_rate_get_vht_mcs(rate); + stat.nss = ieee80211_rate_get_vht_nss(rate); + } else if (rate->flags & IEEE80211_TX_RC_MCS) { + stat.encoding = RX_ENC_HT; + } else { + stat.encoding = RX_ENC_LEGACY; + } + + return ieee80211_calc_rx_airtime(hw, &stat, len); +} + +u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw, + struct ieee80211_tx_info *info, + int len) +{ + u32 duration = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) { + struct ieee80211_tx_rate *rate = &info->status.rates[i]; + u32 cur_duration; + + cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate, + info->band, len); + if (!cur_duration) + break; + + duration += cur_duration * rate->count; + } + + return duration; +} +EXPORT_SYMBOL_GPL(ieee80211_calc_tx_airtime); + + +u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *pubsta, + int len) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_chanctx_conf *conf; + struct ieee80211_rate *rate; + struct sta_info *sta; + u8 band = 0; + + conf = rcu_dereference(vif->chanctx_conf); + if (conf) + band = conf->def.chan->band; + + if (pubsta) { + sta = container_of(pubsta, struct sta_info, sta); + return ieee80211_calc_tx_airtime_rate(hw, &sta->tx_stats.last_rate, + band, len); + } + + if (!conf) + return 0; + + /* No station to get latest rate from, so calculate the + * worst-case duration for the lowest rate. + */ + sband = hw->wiphy->bands[band]; + rate = &sband->bitrates[0]; + + return ieee80211_calc_legacy_rate_duration(rate, false, true, len); +} diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 05406e9c05b3..225ea4e3cd76 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2249,6 +2249,10 @@ const char *ieee80211_get_reason_code_string(u16 reason_code); extern const struct ethtool_ops ieee80211_ethtool_ops; +u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *pubsta, + int len); #ifdef CONFIG_MAC80211_NOINLINE #define debug_noinline noinline #else From patchwork Tue Oct 15 17:19:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 11191299 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 386BF1390 for ; Tue, 15 Oct 2019 17:19:14 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id ED9AF20854 for ; Tue, 15 Oct 2019 17:19:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="s3OdUtgy"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TRfH4eGX" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org ED9AF20854 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:To:From:Subject:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=nr+F+Nf2fUmOIY9Xji0hGpp5jYngF1ibFOdZJYwuqNg=; b=s3OdUtgymMQ040 UFrtWs9D5PjJC2St7AljXmbb/IGwofc0MNyQ0KRNM9NleSCh6m30gyQXxJcVtbW1lDLMsGz2lL8GC UYt5b/tx3JG5OQRzOI4ATdCjZihof673/3+q17S+zIXfeqLslRvz4J7h0UwL0QxJZFg4jI+FBCjqM dl4FOiHKPp6h9dnPH0n70cDmoPEHBhNUq1/RNaUlzN8S3HZ+kWnQ2etew2EYGaceTVemXUc7QW+OJ fy6Qhm2teiVpWgR2H5BnfY3bzUT94AM59Bzsk/g0xMC3shzVLqaf36bRUAMxJqO5UCoOrAGoXTD1w Jm1MWCeaVq42xLH5fSAQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTY-00073K-HT; Tue, 15 Oct 2019 17:19:12 +0000 Received: from us-smtp-1.mimecast.com ([207.211.31.81] helo=us-smtp-delivery-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTU-0006zL-F6 for ath10k@lists.infradead.org; Tue, 15 Oct 2019 17:19:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571159947; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XnkDlyOiYYUttRmAdYa5cySMniZ9t2R59IF001zI9ZE=; b=TRfH4eGXPgrLUe/rM4vO1ClCT0KmvnH4ZjLO5KK27S0J597fEUejLCsz+lWwGcm2WTdset VRokCTARd0ZZL3WzB7p+oYrewjsYcLAy/sKbOigdDtGZvBhJ5XSVHMQJG3KlnUiM4s2rIQ sMjwY2TDedfJEw9hujhAP7SotWn9j0U= Received: from mail-lf1-f71.google.com (mail-lf1-f71.google.com [209.85.167.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-169-cLEWKKAANQSAj_tS1WEXPw-1; Tue, 15 Oct 2019 13:19:05 -0400 Received: by mail-lf1-f71.google.com with SMTP id w22so3927100lfe.2 for ; Tue, 15 Oct 2019 10:19:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=IFzHIo7rEgOEbTBpyBUconBFu5SsXwEfs6ZewoNOLxo=; b=At4SqA2w1xy7C4drUaubsMdAxn0HgOslf9l60BtALbbH+y6CSuiSbZYQFAE55IRtqu 00IzmVYEbjQuGxgdhs3dakhi712Gidn1EsQnqFxHhf9RThlyyE5c+0Y1rShbVwSL5iEq qg3lbz09uDGc5H3tC6pPfTfFCSLaVXJX1/eXeRApbFFGfiixKLHjVnjPX8Ly0wcREtzh xpW1CxbBCkyv6p+3bWB0+xp2PpHBSfGVfTxhD6hTfSxGrSIUnyNkkgqRCXPDZLcJC1IR x5q18x9dHmgSNcsHgXO7HGekZOhP3uE5sPDPUjFTb+hdJYDTCwWuh/TMeX8/EL7pvBuR mAVQ== X-Gm-Message-State: APjAAAUmCks4ntqm7uqieDjPnLRqdYS2qxB4YViPViCfaOL7HJToV6U1 3uTjsEY4qpHELe6rCxGXn+athse2OhInxBgHWukEO6FQrP8ijpyRYTz9gXO5a2lqTfAbRxPaNUP O9j3ghw8YJ+r1O2Pr2ENZaA== X-Received: by 2002:a05:651c:1069:: with SMTP id y9mr13229251ljm.171.1571159942693; Tue, 15 Oct 2019 10:19:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqyjSYa0JNvu0wF2H3xMh8lZQ3RmGD1nKvu+kMymV3E4Jtxv0qcmmb0RHfHWg8pk9ItYXJGm6w== X-Received: by 2002:a05:651c:1069:: with SMTP id y9mr13229214ljm.171.1571159942143; Tue, 15 Oct 2019 10:19:02 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a00:7660:6da:443::2]) by smtp.gmail.com with ESMTPSA id i17sm5248094lfj.35.2019.10.15.10.19.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Oct 2019 10:19:01 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id DBFD41803A9; Tue, 15 Oct 2019 19:19:00 +0200 (CEST) Subject: [PATCH v2 3/4] mac80211: Implement Airtime-based Queue Limit (AQL) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Johannes Berg Date: Tue, 15 Oct 2019 19:19:00 +0200 Message-ID: <157115994083.2500430.6570557769527791276.stgit@toke.dk> In-Reply-To: <157115993755.2500430.12214017471129215800.stgit@toke.dk> References: <157115993755.2500430.12214017471129215800.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: cLEWKKAANQSAj_tS1WEXPw-1 X-Mimecast-Spam-Score: 0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191015_101908_670304_C4EA8853 X-CRM114-Status: GOOD ( 17.65 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [207.211.31.81 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kan Yan , Rajkumar Manoharan , Kevin Hayes , make-wifi-fast@lists.bufferbloat.net, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org From: Kan Yan In order for the Fq_CoDel integrated in mac80211 layer operates effectively to control excessive queueing latency, the CoDel algorithm requires an accurate measure of how long the packets stays in the queue, aka sojourn time. The sojourn time measured at mac80211 layer doesn't include queueing latency in lower layer (firmware/hardware) and CoDel expects lower layer to have a short queue. However, most 802.11ac chipsets offload tasks such TX aggregation to firmware or hardware, thus have a deep lower layer queue. Without a mechanism to control the lower layer queue size, packets only stays in mac80211 layer transiently before being sent to firmware queue. As a result, the sojourn time measured by CoDel in the mac80211 layer is almost always lower than the CoDel latency target, hence CoDel does little to control the latency, even when the lower layer queue causes excessive latency. Byte Queue limits (BQL) is commonly used to address the similar issue with wired network interface. However, this method cannot be applied directly to the wireless network interface. Byte is not a suitable measure of queue depth in the wireless network, as the data rate can vary dramatically from station to station in the same network, from a few Mbps to over Gbps. This patch implemented an Airtime-based Queue Limit (AQL) to make CoDel works effectively with wireless drivers that utilized firmware/hardware offloading. AQL only allows each txq to release just enough packets to the lower layer to form 1-2 large aggregations to keep hardware fully utilized and keep the rest of frames in mac80211 layer to be controlled by the CoDel algorithm. Signed-off-by: Kan Yan [ Toke: Get rid of the driver API to set pending airtime ] Signed-off-by: Toke Høiland-Jørgensen --- include/net/cfg80211.h | 7 ++++ include/net/mac80211.h | 12 +++++++ net/mac80211/debugfs.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ net/mac80211/debugfs_sta.c | 43 +++++++++++++++++++----- net/mac80211/ieee80211_i.h | 4 ++ net/mac80211/main.c | 9 +++++ net/mac80211/sta_info.c | 32 ++++++++++++++++++ net/mac80211/sta_info.h | 8 +++++ net/mac80211/tx.c | 46 ++++++++++++++++++++++++-- 9 files changed, 225 insertions(+), 14 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ff45c3e1abff..8d50c0a60dbd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2602,6 +2602,13 @@ enum wiphy_params_flags { #define IEEE80211_DEFAULT_AIRTIME_WEIGHT 256 +/* The per TXQ device queue limit in airtime */ +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 4000 +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 8000 + +/* The per interface airtime threshold to switch to lower queue limit */ +#define IEEE80211_AQL_THRESHOLD 24000 + /** * struct cfg80211_pmksa - PMK Security Association * diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7619eb74d612..b5727a20754c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -5575,6 +5575,18 @@ void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid); void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, u32 tx_airtime, u32 rx_airtime); +/** + * ieee80211_txq_airtime_check - check if a txq can send frame to device + * + * @hw: pointer obtained from ieee80211_alloc_hw() + * @txq: pointer obtained from station or virtual interface + * + * Return true if the AQL's airtime limit has not been reached and the txq can + * continue to send more packets to the device. Otherwise return false. + */ +bool +ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq); + /** * ieee80211_iter_keys - iterate keys programmed into the device * @hw: pointer obtained from ieee80211_alloc_hw() diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 568b3b276931..d77ea0e51c1d 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -148,6 +148,80 @@ static const struct file_operations aqm_ops = { .llseek = default_llseek, }; +static ssize_t aql_txq_limit_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct ieee80211_local *local = file->private_data; + char buf[400]; + int len = 0; + + len = scnprintf(buf, sizeof(buf), + "AC AQL limit low AQL limit high\n" + "VO %u %u\n" + "VI %u %u\n" + "BE %u %u\n" + "BK %u %u\n", + local->aql_txq_limit_low[IEEE80211_AC_VO], + local->aql_txq_limit_high[IEEE80211_AC_VO], + local->aql_txq_limit_low[IEEE80211_AC_VI], + local->aql_txq_limit_high[IEEE80211_AC_VI], + local->aql_txq_limit_low[IEEE80211_AC_BE], + local->aql_txq_limit_high[IEEE80211_AC_BE], + local->aql_txq_limit_low[IEEE80211_AC_BK], + local->aql_txq_limit_high[IEEE80211_AC_BK]); + return simple_read_from_buffer(user_buf, count, ppos, + buf, len); +} + +static ssize_t aql_txq_limit_write(struct file *file, + const char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct ieee80211_local *local = file->private_data; + char buf[100]; + size_t len; + u32 ac, q_limit_low, q_limit_high; + struct sta_info *sta; + + if (count > sizeof(buf)) + return -EINVAL; + + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + + buf[sizeof(buf) - 1] = 0; + len = strlen(buf); + if (len > 0 && buf[len - 1] == '\n') + buf[len - 1] = 0; + + if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3) + return -EINVAL; + + if (ac >= IEEE80211_NUM_ACS) + return -EINVAL; + + local->aql_txq_limit_low[ac] = q_limit_low; + local->aql_txq_limit_high[ac] = q_limit_high; + + mutex_lock(&local->sta_mtx); + list_for_each_entry(sta, &local->sta_list, list) { + sta->airtime[ac].aql_limit_low = q_limit_low; + sta->airtime[ac].aql_limit_high = q_limit_high; + } + mutex_unlock(&local->sta_mtx); + return count; +} + +static const struct file_operations aql_txq_limit_ops = { + .write = aql_txq_limit_write, + .read = aql_txq_limit_read, + .open = simple_open, + .llseek = default_llseek, +}; + static ssize_t force_tx_status_read(struct file *file, char __user *user_buf, size_t count, @@ -441,6 +515,10 @@ void debugfs_hw_add(struct ieee80211_local *local) debugfs_create_u16("airtime_flags", 0600, phyd, &local->airtime_flags); + DEBUGFS_ADD(aql_txq_limit); + debugfs_create_u32("aql_threshold", 0600, + phyd, &local->aql_threshold); + statsd = debugfs_create_dir("statistics", phyd); /* if the dir failed, don't put all the other things into the root! */ diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index c8ad20c28c43..9f9b8f5ed86a 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -197,10 +197,12 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf, { struct sta_info *sta = file->private_data; struct ieee80211_local *local = sta->sdata->local; - size_t bufsz = 200; + size_t bufsz = 400; char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; u64 rx_airtime = 0, tx_airtime = 0; s64 deficit[IEEE80211_NUM_ACS]; + u32 q_depth[IEEE80211_NUM_ACS]; + u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS]; ssize_t rv; int ac; @@ -212,19 +214,22 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf, rx_airtime += sta->airtime[ac].rx_airtime; tx_airtime += sta->airtime[ac].tx_airtime; deficit[ac] = sta->airtime[ac].deficit; + q_limit_l[ac] = sta->airtime[ac].aql_limit_low; + q_limit_h[ac] = sta->airtime[ac].aql_limit_high; + q_depth[ac] = sta->airtime[ac].aql_tx_pending; spin_unlock_bh(&local->active_txq_lock[ac]); } p += scnprintf(p, bufsz + buf - p, "RX: %llu us\nTX: %llu us\nWeight: %u\n" - "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", - rx_airtime, - tx_airtime, - sta->airtime_weight, - deficit[0], - deficit[1], - deficit[2], - deficit[3]); + "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n" + "Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n" + "Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n", + rx_airtime, tx_airtime, sta->airtime_weight, + deficit[0], deficit[1], deficit[2], deficit[3], + q_depth[0], q_depth[1], q_depth[2], q_depth[3], + q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1], + q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]), rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); kfree(buf); @@ -236,7 +241,25 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf, { struct sta_info *sta = file->private_data; struct ieee80211_local *local = sta->sdata->local; - int ac; + u32 ac, q_limit_l, q_limit_h; + char _buf[100] = {}, *buf = _buf; + + if (count > sizeof(_buf)) + return -EINVAL; + + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[sizeof(_buf) - 1] = '\0'; + if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h) + != 3) + return -EINVAL; + + if (ac >= IEEE80211_NUM_ACS) + return -EINVAL; + + sta->airtime[ac].aql_limit_low = q_limit_l; + sta->airtime[ac].aql_limit_high = q_limit_h; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { spin_lock_bh(&local->active_txq_lock[ac]); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 225ea4e3cd76..6fa690757388 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1142,6 +1142,10 @@ struct ieee80211_local { u16 schedule_round[IEEE80211_NUM_ACS]; u16 airtime_flags; + u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; + u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; + u32 aql_threshold; + u32 aql_total_pending_airtime; const struct ieee80211_ops *ops; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index aba094b4ccfc..0792c9b9c850 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -667,8 +667,15 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, for (i = 0; i < IEEE80211_NUM_ACS; i++) { INIT_LIST_HEAD(&local->active_txqs[i]); spin_lock_init(&local->active_txq_lock[i]); + local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; + local->aql_txq_limit_high[i] = + IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; } - local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX; + + local->airtime_flags = AIRTIME_USE_TX | + AIRTIME_USE_RX | + AIRTIME_USE_AQL; + local->aql_threshold = IEEE80211_AQL_THRESHOLD; INIT_LIST_HEAD(&local->chanctx_list); mutex_init(&local->chanctx_mtx); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index bd11fef2139f..64bacf4f068c 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -396,6 +396,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, skb_queue_head_init(&sta->ps_tx_buf[i]); skb_queue_head_init(&sta->tx_filtered[i]); sta->airtime[i].deficit = sta->airtime_weight; + sta->airtime[i].aql_tx_pending = 0; + sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i]; + sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i]; } for (i = 0; i < IEEE80211_NUM_TIDS; i++) @@ -1893,6 +1896,35 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, } EXPORT_SYMBOL(ieee80211_sta_register_airtime); +void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, + struct sta_info *sta, u8 ac, + u16 tx_airtime, bool tx_completed) +{ + spin_lock_bh(&local->active_txq_lock[ac]); + if (tx_completed) { + if (sta) { + if (WARN_ONCE(sta->airtime[ac].aql_tx_pending < tx_airtime, + "TXQ pending airtime underflow: %u, %u", + sta->airtime[ac].aql_tx_pending, tx_airtime)) + sta->airtime[ac].aql_tx_pending = 0; + else + sta->airtime[ac].aql_tx_pending -= tx_airtime; + } + + if (WARN_ONCE(local->aql_total_pending_airtime < tx_airtime, + "Device pending airtime underflow: %u, %u", + local->aql_total_pending_airtime, tx_airtime)) + local->aql_total_pending_airtime = 0; + else + local->aql_total_pending_airtime -= tx_airtime; + } else { + if (sta) + sta->airtime[ac].aql_tx_pending += tx_airtime; + local->aql_total_pending_airtime += tx_airtime; + } + spin_unlock_bh(&local->active_txq_lock[ac]); +} + int sta_info_move_state(struct sta_info *sta, enum ieee80211_sta_state new_state) { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 369c2dddce52..4e4d76e81b0f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -127,13 +127,21 @@ enum ieee80211_agg_stop_reason { /* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */ #define AIRTIME_USE_TX BIT(0) #define AIRTIME_USE_RX BIT(1) +#define AIRTIME_USE_AQL BIT(2) struct airtime_info { u64 rx_airtime; u64 tx_airtime; s64 deficit; + u32 aql_tx_pending; /* Estimated airtime for frames pending in queue */ + u32 aql_limit_low; + u32 aql_limit_high; }; +void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, + struct sta_info *sta, u8 ac, + u16 tx_airtime, bool tx_completed); + struct sta_info; /** diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 938c10f7955b..405f622b3fe0 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3665,7 +3665,8 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) { struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_txq *ret = NULL; - struct txq_info *txqi = NULL; + struct txq_info *txqi = NULL, *head = NULL; + bool found_eligible_txq = false; spin_lock_bh(&local->active_txq_lock[ac]); @@ -3676,13 +3677,26 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) if (!txqi) goto out; + if (txqi == head && !found_eligible_txq) + goto out; + + if (!head) + head = txqi; + if (txqi->txq.sta) { struct sta_info *sta = container_of(txqi->txq.sta, - struct sta_info, sta); + struct sta_info, sta); + bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); + s64 deficit = sta->airtime[txqi->txq.ac].deficit; + + if (aql_check) + found_eligible_txq = true; - if (sta->airtime[txqi->txq.ac].deficit < 0) { + if (deficit < 0) sta->airtime[txqi->txq.ac].deficit += sta->airtime_weight; + + if (deficit < 0 || !aql_check) { list_move_tail(&txqi->schedule_order, &local->active_txqs[txqi->txq.ac]); goto begin; @@ -3736,6 +3750,32 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *hw, } EXPORT_SYMBOL(__ieee80211_schedule_txq); +bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct sta_info *sta; + struct ieee80211_local *local = hw_to_local(hw); + + if (!(local->airtime_flags & AIRTIME_USE_AQL)) + return true; + + if (!txq->sta) + return true; + + sta = container_of(txq->sta, struct sta_info, sta); + if (sta->airtime[txq->ac].aql_tx_pending < + sta->airtime[txq->ac].aql_limit_low) + return true; + + if (local->aql_total_pending_airtime < local->aql_threshold && + sta->airtime[txq->ac].aql_tx_pending < + sta->airtime[txq->ac].aql_limit_high) + return true; + + return false; +} +EXPORT_SYMBOL(ieee80211_txq_airtime_check); + bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { From patchwork Tue Oct 15 17:19:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 11191307 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0ECD21390 for ; Tue, 15 Oct 2019 17:19:28 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E085C20854 for ; Tue, 15 Oct 2019 17:19:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="GvMpOK0V"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="OLYFNKrd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E085C20854 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:To:From:Subject:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=KpeiwxLeEEOpsUldsZuLkLgKhmrq3UqzxTExO9o9NjY=; b=GvMpOK0VvyIarC HK3raXoNwXrV9m1NNYCDgaW5tPpl0iTwmMqzX4VOAVQ3O/LwCvBdcIO0DLSi6HTS5eq7swUVYwFDf cafCslVyRjZa3/7kMd71V7zSwWnGusfZcpXJyfqdpZiN+igoDVOY7yyjaAAAF0swsgArVI392wgKl xjTX50WMQ+Wlx2uCjB8unlJaVytDDdRxVBzlHWm/4KE0m8KuUGvsFo9uw0xgGVdwInP1KudvrG17q zNFso7ewuA6q6brhzQgleBvMrA6YdRDPi1YejLuCzyroMylech8Qi4Lheef5s7fr/p+U9eP2B4hy5 0YIdr8gqmscsTwWEwLjA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTn-0007If-B9; Tue, 15 Oct 2019 17:19:27 +0000 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120] helo=us-smtp-1.mimecast.com) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1iKQTW-0006zF-Sb for ath10k@lists.infradead.org; Tue, 15 Oct 2019 17:19:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571159947; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GyvbrDu8qEmiyON3oCp/2+bOvx6xuJkqb2dCqG+bTwY=; b=OLYFNKrd+y1DoVjsXyeK4O1rxkkNiGXWoDOsvDuT3zxblaGxW3dad9ECDFFryVbemCAL4N 35B23nliB2jQUkAxcBKBnFUxu7Oq4Ys5awnyZYge1RK4VS5+12pqpGI8QOp+bnrG50maBH ioiPA6cZ4Sh4+ITH0E/uXbjE1nwfc4E= Received: from mail-lj1-f198.google.com (mail-lj1-f198.google.com [209.85.208.198]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-46-XJKhUdL3MSCO8ncdiU5RMw-1; Tue, 15 Oct 2019 13:19:05 -0400 Received: by mail-lj1-f198.google.com with SMTP id i18so4044685ljg.14 for ; Tue, 15 Oct 2019 10:19:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=mshGTrJaOuTUiekVjuspbBrpGAw6s+TpOZLBOSqMh18=; b=PwEtbmBK69PxNDDndN1m4JhAX22e0G1Y+wafROpLlY0uUcQ9d20jh3u30iZfMviDX2 jmFxdNipNy9QSJtB4KWu3HsKBvkS9ZSWgBrL8XYVgurGKiCpTvNx94ANHYqAzsVVaxY4 KFe7SUOzYSlkYb9EOPR8X064Fhd8AKEB7SfyJFnQ9qvmaaQH4sWKoYk7eUdP0oh3u00s f13klr2v9rU3STLpwsVnd7i0UAryBOZfzN4VcM93Z/+kU6j9j+UGnDnchTGuzUCooiNu YHLrhtT+16nxvDnOTueVctbhNDMbdumTgmB4Fw9KfS/XARlgwRiWkygVezHM92VKFZpn HmJA== X-Gm-Message-State: APjAAAX/WDQyDOdfYgFnxJ/Y1EgSayjiaxLuSfVGZ0yHJaXERFvTaCmy EjogG38zQ/kdgUsgzWyrnFuIrQX1R6Y9NcibAFVTXJGT3yHKdrubQNGGWUzvfesdYkjs6tbfiQ2 lwiRVyOHSbUf/q0DyMtGCLg== X-Received: by 2002:ac2:5df0:: with SMTP id z16mr14300267lfq.36.1571159943775; Tue, 15 Oct 2019 10:19:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqwtmWhVJzibU3fbFh0zzmpTOwLDpwyRfz8OIjlJgF3lnE3XdYDXQ1Jt6j749UmjRgzPR7qwpg== X-Received: by 2002:ac2:5df0:: with SMTP id z16mr14300247lfq.36.1571159943542; Tue, 15 Oct 2019 10:19:03 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk (borgediget.toke.dk. [85.204.121.218]) by smtp.gmail.com with ESMTPSA id z18sm5130432ljh.17.2019.10.15.10.19.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Oct 2019 10:19:02 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id F1C501803A8; Tue, 15 Oct 2019 19:19:01 +0200 (CEST) Subject: [PATCH v2 4/4] mac80211: Use Airtime-based Queue Limits (AQL) on packet dequeue From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= To: Johannes Berg Date: Tue, 15 Oct 2019 19:19:01 +0200 Message-ID: <157115994190.2500430.14955682016008497593.stgit@toke.dk> In-Reply-To: <157115993755.2500430.12214017471129215800.stgit@toke.dk> References: <157115993755.2500430.12214017471129215800.stgit@toke.dk> User-Agent: StGit/0.20 MIME-Version: 1.0 X-MC-Unique: XJKhUdL3MSCO8ncdiU5RMw-1 X-Mimecast-Spam-Score: 0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191015_101911_043662_52AEB566 X-CRM114-Status: GOOD ( 12.15 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [205.139.110.120 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: ath10k@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kan Yan , Rajkumar Manoharan , Kevin Hayes , make-wifi-fast@lists.bufferbloat.net, linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, John Crispin , Lorenzo Bianconi , Felix Fietkau Sender: "ath10k" Errors-To: ath10k-bounces+patchwork-ath10k=patchwork.kernel.org@lists.infradead.org From: Toke Høiland-Jørgensen The previous commit added the ability to throttle stations when they queue too much airtime in the hardware. This commit enables the functionality by calculating the expected airtime usage of each packet that is dequeued from the TXQs in mac80211, and accounting that as pending airtime. The estimated airtime for each skb is stored in the tx_info, so we can subtract the same amount from the running total when the skb is freed or recycled. The throttling mechanism relies on this accounting to be accurate (i.e., that we are not freeing skbs without subtracting any airtime they were accounted for), so we put the subtraction into ieee80211_report_used_skb(). As an optimisation, we also subtract the airtime on regular TX completion, zeroing out the value stored in the packet afterwards, to avoid having to do an expensive lookup of the station from the packet data on every packet. This patch does *not* include any mechanism to wake a throttled TXQ again, on the assumption that this will happen anyway as a side effect of whatever freed the skb (most commonly a TX completion). Signed-off-by: Toke Høiland-Jørgensen --- net/mac80211/status.c | 38 ++++++++++++++++++++++++++++++++++++++ net/mac80211/tx.c | 16 ++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/net/mac80211/status.c b/net/mac80211/status.c index ab8ba5835ca0..ce990a1e9043 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -676,6 +676,33 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, if (dropped) acked = false; + if (info->status.tx_time_est) { + struct ieee80211_sub_if_data *sdata; + struct sta_info *sta = NULL; + u8 *qc, ac; + int tid; + + rcu_read_lock(); + + sdata = ieee80211_sdata_from_skb(local, skb); + if (sdata) + sta = sta_info_get_bss(sdata, skb_mac_header(skb)); + + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + ac = ieee80211_ac_from_tid(tid); + } else { + ac = IEEE80211_AC_BE; + } + + ieee80211_sta_update_pending_airtime(local, sta, ac, + info->status.tx_time_est, + true); + rcu_read_unlock(); + + } + if (info->flags & IEEE80211_TX_INTFL_MLME_CONN_TX) { struct ieee80211_sub_if_data *sdata; @@ -930,6 +957,17 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw, tid = qc[0] & 0xf; } + if (info->status.tx_time_est) { + /* Do this here to avoid the expensive lookup of the sta + * in ieee80211_report_used_skb(). + */ + ieee80211_sta_update_pending_airtime(local, sta, + ieee80211_ac_from_tid(tid), + info->status.tx_time_est, + true); + info->status.tx_time_est = 0; + } + if (!acked && ieee80211_is_back_req(fc)) { u16 control; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 405f622b3fe0..b6b47171b340 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3539,9 +3539,14 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_tx_data tx; ieee80211_tx_result r; struct ieee80211_vif *vif = txq->vif; + u8 ac = txq->ac; + u32 airtime; WARN_ON_ONCE(softirq_count() == 0); + if (!ieee80211_txq_airtime_check(hw, txq)) + return NULL; + begin: spin_lock_bh(&fq->lock); @@ -3652,6 +3657,17 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, } IEEE80211_SKB_CB(skb)->control.vif = vif; + + if (local->airtime_flags & AIRTIME_USE_AQL) { + airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta, + skb->len + 38); + if (airtime) { + info->control.tx_time_est = airtime; + ieee80211_sta_update_pending_airtime(local, tx.sta, ac, + airtime, false); + } + } + return skb; out: