Skip to content

Commit 28d519d

Browse files
LorenzoBianconinbd168
authored andcommitted
wifi: mt76: Move RCU section in mt7996_mcu_add_rate_ctrl_fixed()
Since mt7996_mcu_set_fixed_field() can't be executed in a RCU critical section, move RCU section in mt7996_mcu_add_rate_ctrl_fixed() and run mt7996_mcu_set_fixed_field() in non-atomic context. This is a preliminary patch to fix a 'sleep while atomic' issue in mt7996_mac_sta_rc_work(). Fixes: 0762bdd ("wifi: mt76: mt7996: rework mt7996_mac_sta_rc_work to support MLO") Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Link: https://patch.msgid.link/20250605-mt7996-sleep-while-atomic-v1-3-d46d15f9203c@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent c772cd7 commit 28d519d

File tree

1 file changed

+57
-29
lines changed
  • drivers/net/wireless/mediatek/mt76/mt7996

1 file changed

+57
-29
lines changed

drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,51 +1977,74 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct mt7996_sta *msta,
19771977
}
19781978

19791979
static int
1980-
mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev,
1981-
struct ieee80211_link_sta *link_sta,
1982-
struct mt7996_vif_link *link,
1983-
struct mt7996_sta_link *msta_link,
1984-
u8 link_id)
1980+
mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct mt7996_sta *msta,
1981+
struct ieee80211_vif *vif, u8 link_id)
19851982
{
1986-
struct cfg80211_chan_def *chandef = &link->phy->mt76->chandef;
1987-
struct cfg80211_bitrate_mask *mask = &link->bitrate_mask;
1988-
enum nl80211_band band = chandef->chan->band;
1989-
struct mt7996_sta *msta = msta_link->sta;
1983+
struct ieee80211_link_sta *link_sta;
1984+
struct cfg80211_bitrate_mask mask;
1985+
struct mt7996_sta_link *msta_link;
1986+
struct mt7996_vif_link *link;
19901987
struct sta_phy_uni phy = {};
1991-
int ret, nrates = 0;
1988+
struct ieee80211_sta *sta;
1989+
int ret, nrates = 0, idx;
1990+
enum nl80211_band band;
1991+
bool has_he;
19921992

19931993
#define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he) \
19941994
do { \
1995-
u8 i, gi = mask->control[band]._gi; \
1995+
u8 i, gi = mask.control[band]._gi; \
19961996
gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \
19971997
phy.sgi = gi; \
1998-
phy.he_ltf = mask->control[band].he_ltf; \
1999-
for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) { \
2000-
if (!mask->control[band]._mcs[i]) \
1998+
phy.he_ltf = mask.control[band].he_ltf; \
1999+
for (i = 0; i < ARRAY_SIZE(mask.control[band]._mcs); i++) { \
2000+
if (!mask.control[band]._mcs[i]) \
20012001
continue; \
2002-
nrates += hweight16(mask->control[band]._mcs[i]); \
2003-
phy.mcs = ffs(mask->control[band]._mcs[i]) - 1; \
2002+
nrates += hweight16(mask.control[band]._mcs[i]); \
2003+
phy.mcs = ffs(mask.control[band]._mcs[i]) - 1; \
20042004
if (_ht) \
20052005
phy.mcs += 8 * i; \
20062006
} \
20072007
} while (0)
20082008

2009-
if (link_sta->he_cap.has_he) {
2009+
rcu_read_lock();
2010+
2011+
link = mt7996_vif_link(dev, vif, link_id);
2012+
if (!link)
2013+
goto error_unlock;
2014+
2015+
msta_link = rcu_dereference(msta->link[link_id]);
2016+
if (!msta_link)
2017+
goto error_unlock;
2018+
2019+
sta = wcid_to_sta(&msta_link->wcid);
2020+
link_sta = rcu_dereference(sta->link[link_id]);
2021+
if (!link_sta)
2022+
goto error_unlock;
2023+
2024+
band = link->phy->mt76->chandef.chan->band;
2025+
has_he = link_sta->he_cap.has_he;
2026+
mask = link->bitrate_mask;
2027+
idx = msta_link->wcid.idx;
2028+
2029+
if (has_he) {
20102030
__sta_phy_bitrate_mask_check(he_mcs, he_gi, 0, 1);
20112031
} else if (link_sta->vht_cap.vht_supported) {
20122032
__sta_phy_bitrate_mask_check(vht_mcs, gi, 0, 0);
20132033
} else if (link_sta->ht_cap.ht_supported) {
20142034
__sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);
20152035
} else {
2016-
nrates = hweight32(mask->control[band].legacy);
2017-
phy.mcs = ffs(mask->control[band].legacy) - 1;
2036+
nrates = hweight32(mask.control[band].legacy);
2037+
phy.mcs = ffs(mask.control[band].legacy) - 1;
20182038
}
2039+
2040+
rcu_read_unlock();
2041+
20192042
#undef __sta_phy_bitrate_mask_check
20202043

20212044
/* fall back to auto rate control */
2022-
if (mask->control[band].gi == NL80211_TXRATE_DEFAULT_GI &&
2023-
mask->control[band].he_gi == GENMASK(7, 0) &&
2024-
mask->control[band].he_ltf == GENMASK(7, 0) &&
2045+
if (mask.control[band].gi == NL80211_TXRATE_DEFAULT_GI &&
2046+
mask.control[band].he_gi == GENMASK(7, 0) &&
2047+
mask.control[band].he_ltf == GENMASK(7, 0) &&
20252048
nrates != 1)
20262049
return 0;
20272050

@@ -2034,16 +2057,16 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev,
20342057
}
20352058

20362059
/* fixed GI */
2037-
if (mask->control[band].gi != NL80211_TXRATE_DEFAULT_GI ||
2038-
mask->control[band].he_gi != GENMASK(7, 0)) {
2060+
if (mask.control[band].gi != NL80211_TXRATE_DEFAULT_GI ||
2061+
mask.control[band].he_gi != GENMASK(7, 0)) {
20392062
u32 addr;
20402063

20412064
/* firmware updates only TXCMD but doesn't take WTBL into
20422065
* account, so driver should update here to reflect the
20432066
* actual txrate hardware sends out.
20442067
*/
2045-
addr = mt7996_mac_wtbl_lmac_addr(dev, msta_link->wcid.idx, 7);
2046-
if (link_sta->he_cap.has_he)
2068+
addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 7);
2069+
if (has_he)
20472070
mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);
20482071
else
20492072
mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);
@@ -2055,14 +2078,19 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev,
20552078
}
20562079

