Lets make wifi fast again!
 help / color / mirror / Atom feed
From: "Toke Høiland-Jørgensen" <toke@toke.dk>
To: Johannes Berg <johannes@sipsolutions.net>,
	linux-wireless@vger.kernel.org,
	make-wifi-fast@lists.bufferbloat.net
Cc: Rajkumar Manoharan <rmanohar@codeaurora.org>,
	Felix Fietkau <nbd@nbd.name>
Subject: Re: [Make-wifi-fast] [PATCH RFC v3 2/4] mac80211: Add airtime accounting and scheduling to TXQs
Date: Mon, 10 Sep 2018 13:13:55 +0200	[thread overview]
Message-ID: <87h8ixli4s.fsf@toke.dk> (raw)
In-Reply-To: <1536567496.3224.36.camel@sipsolutions.net>

Johannes Berg <johannes@sipsolutions.net> writes:

> On Sat, 2018-09-08 at 00:22 +0200, Toke Høiland-Jørgensen wrote:
>> 
>> +/**
>> + * ieee80211_airtime_may_transmit - check whether TXQ is allowed to transmit
>> + *
>> + * This function is used to check whether given txq is allowed to transmit by
>> + * the airtime scheduler, and can be used by drivers to access the airtime
>> + * fairness accounting without going using the scheduling order enfored by
>> + * next_txq().
>> + *
>> + * Returns %true if the airtime scheduler does not think the TXQ should be
>> + * throttled. This function can also have the side effect of rotating the TXQ in
>> + * the scheduler rotation, which will eventually bring the deficit to positive
>> + * and allow the station to transmit again.
>> + *
>> + * If this function returns %true, the TXQ will have been removed from the
>> + * scheduling. It is the driver's responsibility to add it back (by calling
>> + * ieee80211_schedule_txq()) if needed.
>> + *
>> + * @hw: pointer as obtained from ieee80211_alloc_hw()
>> + * @txq: pointer obtained from station or virtual interface
>> + *
>> + */
>
> Spurious newline there at the end.
>
> (As an aside from the review, perhaps this would be what we could use in
> iwlwifi, but I'll need to think about _when_ to add it back to the
> scheduling later).

Yeah, this is the API that would be used by drivers where the actual
scheduling of TXQs is done by the hardware (i.e., ath10k in pull/push
mode, and iwlwifi if I understand you correctly); whereas the next_txq()
call is for drivers that do the scheduling in software (ath10k without
pull/push, ath9k and mt76).

Basically, the way I envision this is the drivers doing something like:

function on_hw_notify(hw, txq) {
  if (ieee80211_airtime_may_transmit(txq)) {
     while (hw_has_space() && (pkt = ieee80211_tx_dequeue(hw, txq)))
         push_to_hw(pkt);

     ieee80211_schedule_txq(txq);
  }
}
      
>> + * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports airtime fairness
>> + *      scheduling.
>> + *
>>   * @NUM_NL80211_EXT_FEATURES: number of extended features.
>>   * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
>>   */
>> @@ -5269,6 +5272,7 @@ enum nl80211_ext_feature_index {
>>  	NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
>>  	NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
>>  	NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
>> +	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
>
> Why is this necessary in this patch?

It's meant as a way for the driver to signal that it has a source of
airtime information, and thus would like to be scheduled to take this
into account.

> I think that this should probably come with more documentation too,
> particularly what's expected of the driver here.

Right :)

> I'd prefer you reorder patches 2 and 3, and define everything in
> cfg80211 first. That also makes it easier to reason about what happens
> when the feature is not supported (since it will not be supported
> anywhere). Then this can be included in the cfg80211 patch instead,
> which places it better, and the mac80211 bits from the cfg80211 patch 
> can be included here, which also places those better.

Good idea, will do!

