Module: xenomai-3 Branch: stable-3.0.x Commit: 9b8d7c947089dfb0b3ca4b6f1e17a989ddc9a3e4 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=9b8d7c947089dfb0b3ca4b6f1e17a989ddc9a3e4
Author: Philippe Gerum <r...@xenomai.org> Date: Sat Nov 12 11:56:09 2016 +0100 cobalt/timer: fixup CPU affinity mismatch at init Since recently, POSIX timers can be backed by external clock devices. Unlike the core clock, some of those devices may be ticking only on a restricted set of CPUs, compared to the broader real-time CPU set. This may lead to an affinity mismatch between a thread creating a timer, and the CPU set that can receive timer events from the backing device. When this happens, warning on detecting such issue while initializing the timer without fixing up the situation is not of a great help. It is better to pick a CPU which is a member of the clock affinity set and make such timer affine to it instead. In such a case, the overhead induced by rescheduling a remote thread upon timer expiry is acceptable compared to leaving a thread waiting indefinitely for timer events that will never come. --- include/cobalt/kernel/timer.h | 2 -- kernel/cobalt/sched.c | 6 +++--- kernel/cobalt/thread.c | 2 -- kernel/cobalt/timer.c | 30 ++++++++---------------------- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/include/cobalt/kernel/timer.h b/include/cobalt/kernel/timer.h index d92c8c8..6cb2bb3 100644 --- a/include/cobalt/kernel/timer.h +++ b/include/cobalt/kernel/timer.h @@ -56,8 +56,6 @@ typedef enum xntmode { #define XNTIMER_GRAVITY_MASK (XNTIMER_KGRAVITY|XNTIMER_UGRAVITY) #define XNTIMER_INIT_MASK (XNTIMER_GRAVITY_MASK|XNTIMER_NOBLCK) -#define __XNTIMER_CORE 0x10000000 - /* These flags are available to the real-time interfaces */ #define XNTIMER_SPARE0 0x01000000 #define XNTIMER_SPARE1 0x02000000 diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c index 7cb91a5..cbe14bd 100644 --- a/kernel/cobalt/sched.c +++ b/kernel/cobalt/sched.c @@ -194,11 +194,11 @@ void xnsched_init(struct xnsched *sched, int cpu) * exit code. */ xntimer_init(&sched->htimer, &nkclock, NULL, - sched, XNTIMER_IGRAVITY|__XNTIMER_CORE); + sched, XNTIMER_IGRAVITY); xntimer_set_priority(&sched->htimer, XNTIMER_LOPRIO); xntimer_set_name(&sched->htimer, htimer_name); xntimer_init(&sched->rrbtimer, &nkclock, roundrobin_handler, - sched, XNTIMER_IGRAVITY|__XNTIMER_CORE); + sched, XNTIMER_IGRAVITY); xntimer_set_name(&sched->rrbtimer, rrbtimer_name); xntimer_set_priority(&sched->rrbtimer, XNTIMER_LOPRIO); @@ -213,7 +213,7 @@ void xnsched_init(struct xnsched *sched, int cpu) #ifdef CONFIG_XENO_OPT_WATCHDOG xntimer_init(&sched->wdtimer, &nkclock, watchdog_handler, - sched, XNTIMER_NOBLCK|XNTIMER_IGRAVITY|__XNTIMER_CORE); + sched, XNTIMER_NOBLCK|XNTIMER_IGRAVITY); xntimer_set_name(&sched->wdtimer, "[watchdog]"); xntimer_set_priority(&sched->wdtimer, XNTIMER_LOPRIO); #endif /* CONFIG_XENO_OPT_WATCHDOG */ diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c index fb856a4..34eca35 100644 --- a/kernel/cobalt/thread.c +++ b/kernel/cobalt/thread.c @@ -209,8 +209,6 @@ int __xnthread_init(struct xnthread *thread, init_completion(&thread->exited); gravity = flags & XNUSER ? XNTIMER_UGRAVITY : XNTIMER_KGRAVITY; - if (flags & XNROOT) - gravity |= __XNTIMER_CORE; xntimer_init(&thread->rtimer, &nkclock, timeout_handler, sched, gravity); xntimer_set_name(&thread->rtimer, thread->name); diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c index 3563636..dd78c38 100644 --- a/kernel/cobalt/timer.c +++ b/kernel/cobalt/timer.c @@ -349,29 +349,15 @@ void __xntimer_init(struct xntimer *timer, timer->handler = handler; timer->interval_ns = 0; /* - * Timers are affine to a real-time CPU. If no affinity was - * specified, assign the timer to the first possible CPU which - * can receive interrupt events from the clock device attached - * to the reference clock for this timer. + * Unlike common IRQs, timer events are per-CPU by design. If + * the CPU the caller is affine to does not receive timer + * events, or no affinity was specified (i.e. sched == NULL), + * assign the timer to the first possible CPU which can + * receive interrupt events from the clock device backing this + * timer. */ - if (sched) { - /* - * Complain loudly if no tick is expected from the - * clock device on the CPU served by the specified - * scheduler slot. This reveals a CPU affinity - * mismatch between the clock hardware and the client - * code initializing the timer. This check excludes - * core timers which may have their own reason to bind - * to a passive CPU (e.g. host timer). - */ - XENO_WARN_ON_SMP(COBALT, !(flags & __XNTIMER_CORE) && - !cpumask_test_cpu(xnsched_cpu(sched), - &clock->affinity)); - timer->sched = sched; - } else { - cpu = xnclock_get_default_cpu(clock, 0); - timer->sched = xnsched_struct(cpu); - } + cpu = xnclock_get_default_cpu(clock, sched ? xnsched_cpu(sched) : 0); + timer->sched = xnsched_struct(cpu); #ifdef CONFIG_XENO_OPT_STATS #ifdef CONFIG_XENO_OPT_EXTCLOCK _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git