From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:38
Hello rtw88 and mac80211 maintainers/contributors,
there is an ongoing effort where Jernej and I are working on adding
SDIO support to the rtw88 driver [0].
The hardware we use at the moment is RTL8822BS and RTL8822CS.
We are at a point where scanning, assoc etc. works (though it's not
fast yet, in my tests I got ~6Mbit/s in either direction).
This series contains some preparation work for adding SDIO support.
While testing our changes we found that there are some "scheduling
while atomic" errors in the kernel log. These are due to the fact
that the SDIO accessors (sdio_readb, sdio_writeb and friends) may
sleep internally.
Some background on why SDIO access (for example: sdio_writeb) cannot
be done with a spinlock held (this is a copy from my previous mail,
see [1]):
- when using for example sdio_writeb the MMC subsystem in Linux
prepares a so-called MMC request
- this request is submitted to the MMC host controller hardware
- the host controller hardware forwards the MMC request to the card
- the card signals when it's done processing the request
- the MMC subsystem in Linux waits for the card to signal that it's
done processing the request in mmc_wait_for_req_done() -> this uses
wait_for_completion() internally, which might sleep (which is not
allowed while a spinlock is held)
Based on Ping-Ke's suggestion I came up with the code in this series.
The goal is to use non-atomic locking for all register access in the
rtw88 driver. One patch adds a new function to mac80211 which did not
have a "non-atomic" version of it's "atomic" counterpart yet.
As mentioned before I don't have any rtw88 PCIe device so I am unable
to test on that hardware.
I am sending this as an RFC series since I am new to the mac80211
subsystem as well as the rtw88 driver. So any kind of feedback is
very welcome!
The actual changes for adding SDIO support will be sent separately in
the future.
Changes since v1 at [2] (which I sent back in summer):
- patch #1: fixed kernel doc copy & paste (remove _atomic) as suggested
by Ping-Ke and Johannes
- patch #1: added paragraph about driver authors having to be careful
where they use this new function as suggested by Johannes
- patch #2 (new): keep rtw_iterate_vifs_atomic() to not undo the fix
from commit 5b0efb4d670c8 ("rtw88: avoid circular locking between
local->iflist_mtx and rtwdev->mutex") and instead call
rtw_bf_cfg_csi_rate() from rtw_watch_dog_work() (outside the atomic
section) as suggested by Ping-Ke.
- patch #3 (new): keep rtw_iterate_vifs_atomic() to prevent deadlocks
as Johannes suggested. Keep track of all relevant stations inside
rtw_ra_mask_info_update_iter() and the iter-data and then call
rtw_update_sta_info() while held under rtwdev->mutex instead
- patch #7: shrink the critical section as suggested by Ping-Ke
[0] https://github.com/xdarklight/linux/tree/rtw88-sdio-locking-prep-linux-next-20211226
[1] https://lore.kernel.org/linux-wireless/CAFBinCDMPPJ7qW7xTkep1Trg+zP0B9Jxei6sgjqmF4NDA1JAhQ@mail.gmail.com/
[2] https://lore.kernel.org/netdev/2170471a1c144adb882d06e08f3c9d1a@realtek.com/T/
Martin Blumenstingl (9):
mac80211: Add stations iterator where the iterator function may sleep
rtw88: Move rtw_chip_cfg_csi_rate() out of rtw_vif_watch_dog_iter()
rtw88: Move rtw_update_sta_info() out of
rtw_ra_mask_info_update_iter()
rtw88: Use rtw_iterate_vifs where the iterator reads or writes
registers
rtw88: Use rtw_iterate_stas where the iterator reads or writes
registers
rtw88: Replace usage of rtw_iterate_keys_rcu() with rtw_iterate_keys()
rtw88: Configure the registers from rtw_bf_assoc() outside the RCU
lock
rtw88: hci: Convert rf_lock from a spinlock to a mutex
rtw88: fw: Convert h2c.lock from a spinlock to a mutex
drivers/net/wireless/realtek/rtw88/bf.c | 13 ++---
drivers/net/wireless/realtek/rtw88/fw.c | 14 +++---
drivers/net/wireless/realtek/rtw88/hci.h | 11 ++---
drivers/net/wireless/realtek/rtw88/mac80211.c | 14 +++++-
drivers/net/wireless/realtek/rtw88/main.c | 47 +++++++++----------
drivers/net/wireless/realtek/rtw88/main.h | 4 +-
drivers/net/wireless/realtek/rtw88/phy.c | 4 +-
drivers/net/wireless/realtek/rtw88/ps.c | 2 +-
drivers/net/wireless/realtek/rtw88/util.h | 4 +-
drivers/net/wireless/realtek/rtw88/wow.c | 2 +-
include/net/mac80211.h | 21 +++++++++
net/mac80211/util.c | 13 +++++
12 files changed, 94 insertions(+), 55 deletions(-)
--
2.34.1
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:38
ieee80211_iterate_active_interfaces() and
ieee80211_iterate_active_interfaces_atomic() already exist, where the
former allows the iterator function to sleep. Add
ieee80211_iterate_stations() which is similar to
ieee80211_iterate_stations_atomic() but allows the iterator to sleep.
This is needed for adding SDIO support to the rtw88 driver. Some
interators there are reading or writing registers. With the SDIO ops
(sdio_readb, sdio_writeb and friends) this means that the iterator
function may sleep.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
v1 -> v2:
- fixed kernel doc copy & paste (remove _atomic) as suggested by Ping-Ke
and Johannes
- added paragraph about driver authors having to be careful where they
use this new function as suggested by Johannes
include/net/mac80211.h | 21 +++++++++++++++++++++
net/mac80211/util.c | 13 +++++++++++++
2 files changed, 34 insertions(+)
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:39
rtw_bf_cfg_csi_rate() internally access some registers while being
called unter an atomic lock acquired by rtw_iterate_vifs_atomic(). Move
the rtw_bf_cfg_csi_rate() call out of rtw_vif_watch_dog_iter() in
preparation for SDIO support where register access may sleep.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
v1 -> v2:
- this patch is new in v2
- keep rtw_iterate_vifs_atomic() to not undo the fix from commit
5b0efb4d670c8 ("rtw88: avoid circular locking between
local->iflist_mtx and rtwdev->mutex") and instead call
rtw_bf_cfg_csi_rate() from rtw_watch_dog_work() (outside the atomic
section) as suggested by Ping-Ke.
drivers/net/wireless/realtek/rtw88/main.c | 35 +++++++++++------------
1 file changed, 16 insertions(+), 19 deletions(-)
@@ -241,6 +225,19 @@ static void rtw_watch_dog_work(struct work_struct *work)/* use atomic version to avoid taking local->iflist_mtx mutex */rtw_iterate_vifs_atomic(rtwdev,rtw_vif_watch_dog_iter,&data);+if(data.cfg_csi_rate){+structrtw_bf_info*bf_info=&rtwdev->bf_info;+u8fix_rate_enable=0;+u8new_csi_rate_idx;++rtw_chip_cfg_csi_rate(rtwdev,rtwdev->dm_info.min_rssi,+bf_info->cur_csi_rpt_rate,+fix_rate_enable,&new_csi_rate_idx);++if(new_csi_rate_idx!=bf_info->cur_csi_rpt_rate)+bf_info->cur_csi_rpt_rate=new_csi_rate_idx;+}+/* fw supports only one station associated to enter lps, if there are*morethantwostationsassociatedtotheAP,thenwecannotenter*lps,becausefwdoesnothandletheoverlappedbeaconinterval
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:39
Upcoming SDIO support may sleep in the read/write handlers. The only
occurrence of rtw_iterate_keys_rcu() reads and writes registers from
it's iterator function. Replace it with rtw_iterate_keys() (the non-RCU
version). This will prevent an "scheduling while atomic" issue when
using an SDIO device.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 4 +---
drivers/net/wireless/realtek/rtw88/util.h | 2 --
2 files changed, 1 insertion(+), 5 deletions(-)
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:39
Upcoming SDIO support may sleep in the read/write handlers. Shrink the
RCU critical section so it only cover the ieee80211_find_sta() call and
finding the ic_vht_cap/vht_cap based on the found station. This moves
the chip's BFEE configuration outside the rcu_read_lock section and thus
prevent a "scheduling while atomic" issue when accessing the registers
using an SDIO card.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
v1 -> v2:
- shrink the critical section as suggested by Ping-Ke
drivers/net/wireless/realtek/rtw88/bf.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
@@ -49,19 +49,23 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,sta=ieee80211_find_sta(vif,bssid);if(!sta){+rcu_read_unlock();+rtw_warn(rtwdev,"failed to find station entry for bss %pM\n",bssid);-gotoout_unlock;+return;}ic_vht_cap=&hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap;vht_cap=&sta->vht_cap;+rcu_read_unlock();+if((ic_vht_cap->cap&IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)&&(vht_cap->cap&IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)){if(bfinfo->bfer_mu_cnt>=chip->bfer_mu_max_num){rtw_dbg(rtwdev,RTW_DBG_BF,"mu bfer number over limit\n");-gotoout_unlock;+return;}ether_addr_copy(bfee->mac_addr,bssid);
@@ -75,7 +79,7 @@ void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,(vht_cap->cap&IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)){if(bfinfo->bfer_su_cnt>=chip->bfer_su_max_num){rtw_dbg(rtwdev,RTW_DBG_BF,"su bfer number over limit\n");-gotoout_unlock;+return;}sound_dim=vht_cap->cap&
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:41
Upcoming SDIO support may sleep in the read/write handlers. Switch
rf_lock from a spinlock to a mutex to allow for this behavior.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/wireless/realtek/rtw88/hci.h | 11 ++++-------
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/main.h | 2 +-
3 files changed, 6 insertions(+), 9 deletions(-)
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:42
Upcoming SDIO support may sleep in the read/write handlers. Switch
the h2c.lock from a spinlock to a mutex to allow for this behavior.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/wireless/realtek/rtw88/fw.c | 14 +++++++-------
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/main.h | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)
@@ -1975,7 +1975,7 @@ struct rtw_dev {/* incicate the mail box to use with fw */u8last_box_num;/* protect to send h2c to fw */-spinlock_tlock;+structmutexlock;u32seq;}h2c;
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:45
Upcoming SDIO support may sleep in the read/write handlers. Switch
all users of rtw_iterate_stas_atomic() which are either reading or
writing a register to rtw_iterate_stas().
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/phy.c | 4 ++--
drivers/net/wireless/realtek/rtw88/util.h | 2 ++
drivers/net/wireless/realtek/rtw88/wow.c | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:51
Upcoming SDIO support may sleep in the read/write handlers. Switch
all users of rtw_iterate_vifs_atomic() which are either reading or
writing a register to rtw_iterate_vifs().
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
drivers/net/wireless/realtek/rtw88/ps.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2021-12-28 21:15:52
rtw_update_sta_info() internally access some registers while being
called unter an atomic lock acquired by rtw_iterate_vifs_atomic(). Move
rtw_update_sta_info() call out of (rtw_ra_mask_info_update_iter) in
preparation for SDIO support where register access may sleep.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
v1 -> v2:
- this patch is new in v2
- keep rtw_iterate_vifs_atomic() to prevent deadlocks as Johannes
suggested. Keep track of all relevant stations inside
rtw_ra_mask_info_update_iter() and the iter-data and then call
rtw_update_sta_info() while held under rtwdev->mutex instead
drivers/net/wireless/realtek/rtw88/mac80211.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
-----Original Message-----
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Sent: Wednesday, December 29, 2021 5:15 AM
To: linux-wireless@vger.kernel.org
Cc: tony0620emma@gmail.com; kvalo@codeaurora.org; johannes@sipsolutions.net; netdev@vger.kernel.org;
linux-kernel@vger.kernel.org; Neo Jou [off-list ref]; Jernej Skrabec [off-list ref];
Pkshih [off-list ref]; Martin Blumenstingl [off-list ref]
Subject: [PATCH 3/9] rtw88: Move rtw_update_sta_info() out of rtw_ra_mask_info_update_iter()
rtw_update_sta_info() internally access some registers while being
called unter an atomic lock acquired by rtw_iterate_vifs_atomic(). Move
rtw_update_sta_info() call out of (rtw_ra_mask_info_update_iter) in
preparation for SDIO support where register access may sleep.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
v1 -> v2:
- this patch is new in v2
- keep rtw_iterate_vifs_atomic() to prevent deadlocks as Johannes
suggested. Keep track of all relevant stations inside
rtw_ra_mask_info_update_iter() and the iter-data and then call
rtw_update_sta_info() while held under rtwdev->mutex instead
drivers/net/wireless/realtek/rtw88/mac80211.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
-----Original Message-----
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Sent: Wednesday, December 29, 2021 5:15 AM
To: linux-wireless@vger.kernel.org
Cc: tony0620emma@gmail.com; kvalo@codeaurora.org; johannes@sipsolutions.net; netdev@vger.kernel.org;
linux-kernel@vger.kernel.org; Neo Jou [off-list ref]; Jernej Skrabec [off-list ref];
Pkshih [off-list ref]; Martin Blumenstingl [off-list ref]
Subject: [PATCH 0/9] rtw88: prepare locking for SDIO support
Hello rtw88 and mac80211 maintainers/contributors,
there is an ongoing effort where Jernej and I are working on adding
SDIO support to the rtw88 driver [0].
The hardware we use at the moment is RTL8822BS and RTL8822CS.
We are at a point where scanning, assoc etc. works (though it's not
fast yet, in my tests I got ~6Mbit/s in either direction).
Could I know if you have improvement of this throughput issue?
I have done simple test of this patchset on RTL8822CE, and it works
well. But, I think I don't test all flows yet, so I will do more
test that will take a while. After that, I can give a Tested-by tag.
Thank you
Ping-Ke
Thank you for this hint - if I do it like you suggest then the locking
will be consistent with other functions.
I'll send a v3 with this fixed.
Best regards,
Martin
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Date: 2022-01-07 21:49:38
Hi Ping-Ke,
On Fri, Jan 7, 2022 at 10:19 AM Pkshih [off-list ref] wrote:
quoted
-----Original Message-----
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Sent: Wednesday, December 29, 2021 5:15 AM
To: linux-wireless@vger.kernel.org
Cc: tony0620emma@gmail.com; kvalo@codeaurora.org; johannes@sipsolutions.net; netdev@vger.kernel.org;
linux-kernel@vger.kernel.org; Neo Jou [off-list ref]; Jernej Skrabec [off-list ref];
Pkshih [off-list ref]; Martin Blumenstingl [off-list ref]
Subject: [PATCH 0/9] rtw88: prepare locking for SDIO support
Hello rtw88 and mac80211 maintainers/contributors,
there is an ongoing effort where Jernej and I are working on adding
SDIO support to the rtw88 driver [0].
The hardware we use at the moment is RTL8822BS and RTL8822CS.
We are at a point where scanning, assoc etc. works (though it's not
fast yet, in my tests I got ~6Mbit/s in either direction).
Could I know if you have improvement of this throughput issue?
Yes, in the meantime we have made some performance improvements.
Currently the throughput numbers are approx.:
TX: 30Mbit/s
RX: 20Mbit/s
I have seen RX and TX throughputs of up to 50Mbit/s on my RTL8822CS,
but I cannot reliably reproduce this (meaning: if I don't touch my
board and run the same iperf3 test again then in one run it may
achieve 50Mbit/s, but in the next run only 25Mbit/s).
In other words: throughput is much better than what we started with in
summer, but I think it can be improved further.
I have done simple test of this patchset on RTL8822CE, and it works
well. But, I think I don't test all flows yet, so I will do more
test that will take a while. After that, I can give a Tested-by tag.
I also got feedback off-list from a user who used the patches from
this series on top of the out-of-tree rtw88-usb driver. These patches
fix one "scheduling while atomic" issue for him as well.
Maybe you can do your extensive tests after I sent v3 of this series?
Also thanks for offering to test this, I don't have any Realtek PCIe
wifi, so I am unable to verify I broke anything myself.
Best regards,
Martin