qcacmn: Disable CE-IRQ interrupt before cleaning up the tasklets
Current driver calls ce_tasklet_kill API which does tasklet_disable() first and then does tasklet_kill which invites race condition as follows. 1) Lets say CPU-0 is executing ce_tasklet_kill() API for CE1 (in process ctx) to kill any tasklets associated with CE1-IRQ 2) t1 time- CPU-1 has scheduled the tasklet as part of rescheduled API ce_schedule_tasklet(), so this tasklet goes to be scheduled list of kernel. 3) t2 time- CPU-0 executes tasklet_disable() and about to execute tasklet_kill() 4) t3 time - kernel got a chance and wants to run the tasklet which was scheduled at t1 time but it can't because t2 time, tasklet has been disable. 5) t5 time- CPU-0 now executes tasklet_kill which checks if any tasklet which is in "SCHEDULE" state to go to "RUNNING" state and finish and tasklet on CPU-1 can't go to "RUNNING" state due to tasklet_disable(), driver is stuck waiting for it to finish. Fix the situation by removing tasklet_disable() Change-Id: I3ac56975dc1f6538962060dd20e881c43e7516ca CRs-Fixed: 2301368
This commit is contained in:

zatwierdzone przez
nshrivas

rodzic
7d991b3f72
commit
287dee3f43
@@ -239,7 +239,7 @@ void ce_tasklet_kill(struct hif_softc *scn)
|
||||
|
||||
work_initialized = false;
|
||||
|
||||
for (i = 0; i < CE_COUNT_MAX; i++)
|
||||
for (i = 0; i < CE_COUNT_MAX; i++) {
|
||||
if (hif_ce_state->tasklets[i].inited) {
|
||||
hif_ce_state->tasklets[i].inited = false;
|
||||
/*
|
||||
@@ -251,9 +251,9 @@ void ce_tasklet_kill(struct hif_softc *scn)
|
||||
* tasklet_disable() will take care of that.
|
||||
*/
|
||||
cancel_work_sync(&tasklet_workers[i].work);
|
||||
tasklet_disable(&hif_ce_state->tasklets[i].intr_tq);
|
||||
tasklet_kill(&hif_ce_state->tasklets[i].intr_tq);
|
||||
}
|
||||
}
|
||||
qdf_atomic_set(&scn->active_tasklet_cnt, 0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user