scheduler: check task state prior to completion

High priority IRQ handlers can potentially reschedule tasks prior to task
completion. i.e.

1. Task runs and unmasks high priority IRQ prior to completion.
2. High priority IRQ prempts task context and reschedules task (changing
   task->state).
3. Initial task resumes and then completes (clobbering task->state in 2).

Make sure this flow is supported for high priority IRQ scheduling.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
This commit is contained in:
Liam Girdwood 2018-12-17 16:54:04 +00:00 committed by Liam Girdwood
parent 482abfd232
commit a1e292b082
1 changed files with 20 additions and 1 deletions

View File

@ -343,7 +343,26 @@ void schedule_task_complete(struct task *task)
tracev_pipe("schedule_task_complete()");
spin_lock_irq(&sch->lock, flags);
task->state = TASK_STATE_COMPLETED;
/* Some high priority HW based IRQ handlers can reschedule tasks
* immediately. i.e. before the task context can change task state
* back to COMPLETED. Check here to make sure we dont clobber
* task->state for regular non IRQ users.
*/
switch (task->state) {
case TASK_STATE_RUNNING:
task->state = TASK_STATE_COMPLETED;
break;
case TASK_STATE_QUEUED:
case TASK_STATE_PENDING:
/* nothing to do here, high priority IRQ has scheduled us */
break;
default:
trace_error(TRACE_CLASS_PIPE, "unexpected task state %d at task completion",
task->state);
task->state = TASK_STATE_COMPLETED;
break;
}
spin_unlock_irq(&sch->lock, flags);
/* tell any waiter that task has completed */