>> -			       txqi->flags & (1<<IEEE80211_TXQ_STOP) ? "STOP" : "RUN",
>> -			       txqi->flags & (1<<IEEE80211_TXQ_AMPDU) ? " AMPDU" : "",
>> -			       txqi->flags & (1<<IEEE80211_TXQ_NO_AMSDU) ? " NO-AMSDU" : "");
>> +			       txqi->flags & (1 << IEEE80211_TXQ_STOP) ? "STOP" : "RUN",
>> +			       txqi->flags & (1 << IEEE80211_TXQ_AMPDU) ? " AMPDU" : "",
>> +			       txqi->flags & (1 << IEEE80211_TXQ_NO_AMSDU) ? " NO-AMSDU" : "");
>
> consider BIT() instead as a cleanup? :)
>
> (or maybe this is just a leftover from merging some other patches?)

Yeah, this is a merging artifact; Rajkumar's patch added another flag,
that I removed again. Didn't notice that there was still a whitespace
change in this patch...

>> +static bool ieee80211_txq_check_deficit(struct ieee80211_local *local,
>> +					struct txq_info *txqi)
>
> Maybe this should be called "has_deficit" or so - the polarity isn't
> immediately clear to me.

Yup, I suck at naming; gotcha ;)

>> +{
>> +	struct sta_info *sta;
>> +
>> +	lockdep_assert_held(&local->active_txq_lock);
>> +
>> +	if (!txqi->txq.sta)
>> +		return true;
>> +
>> +	sta = container_of(txqi->txq.sta, struct sta_info, sta);
>> +
>> +	if (sta->airtime.deficit[txqi->txq.ac] > 0)
>> +		return true;
>> +
>> +	if (txqi == list_first_entry_or_null(&local->active_txqs[txqi->txq.ac],
>
> nit: I don't think you need _or_null here, since list_first_entry() will
> "return" the head itself if the list is empty, which cannot match txqi?
> Doesn't matter that much though, and if you think this is easier to
> understand then that's fine.
>
>> +					     struct txq_info,
>> +					     schedule_order)) {
>> +		sta->airtime.deficit[txqi->txq.ac] += sta->airtime.weight;
>> +		list_move_tail(&txqi->schedule_order,
>> +			       &local->active_txqs[txqi->txq.ac]);
>> +	}
>> +
>> +	return false;
>> +}
>> +
>>  struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, s8 ac,
>>  					 bool first)
>>  {
>> @@ -3659,6 +3701,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, s8 ac,
>>  	if (first)
>>  		local->schedule_round[ac]++;
>>  
>> + begin:
>>  	if (list_empty(&local->active_txqs[ac]))
>>  		goto out;
>>  
>> @@ -3666,6 +3709,9 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, s8 ac,
>>  				struct txq_info,
>>  				schedule_order);
>>  
>> +	if (!ieee80211_txq_check_deficit(local, txqi))
>> +		goto begin;
>
> This code isn't so badly indented - you could use a do { } while () loop
> instead?
>
>>  	if (txqi->schedule_round == local->schedule_round[ac])
>>  		txqi = NULL;
>
> and maybe you want this check first, it's much cheaper?
>
> do {
> ...
> } while (txqi->schedule_round != local->schedule_round[ac] &&
>          !has_deficit())
>
> or so?
>
> That is to say, I'm not sure why you'd want to abort if you find a
> queue that has no deficit but is part of the next round? Or is that
> the abort condition for having gone around the whole list once? Hmm.
> But check_deficit() also moves them to the end, so you don't really
> get that anyway?

The move to the end for check_deficit() is what replenishes the airtime
deficit and ensures fairness. So that can loop several times in a single
call to the function. The schedule_round counter is there to prevent the
driver from looping indefinitely when doing `while (txq =
ieee80211_next_txq())`. We'd generally want the deficit replenish to
happen in any case; previously, the schedule_round type check was in the
driver; moving it here is an attempt at simplifying the logic needed in
the driver when using the API.

