2016-06-25 18:38:11

by Larry Finger

[permalink] [raw]
Subject: [PATCH 0/6] rtlwifi: Miscellaneous fixes and cleanups

This set of patches removes an unused paramter from routine rtl_ps_set_rf_state()
in rtlwifi. The routine is also no longer exported. In addition, a potential
race condition in 5 of the drivers is fixed.

This material is suitable for kernel 4.8. To my knowledge, the race condition
has not been shown to occur, thus these patches are not backported to stable
kernels.

Signed-off-by: Larry Finger <[email protected]>

Larry Finger (6):
rtlwifi: Remove unused parameter from rtl_ps_set_rf_state()
rtlwifi: rtl8188ee: Fix potential race condition
rtlwifi: rtl8192ee: Fix potential race condition
rtlwifi: rtl8723be: Fix potential race condition
rtlwifi: rtl8723ae: Fix potential race condition
rtlwifi: rtl8821ae: Fix potential race condition

drivers/net/wireless/realtek/rtlwifi/ps.c | 25 ++++++++--------------
drivers/net/wireless/realtek/rtlwifi/ps.h | 3 ---
.../net/wireless/realtek/rtlwifi/rtl8188ee/dm.c | 2 ++
.../net/wireless/realtek/rtlwifi/rtl8192ee/dm.c | 2 ++
.../net/wireless/realtek/rtlwifi/rtl8723ae/dm.c | 2 ++
.../net/wireless/realtek/rtlwifi/rtl8723be/dm.c | 2 ++
.../net/wireless/realtek/rtlwifi/rtl8821ae/dm.c | 2 ++
7 files changed, 19 insertions(+), 19 deletions(-)

--
2.1.4



2016-06-25 18:38:18

by Larry Finger

[permalink] [raw]
Subject: [PATCH 5/6] rtlwifi: rtl8723ae: Fix potential race condition

Flag rfchange_inprogress in struct rtl_ps_ctl is protected by a spinlock
in most routines but not in rtl8723e_dm_watchdog(), which could
lead to a race condition. The necessary locking to prevent this condition
is added.

Reported-by: Pavel Andrianov <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Pavel Andrianov <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
index 4c1c96c..3900e10 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
@@ -816,6 +816,7 @@ void rtl8723e_dm_watchdog(struct ieee80211_hw *hw)
if (ppsc->p2p_ps_info.p2p_ps_mode)
fw_ps_awake = false;

+ spin_lock(&rtlpriv->locks.rf_ps_lock);
if ((ppsc->rfpwr_state == ERFON) &&
((!fw_current_inpsmode) && fw_ps_awake) &&
(!ppsc->rfchange_inprogress)) {
@@ -829,6 +830,7 @@ void rtl8723e_dm_watchdog(struct ieee80211_hw *hw)
rtl8723e_dm_bt_coexist(hw);
rtl8723e_dm_check_edca_turbo(hw);
}
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
if (rtlpriv->btcoexist.init_set)
rtl_write_byte(rtlpriv, 0x76e, 0xc);
}
--
2.1.4


2016-06-25 18:38:16

by Larry Finger

[permalink] [raw]
Subject: [PATCH 3/6] rtlwifi: rtl8192ee: Fix potential race condition

Flag rfchange_inprogress in struct rtl_ps_ctl is protected by a spinlock
in most routines but not in rtl92ee_dm_watchdog(), which could
lead to a race condition. The necessary locking to prevent this condition
is added.

Reported-by: Pavel Andrianov <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Pavel Andrianov <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c
index 459f3d0..46efba0 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/dm.c
@@ -1219,6 +1219,7 @@ void rtl92ee_dm_watchdog(struct ieee80211_hw *hw)
if (ppsc->p2p_ps_info.p2p_ps_mode)
fw_ps_awake = false;

+ spin_lock(&rtlpriv->locks.rf_ps_lock);
if ((ppsc->rfpwr_state == ERFON) &&
((!fw_current_inpsmode) && fw_ps_awake) &&
(!ppsc->rfchange_inprogress)) {
@@ -1233,4 +1234,5 @@ void rtl92ee_dm_watchdog(struct ieee80211_hw *hw)
rtl92ee_dm_dynamic_atc_switch(hw);
rtl92ee_dm_dynamic_primary_cca_ckeck(hw);
}
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
}
--
2.1.4


2016-06-25 18:38:17

by Larry Finger

[permalink] [raw]
Subject: [PATCH 4/6] rtlwifi: rtl8723be: Fix potential race condition

Flag rfchange_inprogress in struct rtl_ps_ctl is protected by a spinlock
in most routines but not in rtl8723be_dm_watchdog(), which could
lead to a race condition. The necessary locking to prevent this condition
is added.

Reported-by: Pavel Andrianov <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Pavel Andrianov <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
index 3a81cdb..9a4715ab 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/dm.c
@@ -1279,6 +1279,7 @@ void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
if (ppsc->p2p_ps_info.p2p_ps_mode)
fw_ps_awake = false;

+ spin_lock(&rtlpriv->locks.rf_ps_lock);
if ((ppsc->rfpwr_state == ERFON) &&
((!fw_current_inpsmode) && fw_ps_awake) &&
(!ppsc->rfchange_inprogress)) {
@@ -1294,5 +1295,6 @@ void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
rtl8723be_dm_check_txpower_tracking(hw);
rtl8723be_dm_dynamic_txpower(hw);
}
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
}
--
2.1.4


2016-06-25 18:38:16

by Larry Finger

[permalink] [raw]
Subject: [PATCH 2/6] rtlwifi: rtl8188ee: Fix potential race condition

Flag rfchange_inprogress in struct rtl_ps_ctl is protected by a spinlock
in most routines but not in rtl88e_dm_watchdog(), which could
lead to a race condition. The necessary locking to prevent this condition
is added.

Reported-by: Pavel Andrianov <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Pavel Andrianov <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
index db9a782..7f2650d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c
@@ -1790,6 +1790,7 @@ void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
if (ppsc->p2p_ps_info.p2p_ps_mode)
fw_ps_awake = false;

+ spin_lock(&rtlpriv->locks.rf_ps_lock);
if ((ppsc->rfpwr_state == ERFON) &&
((!fw_current_inpsmode) && fw_ps_awake) &&
(!ppsc->rfchange_inprogress)) {
@@ -1802,4 +1803,5 @@ void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
rtl88e_dm_check_edca_turbo(hw);
rtl88e_dm_antenna_diversity(hw);
}
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);
}
--
2.1.4


2016-06-25 18:38:19

by Larry Finger

[permalink] [raw]
Subject: [PATCH 6/6] rtlwifi: rtl8821ae: Fix potential race condition

Flag rfchange_inprogress in struct rtl_ps_ctl is protected by a spinlock
in most routines but not in rtl8821ae_dm_watchdog() which could
lead to a race condition. The necessary locking to prevent this condition
is added.

Reported-by: Pavel Andrianov <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Pavel Andrianov <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
index 17a6817..35c6f8a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/dm.c
@@ -2949,6 +2949,7 @@ void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
if (ppsc->p2p_ps_info.p2p_ps_mode)
fw_ps_awake = false;

+ spin_lock(&rtlpriv->locks.rf_ps_lock);
if ((ppsc->rfpwr_state == ERFON) &&
((!fw_current_inpsmode) && fw_ps_awake) &&
(!ppsc->rfchange_inprogress)) {
@@ -2967,6 +2968,7 @@ void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
rtl8821ae_dm_iq_calibrate(hw);
}
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);

rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
RT_TRACE(rtlpriv, COMP_DIG, DBG_DMESG, "\n");
--
2.1.4


2016-06-25 18:38:15

by Larry Finger

[permalink] [raw]
Subject: [PATCH 1/6] rtlwifi: Remove unused parameter from rtl_ps_set_rf_state()

Commit 4b9d8d67b44a ("rtlwifi: rtl8192cu: Remove unused parameter") reworked
this routine. Those changes were later reverted by commit d3feae41a347
("rtlwifi: Update power-save routines for 062814 driver").

There were two changes in commit 4b9d8d67b44a. The first of these removed
a parameter from rtl_ps_set_rf_state() that was always false. This is the
change that is restored in the current patch. A second change that reworked
the locking is still being analyzed.

In addition to removing the unused parameter, there is no need for
rtl_ps_set_rf_state() to be exported.

