From f96f8ae08d33eeae65581b6dbf25d12e307e7b2c Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Mon, 11 Apr 2022 08:16:20 -0700 Subject: [PATCH] staging/rtl8192e,ieee80211: replace ps tasklet with work Tasklets have long been deprecated as being too heavy on the system by running in irq context - and this is not a performance critical path. If a higher priority process wants to run, it must wait for the tasklet to finish before doing so. rtllib_sta_ps() and ieee80211_sta_ps() will now run in process context and have further concurrency (tasklets being serialized among themselves), but this is done holding the ieee->lock, so it should be fine. Signed-off-by: Davidlohr Bueso Link: https://lore.kernel.org/r/20220411151620.129178-7-dave@stgolabs.net Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 2 +- drivers/staging/rtl8192e/rtllib_rx.c | 2 +- drivers/staging/rtl8192e/rtllib_softmac.c | 12 ++++++++---- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 15 +++++++++------ 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index c985e4e..0ecd81a 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -1585,7 +1585,7 @@ struct rtllib_device { short sta_sleep; int ps_timeout; int ps_period; - struct tasklet_struct ps_task; + struct work_struct ps_task; u64 ps_time; bool polling; diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index eb904b4..f5a44bc 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -2721,7 +2721,7 @@ static void rtllib_rx_mgt(struct rtllib_device *ieee, if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED && ieee->iw_mode == IW_MODE_INFRA && ieee->state == RTLLIB_LINKED)) - tasklet_schedule(&ieee->ps_task); + schedule_work(&ieee->ps_task); break; diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index 4b6c229..82bf05e 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -2042,13 +2042,17 @@ static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) } -static inline void rtllib_sta_ps(struct tasklet_struct *t) +static inline void rtllib_sta_ps(struct work_struct *work) { - struct rtllib_device *ieee = from_tasklet(ieee, t, ps_task); + struct rtllib_device *ieee; u64 time; short sleep; unsigned long flags, flags2; + ieee = container_of(work, struct rtllib_device, ps_task); + if (!ieee) + return; + spin_lock_irqsave(&ieee->lock, flags); if ((ieee->ps == RTLLIB_PS_DISABLED || @@ -3028,7 +3032,7 @@ int rtllib_softmac_init(struct rtllib_device *ieee) spin_lock_init(&ieee->mgmt_tx_lock); spin_lock_init(&ieee->beacon_lock); - tasklet_setup(&ieee->ps_task, rtllib_sta_ps); + INIT_WORK(&ieee->ps_task, rtllib_sta_ps); return 0; } @@ -3050,8 +3054,8 @@ void rtllib_softmac_free(struct rtllib_device *ieee) cancel_work_sync(&ieee->associate_complete_wq); cancel_work_sync(&ieee->ips_leave_wq); cancel_work_sync(&ieee->wx_sync_scan_wq); + cancel_work_sync(&ieee->ps_task); mutex_unlock(&ieee->wx_mutex); - tasklet_kill(&ieee->ps_task); } static inline struct sk_buff * diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 68c0bf9..b577f9c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -1790,7 +1790,7 @@ struct ieee80211_device { short sta_sleep; int ps_timeout; int ps_period; - struct tasklet_struct ps_task; + struct work_struct ps_task; u32 ps_th; u32 ps_tl; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 1a43979..4e8fbd2 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1687,14 +1687,17 @@ static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, return 1; } -static inline void ieee80211_sta_ps(struct tasklet_struct *t) +static inline void ieee80211_sta_ps(struct work_struct *work) { - struct ieee80211_device *ieee = from_tasklet(ieee, t, ps_task); + struct ieee80211_device *ieee; u32 th, tl; short sleep; - unsigned long flags, flags2; + ieee = container_of(work, struct ieee80211_device, ps_task); + if (!ieee) + return; + spin_lock_irqsave(&ieee->lock, flags); if ((ieee->ps == IEEE80211_PS_DISABLED || @@ -1897,7 +1900,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && ieee->iw_mode == IW_MODE_INFRA && ieee->state == IEEE80211_LINKED)) - tasklet_schedule(&ieee->ps_task); + schedule_work(&ieee->ps_task); if (WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) @@ -2602,7 +2605,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) spin_lock_init(&ieee->mgmt_tx_lock); spin_lock_init(&ieee->beacon_lock); - tasklet_setup(&ieee->ps_task, ieee80211_sta_ps); + INIT_WORK(&ieee->ps_task, ieee80211_sta_ps); } void ieee80211_softmac_free(struct ieee80211_device *ieee) @@ -2613,7 +2616,7 @@ void ieee80211_softmac_free(struct ieee80211_device *ieee) del_timer_sync(&ieee->associate_timer); cancel_delayed_work(&ieee->associate_retry_wq); - + cancel_work_sync(&ieee->ps_task); mutex_unlock(&ieee->wx_mutex); } -- 2.7.4