All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: Manikanta Pubbisetty <mpubbise@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Subject: Re: [PATCH] mac80211: add stop/start logic for software TXQs
Date: Fri, 29 Jun 2018 11:09:35 +0200	[thread overview]
Message-ID: <1530263375.3481.23.camel@sipsolutions.net> (raw)
In-Reply-To: <1529997415-20551-1-git-send-email-mpubbise@codeaurora.org>

On Tue, 2018-06-26 at 12:46 +0530, Manikanta Pubbisetty wrote:
> 
> -	if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags))
> +	if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
> +	    test_bit(IEEE80211_TXQ_PAUSED, &txqi->flags))
>  		goto out;
>  
> +	if (local->txqs_stopped) {

How is it even possible to have txqs_stopped set, but not TXQ_PAUSED? It
 seemed to me - from a first glance at the rest of the code - that the
txqs_stopped is just tracking when you can re-enable, but you propagate
it to the TXQs?

> +		set_bit(IEEE80211_TXQ_PAUSED, &txqi->flags);

Oh. Or maybe I just misread that and you're only "lazily" propagating it
here?

> +		if (txq->sta) {
> +			sta = container_of(txq->sta, struct sta_info, sta);
> +			atomic_set(&sta->txqs_paused, 1);
> +		}

It seems to me you could remove this - possibly at the expense of doing
a little more work in ieee80211_wake_txqs()?

Have you measured it and found it to be a problem?

The atomic stuff here doesn't work the way you want it to though. In
fact, even the lazy propagation doesn't work the way you want it to, I
think!

Thinking about it:

CPU 1                           CPU 2
 * you're disabling TX
   -> local->txqs_stopped = 1
                                 * check local->txqs_stopped
 * re-enable TX
   -> local->txqs_stopped = 0
 * call ieee80211_wake_txqs()
   check sta->txqs_paused
                                 * set txq->flags |= PAUSED
                                 * set sta->txqs_paused

I don't see how you can prevent this right now? In
ieee80211_tx_dequeue() you have the fq lock, but you're not taking it on
the other side (in __ieee80211_stop_queue/__ieee80211_wake_queue).

If you always iterate the stas/TXQs and set the PAUSED bit non-lazily at
least you have a single source of truth. You may still need the
txqs_stopped bitmap, but only in stop_queue/wake_queue which has its own
locking.


> +		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
> +			txqi = to_txq_info(sta->sta.txq[i]);
> +
> +			if (!test_and_clear_bit(IEEE80211_TXQ_PAUSED,
> +						&txqi->flags))
> +				continue;
> +
> +			drv_wake_tx_queue(local, txqi);

Maybe that should be conditional on there being packets? Actually, no
... ok, the lazy setting helps you with this because it means that the
driver wanted a packet but didn't get one, so now you should wake it. If
it never wanted a packet, then you don't care about the state.

Ok - so that means we need to keep the lazy setting, but fix the locking
:-)

> +		/* Software interfaces like AP_VLAN, monitor do not have
> +		 * vif specific queues.
> +		 */
> +		if (!sdata->dev || !vif->txq)
> +			continue;

Is there any way you can have vif->txq && !sdata->dev? It seems to me
that no, and then you only need the vif->txq check?

> @@ -298,10 +354,15 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
>  	if (local->q_stop_reasons[queue][reason] == 0)
>  		__clear_bit(reason, &local->queue_stop_reasons[queue]);
>  
> +	if (local->ops->wake_tx_queue)
> +		__clear_bit(reason, &local->txqs_stopped);
> +
>  	if (local->queue_stop_reasons[queue] != 0)
>  		/* someone still has this queue stopped */
>  		return;
>  
> +	ieee80211_wake_txqs(local);

I'm not sure this is the right place to hook in?

This might interact really strangely with drivers - which also get here.
Perhaps we should make this conditional on reason != DRIVER?

Also, your bitmap setting should be different - it should be per queue?
But then since "queue" here should basically be an AC for iTXQ drivers,
I think you need to handle that properly.

Right now you get bugs if you do

stop_queue(0, reason=aggregation)
stop_queue(1, reason=aggregation)
wake_queue(0, reason=aggregation)

-> TXQs will wake up because local->txqs_stopped is only stopping the
reason, not the queue number.


So to summarize:
 * overall the approach seems fine, and the lazy disabling is probably
   for the better, but
 * need to address locking issues with that, and
 * need to address the refcounting issues.


johannes

  parent reply	other threads:[~2018-06-29  9:09 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-26  7:16 [PATCH] mac80211: add stop/start logic for software TXQs Manikanta Pubbisetty
2018-06-26 11:25 ` Toke Høiland-Jørgensen
2018-06-26 12:31   ` Manikanta Pubbisetty
2018-06-27 12:28     ` Toke Høiland-Jørgensen
2018-06-29  7:58     ` Johannes Berg
2018-06-29  7:57   ` Johannes Berg
2018-07-02  9:34     ` Manikanta Pubbisetty
2018-06-26 11:27 ` kbuild test robot
2018-06-29  9:09 ` Johannes Berg [this message]
2018-07-02  9:18   ` Manikanta Pubbisetty
2018-07-03  9:45     ` Johannes Berg

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=1530263375.3481.23.camel@sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=mpubbise@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.