From 5104f5e02df5a720f2896d8403a880cde286f657 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Thu, 4 Feb 2021 10:44:12 +0800 Subject: [PATCH] timer_domain: refine the timer_domain_set() logic Do timer_domain refining as below: Use unified LL_TIMER_SET_OVERHEAD_TICKS=1000 which denote the max overhead that the timer_domain_set() will take, and remove the definition from each platforms. Don't add any overhead if no needed(e.g. if the start > current + overhead). This will help to schedule the task ASAP, and make the catching up (of the previous delay) possible. Signed-off-by: Keyon Jie --- src/include/sof/schedule/ll_schedule_domain.h | 3 +- src/platform/baytrail/platform.c | 3 +- src/platform/haswell/platform.c | 3 +- src/platform/imx8/platform.c | 3 +- src/platform/imx8m/platform.c | 3 +- src/platform/intel/cavs/platform.c | 3 +- src/schedule/timer_domain.c | 28 ++++++++++--------- 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/include/sof/schedule/ll_schedule_domain.h b/src/include/sof/schedule/ll_schedule_domain.h index 68bf16566..d7b41a17f 100644 --- a/src/include/sof/schedule/ll_schedule_domain.h +++ b/src/include/sof/schedule/ll_schedule_domain.h @@ -165,8 +165,7 @@ static inline bool domain_is_pending(struct ll_schedule_domain *domain, return ret; } -struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk, - uint64_t timeout); +struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk); struct ll_schedule_domain *dma_multi_chan_domain_init(struct dma *dma_array, uint32_t num_dma, int clk, diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index c0e54fb3e..863b077af 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -219,8 +219,7 @@ int platform_init(struct sof *sof) /* init low latency timer domain and scheduler */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); /* init the system agent */ diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c index 6bcd0e368..857a6e223 100644 --- a/src/platform/haswell/platform.c +++ b/src/platform/haswell/platform.c @@ -192,8 +192,7 @@ int platform_init(struct sof *sof) /* init low latency timer domain and scheduler */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); /* init the system agent */ diff --git a/src/platform/imx8/platform.c b/src/platform/imx8/platform.c index aa3cd0a68..da86a3179 100644 --- a/src/platform/imx8/platform.c +++ b/src/platform/imx8/platform.c @@ -158,8 +158,7 @@ int platform_init(struct sof *sof) /* init low latency domains and schedulers */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); platform_timer_start(sof->platform_timer); diff --git a/src/platform/imx8m/platform.c b/src/platform/imx8m/platform.c index e57fb8407..238a6ebc1 100644 --- a/src/platform/imx8m/platform.c +++ b/src/platform/imx8m/platform.c @@ -157,8 +157,7 @@ int platform_init(struct sof *sof) /* init low latency domains and schedulers */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); platform_timer_start(sof->platform_timer); diff --git a/src/platform/intel/cavs/platform.c b/src/platform/intel/cavs/platform.c index 098deddf6..c5b5762c2 100644 --- a/src/platform/intel/cavs/platform.c +++ b/src/platform/intel/cavs/platform.c @@ -386,8 +386,7 @@ int platform_init(struct sof *sof) /* init low latency timer domain and scheduler */ sof->platform_timer_domain = - timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK, - CONFIG_SYSTICK_PERIOD); + timer_domain_init(sof->platform_timer, PLATFORM_DEFAULT_CLOCK); scheduler_init_ll(sof->platform_timer_domain); /* init the system agent */ diff --git a/src/schedule/timer_domain.c b/src/schedule/timer_domain.c index 1d6a22320..9df53e9ca 100644 --- a/src/schedule/timer_domain.c +++ b/src/schedule/timer_domain.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,8 @@ K_THREAD_STACK_DEFINE(ll_workq_stack3, ZEPHYR_LL_WORKQ_SIZE); #endif #endif +#define LL_TIMER_SET_OVERHEAD_TICKS 1000 /* overhead/delay to set the tick, in ticks */ + struct timer_domain { #ifdef __ZEPHYR__ struct k_work_q ll_workq[CONFIG_CORE_COUNT]; @@ -60,7 +63,7 @@ struct timer_domain { #endif struct timer *timer; void *arg[CONFIG_CORE_COUNT]; - uint64_t timeout; /* in microseconds */ + uint64_t timeout; /* in ticks */ }; #ifdef __ZEPHYR__ @@ -228,11 +231,13 @@ static void timer_domain_disable(struct ll_schedule_domain *domain, int core) static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start) { struct timer_domain *timer_domain = ll_sch_domain_get_pdata(domain); - uint64_t ticks_tout = domain->ticks_per_ms * timer_domain->timeout / - 1000; + uint64_t ticks_tout = timer_domain->timeout; uint64_t ticks_set; #ifndef __ZEPHYR__ - uint64_t ticks_req = start + ticks_tout; + uint64_t ticks_req; + + /* make sure to require for ticks later than tout from now */ + ticks_req = MAX(start, platform_timer_get_atomic(timer_domain->timer) + ticks_tout); ticks_set = platform_timer_set(timer_domain->timer, ticks_req); #else @@ -276,6 +281,10 @@ static void timer_domain_set(struct ll_schedule_domain *domain, uint64_t start) current - current % CYC_PER_TICK; #endif + tr_dbg(&ll_tr, "timer_domain_set(): ticks_set %u ticks_req %u current %u", + (unsigned int)ticks_set, (unsigned int)ticks_req, + (unsigned int)platform_timer_get_atomic(timer_get())); + /* Was timer set to the value we requested? If no it means some * delay occurred and we should report that in error log. */ @@ -305,24 +314,17 @@ static bool timer_domain_is_pending(struct ll_schedule_domain *domain, return task->start <= platform_timer_get_atomic(timer_get()); } -struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk, - uint64_t timeout) +struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk) { struct ll_schedule_domain *domain; struct timer_domain *timer_domain; - if (timeout <= UINT_MAX) - tr_info(&ll_tr, "timer_domain_init clk %d timeout %u", clk, - (unsigned int)timeout); - else - tr_info(&ll_tr, "timer_domain_init clk %d timeout > %u", clk, UINT_MAX); - domain = domain_init(SOF_SCHEDULE_LL_TIMER, clk, false, &timer_domain_ops); timer_domain = rzalloc(SOF_MEM_ZONE_SYS_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*timer_domain)); timer_domain->timer = timer; - timer_domain->timeout = timeout; + timer_domain->timeout = LL_TIMER_SET_OVERHEAD_TICKS; ll_sch_domain_set_pdata(domain, timer_domain);