All of lore.kernel.org
 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: [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=C3=B8iland-J=C3=B8rgensen wrote:
>>=20
>> +/**
>> + * ieee80211_airtime_may_transmit - check whether TXQ is allowed to tra=
nsmit
>> + *
>> + * This function is used to check whether given txq is allowed to trans=
mit by
>> + * the airtime scheduler, and can be used by drivers to access the airt=
ime
>> + * 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 t=
he TXQ in
>> + * the scheduler rotation, which will eventually bring the deficit to p=
ositive
>> + * 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 cal=
ling
>> + * 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 =3D ieee80211_tx_dequeue(hw, txq)))
         push_to_hw(pkt);

     ieee80211_schedule_txq(txq);
  }
}
=20=20=20=20=20=20
>> + * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports airtime fairn=
ess
>> + *      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=20
> 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 =3D container_of(txqi->txq.sta, struct sta_info, sta);
>> +
>> +	if (sta->airtime.deficit[txqi->txq.ac] > 0)
>> +		return true;
>> +
>> +	if (txqi =3D=3D 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] +=3D 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 ie=
ee80211_hw *hw, s8 ac,
>>  	if (first)
>>  		local->schedule_round[ac]++;
>>=20=20
>> + begin:
>>  	if (list_empty(&local->active_txqs[ac]))
>>  		goto out;
>>=20=20
>> @@ -3666,6 +3709,9 @@ struct ieee80211_txq *ieee80211_next_txq(struct ie=
ee80211_hw *hw, s8 ac,
>>  				struct txq_info,
>>  				schedule_order);
>>=20=20
>> +	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 =3D=3D local->schedule_round[ac])
>>  		txqi =3D NULL;
>
> and maybe you want this check first, it's much cheaper?
>
> do {
> ...
> } while (txqi->schedule_round !=3D 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 =3D
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 i=
eee80211_hw *hw, s8 ac,
>>  }
>>  EXPORT_SYMBOL(ieee80211_next_txq);
>>=20=20
>> +bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
>> +				struct ieee80211_txq *txq)
>> +{
>> +	struct ieee80211_local *local =3D hw_to_local(hw);
>> +	struct txq_info *txqi =3D to_txq_info(txq);
>> +	bool may_tx =3D false;
>> +
>> +	spin_lock_bh(&local->active_txq_lock);
>> +
>> +	if (ieee80211_txq_check_deficit(local, txqi)) {
>> +		may_tx =3D 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 16:07 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-07 22:22 [PATCH RFC v3 0/4] Move TXQ scheduling into mac80211 Toke Høiland-Jørgensen
2018-09-07 22:22 ` [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 ` [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 ` [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 ` [PATCH RFC v3 4/4] ath9k: Switch to mac80211 TXQ scheduling and airtime APIs Toke Høiland-Jørgensen
2018-09-09 22:08 ` [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

* 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 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.