瀏覽代碼

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
Ashish Kumar Dhanotiya 5 年之前
父節點
當前提交
18d4b6fe84
共有 1 個文件被更改,包括 13 次插入5 次删除
  1. 13 5
      qdf/linux/src/qdf_mc_timer.c

+ 13 - 5
qdf/linux/src/qdf_mc_timer.c

@@ -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 timer_state = QDF_TIMER_STATE_UNUSED;
+
 	if (!timer) {
 		QDF_ASSERT(0);
-		return QDF_TIMER_STATE_UNUSED;
+		return timer_state;
 	}
 
+	qdf_spin_lock_irqsave(&timer->platform_info.spinlock);
+
 	switch (timer->state) {
 	case QDF_TIMER_STATE_STOPPED:
 	case QDF_TIMER_STATE_STARTING:
 	case QDF_TIMER_STATE_RUNNING:
 	case QDF_TIMER_STATE_UNUSED:
-		return timer->state;
+		timer_state = timer->state;
+		break;
 	default:
 		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);
 
@@ -741,12 +747,14 @@ QDF_STATUS qdf_mc_timer_stop(qdf_mc_timer_t *timer)
 		return QDF_STATUS_SUCCESS;
 	}
 
-	timer->state = QDF_TIMER_STATE_STOPPED;
-
 	qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock);
 
 	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);
 
 	return QDF_STATUS_SUCCESS;