20572080
/* fixed HE_LTF */
2058-
if (mask->control[band].he_ltf != GENMASK(7, 0)) {
2081+
if (mask.control[band].he_ltf != GENMASK(7, 0)) {
20592082
ret = mt7996_mcu_set_fixed_field(dev, msta, &phy, link_id,
20602083
RATE_PARAM_FIXED_HE_LTF);
20612084
if (ret)
20622085
return ret;
20632086
}
20642087

20652088
return 0;
2089+
2090+
error_unlock:
2091+
rcu_read_unlock();
2092+
2093+
return -ENODEV;
20662094
}
20672095

20682096
static void
@@ -2181,6 +2209,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
21812209
struct mt7996_sta_link *msta_link,
21822210
u8 link_id, bool changed)
21832211
{
2212+
struct mt7996_sta *msta = msta_link->sta;
21842213
struct sk_buff *skb;
21852214
int ret;
21862215

@@ -2207,8 +2236,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
22072236
if (ret)
22082237
return ret;
22092238

2210-
return mt7996_mcu_add_rate_ctrl_fixed(dev, link_sta, link, msta_link,
2211-
link_id);
2239+
return mt7996_mcu_add_rate_ctrl_fixed(dev, msta, vif, link_id);
22122240
}
22132241

22142242
static int

0 commit comments

Comments
 (0)