Search Linux Wireless

Re: [PATCH] mac80211: keep BHs disabled while calling drv_tx_wake_queue()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Johannes Berg <johannes@xxxxxxxxxxxxxxxx> writes:

> From: Johannes Berg <johannes.berg@xxxxxxxxx>
>
> Drivers typically expect this, as it's the case for almost all cases
> where this is called (i.e. from the TX path). Also, the code in mac80211
> itself (if the driver calls ieee80211_tx_dequeue()) expects this as it
> uses this_cpu_ptr() without additional protection.
>
> This should fix various reports of the problem:
> https://bugzilla.kernel.org/show_bug.cgi?id=204127
> https://lore.kernel.org/linux-wireless/CAN5HydrWb3o_FE6A1XDnP1E+xS66d5kiEuhHfiGKkLNQokx13Q@xxxxxxxxxxxxxx/
> https://lore.kernel.org/lkml/nycvar.YFH.7.76.1909111238470.473@xxxxxxxxxxxxx/
>
> Reported-by: Jiri Kosina <jikos@xxxxxxxxxx>
> Reported-by: Aaron Hill <aa1ronham@xxxxxxxxx>
> Reported-by: Lukas Redlinger <rel+kernel@xxxxxxxxxx>
> Reported-by: Oleksii Shevchuk <alxchk@xxxxxxxxx>
> Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
> ---
>  net/mac80211/util.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> index 051a02ddcb85..ad1e88958da2 100644
> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -273,9 +273,9 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
>  						&txqi->flags))
>  				continue;
>  
> -			spin_unlock_bh(&fq->lock);
> +			spin_unlock(&fq->lock);
>  			drv_wake_tx_queue(local, txqi);
> -			spin_lock_bh(&fq->lock);
> +			spin_lock(&fq->lock);

Okay, so this will mean that the drv_wake_tx_queue() entry point will be
called with bhs disabled. But there are lots of uses of
spin_{,un}lock_bh() in tx.c:

$ git grep lock_bh tx.c
tx.c:   spin_lock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
tx.c:   spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
tx.c:           spin_lock_bh(&fq->lock);
tx.c:           spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&sta->lock);
tx.c:   spin_unlock_bh(&sta->lock);
tx.c:   spin_lock_bh(&sta->lock);
tx.c:   spin_unlock_bh(&sta->lock);
tx.c:   spin_lock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:                   spin_lock_bh(&fq->lock);
tx.c:                   spin_unlock_bh(&fq->lock);
tx.c:   spin_unlock_bh(&fq->lock);
tx.c:   spin_lock_bh(&local->active_txq_lock[ac]);
tx.c:   spin_unlock_bh(&local->active_txq_lock[ac]);
tx.c:   spin_lock_bh(&local->active_txq_lock[txq->ac]);
tx.c:   spin_unlock_bh(&local->active_txq_lock[txq->ac]);
tx.c:   spin_lock_bh(&local->active_txq_lock[ac]);
tx.c:   spin_unlock_bh(&local->active_txq_lock[ac]);
tx.c:   spin_unlock_bh(&local->active_txq_lock[ac]);
tx.c:   spin_lock_bh(&local->active_txq_lock[ac]);
tx.c:   spin_unlock_bh(&local->active_txq_lock[ac]);
tx.c:           spin_lock_bh(&local->tim_lock);
tx.c:           spin_unlock_bh(&local->tim_lock);

so won't that mean that the driver still gets bhs re-enabled after (for
instance) the first call to ieee80211_tx_dequeue()?

I must admit that I'm a bit fuzzy on this whole bh/not-bh thing; I've
mostly been cargo-culting the _bh variant of the locking... :)

-Toke





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux