bcm4329: Fix add_timer race conditions (b/2249878)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c
index 135db37..54fb62f 100644
--- a/bcm4329/src/dhd/sys/dhd_linux.c
+++ b/bcm4329/src/dhd/sys/dhd_linux.c
@@ -1890,7 +1890,7 @@
#if defined(OOB_INTR_ONLY)
/* Host registration for OOB interrupt */
if (bcmsdh_register_oob_intr(dhdp)) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__));
return -ENODEV;
@@ -1902,7 +1902,7 @@
/* If bus is not ready, can't come up */
if (dhd->pub.busstate != DHD_BUS_DATA) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
return -ENODEV;
@@ -2029,7 +2029,7 @@
#endif /* defined(OOB_INTR_ONLY) */
/* Clear the watchdog timer */
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
}
}
@@ -2280,7 +2280,7 @@
#if defined(CONTINUOUS_WATCHDOG)
/* Stop timer and restart at new value */
if (dhd->wd_timer_valid == TRUE) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
}
@@ -2292,7 +2292,7 @@
#else
/* Totally stop the timer */
if (!wdtick && dhd->wd_timer_valid == TRUE) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
save_dhd_watchdog_ms = wdtick;
return;
@@ -2304,7 +2304,7 @@
if (dhd->wd_timer_valid == TRUE)
/* Stop timer and restart at new value */
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
/* Create timer again when watchdog period is
dynamically changed or in the first instance
diff --git a/bcm4329/src/wl/sys/wl_iw.c b/bcm4329/src/wl/sys/wl_iw.c
index fd5caf0..5628d89 100644
--- a/bcm4329/src/wl/sys/wl_iw.c
+++ b/bcm4329/src/wl/sys/wl_iw.c
@@ -603,7 +603,7 @@
g_bt->bt_state = BT_DHCP_START;
g_bt->timer_on = 1;
- add_timer(&g_bt->timer);
+ mod_timer(&g_bt->timer, g_bt->timer.expires);
WL_TRACE(("%s enable BT DHCP Timer\n", __FUNCTION__));
}
@@ -618,8 +618,8 @@
WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
if (g_bt->timer_on) {
- del_timer(&g_bt->timer);
g_bt->timer_on = 0;
+ del_timer_sync(&g_bt->timer);
}
@@ -840,7 +840,7 @@
WL_TRACE(("%s\n", __FUNCTION__));
- del_timer(wl_ctl->timer);
+ del_timer_sync(wl_ctl->timer);
up(&wl_ctl->timer_sem);
}
@@ -1789,8 +1789,8 @@
net_os_wake_lock(iscan->dev);
if (iscan->timer_on) {
- del_timer(&iscan->timer);
iscan->timer_on = 0;
+ del_timer_sync(&iscan->timer);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -1853,8 +1853,8 @@
}
if (iscan->timer_on) {
- del_timer(&iscan->timer);
iscan->timer_on = 0;
+ del_timer_sync(&iscan->timer);
}
complete_and_exit(&iscan->sysioc_exited, 0);
@@ -1925,7 +1925,7 @@
}
else {
if (*timer) {
- del_timer(*timer);
+ del_timer_sync(*timer);
kfree(*timer);
*timer = NULL;
}
@@ -2196,9 +2196,7 @@
&iscan->scan_flag, sizeof(iscan->scan_flag));
wl_iw_set_event_mask(dev);
wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
- del_timer(&iscan->timer);
- iscan->timer.expires = jiffies + iscan->timer_ms*HZ/1000;
- add_timer(&iscan->timer);
+ mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000);
iscan->timer_on = 1;
return 0;
@@ -3854,17 +3852,16 @@
net_os_wake_lock(dev);
if (dwrq->length && extra) {
+ if (strnicmp(extra, "START", strlen("START")) == 0) {
+ wl_iw_control_wl_on(dev, info);
+ WL_TRACE(("%s, Received regular START command\n", __FUNCTION__));
+ }
+
if (g_onoff == G_WLAN_SET_OFF) {
- if (strnicmp(extra, "START", strlen("START")) != 0) {
- WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__));
- kfree(extra);
- net_os_wake_unlock(dev);
- return -EFAULT;
- }
- else {
- wl_iw_control_wl_on(dev, info);
- WL_TRACE(("%s, Received regular START command\n", __FUNCTION__));
- }
+ WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__));
+ kfree(extra);
+ net_os_wake_unlock(dev);
+ return -EFAULT;
}
if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) {
@@ -4579,16 +4576,15 @@
net_os_wake_lock(g_bt->dev);
if (g_bt->timer_on) {
- del_timer(&g_bt->timer);
g_bt->timer_on = 0;
+ del_timer_sync(&g_bt->timer);
}
switch (g_bt->bt_state) {
case BT_DHCP_START:
g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW;
- mod_timer(&g_bt->timer, jiffies + \
- BT_DHCP_OPPORTUNITY_WINDOW_TIEM*HZ/1000);
+ mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIEM*HZ/1000);
g_bt->timer_on = 1;
break;
case BT_DHCP_OPPORTUNITY_WINDOW:
@@ -4622,8 +4618,8 @@
}
if (g_bt->timer_on) {
- del_timer(&g_bt->timer);
g_bt->timer_on = 0;
+ del_timer_sync(&g_bt->timer);
}
complete_and_exit(&g_bt->bt_exited, 0);