Skip to content

Commit 20acc16

Browse files
tlaudalgirdwood
authored andcommitted
edf_schedule: implement the new version of EDF scheduler
This patch implements the new version of EDF scheduler. This is the first basic implementation, which can be easily extended in the future. Previous implementation had two major flaws: - Tasks could only be preempted based on the interrupt level on which they have been scheduled, so it was limited based on the hardware. - This led to the system not fully utilized, so we could never achieve full EDF functionality. The new implementation uses only one software interrupt and allows for dynamic context switching between different tasks based on the deadline. Also for some cases priority is taken into consideration e.g. for idle and almost idle tasks, which don't have deadline at all and should be executed only if the system is free. All other normal tasks should have the same priority. Task chosen to be run is executed on passive level, so automatically can be preempted by every interrupt. Every task has its own private stack on which current context is saved and restored if needed. Note that main firmware loop is task scheduled with idle priority, so it will be executed only after every other task is completed. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent fe9f9a1 commit 20acc16

File tree

29 files changed

+899
-2017
lines changed

29 files changed

+899
-2017
lines changed

Kconfig

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@ config HOST_PTABLE
3838
bool
3939
default n
4040

41-
config TASK_HAVE_PRIORITY_MEDIUM
42-
bool
43-
default n
44-
45-
config TASK_HAVE_PRIORITY_LOW
46-
bool
47-
default n
48-
4941
config BOOT_LOADER
5042
bool
5143
default n

src/arch/host/include/arch/schedule/task.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,6 @@
1616
#ifndef __ARCH_SCHEDULE_TASK_H__
1717
#define __ARCH_SCHEDULE_TASK_H__
1818

19-
struct task;
20-
21-
/**
22-
* \brief Allocates IRQ tasks.
23-
*/
24-
static inline int arch_allocate_tasks(void)
25-
{
26-
return 0;
27-
}
28-
29-
/**
30-
* \brief Runs task.
31-
* \param[in,out] task Task data.
32-
*/
33-
static inline int arch_run_task(struct task *task)
34-
{
35-
return 0;
36-
}
37-
3819
#endif /* __ARCH_SCHEDULE_TASK_H__ */
3920

4021
#else

src/arch/xtensa/drivers/idc.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <sof/lib/notifier.h>
1919
#include <sof/lib/shim.h>
2020
#include <sof/platform.h>
21+
#include <sof/schedule/edf_schedule.h>
2122
#include <sof/schedule/schedule.h>
2223
#include <sof/schedule/task.h>
2324
#include <ipc/control.h>
@@ -166,6 +167,8 @@ static int idc_pipeline_trigger(uint32_t cmd)
166167
struct ipc *ipc = cache_to_uncache(_ipc);
167168
struct sof_ipc_stream *data = ipc->comp_data;
168169
struct ipc_comp_dev *pcm_dev;
170+
struct edf_task_pdata *edf_pdata;
171+
struct task *task;
169172
int ret;
170173

171174
/* invalidate stream data */
@@ -183,6 +186,17 @@ static int idc_pipeline_trigger(uint32_t cmd)
183186

184187
pipeline_cache(pcm_dev->cd->pipeline,
185188
pcm_dev->cd, CACHE_INVALIDATE);
189+
190+
/* TODO: Temporary W/A for task sharing between cores.
191+
* Should be removed after changing memory management for
192+
* slave cores.
193+
*/
194+
if (pcm_dev->cd->pipeline->pipe_task.type == SOF_SCHEDULE_EDF) {
195+
task = &pcm_dev->cd->pipeline->pipe_task;
196+
edf_pdata = edf_sch_get_pdata(task);
197+
dcache_invalidate_region(edf_pdata, sizeof(*edf_pdata));
198+
task_context_cache(edf_pdata->ctx, CACHE_INVALIDATE);
199+
}
186200
}
187201

188202
/* check whether we are executing from the right core */
@@ -193,9 +207,22 @@ static int idc_pipeline_trigger(uint32_t cmd)
193207
ret = pipeline_trigger(pcm_dev->cd->pipeline, pcm_dev->cd, cmd);
194208

195209
/* writeback pipeline on stop */
196-
if (cmd == COMP_TRIGGER_STOP)
210+
if (cmd == COMP_TRIGGER_STOP) {
211+
/* TODO: Temporary W/A for task sharing between cores.
212+
* Should be removed after changing memory management for
213+
* slave cores.
214+
*/
215+
if (pcm_dev->cd->pipeline->pipe_task.type == SOF_SCHEDULE_EDF) {
216+
task = &pcm_dev->cd->pipeline->pipe_task;
217+
edf_pdata = edf_sch_get_pdata(task);
218+
task_context_cache(edf_pdata->ctx, CACHE_WRITEBACK_INV);
219+
dcache_writeback_invalidate_region(edf_pdata,
220+
sizeof(*edf_pdata));
221+
}
222+
197223
pipeline_cache(pcm_dev->cd->pipeline,
198224
pcm_dev->cd, CACHE_WRITEBACK_INV);
225+
}
199226

