Skip to content

Commit

Permalink
rtlwifi: add protection before calling {enable|disable}_interrupt()
Browse files Browse the repository at this point in the history
Detected on pcie/rtl8192ce embedded armv7/arm64 plaform
Call to {enable|disable}_interrupt() seem not enought protected,
so, add extra protection to avoid collision

    Without this patch (randomly)
    [  184.243426] rcu: INFO: rcu_sched self-detected stall on CPU
    [  184.249008] rcu:     0-....: (8405 ticks this GP) idle=df74/1/0x40000002 softirq=3607/3607 fqs=2972
    [  184.257790]  (t=8407 jiffies g=6613 q=56899 ncpus=4)
    [  184.257803] CPU: 0 PID: 1059 Comm: ifconfig Not tainted 6.2.7 #3
    [  184.257813] Hardware name: STi SoC with Flattened Device Tree
    [  184.257818] PC is at pci_read32_sync+0x10/0x14 [rtl_pci]
    [  184.257860] LR is at rtl92ce_enable_interrupt+0x4c/0x8c [rtl8192ce]
    [  184.257921] pc : [<bf46d03c>]    lr : [<bf478e44>]    psr: 20060013
    [  184.257928] sp : f1375ce0  ip : bf451b34  fp : c14f3c00
    [  184.257933] r10: c2c4b780  r9 : c28f4000  r8 : c15b18bc
    [  184.257938] r7 : 00000000  r6 : c15bd880  r5 : c15bc880  r4 : c15b1880
    [  184.257944] r3 : f09e8000  r2 : 00000730  r1 : f09e8120  r0 : 00001b5f
    [  184.257950] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
    [  184.257959] Control: 10c5387d  Table: 86c0804a  DAC: 00000051
    [  184.257970]  pci_read32_sync [rtl_pci] from rtl92ce_enable_interrupt+0x4c/0x8c [rtl8192ce]
    [  184.258018]  rtl92ce_enable_interrupt [rtl8192ce] from rtl_pci_start+0xbc/0x18c [rtl_pci]
    [  184.258059]  rtl_pci_start [rtl_pci] from rtl_op_start+0x58/0x7c [rtlwifi]
    [  184.258269]  rtl_op_start [rtlwifi] from drv_start+0x4c/0x10c [mac80211]
    [  184.259512]  drv_start [mac80211] from ieee80211_do_open+0x370/0x6d8 [mac80211]
    [  184.260444]  ieee80211_do_open [mac80211] from ieee80211_open+0x60/0x84 [mac80211]
    [  184.261374]  ieee80211_open [mac80211] from __dev_open+0xfc/0x1d0
    [  184.261860]  __dev_open from __dev_change_flags+0x190/0x214
    [  184.261878]  __dev_change_flags from dev_change_flags+0x20/0x5c
    [  184.261894]  dev_change_flags from devinet_ioctl+0x7a8/0x7dc
    [  184.261918]  devinet_ioctl from inet_ioctl+0x1a4/0x244
    [  184.261937]  inet_ioctl from sock_ioctl+0x4dc/0x5b8
    [  184.261962]  sock_ioctl from sys_ioctl+0x510/0xbd8
    [  184.261985]  sys_ioctl from ret_fast_syscall+0x0/0x1c

this can be reproduced using NetworkManager
or with this simple script: (~1-2min to deadlock)
$ while : ; do ifconfig wlan0 up; ifconfig wlan0 done; echo -n "."; done'

Signed-off-by: Jerome AUDU <jau@free.fr>
  • Loading branch information
waby38b committed Apr 11, 2023
1 parent fe15c26 commit 2318558
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/net/wireless/realtek/rtlwifi/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
unsigned long flags;

int err;

Expand All @@ -1794,7 +1795,9 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
&rtlmac->retry_long);

spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->enable_interrupt(hw);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n");

rtl_init_rx_config(hw);
Expand Down Expand Up @@ -1831,7 +1834,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
set_hal_stop(rtlhal);

rtlpci->driver_is_goingto_unload = true;
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->disable_interrupt(hw);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
cancel_work_sync(&rtlpriv->works.lps_change_work);

spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/realtek/rtlwifi/ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
unsigned long flags;

/*<1> reset trx ring */
if (rtlhal->interface == INTF_PCI)
Expand All @@ -35,7 +36,9 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
cfg80211_get_chandef_type(&hw->conf.chandef));

/*<3> Enable Interrupt */
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
rtlpriv->cfg->ops->enable_interrupt(hw);
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);

/*<enable timer> */
rtl_watch_dog_timer_callback(&rtlpriv->works.watchdog_timer);
Expand Down

0 comments on commit 2318558

Please sign in to comment.