From patchwork Thu Apr 14 12:18:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kazior X-Patchwork-Id: 8835531 X-Patchwork-Delegate: johannes@sipsolutions.net 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 D6C7AC0553 for ; Thu, 14 Apr 2016 12:16:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 98C17201C7 for ; Thu, 14 Apr 2016 12:16:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5149C20204 for ; Thu, 14 Apr 2016 12:16:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755271AbcDNMQf (ORCPT ); Thu, 14 Apr 2016 08:16:35 -0400 Received: from mail-lf0-f43.google.com ([209.85.215.43]:35664 "EHLO mail-lf0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754631AbcDNMQd (ORCPT ); Thu, 14 Apr 2016 08:16:33 -0400 Received: by mail-lf0-f43.google.com with SMTP id c126so106253310lfb.2 for ; Thu, 14 Apr 2016 05:16:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tieto.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=o6A7uwoXdfAB/pn5u4QXXWZstnbtVx97Kdr9VXhirlc=; b=3lvJDNV0CRqhTQWm0L0M4M9AiE8Iz75m9Va8H4YdVaNvjxVCuPGJPyCJeIX7kZFIrG npXEF1TBYafCzTh25UGLvz6Fby1FxbguoDwjpK5543i1yCqPPC0ZpkSr+caRrFFNbt0o SwBVsOuNfRUBGxPlvyj6/lstxDrEqJ+sK5wtE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=o6A7uwoXdfAB/pn5u4QXXWZstnbtVx97Kdr9VXhirlc=; b=SGmBE+wzxK03SaR07c8oIcJL/0NZlLCWJu0kZFi3XsocsX/46Y10JqR4IJhWZQEXXb th9xfrU8vrtW0zckBksuPTCKWptWREb1Pm/N5L20RsWMmRlOEDjOI/6zr2IHYeJlarLr +ETXb33nbdCOg2V5c2Vir6xFLm7od3jrteS29rKG8dk022nOLtcVsXl/v6qAFRJayaPu CTZXKO+/+h1VR8FPaybNaehmfmNUmCglupCO4SYWqY3biM6g2FiQpz0LzlbaUQ2pcRcv Bs93ctCdQ5AuwG2k/eX7UWfqWjEB/AcFLAU4rZp+ewQfbz6j3GiXXIcRK9BbORz4KxIP c40w== X-Gm-Message-State: AOPr4FUkM5vpt21WaxVcqi9BmZmWVNtVeilH74zVQoFz0tozvezJnp+tZL8MZ1R3JYeGNYrg+y3B+SUz0WGOA4qxUrBsxO3MDgfcHItZMqGdmw8PJF22ouaeD0abiC+xzTmOwLpXeCA3kHntxFRVszS6SnoiyzPFnk1UXNavl4t1hz6GF9Q3YodttbE+C5k0vdDWt98= X-Received: by 10.25.32.65 with SMTP id g62mr6436322lfg.138.1460636190766; Thu, 14 Apr 2016 05:16:30 -0700 (PDT) Received: from localhost.localdomain ([91.198.246.10]) by smtp.gmail.com with ESMTPSA id b195sm6940112lfb.5.2016.04.14.05.16.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Apr 2016 05:16:29 -0700 (PDT) From: Michal Kazior To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, dave.taht@gmail.com, make-wifi-fast@lists.bufferbloat.net, codel@lists.bufferbloat.net, apenwarr@gmail.com, Michal Kazior Subject: [PATCHv3 3/5] mac80211: add debug knobs for fair queuing Date: Thu, 14 Apr 2016 14:18:20 +0200 Message-Id: <1460636302-31161-4-git-send-email-michal.kazior@tieto.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1460636302-31161-1-git-send-email-michal.kazior@tieto.com> References: <1459420104-31554-1-git-send-email-michal.kazior@tieto.com> <1460636302-31161-1-git-send-email-michal.kazior@tieto.com> X-DomainID: tieto.com Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham 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 This adds a few debugfs entries and a module parameter to make it easier to test, debug and experiment. Signed-off-by: Michal Kazior --- net/mac80211/debugfs.c | 77 +++++++++++++++++++++++++++++++++++++++++++ net/mac80211/debugfs_netdev.c | 28 +++++++++++++++- net/mac80211/debugfs_sta.c | 45 +++++++++++++++++++++++++ net/mac80211/fq.h | 13 +++++++- net/mac80211/fq_i.h | 7 ++++ net/mac80211/tx.c | 8 ++++- 6 files changed, 175 insertions(+), 3 deletions(-) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 4ab5c522ceee..5cbaa5872e6b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -31,6 +31,30 @@ int mac80211_format_buffer(char __user *userbuf, size_t count, return simple_read_from_buffer(userbuf, count, ppos, buf, res); } +static int mac80211_parse_buffer(const char __user *userbuf, + size_t count, + loff_t *ppos, + char *fmt, ...) +{ + va_list args; + char buf[DEBUGFS_FORMAT_BUFFER_SIZE] = {}; + int res; + + if (count > sizeof(buf)) + return -EINVAL; + + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[sizeof(buf) - 1] = '\0'; + + va_start(args, fmt); + res = vsscanf(buf, fmt, args); + va_end(args); + + return count; +} + #define DEBUGFS_READONLY_FILE_FN(name, fmt, value...) \ static ssize_t name## _read(struct file *file, char __user *userbuf, \ size_t count, loff_t *ppos) \ @@ -70,6 +94,52 @@ DEBUGFS_READONLY_FILE(wep_iv, "%#08x", DEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s", local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); +#define DEBUGFS_RW_FILE_FN(name, expr) \ +static ssize_t name## _write(struct file *file, \ + const char __user *userbuf, \ + size_t count, \ + loff_t *ppos) \ +{ \ + struct ieee80211_local *local = file->private_data; \ + return expr; \ +} + +#define DEBUGFS_RW_FILE(name, expr, fmt, value...) \ + DEBUGFS_READONLY_FILE_FN(name, fmt, value) \ + DEBUGFS_RW_FILE_FN(name, expr) \ + DEBUGFS_RW_FILE_OPS(name) + +#define DEBUGFS_RW_FILE_OPS(name) \ +static const struct file_operations name## _ops = { \ + .read = name## _read, \ + .write = name## _write, \ + .open = simple_open, \ + .llseek = generic_file_llseek, \ +} + +#define DEBUGFS_RW_EXPR_FQ(args...) \ +({ \ + int res; \ + res = mac80211_parse_buffer(userbuf, count, ppos, args); \ + res; \ +}) + +DEBUGFS_READONLY_FILE(fq_flows_cnt, "%u", + local->fq.flows_cnt); +DEBUGFS_READONLY_FILE(fq_backlog, "%u", + local->fq.backlog); +DEBUGFS_READONLY_FILE(fq_overlimit, "%u", + local->fq.overlimit); +DEBUGFS_READONLY_FILE(fq_collisions, "%u", + local->fq.collisions); + +DEBUGFS_RW_FILE(fq_limit, + DEBUGFS_RW_EXPR_FQ("%u", &local->fq.limit), + "%u", local->fq.limit); +DEBUGFS_RW_FILE(fq_quantum, + DEBUGFS_RW_EXPR_FQ("%u", &local->fq.quantum), + "%u", local->fq.quantum); + #ifdef CONFIG_PM static ssize_t reset_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -254,6 +324,13 @@ void debugfs_hw_add(struct ieee80211_local *local) DEBUGFS_ADD(user_power); DEBUGFS_ADD(power); + DEBUGFS_ADD(fq_flows_cnt); + DEBUGFS_ADD(fq_backlog); + DEBUGFS_ADD(fq_overlimit); + DEBUGFS_ADD(fq_collisions); + DEBUGFS_ADD(fq_limit); + DEBUGFS_ADD(fq_quantum); + 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_netdev.c b/net/mac80211/debugfs_netdev.c index 37ea30e0754c..471cab40a25f 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -30,7 +30,7 @@ static ssize_t ieee80211_if_read( size_t count, loff_t *ppos, ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int)) { - char buf[70]; + char buf[200]; ssize_t ret = -EINVAL; read_lock(&dev_base_lock); @@ -236,6 +236,31 @@ ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata, } IEEE80211_IF_FILE_R(hw_queues); +static ssize_t +ieee80211_if_fmt_txq(const struct ieee80211_sub_if_data *sdata, + char *buf, int buflen) +{ + struct txq_info *txqi; + int len = 0; + + if (!sdata->vif.txq) + return 0; + + txqi = to_txq_info(sdata->vif.txq); + len += scnprintf(buf + len, buflen - len, + "CAB backlog %ub %up flows %u overlimit %u collisions %u tx %ub %up\n", + txqi->tin.backlog_bytes, + txqi->tin.backlog_packets, + txqi->tin.flows, + txqi->tin.overlimit, + txqi->tin.collisions, + txqi->tin.tx_bytes, + txqi->tin.tx_packets); + + return len; +} +IEEE80211_IF_FILE_R(txq); + /* STA attributes */ IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); @@ -618,6 +643,7 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata) DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_2ghz); DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz); DEBUGFS_ADD(hw_queues); + DEBUGFS_ADD(txq); } static void add_sta_files(struct ieee80211_sub_if_data *sdata) diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index a39512f09f9e..b5eb4f402710 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -319,6 +319,50 @@ static ssize_t sta_vht_capa_read(struct file *file, char __user *userbuf, } STA_OPS(vht_capa); +static ssize_t sta_txqs_read(struct file *file, + char __user *userbuf, + size_t count, + loff_t *ppos) +{ + struct sta_info *sta = file->private_data; + struct txq_info *txqi; + char *buf; + int buflen; + int len; + int res; + int i; + + len = 0; + buflen = 200 * IEEE80211_NUM_TIDS; + buf = kzalloc(buflen, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { + if (!sta->sta.txq[i]) + break; + + txqi = to_txq_info(sta->sta.txq[i]); + len += scnprintf(buf + len, buflen - len, + "TID %d AC %d backlog %ub %up flows %u overlimit %u collisions %u tx %ub %up\n", + i, + txqi->txq.ac, + txqi->tin.backlog_bytes, + txqi->tin.backlog_packets, + txqi->tin.flows, + txqi->tin.overlimit, + txqi->tin.collisions, + txqi->tin.tx_bytes, + txqi->tin.tx_packets); + } + + res = simple_read_from_buffer(userbuf, count, ppos, buf, len); + kfree(buf); + + return res; +} +STA_OPS(txqs); + #define DEBUGFS_ADD(name) \ debugfs_create_file(#name, 0400, \ @@ -365,6 +409,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) DEBUGFS_ADD(agg_status); DEBUGFS_ADD(ht_capa); DEBUGFS_ADD(vht_capa); + DEBUGFS_ADD(txqs); DEBUGFS_ADD_COUNTER(rx_duplicates, rx_stats.num_duplicates); DEBUGFS_ADD_COUNTER(rx_fragments, rx_stats.fragments); diff --git a/net/mac80211/fq.h b/net/mac80211/fq.h index fa98576e1825..aa68363d6221 100644 --- a/net/mac80211/fq.h +++ b/net/mac80211/fq.h @@ -102,6 +102,8 @@ begin: } flow->deficit -= skb->len; + tin->tx_bytes += skb->len; + tin->tx_packets++; return skb; } @@ -120,8 +122,14 @@ static struct fq_flow *fq_flow_classify(struct fq *fq, idx = reciprocal_scale(hash, fq->flows_cnt); flow = &fq->flows[idx]; - if (flow->tin && flow->tin != tin) + if (flow->tin && flow->tin != tin) { flow = fq_flow_get_default_fn(fq, tin, idx, skb); + tin->collisions++; + fq->collisions++; + } + + if (!flow->tin) + tin->flows++; return flow; } @@ -174,6 +182,9 @@ static void fq_tin_enqueue(struct fq *fq, return; fq_skb_free_fn(fq, flow->tin, flow, skb); + + flow->tin->overlimit++; + fq->overlimit++; } } diff --git a/net/mac80211/fq_i.h b/net/mac80211/fq_i.h index 5d8423f22e8d..0e25dda4fce3 100644 --- a/net/mac80211/fq_i.h +++ b/net/mac80211/fq_i.h @@ -51,6 +51,11 @@ struct fq_tin { struct list_head old_flows; u32 backlog_bytes; u32 backlog_packets; + u32 overlimit; + u32 collisions; + u32 flows; + u32 tx_bytes; + u32 tx_packets; }; /** @@ -70,6 +75,8 @@ struct fq { u32 limit; u32 quantum; u32 backlog; + u32 overlimit; + u32 collisions; }; #endif diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d4e0c87ecec5..396d0d17edeb 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,11 @@ #include "rate.h" #include "fq.h" +static unsigned int fq_flows_cnt = 4096; +module_param(fq_flows_cnt, uint, 0644); +MODULE_PARM_DESC(fq_flows_cnt, + "Maximum number of txq fair queuing flows. "); + /* misc utils */ static inline void ieee80211_tx_stats(struct net_device *dev, u32 len) @@ -1336,7 +1342,7 @@ int ieee80211_txq_setup_flows(struct ieee80211_local *local) if (!local->ops->wake_tx_queue) return 0; - ret = fq_init(fq, 4096); + ret = fq_init(fq, max_t(u32, fq_flows_cnt, 1)); if (ret) return ret;