[PATCH] net: wireless: ath: ath9k: Fix a possible data race in ath_chanctx_set_next
The write operation to "sc->next_chan" is protected by the lock on line 1287, but the read operation to this data on line 1262 is not protected by the lock. Thus, there may exist a data race for "sc->next_chan". To fix this data race, the read operation to "sc->next_chan" should be also protected by the lock. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/ath/ath9k/channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 1b05b5d7a038..ed3cd5523481 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c @@ -1257,12 +1257,12 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) "Stopping current chanctx: %d\n", sc->cur_chan->chandef.center_freq1); sc->cur_chan->stopped = true; - spin_unlock_bh(>chan_lock); if (sc->next_chan == >offchannel.chan) { getrawmonotonic(); measure_time = true; } + spin_unlock_bh(>chan_lock); ath9k_chanctx_stop_queues(sc, sc->cur_chan); queues_stopped = true; -- 2.17.0
[PATCH] net: wireless: b43legacy: Replace GFP_ATOMIC with GFP_KERNEL in dma_tx_fragment
dma_tx_fragment() is never called in atomic context. dma_tx_fragment() is only called by b43legacy_dma_tx(), which is only called by b43legacy_tx_work(). b43legacy_tx_work() is only set a parameter of INIT_WORK() in b43legacy_wireless_init(). Despite never getting called from atomic context, dma_tx_fragment() calls alloc_skb() with GFP_ATOMIC, which does not sleep for allocation. GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL, which can sleep and improve the possibility of sucessful allocation. This is found by a static analysis tool named DCNS written by myself. And I also manually check it. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/broadcom/b43legacy/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43legacy/dma.c b/drivers/net/wireless/broadcom/b43legacy/dma.c index cfa617d..2f0c64c 100644 --- a/drivers/net/wireless/broadcom/b43legacy/dma.c +++ b/drivers/net/wireless/broadcom/b43legacy/dma.c @@ -1064,7 +1064,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { - bounce_skb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); + bounce_skb = alloc_skb(skb->len, GFP_KERNEL | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; -- 1.9.1
[PATCH] net: wireless: cisco: airo: Replace mdelay with usleep_range in flashgchar
flashgchar() is never called in atomic context. flashgchar() is only called by flashcard(). flashcard() calls copy_from_user() and kmalloc(GFP_KERNEL), which indicates this function is not called in atomic context. Despite never getting called from atomic context, flashgchar() calls mdelay() to busily wait. This is not necessary and can be replaced with usleep_range() to avoid busy waiting. This is found by a static analysis tool named DCNS written by myself. And I also manually check it. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/cisco/airo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index 54201c0..45747b7 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -8106,7 +8106,7 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){ if(dwelltime && !(0x8000 & rchar)){ dwelltime -= 10; - mdelay(10); + usleep_range(1, 11000); continue; } rbyte = 0xff & rchar; -- 1.9.1
[PATCH 2/2] net: wireless: zydas: Replace GFP_ATOMIC with GFP_KERNEL in zd1201_fw_upload
zd1201_probe() is never called in atomic context. zd1201_fw_upload() is only called by zd1201_probe(), which is only set as ".probe" in struct usb_driver. Despite never getting called from atomic context, zd1201_fw_upload() calls kmalloc() with GFP_ATOMIC, which does not sleep for allocation. GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL, which can sleep and improve the possibility of sucessful allocation. This is found by a static analysis tool named DCNS written by myself. And I also manually check it. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/zydas/zd1201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/zydas/zd1201.c b/drivers/net/wireless/zydas/zd1201.c index 581e857..cba2bed 100644 --- a/drivers/net/wireless/zydas/zd1201.c +++ b/drivers/net/wireless/zydas/zd1201.c @@ -74,7 +74,7 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw) data = fw_entry->data; len = fw_entry->size; - buf = kmalloc(1024, GFP_ATOMIC); + buf = kmalloc(1024, GFP_KERNEL); if (!buf) { err = -ENOMEM; goto exit; -- 1.9.1
[PATCH 1/2] net: wireless: zydas: Replace mdelay with msleep in zd1201_probe
zd1201_probe() is never called in atomic context. zd1201_probe() is only set as ".probe" in struct usb_driver. Despite never getting called from atomic context, zd1201_probe() calls mdelay() to busily wait. This is not necessary and can be replaced with msleep() to avoid busy waiting. This is found by a static analysis tool named DCNS written by myself. And I also manually check it. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/zydas/zd1201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/zydas/zd1201.c b/drivers/net/wireless/zydas/zd1201.c index 581e857..12774e9 100644 --- a/drivers/net/wireless/zydas/zd1201.c +++ b/drivers/net/wireless/zydas/zd1201.c @@ -1767,7 +1767,7 @@ static int zd1201_probe(struct usb_interface *interface, goto err_zd; } - mdelay(100); + msleep(100); err = zd1201_drvr_start(zd); if (err) goto err_zd; -- 1.9.1
Re: [PATCH] bcma: Replace mdelay with usleep_range in bcma_pmu_resources_init
On 2018/1/27 0:26, Larry Finger wrote: On 01/26/2018 03:13 AM, Jia-Ju Bai wrote: After checking all possible call chains to bcma_pmu_resources_init() here, my tool finds that this function is never called in atomic context, namely never in an interrupt handler or holding a spinlock. Thus mdelay can be replaced with usleep_range to avoid busy wait. This is found by a static analysis tool named DCNS written by myself. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/bcma/driver_chipcommon_pmu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index f1eb4d3..478948c 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -203,7 +203,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) * Add some delay; allow resources to come up and settle. * Delay is required for SoC (early init). */ -mdelay(2); +usleep_range(1500, 2000); I have no idea how critical this delay might be, but it would be safer to never make the sleep be shorter than the original delay. Using (2000, 2500) would be a better choice of arguments for usleep_range(). Okay, I have used usleep_range(2000, 2500) and sent patch v2. Thanks, Jia-Ju Bai
[PATCH] bcma: Replace mdelay with usleep_range in bcma_pmu_resources_init
After checking all possible call chains to bcma_pmu_resources_init() here, my tool finds that this function is never called in atomic context, namely never in an interrupt handler or holding a spinlock. Thus mdelay can be replaced with usleep_range to avoid busy wait. This is found by a static analysis tool named DCNS written by myself. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/bcma/driver_chipcommon_pmu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index f1eb4d3..478948c 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -203,7 +203,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) * Add some delay; allow resources to come up and settle. * Delay is required for SoC (early init). */ - mdelay(2); + usleep_range(1500, 2000); } /* Disable to allow reading SPROM. Don't know the adventages of enabling it. */ -- 1.7.9.5
Re: [PATCH v2] b43: Replace mdelay with usleep_range in b43_radio_2057_init_post
On 2018/1/9 17:07, Arend van Spriel wrote: On 1/9/2018 9:39 AM, Jia-Ju Bai wrote: On 2018/1/9 16:35, Greg KH wrote: On Tue, Jan 09, 2018 at 09:40:06AM +0800, Jia-Ju Bai wrote: b43_radio_2057_init_post is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with usleep_range, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- v2: * Replace mdelay with usleep_range, instead of msleep in v1. Thank Larry for good advice. --- drivers/net/wireless/broadcom/b43/phy_n.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index a5557d7..f2a2f41 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -1031,7 +1031,7 @@ static void b43_radio_2057_init_post(struct b43_wldev *dev) b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78); b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80); -mdelay(2); +usleep_range(2000, 3000); Where did 3000 come from? Are you sure about that? I am not very sure, and I use it according to Larry's message: Hi Jia-Ju Bai, The duration here is for settling the registers so hardware can pick it up. Right after this they are written again. Now this is during initialization of the radio so not time critical, but probably anything in the range of 2000..3000 would also have been fine. Hi Arend, Thanks for your detailed explanation :) So I think usleep_range(2000, 3000) is okay. Thanks, Jia-Ju Bai
[PATCH v2] b43: Replace mdelay with usleep_range in b43_radio_2057_init_post
b43_radio_2057_init_post is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with usleep_range, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- v2: * Replace mdelay with usleep_range, instead of msleep in v1. Thank Larry for good advice. --- drivers/net/wireless/broadcom/b43/phy_n.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index a5557d7..f2a2f41 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -1031,7 +1031,7 @@ static void b43_radio_2057_init_post(struct b43_wldev *dev) b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78); b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80); - mdelay(2); + usleep_range(2000, 3000); b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78); b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80); -- 1.7.9.5
Re: b43: Replace mdelay with msleep in b43_radio_2057_init_post
On 2018/1/9 0:31, Larry Finger wrote: On 01/08/2018 10:21 AM, Kalle Valo wrote: Jia-Ju Bai <baijiaju1...@gmail.com> wrote: b43_radio_2057_init_post is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with msleep, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> You submitted an identical patch a week earlier: https://patchwork.kernel.org/patch/10137671/ How is this different? Also always add version number to the patch so that the maintainers can follow the changes easily: https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#patch_version_missing https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#changelog_missing I had negative comments on one of those due to the possibility of msleep(2) extending as long as 20 msec. Until the author, or someone else, can test that this is OK, then the mdelay(2) can only be replaced with usleep_range(2000, 3000). NACK for both. Larry Sorry for my mistake. I have sent a patch v2 using usleep_range(2000, 3000), and you can have a look :) Thanks, Jia-Ju Bai
[PATCH] b43: Replace mdelay with msleep in b43_radio_2057_init_post
b43_radio_2057_init_post is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with msleep, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/broadcom/b43/phy_n.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index a5557d7..5bc838e 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -1031,7 +1031,7 @@ static void b43_radio_2057_init_post(struct b43_wldev *dev) b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78); b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80); - mdelay(2); + msleep(2); b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78); b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80); -- 1.7.9.5
[PATCH] b43: Replace mdelay with msleep in b43_radio_2057_init_post
b43_radio_2057_init_post is not called in an interrupt handler nor holding a spinlock. The function mdelay in it can be replaced with msleep, to reduce busy wait. Signed-off-by: Jia-Ju Bai <baijiaju1...@gmail.com> --- drivers/net/wireless/broadcom/b43/phy_n.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index a5557d7..5bc838e 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -1031,7 +1031,7 @@ static void b43_radio_2057_init_post(struct b43_wldev *dev) b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78); b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80); - mdelay(2); + msleep(2); b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78); b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80); -- 1.7.9.5
[PATCH] mac80211_hwsim: Fix a possible sleep-in-atomic bug in hwsim_get_radio_nl
The driver may sleep under a spinlock. The function call path is: hwsim_get_radio_nl (acquire the spinlock) nlmsg_new(GFP_KERNEL) --> may sleep To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/mac80211_hwsim.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 10b075a..f2ebf4a 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -3215,7 +3215,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info) if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info))) continue; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); if (!skb) { res = -ENOMEM; goto out_err; -- 1.7.9.5
[BUG] wl3501: a possible sleep-in-atomic bug in wl3501_reset
According to drivers/net/wireless/wl3501_cs.c, the driver may sleep under a spinlock. The function call path is: wl3501_reset (acquire the spinlock) free_irq --> may sleep I do not find a good way to fix it, so I only report. This possible bug is found by my static analysis tool (DSAC) and checked by my code review. Thanks, Jia-Ju Bai
[BUG] ssb: Possible sleep-in-atomic bugs in ssb_pcmcia_read8
According to pcmcia.c, the driver may sleep under a spinlock. The function call paths are: ssb_pcmcia_read8 (acquire the spinlock) select_core_and_segment ssb_pcmcia_switch_segment ssb_pcmcia_cfg_write pcmcia_write_config_byte pcmcia_access_config (drivers/pcmcia/pcmcia_resource.c) mutex_lock --> may sleep ssb_pcmcia_read8 (acquire the spinlock) select_core_and_segment ssb_pcmcia_switch_segment sssb_pcmcia_cfg_read pcmcia_read_config_byte pcmcia_access_config (drivers/pcmcia/pcmcia_resource.c) mutex_lock --> may sleep A possible fix is to use spinlock instead of mutex lock in pcmcia_access_config in drivers/pcmcia/pcmcia_resource.c. These bugs are found by my static analysis tool and my code review. Thanks, Jia-Ju Bai
[PATCH] wcn36xx: Remove unnecessary rcu_read_unlock in wcn36xx_bss_info_changed
No rcu_read_lock is called, but rcu_read_unlock is still called. Thus rcu_read_unlock should be removed. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/ath/wcn36xx/main.c |1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 35bd50b..b83f01d 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -812,7 +812,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, if (!sta) { wcn36xx_err("sta %pM is not found\n", bss_conf->bssid); - rcu_read_unlock(); goto out; } sta_priv = wcn36xx_sta_to_priv(sta); -- 1.7.9.5
[PATCH V2] Fix a sleep-in-atomic bug in shash_setkey_unaligned
The SCTP program may sleep under a spinlock, and the function call path is: sctp_generate_t3_rtx_event (acquire the spinlock) sctp_do_sm sctp_side_effects sctp_cmd_interpreter sctp_make_init_ack sctp_pack_cookie crypto_shash_setkey shash_setkey_unaligned kmalloc(GFP_KERNEL) For the same reason, the orinoco driver may sleep in interrupt handler, and the function call path is: orinoco_rx_isr_tasklet orinoco_rx orinoco_mic crypto_shash_setkey shash_setkey_unaligned kmalloc(GFP_KERNEL) To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- crypto/shash.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/shash.c b/crypto/shash.c index 5e31c8d..8fcecc6 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -41,7 +41,7 @@ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, int err; absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); - buffer = kmalloc(absize, GFP_KERNEL); + buffer = kmalloc(absize, GFP_ATOMIC); if (!buffer) return -ENOMEM; -- 1.7.9.5
[PATCH] Fix a sleep-in-atomic bug in shash_setkey_unaligned
For the same reason, the orinoco driver may sleep in interrupt handler, and the function call path is: orinoco_rx_isr_tasklet orinoco_rx orinoco_mic crypto_shash_setkey shash_setkey_unaligned kmalloc(GFP_KERNEL) To fix it, GFP_KERNEL is replaced with GFP_ATOMIC. This bug is found by my static analysis tool and my code review. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- crypto/shash.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/shash.c b/crypto/shash.c index 5e31c8d..8fcecc6 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -41,7 +41,7 @@ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, int err; absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); - buffer = kmalloc(absize, GFP_KERNEL); + buffer = kmalloc(absize, GFP_ATOMIC); if (!buffer) return -ENOMEM; -- 1.7.9.5
[PATCH] cw1200: Fix a sleep-in-atomic bug in cw1200_tx_confirm_cb and cw1200_cqm_bssloss_sm
The driver may sleep under a spin lock, and the function call path is: cw1200_tx_confirm_cb (acquire the lock by spin_lock) __cw1200_cqm_bssloss_sm cancel_work_sync --> may sleep cw1200_cqm_bssloss_sm __cw1200_cqm_bssloss_sm cancel_work_sync --> may sleep To fix it, the lock is released before cancel_work_sync, and the lock is acquired again after this function. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/st/cw1200/sta.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/st/cw1200/sta.c b/drivers/net/wireless/st/cw1200/sta.c index a522248..d5f7698 100644 --- a/drivers/net/wireless/st/cw1200/sta.c +++ b/drivers/net/wireless/st/cw1200/sta.c @@ -154,7 +154,9 @@ void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv, int tx = 0; priv->delayed_link_loss = 0; + spin_unlock(>bss_loss_lock); cancel_work_sync(>bss_params_work); + spin_lock(>bss_loss_lock); pr_debug("[STA] CQM BSSLOSS_SM: state: %d init %d good %d bad: %d txlock: %d uj: %d\n", priv->bss_loss_state, -- 1.7.9.5
Re: [PATCH] b43legacy: Fix a sleep-in-atomic bug in b43legacy_op_bss_info_changed
On 06/01/2017 08:07 AM, Larry Finger wrote: On 05/31/2017 10:32 AM, Michael Büsch wrote: On Wed, 31 May 2017 13:26:43 +0300 Kalle Valo <kv...@codeaurora.org> wrote: Jia-Ju Bai <baijiaju1...@163.com> writes: The driver may sleep under a spin lock, and the function call path is: b43legacy_op_bss_info_changed (acquire the lock by spin_lock_irqsave) b43legacy_synchronize_irq synchronize_irq --> may sleep To fix it, the lock is released before b43legacy_synchronize_irq, and the lock is acquired again after this function. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/broadcom/b43legacy/main.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index f1e3dad..31ead21 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -2859,7 +2859,9 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw, b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0); if (changed & BSS_CHANGED_BSSID) { +spin_unlock_irqrestore(>irq_lock, flags); b43legacy_synchronize_irq(dev); +spin_lock_irqsave(>irq_lock, flags); To me this looks like a fragile workaround and not a real fix. You can easily add new race conditions with releasing the lock like this. I think releasing the lock possibly is fine. It certainly is better than sleeping with a lock held. We disabled the device interrupts just before this line. However I think the synchronize_irq should be outside of the conditional right after the write to B43legacy_MMIO_GEN_IRQ_MASK. (So two lines above) I don't think it makes sense to only synchronize if BSS_CHANGED_BSSID is set. On the other hand b43 does not have this irq-disabling foobar anymore. So somebody must have removed it. Maybe you can find the commit that removed this stuff from b43 and port it to b43legacy? So I would vote for moving the synchronize_irq up outside of the conditional and put the unlock/lock sequence around it. And as a second patch on top of that try to remove this stuff altogether like b43 did. The patch that removed it in b43 is commit 36dbd9548e92268127b0c31b0e121e63e9207108 Author: Michael Buesch <m...@bu3sch.de> Date: Fri Sep 4 22:51:29 2009 +0200 b43: Use a threaded IRQ handler Use a threaded IRQ handler to allow locking the mutex and sleeping while executing an interrupt. This removes usage of the irq_lock spinlock, but introduces a new hardirq_lock, which is _only_ used for the PCI/SSB lowlevel hard-irq handler. Sleeping busses (SDIO) will use mutex instead. Signed-off-by: Michael Buesch <m...@bu3sch.de> Tested-by: Larry Finger <larry.fin...@lwfinger.net> Signed-off-by: John W. Linville <linvi...@tuxdriver.com> I vaguely remember this patch. Although it is roughly a 1000-line fix, I will try to port it to b43legacy. I still have an old BCM4306 PCMCIA card that I can test in a PowerBook G4. I agree with Michael that this is the way to go. Both of Jia-Ju's patches should be rejected. Larry It is fine to me to fix the bug by porting this former patch. Thanks, Jia-Ju Bai
Re: [PATCH] b43legacy: Fix a sleep-in-atomic bug in b43legacy_attr_interfmode_store
On 06/01/2017 01:33 AM, Larry Finger wrote: On 05/31/2017 05:29 AM, Jia-Ju Bai wrote: The driver may sleep under a spin lock, and the function call path is: b43legacy_attr_interfmode_store (acquire the lock by spin_lock_irqsave) b43legacy_radio_set_interference_mitigation b43legacy_radio_interference_mitigation_disable b43legacy_calc_nrssi_slope b43legacy_synth_pu_workaround might_sleep and msleep --> may sleep Fixing it may be complex, and a possible way is to remove spin_lock_irqsave and spin_lock_irqrestore in b43legacy_attr_interfmode_store, and the code has been protected by mutex_lock and mutex_unlock. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/broadcom/b43legacy/sysfs.c |2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43legacy/sysfs.c b/drivers/net/wireless/broadcom/b43legacy/sysfs.c index 2a1da15..9ede143 100644 --- a/drivers/net/wireless/broadcom/b43legacy/sysfs.c +++ b/drivers/net/wireless/broadcom/b43legacy/sysfs.c @@ -137,14 +137,12 @@ static ssize_t b43legacy_attr_interfmode_store(struct device *dev, } mutex_lock(>wl->mutex); -spin_lock_irqsave(>wl->irq_lock, flags); err = b43legacy_radio_set_interference_mitigation(wldev, mode); if (err) b43legacyerr(wldev->wl, "Interference Mitigation not " "supported by device\n"); mmiowb(); -spin_unlock_irqrestore(>wl->irq_lock, flags); mutex_unlock(>wl->mutex); return err ? err : count; Jia-Ju, Did you actually observe the attempt to sleep under the spin lock, or did you discover this using some tool? In other words, have either of your patches been tested? Larry Hi, In fact, my reported bugs are found by a static analysis tool written by me, and they are checked by my review of the driver code. I admit my patches are not well tested, and they may not well fix the bugs. I am looking forward to opinions and suggestions :) Thanks, Jia-Ju Bai
[PATCH] b43legacy: Fix a sleep-in-atomic bug in b43legacy_attr_interfmode_store
The driver may sleep under a spin lock, and the function call path is: b43legacy_attr_interfmode_store (acquire the lock by spin_lock_irqsave) b43legacy_radio_set_interference_mitigation b43legacy_radio_interference_mitigation_disable b43legacy_calc_nrssi_slope b43legacy_synth_pu_workaround might_sleep and msleep --> may sleep Fixing it may be complex, and a possible way is to remove spin_lock_irqsave and spin_lock_irqrestore in b43legacy_attr_interfmode_store, and the code has been protected by mutex_lock and mutex_unlock. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/broadcom/b43legacy/sysfs.c |2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43legacy/sysfs.c b/drivers/net/wireless/broadcom/b43legacy/sysfs.c index 2a1da15..9ede143 100644 --- a/drivers/net/wireless/broadcom/b43legacy/sysfs.c +++ b/drivers/net/wireless/broadcom/b43legacy/sysfs.c @@ -137,14 +137,12 @@ static ssize_t b43legacy_attr_interfmode_store(struct device *dev, } mutex_lock(>wl->mutex); - spin_lock_irqsave(>wl->irq_lock, flags); err = b43legacy_radio_set_interference_mitigation(wldev, mode); if (err) b43legacyerr(wldev->wl, "Interference Mitigation not " "supported by device\n"); mmiowb(); - spin_unlock_irqrestore(>wl->irq_lock, flags); mutex_unlock(>wl->mutex); return err ? err : count; -- 1.7.9.5
[PATCH] b43legacy: Fix a sleep-in-atomic bug in b43legacy_op_bss_info_changed
The driver may sleep under a spin lock, and the function call path is: b43legacy_op_bss_info_changed (acquire the lock by spin_lock_irqsave) b43legacy_synchronize_irq synchronize_irq --> may sleep To fix it, the lock is released before b43legacy_synchronize_irq, and the lock is acquired again after this function. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/broadcom/b43legacy/main.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index f1e3dad..31ead21 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -2859,7 +2859,9 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw, b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0); if (changed & BSS_CHANGED_BSSID) { + spin_unlock_irqrestore(>irq_lock, flags); b43legacy_synchronize_irq(dev); + spin_lock_irqsave(>irq_lock, flags); if (conf->bssid) memcpy(wl->bssid, conf->bssid, ETH_ALEN); -- 1.7.9.5
[PATCH] iwl4965: Fix a memory leak in error handling code of __il4965_up
When il4965_hw_nic_init in __il4965_up fails, the memory allocated by iwl4965_sta_alloc_lq in iwl4965_alloc_bcast_station is not freed. This patches adds il_dealloc_bcast_stations in the error handling code of __il4965_up to fix this problem. This patch has been tested in real device, and it actually fixes the bug. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/iwlegacy/4965-mac.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 6656215..fd7b5c7 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5577,6 +5577,7 @@ __il4965_up(struct il_priv *il) ret = il4965_hw_nic_init(il); if (ret) { IL_ERR("Unable to init nic\n"); + il_dealloc_bcast_stations(il); return ret; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] rt2x00pci: Disable memory-write-invalidate when the driver exits
On 01/05/2016 12:50 AM, Helmut Schaa wrote: On Mon, Jan 4, 2016 at 8:55 AM, Jia-Ju Bai<baijiaju1...@163.com> wrote: The driver calls pci_set_mwi to enable memory-write-invalidate when it is initialized, but does not call pci_clear_mwi when it is removed. Many other drivers calls pci_clear_mwi when pci_set_mwi is called, such as r8169, 8139cp and e1000. This patch adds pci_clear_mwi in error handling and removal procedure, which can fix the problem. Signed-off-by: Jia-Ju Bai<baijiaju1...@163.com> Looks good to me. Does this fix any actual issue? If yes it might we worth to mention it in the commit message. Helmut Lacking pci_clear_mwi may cause a resource-release omission, but this omission may not cause obvious issues. For reliability, it is better to add pci_clear_mwi in the driver. Many other drivers do so, such as r8169, 8139cp and e1000. Jia-Ju Bai -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] rt2x00pci: Disable memory-write-invalidate when the driver exits
The driver calls pci_set_mwi to enable memory-write-invalidate when it is initialized, but does not call pci_clear_mwi when it is removed. Many other drivers calls pci_clear_mwi when pci_set_mwi is called, such as r8169, 8139cp and e1000. This patch adds pci_clear_mwi in error handling and removal procedure, which can fix the problem. Signed-off-by: Jia-Ju Bai <baijiaju1...@163.com> --- drivers/net/wireless/rt2x00/rt2x00pci.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index d93db4b..eb6dbcd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -149,6 +149,7 @@ exit_free_device: ieee80211_free_hw(hw); exit_release_regions: + pci_clear_mwi(pci_dev); pci_release_regions(pci_dev); exit_disable_device: @@ -173,6 +174,7 @@ void rt2x00pci_remove(struct pci_dev *pci_dev) /* * Free the PCI device data. */ + pci_clear_mwi(pci_dev); pci_disable_device(pci_dev); pci_release_regions(pci_dev); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html