From 96d1c0d166acc8844524ce65b3bfc58cd9641d44 Mon Sep 17 00:00:00 2001 From: Hanumanth Reddy Pothula Date: Tue, 27 Dec 2016 19:32:14 +0530 Subject: qcacld-2.0: Mitigate timer race condition As part of thermal throttling, tx_throttle.phase_timer is being started as part of ioctl setTmLevel. Upon timer expiry, the timer handler is again restarting the phase timer. This situation can lead to phase timer being started twice leading to a kernel BUG and subsequent crash. To mitigate this, convert adf_os_timer_start to adf_os_timer_mod which won't start the timer again rather updates timer value. Change-Id: I1db5a70b67f5c649bf9ccb13d9082addc56b01a0 CRs-Fixed: 1104058 --- CORE/CLD_TXRX/TXRX/ol_tx_queue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c index 280287afe92a..fa632e0fcce0 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -1209,7 +1209,7 @@ void ol_tx_pdev_throttle_phase_timer(void *context) if (pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0) { TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "start timer %d ms\n", ms); - adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms); } } } @@ -1229,7 +1229,7 @@ void ol_tx_pdev_throttle_phase_timer(void *context) ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase]; if (pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0) { TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "start timer %d ms\n", ms); - adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms); } } } @@ -1268,7 +1268,7 @@ void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, int level) ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_OFF]; /* pause all */ ol_txrx_throttle_pause(pdev); - adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms); } else { pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_ON; ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_ON]; @@ -1283,7 +1283,7 @@ void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, int level) ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_OFF]; adf_os_timer_cancel(&pdev->tx_throttle.phase_timer); - adf_os_timer_start(&pdev->tx_throttle.phase_timer, ms); + adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms); } } -- cgit v1.2.3