200227
return ret;
201228
}

src/arch/xtensa/include/arch/schedule/task.h

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,59 @@
33
* Copyright(c) 2017 Intel Corporation. All rights reserved.
44
*
55
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6+
* Tomasz Lauda <tomasz.lauda@linux.intel.com>
67
*/
78

89
/**
910
* \file arch/xtensa/include/arch/schedule/task.h
1011
* \brief Arch task header file
1112
* \authors Liam Girdwood <liam.r.girdwood@linux.intel.com>
13+
* Tomasz Lauda <tomasz.lauda@linux.intel.com>
1214
*/
1315

1416
#ifdef __SOF_SCHEDULE_TASK_H__
1517

1618
#ifndef __ARCH_SCHEDULE_TASK_H__
1719
#define __ARCH_SCHEDULE_TASK_H__
1820

19-
#include <sof/list.h>
20-
#include <config.h>
21-
22-
/** \brief IRQ task data. */
23-
struct irq_task {
24-
struct list_item list; /**< list of tasks */
25-
int irq; /**< IRQ level */
26-
};
27-
28-
struct sof;
2921
struct task;
3022

31-
#if CONFIG_SMP
32-
33-
/**
34-
* \brief Starts slave core main task.
35-
* \param[in,out] sof Main context.
36-
* \return Error code.
37-
*/
38-
int do_task_slave_core(struct sof *sof);
39-
40-
#endif
41-
4223
/**
43-
* \brief Returns IRQ low task data.
44-
* \return Pointer to pointer of IRQ low task data.
24+
* \brief Returns main task data.
25+
* \return Pointer to pointer of main task data.
4526
*/
46-
struct irq_task **task_irq_low_get(void);
27+
struct task **task_main_get(void);
4728

4829
/**
49-
* \brief Returns IRQ medium task data.
50-
* \return Pointer to pointer of IRQ medium task data.
30+
* \brief Returns current system context.
5131
*/
52-
struct irq_task **task_irq_med_get(void);
32+
volatile void *task_context_get(void);
5333

5434
/**
55-
* \brief Returns IRQ high task data.
56-
* \return Pointer to pointer of IRQ high task data.
35+
* \brief Switches system context.
36+
* \param[in,out] task Task context to be set.
5737
*/
58-
struct irq_task **task_irq_high_get(void);
38+
void task_context_set(void *task_ctx);
5939

6040
/**
61-
* \brief Runs task.
62-
* \param[in,out] task Task data.
41+
* \brief Initializes task context.
42+
* \param[in,out] task Task with context to be initialized.
43+
* \param[in,out] entry Entry point for task execution.
6344
*/
64-
int arch_run_task(struct task *task);
45+
int task_context_init(struct task *task, void *entry);
6546

6647
/**
67-
* \brief Allocates IRQ tasks.
48+
* \brief Frees task context.
49+
* \param[in,out] task Task with context to be freed.
6850
*/
69-
int arch_allocate_tasks(void);
51+
void task_context_free(struct task *task);
7052

7153
/**
72-
* \brief Frees IRQ tasks.
54+
* \brief Performs cache operation on task's context.
55+
* \param[in,out] task_ctx Context to be wtb/inv.
56+
* \param[in] cmd Cache operation to be performed.
7357
*/
74-
void arch_free_tasks(void);
58+
void task_context_cache(void *task_ctx, int cmd);
7559

7660
#endif /* __ARCH_SCHEDULE_TASK_H__ */
7761

src/arch/xtensa/include/arch/sof.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#ifndef __ARCH_SOF_H__
1212
#define __ARCH_SOF_H__
1313

14+
#include <sof/schedule/task.h>
15+
#include <xtensa/xtruntime-frames.h>
16+
#include <stdint.h>
17+
1418
/* entry point to main firmware */
1519
void _ResetVector(void);
1620

@@ -28,6 +32,20 @@ static inline void *arch_get_stack_ptr(void)
2832
return ptr;
2933
}
3034

35+
static inline void *arch_get_stack_entry(void)
36+
{
37+
volatile xtos_task_context *task_ctx = task_context_get();
38+
39+
return task_ctx->stack_base;
40+
}
41+
42+
static inline uint32_t arch_get_stack_size(void)
43+
{
44+
volatile xtos_task_context *task_ctx = task_context_get();
45+
46+
return task_ctx->stack_size;
47+
}
48+
3149
#endif /* __ARCH_SOF_H__ */
3250

3351
#else

src/arch/xtensa/init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ int slave_core_init(struct sof *sof)
130130

131131
trace_point(TRACE_BOOT_PLATFORM);
132132

133-
/* should not return */
134-
err = do_task_slave_core(sof);
133+
/* task initialized in edf_scheduler_init */
134+
schedule_task(*task_main_get(), 0, UINT64_MAX);
135135

136136
return err;
137137
}

0 commit comments

Comments
 (0)