Reported-by: Pavel Andrianov <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Pavel Andrianov <[email protected]>
---
drivers/net/wireless/realtek/rtlwifi/ps.c | 25 +++++++++----------------
drivers/net/wireless/realtek/rtlwifi/ps.h | 3 ---
2 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c
index 93579ca..9a64f9b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -76,9 +76,9 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL(rtl_ps_disable_nic);

-bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
- enum rf_pwrstate state_toset,
- u32 changesource, bool protect_or_not)
+static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
+ enum rf_pwrstate state_toset,
+ u32 changesource)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
@@ -86,9 +86,6 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
bool actionallowed = false;
u16 rfwait_cnt = 0;

- if (protect_or_not)
- goto no_protect;
-
/*Only one thread can change
*the RF state at one time, and others
*should wait to be executed.
@@ -119,7 +116,6 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
}
}

-no_protect:
rtstate = ppsc->rfpwr_state;

switch (state_toset) {
@@ -162,15 +158,12 @@ no_protect:
if (actionallowed)
rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);

- if (!protect_or_not) {
- spin_lock(&rtlpriv->locks.rf_ps_lock);
- ppsc->rfchange_inprogress = false;
- spin_unlock(&rtlpriv->locks.rf_ps_lock);
- }
+ spin_lock(&rtlpriv->locks.rf_ps_lock);
+ ppsc->rfchange_inprogress = false;
+ spin_unlock(&rtlpriv->locks.rf_ps_lock);

return actionallowed;
}
-EXPORT_SYMBOL(rtl_ps_set_rf_state);

static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
{
@@ -191,7 +184,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
}

rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
- RF_CHANGE_BY_IPS, false);
+ RF_CHANGE_BY_IPS);

if (ppsc->inactive_pwrstate == ERFOFF &&
rtlhal->interface == INTF_PCI) {
@@ -587,7 +580,7 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
}

spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
- rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
+ rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
}

@@ -630,7 +623,7 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
spin_unlock(&rtlpriv->locks.rf_ps_lock);

spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
- rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS , false);
+ rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);

if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.h b/drivers/net/wireless/realtek/rtlwifi/ps.h
index 29dfc51..0df2b52 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.h
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.h
@@ -28,9 +28,6 @@

#define MAX_SW_LPS_SLEEP_INTV 5

-bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
- enum rf_pwrstate state_toset, u32 changesource,
- bool protect_or_not);
bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
void rtl_ips_nic_off(struct ieee80211_hw *hw);
--
2.1.4


2016-07-05 14:32:10

by Kalle Valo

[permalink] [raw]
Subject: Re: [1/6] rtlwifi: Remove unused parameter from rtl_ps_set_rf_state()

Larry Finger <[email protected]> wrote:
> Commit 4b9d8d67b44a ("rtlwifi: rtl8192cu: Remove unused parameter") reworked
> this routine. Those changes were later reverted by commit d3feae41a347
> ("rtlwifi: Update power-save routines for 062814 driver").
>
> There were two changes in commit 4b9d8d67b44a. The first of these removed
> a parameter from rtl_ps_set_rf_state() that was always false. This is the
> change that is restored in the current patch. A second change that reworked
> the locking is still being analyzed.
>
> In addition to removing the unused parameter, there is no need for
> rtl_ps_set_rf_state() to be exported.
>
> Reported-by: Pavel Andrianov <[email protected]>
> Signed-off-by: Larry Finger <[email protected]>
> Cc: Pavel Andrianov <[email protected]>

Thanks, 6 patches applied to wireless-drivers-next.git:

30462b514fb3 rtlwifi: Remove unused parameter from rtl_ps_set_rf_state()
204e2ab22e1e rtlwifi: rtl8188ee: Fix potential race condition
c3ae8ec4a264 rtlwifi: rtl8192ee: Fix potential race condition
31c2e76c77fb rtlwifi: rtl8723be: Fix potential race condition
4f29b348bdc0 rtlwifi: rtl8723ae: Fix potential race condition
300c32ca84f5 rtlwifi: rtl8821ae: Fix potential race condition

--
Sent by pwcli
https://patchwork.kernel.org/patch/9198637/