staging: rtl8712: get rid of flush_scheduled_work
authorPavel Skripkin <paskripkin@gmail.com>
Wed, 21 Jul 2021 19:34:36 +0000 (22:34 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Jul 2021 13:15:24 +0000 (15:15 +0200)
This patch is preparation for following patch for error handling
refactoring.

flush_scheduled_work() takes (wq_completion)events lock and
it can lead to deadlock when r871xu_dev_remove() is called from workqueue.
To avoid deadlock sutiation we can change flush_scheduled_work() call to
flush_work() call for all possibly scheduled works in this driver,
since next patch adds device_release_driver() in case of fw load failure.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/6e028b4c457eeb7156c76c6ea3cdb3cb0207c7e1.1626895918.git.paskripkin@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/rtl8712/rtl8712_led.c
drivers/staging/rtl8712/rtl871x_led.h
drivers/staging/rtl8712/rtl871x_pwrctrl.c
drivers/staging/rtl8712/rtl871x_pwrctrl.h
drivers/staging/rtl8712/usb_intf.c

index 5901026..d5fc902 100644 (file)
@@ -1820,3 +1820,11 @@ void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction)
                break;
        }
 }
+
+void r8712_flush_led_works(struct _adapter *padapter)
+{
+       struct led_priv *pledpriv = &padapter->ledpriv;
+
+       flush_work(&pledpriv->SwLed0.BlinkWorkItem);
+       flush_work(&pledpriv->SwLed1.BlinkWorkItem);
+}
index ee19c87..2f07681 100644 (file)
@@ -112,6 +112,7 @@ struct led_priv {
 void r8712_InitSwLeds(struct _adapter *padapter);
 void r8712_DeInitSwLeds(struct _adapter *padapter);
 void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction);
+void r8712_flush_led_works(struct _adapter *padapter);
 
 #endif
 
index 23cff43..cd6d9ff 100644 (file)
@@ -224,3 +224,11 @@ void r8712_unregister_cmd_alive(struct _adapter *padapter)
        }
        mutex_unlock(&pwrctrl->mutex_lock);
 }
+
+void r8712_flush_rwctrl_works(struct _adapter *padapter)
+{
+       struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;
+
+       flush_work(&pwrctrl->SetPSModeWorkItem);
+       flush_work(&pwrctrl->rpwm_workitem);
+}
index bf6623c..b35b9c7 100644 (file)
@@ -108,5 +108,6 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter,
 void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode,
                        uint smart_ps);
 void r8712_set_rpwm(struct _adapter *padapter, u8 val8);
+void r8712_flush_rwctrl_works(struct _adapter *padapter);
 
 #endif  /* __RTL871X_PWRCTRL_H_ */
index 2434b13..643f21e 100644 (file)
@@ -606,7 +606,8 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
                        padapter->surprise_removed = true;
                if (pnetdev->reg_state != NETREG_UNINITIALIZED)
                        unregister_netdev(pnetdev); /* will call netdev_close() */
-               flush_scheduled_work();
+               r8712_flush_rwctrl_works(padapter);
+               r8712_flush_led_works(padapter);
                udelay(1);
                /* Stop driver mlme relation timer */
                r8712_stop_drv_timers(padapter);