diff options
| author | Hanumanth Reddy Pothula <c_hpothu@codeaurora.org> | 2016-12-27 19:32:14 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-30 02:50:39 -0800 |
| commit | 96d1c0d166acc8844524ce65b3bfc58cd9641d44 (patch) | |
| tree | eb14b57df00fd139acdc285045c7e5bbd3cfb8b8 | |
| parent | 19537ac7bff73e669f0bfb68f2ae333228820e70 (diff) | |
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
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx_queue.c | 8 |
1 files 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); } } |
