lkml.org 
[lkml]   [2021]   [Dec]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 080/177] mac80211: agg-tx: dont schedule_and_wake_txq() under sta->lock
    Date
    From: Johannes Berg <johannes.berg@intel.com>

    [ Upstream commit 06c41bda0ea14aa7fba932a9613c4ee239682cf0 ]

    When we call ieee80211_agg_start_txq(), that will in turn call
    schedule_and_wake_txq(). Called from ieee80211_stop_tx_ba_cb()
    this is done under sta->lock, which leads to certain circular
    lock dependencies, as reported by Chris Murphy:
    https://lore.kernel.org/r/CAJCQCtSXJ5qA4bqSPY=oLRMbv-irihVvP7A2uGutEbXQVkoNaw@mail.gmail.com

    In general, ieee80211_agg_start_txq() is usually not called
    with sta->lock held, only in this one place. But it's always
    called with sta->ampdu_mlme.mtx held, and that's therefore
    clearly sufficient.

    Change ieee80211_stop_tx_ba_cb() to also call it without the
    sta->lock held, by factoring it out of ieee80211_remove_tid_tx()
    (which is only called in this one place).

    This breaks the locking chain and makes it less likely that
    we'll have similar locking chain problems in the future.

    Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation")
    Reported-by: Chris Murphy <lists@colorremedies.com>
    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
    Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
    Link: https://lore.kernel.org/r/iwlwifi.20211202152554.f519884c8784.I555fef8e67d93fff3d9a304886c4a9f8b322e591@changeid
    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/mac80211/agg-tx.c | 10 ++++++++--
    1 file changed, 8 insertions(+), 2 deletions(-)

    diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
    index 58761ca7da3c5..74a878f213d3e 100644
    --- a/net/mac80211/agg-tx.c
    +++ b/net/mac80211/agg-tx.c
    @@ -9,7 +9,7 @@
    * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
    * Copyright 2007-2010, Intel Corporation
    * Copyright(c) 2015-2017 Intel Deutschland GmbH
    - * Copyright (C) 2018 - 2020 Intel Corporation
    + * Copyright (C) 2018 - 2021 Intel Corporation
    */

    #include <linux/ieee80211.h>
    @@ -213,6 +213,8 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
    struct ieee80211_txq *txq = sta->sta.txq[tid];
    struct txq_info *txqi;

    + lockdep_assert_held(&sta->ampdu_mlme.mtx);
    +
    if (!txq)
    return;

    @@ -290,7 +292,6 @@ static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid)
    ieee80211_assign_tid_tx(sta, tid, NULL);

    ieee80211_agg_splice_finish(sta->sdata, tid);
    - ieee80211_agg_start_txq(sta, tid, false);

    kfree_rcu(tid_tx, rcu_head);
    }
    @@ -889,6 +890,7 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
    {
    struct ieee80211_sub_if_data *sdata = sta->sdata;
    bool send_delba = false;
    + bool start_txq = false;

    ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
    sta->sta.addr, tid);
    @@ -906,10 +908,14 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
    send_delba = true;

    ieee80211_remove_tid_tx(sta, tid);
    + start_txq = true;

    unlock_sta:
    spin_unlock_bh(&sta->lock);

    + if (start_txq)
    + ieee80211_agg_start_txq(sta, tid, false);
    +
    if (send_delba)
    ieee80211_send_delba(sdata, sta->sta.addr, tid,
    WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
    --
    2.33.0


    \
     
     \ /
      Last update: 2021-12-20 15:58    [W:4.100 / U:24.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site