All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Felix Fietkau <nbd@nbd.name>, linux-wireless@vger.kernel.org
Subject: Re: [PATCH 05/15] mt76: track rx airtime for airtime fairness and survey
Date: Fri, 27 Sep 2019 10:35:59 +0200	[thread overview]
Message-ID: <87v9teyw40.fsf@toke.dk> (raw)
In-Reply-To: <20190926174732.42375-5-nbd@nbd.name>

Felix Fietkau <nbd@nbd.name> writes:

> Report total rx airtime for valid stations as BSS rx time in survey
>
> mt7615 is left out for now, it will be supported later by reading
> hardware counters instead of calculating airtime in software
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
> ---
>  drivers/net/wireless/mediatek/mt76/Makefile   |   2 +-
>  drivers/net/wireless/mediatek/mt76/airtime.c  | 278 ++++++++++++++++++
>  drivers/net/wireless/mediatek/mt76/mac80211.c | 109 ++++++-
>  drivers/net/wireless/mediatek/mt76/mt76.h     |  64 ++--
>  .../net/wireless/mediatek/mt76/mt7603/init.c  |   1 +
>  .../net/wireless/mediatek/mt76/mt7603/mac.c   |   2 +-
>  .../net/wireless/mediatek/mt76/mt7615/mac.c   |   2 +-
>  .../net/wireless/mediatek/mt76/mt76x0/pci.c   |   3 +-
>  .../net/wireless/mediatek/mt76/mt76x0/usb.c   |   1 +
>  .../net/wireless/mediatek/mt76/mt76x02_mac.c  |   4 +-
>  .../net/wireless/mediatek/mt76/mt76x2/pci.c   |   3 +-
>  .../net/wireless/mediatek/mt76/mt76x2/usb.c   |   1 +
>  12 files changed, 433 insertions(+), 37 deletions(-)
>  create mode 100644 drivers/net/wireless/mediatek/mt76/airtime.c
>
> diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile
> index 4d03596e891f..181af60e32db 100644
> --- a/drivers/net/wireless/mediatek/mt76/Makefile
> +++ b/drivers/net/wireless/mediatek/mt76/Makefile
> @@ -6,7 +6,7 @@ obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o
>  
>  mt76-y := \
>  	mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \
> -	tx.o agg-rx.o mcu.o
> +	tx.o agg-rx.o mcu.o airtime.o
>  
>  mt76-usb-y := usb.o usb_trace.o
>  
> diff --git a/drivers/net/wireless/mediatek/mt76/airtime.c b/drivers/net/wireless/mediatek/mt76/airtime.c
> new file mode 100644
> index 000000000000..d5bc4d713a88
> --- /dev/null
> +++ b/drivers/net/wireless/mediatek/mt76/airtime.c
> @@ -0,0 +1,278 @@
> +// SPDX-License-Identifier: ISC
> +/*
> + * Copyright (C) 2019 Felix Fietkau <nbd@nbd.name>
> + */
> +
> +#include "mt76.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 MT_MAX_STREAMS		4
> +#define MT_HT_STREAM_GROUPS	4 /* BW(=2) * SGI(=2) */
> +#define MT_VHT_STREAM_GROUPS	6 /* BW(=3) * SGI(=2) */
> +
> +#define MT_HT_GROUPS_NB	(MT_MAX_STREAMS *		\
> +				 MT_HT_STREAM_GROUPS)
> +#define MT_VHT_GROUPS_NB	(MT_MAX_STREAMS *		\
> +				 MT_VHT_STREAM_GROUPS)
> +#define MT_GROUPS_NB	(MT_HT_GROUPS_NB +	\
> +				 MT_VHT_GROUPS_NB)
> +
> +#define MT_HT_GROUP_0	0
> +#define MT_VHT_GROUP_0	(MT_HT_GROUP_0 + MT_HT_GROUPS_NB)
> +
> +#define MCS_GROUP_RATES		10
> +
> +#define HT_GROUP_IDX(_streams, _sgi, _ht40)	\
> +	MT_HT_GROUP_0 +			\
> +	MT_MAX_STREAMS * 2 * _ht40 +	\
> +	MT_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)				\
> +	(MT_VHT_GROUP_0 +						\
> +	 MT_MAX_STREAMS * 2 * (_bw) +				\
> +	 MT_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
> +mt76_calc_legacy_rate_duration(const struct ieee80211_rate *rate, bool short_pre,
> +			       int len)
> +{
> +	u32 duration;
> +
> +	switch (rate->hw_value >> 8) {
> +	case MT_PHY_TYPE_CCK:
> +		duration = 144 + 48; /* preamble + PLCP */
> +		if (short_pre)
> +			duration >>= 1;
> +
> +		duration += 10; /* SIFS */
> +		break;
> +	case MT_PHY_TYPE_OFDM:
> +		duration = 20 + 16; /* premable + SIFS */
> +		break;
> +	default:
> +		WARN_ON_ONCE(1);
> +		return 0;
> +	}
> +
> +	len <<= 3;
> +	duration += (len * 10) / rate->bitrate;
> +
> +	return duration;
> +}
> +
> +u32 mt76_calc_rx_airtime(struct mt76_dev *dev, struct mt76_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;
> +
> +	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 = dev->hw->wiphy->bands[status->band];
> +		if (!sband || status->rate_idx > sband->n_bitrates)
> +			return 0;
> +
> +		rate = &sband->bitrates[status->rate_idx];
> +
> +		return mt76_calc_legacy_rate_duration(rate, sp, 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;

On an earlier patch of mine you expressed concern over divisions in the
fast path. Does this mean this is no longer a concern? Or is the
compiler doing fancy things with the constant division here? :)

-Toke


  reply	other threads:[~2019-09-27  8:36 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-26 17:47 [PATCH 01/15] mt76: mt7603: remove q_rx field from struct mt7603_dev Felix Fietkau
2019-09-26 17:47 ` [PATCH 02/15] mt76: report rx a-mpdu subframe status Felix Fietkau
2019-09-26 17:47 ` [PATCH 03/15] mt76: rename mt76_driver_ops txwi_flags to drv_flags and include tx aligned4 Felix Fietkau
2019-09-26 17:47 ` [PATCH 04/15] mt76: store current channel survey_state in struct mt76_dev Felix Fietkau
2019-09-26 17:47 ` [PATCH 05/15] mt76: track rx airtime for airtime fairness and survey Felix Fietkau
2019-09-27  8:35   ` Toke Høiland-Jørgensen [this message]
2019-09-27  8:46     ` Felix Fietkau
2019-09-27  9:04       ` Toke Høiland-Jørgensen
2019-09-26 17:47 ` [PATCH 06/15] mt76: mt7603: track tx " Felix Fietkau
2019-09-26 17:47 ` [PATCH 07/15] mt76: mt7603: switch to a different counter for survey busy time Felix Fietkau
2019-09-26 17:47 ` [PATCH 08/15] mt76: unify channel survey update code Felix Fietkau
2019-09-26 17:47 ` [PATCH 09/15] mt76: mt76x02: move MT_CH_TIME_CFG init to mt76x02_mac_cc_reset Felix Fietkau
2019-09-26 17:47 ` [PATCH 10/15] mt76: mt76x02: track approximate tx airtime for airtime fairness and survey Felix Fietkau
2019-09-27  7:45   ` Toke Høiland-Jørgensen
2019-09-27  8:11     ` Felix Fietkau
2019-09-27  8:37       ` Toke Høiland-Jørgensen
2019-09-27  8:47         ` Felix Fietkau
2019-09-27  9:07           ` Toke Høiland-Jørgensen
2019-09-27  9:17             ` Felix Fietkau
2019-09-28 10:31               ` Toke Høiland-Jørgensen
2019-09-26 17:47 ` [PATCH 11/15] mt76: mt7615: report tx_time, bss_rx and busy time to mac80211 Felix Fietkau
2019-09-26 17:47 ` [PATCH 12/15] mt76: mt7615: fix survey channel busy time Felix Fietkau
2019-09-26 17:47 ` [PATCH 13/15] mt76: mt7615: introduce mt7615_mac_wtbl_update routine Felix Fietkau
2019-09-26 17:47 ` [PATCH 14/15] mt76: mt7615: track tx/rx airtime for airtime fairness Felix Fietkau
2019-09-26 17:47 ` [PATCH 15/15] mt76: enable " Felix Fietkau
2019-09-27  7:46   ` Toke Høiland-Jørgensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87v9teyw40.fsf@toke.dk \
    --to=toke@redhat.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=nbd@nbd.name \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.