qcacmn: Update the mc timer state after its deleted
Currently qdf mc timer stop api updates mc timer state to QDF_TIMER_STATE_STOPPED before it deletes the timer which may lead to race condition where if any other thread tries to read the state of the timer and re-start the timer considering it is stopped which may get deleted after that. To address above issue, update the timer state after timer delete. Change-Id: I302b89bdedf23f8277eacb6d42b5bd8e6daa4d05 CRs-Fixed: 2643254
This commit is contained in:

committed by
nshrivas

parent
c50efb4f56
commit
18d4b6fe84
@@ -100,21 +100,27 @@ qdf_export_symbol(qdf_try_allowing_sleep);
|
|||||||
*/
|
*/
|
||||||
QDF_TIMER_STATE qdf_mc_timer_get_current_state(qdf_mc_timer_t *timer)
|
QDF_TIMER_STATE qdf_mc_timer_get_current_state(qdf_mc_timer_t *timer)
|
||||||
{
|
{
|
||||||
|
QDF_TIMER_STATE timer_state = QDF_TIMER_STATE_UNUSED;
|
||||||
|
|
||||||
if (!timer) {
|
if (!timer) {
|
||||||
QDF_ASSERT(0);
|
QDF_ASSERT(0);
|
||||||
return QDF_TIMER_STATE_UNUSED;
|
return timer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qdf_spin_lock_irqsave(&timer->platform_info.spinlock);
|
||||||
|
|
||||||
switch (timer->state) {
|
switch (timer->state) {
|
||||||
case QDF_TIMER_STATE_STOPPED:
|
case QDF_TIMER_STATE_STOPPED:
|
||||||
case QDF_TIMER_STATE_STARTING:
|
case QDF_TIMER_STATE_STARTING:
|
||||||
case QDF_TIMER_STATE_RUNNING:
|
case QDF_TIMER_STATE_RUNNING:
|
||||||
case QDF_TIMER_STATE_UNUSED:
|
case QDF_TIMER_STATE_UNUSED:
|
||||||
return timer->state;
|
timer_state = timer->state;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
QDF_ASSERT(0);
|
QDF_ASSERT(0);
|
||||||
return QDF_TIMER_STATE_UNUSED;
|
|
||||||
}
|
}
|
||||||
|
qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock);
|
||||||
|
return timer_state;
|
||||||
}
|
}
|
||||||
qdf_export_symbol(qdf_mc_timer_get_current_state);
|
qdf_export_symbol(qdf_mc_timer_get_current_state);
|
||||||
|
|
||||||
@@ -741,12 +747,14 @@ QDF_STATUS qdf_mc_timer_stop(qdf_mc_timer_t *timer)
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer->state = QDF_TIMER_STATE_STOPPED;
|
|
||||||
|
|
||||||
qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock);
|
qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock);
|
||||||
|
|
||||||
del_timer(&(timer->platform_info.timer));
|
del_timer(&(timer->platform_info.timer));
|
||||||
|
|
||||||
|
qdf_spin_lock_irqsave(&timer->platform_info.spinlock);
|
||||||
|
timer->state = QDF_TIMER_STATE_STOPPED;
|
||||||
|
qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock);
|
||||||
|
|
||||||
qdf_try_allowing_sleep(timer->type);
|
qdf_try_allowing_sleep(timer->type);
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
|
Reference in New Issue
Block a user