From 3fda7727954f6c17fcaef2f8fc118c680f8ee9ab Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Mon, 17 Sep 2018 14:22:18 +0800 Subject: [PATCH 1/3] scheduler: chagne ipc process task priority Lower IPC process task priority to run the process with lower level interrupt. Signed-off-by: Pan Xiuli --- src/include/sof/schedule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/sof/schedule.h b/src/include/sof/schedule.h index 5629c7defad4..8ee85b102703 100644 --- a/src/include/sof/schedule.h +++ b/src/include/sof/schedule.h @@ -56,7 +56,7 @@ struct sof; #define TASK_PRI_MED 0 #define TASK_PRI_HIGH -20 -#define TASK_PRI_IPC 1 +#define TASK_PRI_IPC 6 /* maximun task time slice in microseconds */ #define SCHEDULE_TASK_MAX_TIME_SLICE 5000 From b970e802d2f69f291f49728c1c170244fa76d105 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Mon, 17 Sep 2018 14:22:32 +0800 Subject: [PATCH 2/3] task: clear interrupt earlier list_item_for_safe is safe for item deletion, but when a new item is appended to the list. It seems the item could not be go through. To fix this limitation, move interrupt clear to make sure every IRQ is handled. Do not try to handle two task with one IRQ handler. Signed-off-by: Pan Xiuli --- src/arch/xtensa/task.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/xtensa/task.c b/src/arch/xtensa/task.c index 38f8b4a0e17c..fd50d68608de 100644 --- a/src/arch/xtensa/task.c +++ b/src/arch/xtensa/task.c @@ -116,6 +116,7 @@ static void _irq_task(void *arg) uint32_t flags; spin_lock_irq(&irq_task->lock, flags); + interrupt_clear(irq_task->irq); list_for_item_safe(clist, tlist, &irq_task->list) { task = container_of(clist, struct task, irq_list); @@ -130,7 +131,6 @@ static void _irq_task(void *arg) spin_lock_irq(&irq_task->lock, flags); } - interrupt_clear(irq_task->irq); spin_unlock_irq(&irq_task->lock, flags); } From 380c067e314cab3a81cdf0deaa4838489feb9727 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Tue, 18 Sep 2018 11:44:10 +0800 Subject: [PATCH 3/3] scheduler: refine schedule_edf function to handle multiple task There will be new task added in schedule_edf function, refine the function to handle multiple task. Signed-off-by: Pan Xiuli --- src/lib/schedule.c | 56 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/lib/schedule.c b/src/lib/schedule.c index 85e1be598c4f..5500099871eb 100644 --- a/src/lib/schedule.c +++ b/src/lib/schedule.c @@ -103,13 +103,9 @@ static inline struct task *edf_get_next(uint64_t current, uint64_t delta; uint64_t deadline; int reschedule = 0; - uint32_t flags; - spin_lock_irq(&sch->lock, flags); - /* any tasks in the scheduler ? */ if (list_is_empty(&sch->list)) { - spin_unlock_irq(&sch->lock, flags); return NULL; } @@ -160,7 +156,6 @@ static inline struct task *edf_get_next(uint64_t current, } } - spin_unlock_irq(&sch->lock, flags); return next_task; } @@ -187,35 +182,40 @@ static struct task *schedule_edf(void) tracev_pipe("edf"); - /* get the current time */ - current = platform_timer_get(platform_timer); - - /* get next task to be scheduled */ - task = edf_get_next(current, NULL); - interrupt_clear(PLATFORM_SCHEDULE_IRQ); - /* any tasks ? */ - if (task == NULL) - return NULL; + while (!list_is_empty(&sch->list)) { + spin_lock_irq(&sch->lock, flags); - /* can task be started now ? */ - if (task->start > current) { - /* no, then schedule wake up */ - future_task = task; - } else { - /* yes, run current task */ - task->start = current; + /* get the current time */ + current = platform_timer_get(platform_timer); - /* init task for running */ - wait_init(&task->complete); - spin_lock_irq(&sch->lock, flags); - task->state = TASK_STATE_RUNNING; - list_item_del(&task->list); + /* get next task to be scheduled */ + task = edf_get_next(current, NULL); spin_unlock_irq(&sch->lock, flags); - /* now run task at correct run level */ - arch_run_task(task); + /* any tasks ? */ + if (!task) + return NULL; + + /* can task be started now ? */ + if (task->start <= current) { + /* yes, run current task */ + task->start = current; + + /* init task for running */ + spin_lock_irq(&sch->lock, flags); + task->state = TASK_STATE_RUNNING; + list_item_del(&task->list); + spin_unlock_irq(&sch->lock, flags); + + /* now run task at correct run level */ + arch_run_task(task); + } else { + /* no, then schedule wake up */ + future_task = task; + break; + } } /* tell caller about future task */