>> @@ -3681,6 +3727,25 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, s8 ac,
>>  }
>>  EXPORT_SYMBOL(ieee80211_next_txq);
>>  
>> +bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
>> +				struct ieee80211_txq *txq)
>> +{
>> +	struct ieee80211_local *local = hw_to_local(hw);
>> +	struct txq_info *txqi = to_txq_info(txq);
>> +	bool may_tx = false;
>> +
>> +	spin_lock_bh(&local->active_txq_lock);
>> +
>> +	if (ieee80211_txq_check_deficit(local, txqi)) {
>> +		may_tx = true;
>> +		list_del_init(&txqi->schedule_order);
>
> Manipulating the list twice like this here seems slightly odd ...
> perhaps move the list manipulation out of txq_check_deficit() entirely?
> Clearly it's logically fine, but seems harder than necessary to
> understand.
>
> Also, if the check_deficit() function just returns a value, the renaming
> I suggested is easier to accept :)

Yeah, maybe; it'll result in some duplication between next_txq() and
txq_may_transmit() (to the point where I'm not sure if the separate
check_deficit() function is really needed anymore), but it may be that
that is actually easier to understand?

-Toke

  reply	other threads:[~2018-09-10 11:13 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-07 22:22 [Make-wifi-fast] [PATCH RFC v3 0/4] Move TXQ scheduling into mac80211 Toke Høiland-Jørgensen
2018-09-07 22:22 ` [Make-wifi-fast] [PATCH RFC v3 2/4] mac80211: Add airtime accounting and scheduling to TXQs Toke Høiland-Jørgensen
2018-09-10  8:18   ` Johannes Berg
2018-09-10 11:13     ` Toke Høiland-Jørgensen [this message]
2018-09-10 11:22       ` Johannes Berg
2018-09-12  0:07       ` Rajkumar Manoharan
2018-09-12 11:10         ` Toke Høiland-Jørgensen
2018-09-12 16:23           ` Rajkumar Manoharan
2018-09-07 22:22 ` [Make-wifi-fast] [PATCH RFC v3 1/4] mac80211: Add TXQ scheduling API Toke Høiland-Jørgensen
2018-09-10  7:48   ` Johannes Berg
2018-09-10 10:57     ` Toke Høiland-Jørgensen
2018-09-10 11:03       ` Johannes Berg
2018-09-10 12:39         ` Toke Høiland-Jørgensen
2018-09-10 12:46           ` Johannes Berg
2018-09-10 13:08             ` Toke Høiland-Jørgensen
2018-09-10 13:10               ` Johannes Berg
2018-09-10 13:18                 ` Toke Høiland-Jørgensen
2018-09-10 14:51                   ` Johannes Berg
2018-09-10 15:00                     ` Toke Høiland-Jørgensen
2018-09-11  9:20                       ` Johannes Berg
2018-09-11  9:48                         ` Toke Høiland-Jørgensen
2018-09-10  8:04   ` Johannes Berg
2018-09-10 11:02     ` Toke Høiland-Jørgensen
2018-09-10 11:12       ` Johannes Berg
2018-09-07 22:22 ` [Make-wifi-fast] [PATCH RFC v3 3/4] cfg80211: Add airtime statistics and settings Toke Høiland-Jørgensen
2018-09-10  8:23   ` Johannes Berg
2018-09-10 11:15     ` Toke Høiland-Jørgensen
2018-09-07 22:22 ` [Make-wifi-fast] [PATCH RFC v3 4/4] ath9k: Switch to mac80211 TXQ scheduling and airtime APIs Toke Høiland-Jørgensen
2018-09-09 22:08 ` [Make-wifi-fast] [PATCH RFC v3 0/4] Move TXQ scheduling into mac80211 Kan Yan
2018-09-10 10:52   ` Toke Høiland-Jørgensen
2018-09-10  7:46 ` Johannes Berg
2018-09-10 11:16   ` Toke Høiland-Jørgensen
2018-09-10 11:24     ` Johannes Berg
2018-09-10  7:52 ` Johannes Berg
2018-09-10 11:17   ` Toke Høiland-Jørgensen
2018-09-10 11:26     ` Johannes Berg
2018-09-13  4:10       ` Kan Yan
2018-09-13  9:25         ` 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

  List information: https://lists.bufferbloat.net/postorius/lists/make-wifi-fast.lists.bufferbloat.net/

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

  git send-email \
    --in-reply-to=87h8ixli4s.fsf@toke.dk \
    --to=toke@toke.dk \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=make-wifi-fast@lists.bufferbloat.net \
    --cc=nbd@nbd.name \
    --cc=rmanohar@codeaurora.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox