Module: xenomai-3
Branch: wip/drivers
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

Reply via email to