mirror of https://github.com/thesofproject/sof.git
zephyr: fix a race in LL-scheduler
If a timer interrupt happens before the scheduler thread suspends, it will be missed. Use a semaphore to count interrupts as they occur. BugLink: https://github.com/thesofproject/sof/issues/4306 Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
parent
91467d0924
commit
1eabb71264
|
@ -63,6 +63,7 @@ struct zephyr_domain_thread {
|
|||
|
||||
struct zephyr_domain {
|
||||
struct k_timer timer;
|
||||
struct k_sem sem;
|
||||
struct timer *ll_timer;
|
||||
struct zephyr_domain_thread domain_thread[CONFIG_CORE_COUNT];
|
||||
struct ll_schedule_domain *ll_domain;
|
||||
|
@ -76,7 +77,7 @@ static void zephyr_domain_thread_fn(void *p1, void *p2, void *p3)
|
|||
|
||||
for (;;) {
|
||||
/* immediately go to sleep, waiting to be woken up by the timer */
|
||||
k_thread_suspend(_current);
|
||||
k_sem_take(&zephyr_domain->sem, K_FOREVER);
|
||||
|
||||
dt->handler(dt->arg);
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ static void zephyr_domain_timer_fn(struct k_timer *timer)
|
|||
|
||||
for (core = 0; core < CONFIG_CORE_COUNT; core++)
|
||||
if (zephyr_domain->domain_thread[core].handler)
|
||||
k_wakeup(&zephyr_domain->domain_thread[core].ll_thread);
|
||||
k_sem_give(&zephyr_domain->sem);
|
||||
}
|
||||
|
||||
static int zephyr_domain_register(struct ll_schedule_domain *domain,
|
||||
|
@ -195,6 +196,8 @@ struct ll_schedule_domain *timer_domain_init(struct timer *timer, int clk)
|
|||
|
||||
zephyr_domain->ll_timer = timer;
|
||||
zephyr_domain->ll_domain = domain;
|
||||
/* 10 is rather random, we better not accumulate 10 missed timer interrupts */
|
||||
k_sem_init(&zephyr_domain->sem, 0, 10);
|
||||
|
||||
ll_sch_domain_set_pdata(domain, zephyr_domain);
|
||||
|
||||
|
|
Loading…
Reference in New Issue