Skip to content

Commit 3dd6f67

Browse files
LorenzoBianconinbd168
authored andcommitted
wifi: mt76: Move RCU section in mt7996_mcu_add_rate_ctrl()
Since mt76_mcu_skb_send_msg() routine can't be executed in atomic context, move RCU section in mt7996_mcu_add_rate_ctrl() and execute mt76_mcu_skb_send_msg() 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-4-d46d15f9203c@kernel.org Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent 28d519d commit 3dd6f67

File tree

4 files changed

+45
-27
lines changed

4 files changed

+45
-27
lines changed

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,7 +2356,6 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
23562356
struct ieee80211_bss_conf *link_conf;
23572357
struct ieee80211_link_sta *link_sta;
23582358
struct mt7996_sta_link *msta_link;
2359-
struct mt7996_vif_link *link;
23602359
struct mt76_vif_link *mlink;
23612360
struct ieee80211_sta *sta;
23622361
struct ieee80211_vif *vif;
@@ -2398,13 +2397,10 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)
23982397

23992398
spin_unlock_bh(&dev->mt76.sta_poll_lock);
24002399

2401-
link = (struct mt7996_vif_link *)mlink;
2402-
24032400
if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED |
24042401
IEEE80211_RC_NSS_CHANGED |
24052402
IEEE80211_RC_BW_CHANGED))
2406-
mt7996_mcu_add_rate_ctrl(dev, vif, link_conf,
2407-
link_sta, link, msta_link,
2403+
mt7996_mcu_add_rate_ctrl(dev, msta_link->sta, vif,
24082404
link_id, true);
24092405

24102406
if (changed & IEEE80211_RC_SMPS_CHANGED)

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,10 +1112,8 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,
11121112
if (err)
11131113
return err;
11141114

1115-
err = mt7996_mcu_add_rate_ctrl(dev, vif, link_conf,
1116-
link_sta, link,
1117-
msta_link, link_id,
1118-
false);
1115+
err = mt7996_mcu_add_rate_ctrl(dev, msta_link->sta, vif,
1116+
link_id, false);
11191117
if (err)
11201118
return err;
11211119

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

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,23 +2201,44 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
22012201
memset(ra->rx_rcpi, INIT_RCPI, sizeof(ra->rx_rcpi));
22022202
}
22032203

2204-
int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
2205-
struct ieee80211_vif *vif,
2206-
struct ieee80211_bss_conf *link_conf,
2207-
struct ieee80211_link_sta *link_sta,
2208-
struct mt7996_vif_link *link,
2209-
struct mt7996_sta_link *msta_link,
2210-
u8 link_id, bool changed)
2204+
int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct mt7996_sta *msta,
2205+
struct ieee80211_vif *vif, u8 link_id,
2206+
bool changed)
22112207
{
2212-
struct mt7996_sta *msta = msta_link->sta;
2208+
struct ieee80211_bss_conf *link_conf;
2209+
struct ieee80211_link_sta *link_sta;
2210+
struct mt7996_sta_link *msta_link;
2211+
struct mt7996_vif_link *link;
2212+
struct ieee80211_sta *sta;
22132213
struct sk_buff *skb;
2214-
int ret;
2214+
int ret = -ENODEV;
2215+
2216+
rcu_read_lock();
2217+
2218+
link = mt7996_vif_link(dev, vif, link_id);
2219+
if (!link)
2220+
goto error_unlock;
2221+
2222+
msta_link = rcu_dereference(msta->link[link_id]);
2223+
if (!msta_link)
2224+
goto error_unlock;
2225+
2226+
sta = wcid_to_sta(&msta_link->wcid);
2227+
link_sta = rcu_dereference(sta->link[link_id]);
2228+
if (!link_sta)
2229+
goto error_unlock;
2230+
2231+
link_conf = rcu_dereference(vif->link_conf[link_id]);
2232+
if (!link_conf)
2233+
goto error_unlock;
22152234

22162235
skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &link->mt76,
22172236
&msta_link->wcid,
22182237
MT7996_STA_UPDATE_MAX_SIZE);
2219-
if (IS_ERR(skb))
2220-
return PTR_ERR(skb);
2238+
if (IS_ERR(skb)) {
2239+
ret = PTR_ERR(skb);
2240+
goto error_unlock;
2241+
}
22212242

22222243
/* firmware rc algorithm refers to sta_rec_he for HE control.
22232244
* once dev->rc_work changes the settings driver should also
@@ -2231,12 +2252,19 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
22312252
*/
22322253
mt7996_mcu_sta_rate_ctrl_tlv(skb, dev, vif, link_conf, link_sta, link);
22332254

2255+
rcu_read_unlock();
2256+
22342257
ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
22352258
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
22362259
if (ret)
22372260
return ret;
22382261

22392262
return mt7996_mcu_add_rate_ctrl_fixed(dev, msta, vif, link_id);
2263+
2264+
error_unlock:
2265+
rcu_read_unlock();
2266+
2267+
return ret;
22402268
}
22412269

22422270
static int

drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -620,13 +620,9 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
620620
int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy,
621621
struct mt7996_vif_link *link,
622622
struct ieee80211_he_obss_pd *he_obss_pd);
623-
int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev,
624-
struct ieee80211_vif *vif,
625-
struct ieee80211_bss_conf *link_conf,
626-
struct ieee80211_link_sta *link_sta,
627-
struct mt7996_vif_link *link,
628-
struct mt7996_sta_link *msta_link,
629-
u8 link_id, bool changed);
623+
int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct mt7996_sta *msta,
624+
struct ieee80211_vif *vif, u8 link_id,
625+
bool changed);
630626
int mt7996_set_channel(struct mt76_phy *mphy);
631627
int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag);
632628
int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif,

0 commit comments

Comments
 (0)