Module: xenomai-forge
Branch: master
Commit: d1b48233f6373cadaaef06091cd985dd48e61794
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=d1b48233f6373cadaaef06091cd985dd48e61794

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Feb 13 11:40:53 2014 +0100

cobalt/timer: sanitize IPI setup

Some configurations may exclude CPU0 from the realtime CPU set, so
installing the timer IPI only when CPU0 is set up for realtime
processing won't work.

---

 include/cobalt/kernel/timer.h |   11 +++++++++++
 kernel/cobalt/init.c          |   26 ++++++++++++++++++--------
 kernel/cobalt/timer.c         |   30 +++++++++++++-----------------
 3 files changed, 42 insertions(+), 25 deletions(-)

diff --git a/include/cobalt/kernel/timer.h b/include/cobalt/kernel/timer.h
index 21d4863..3c04cd0 100644
--- a/include/cobalt/kernel/timer.h
+++ b/include/cobalt/kernel/timer.h
@@ -433,12 +433,23 @@ void xntimer_migrate(struct xntimer *timer, struct 
xnsched *sched)
                __xntimer_migrate(timer, sched);
 }
 
+int xntimer_setup_ipi(void);
+
+void xntimer_release_ipi(void);
+
 #else /* ! CONFIG_SMP */
 
 static inline void xntimer_migrate(struct xntimer *timer,
                                   struct xnsched *sched)
 { }
 
+static inline int xntimer_setup_ipi(void)
+{
+       return 0;
+}
+
+static inline void xntimer_release_ipi(void) { }
+
 #endif /* CONFIG_SMP */
 
 static inline void xntimer_set_sched(struct xntimer *timer,
diff --git a/kernel/cobalt/init.c b/kernel/cobalt/init.c
index 89df1ef..4062f84 100644
--- a/kernel/cobalt/init.c
+++ b/kernel/cobalt/init.c
@@ -86,6 +86,8 @@ static void disable_timesource(void)
        for_each_realtime_cpu(cpu)
                xntimer_release_hardware(cpu);
 
+       xntimer_release_ipi();
+
 #ifdef CONFIG_XENO_OPT_STATS
        xnintr_destroy(&nktimer);
 #endif /* CONFIG_XENO_OPT_STATS */
@@ -235,8 +237,8 @@ static __init void mach_cleanup(void)
 
 static __init int enable_timesource(void)
 {
-       int htickval, cpu, _cpu;
        struct xnsched *sched;
+       int ret, cpu, _cpu;
        spl_t s;
 
        trace_mark(xn_nucleus, enable_timesource, MARK_NOARGS);
@@ -254,14 +256,19 @@ static __init int enable_timesource(void)
                xnclock_get_host_time() - xnclock_read_monotonic(&nkclock);
        nkvdso->wallclock_offset = nkclock.wallclock_offset;
 
+       ret = xntimer_setup_ipi();
+       if (ret)
+               return ret;
+
        for_each_realtime_cpu(cpu) {
-               htickval = xntimer_grab_hardware(cpu);
-               if (htickval < 0)
+               ret = xntimer_grab_hardware(cpu);
+               if (ret < 0)
                        goto fail;
 
                xnlock_get_irqsave(&nklock, s);
 
-               /* If the current tick device for the target CPU is
+               /*
+                * If the current tick device for the target CPU is
                 * periodic, we won't be called back for host tick
                 * emulation. Therefore, we need to start a periodic
                 * nucleus timer which will emulate the ticking for
@@ -285,9 +292,10 @@ static __init int enable_timesource(void)
                 */
 
                sched = xnsched_struct(cpu);
-               if (htickval > 1)
-                       xntimer_start(&sched->htimer, htickval, htickval, 
XN_RELATIVE);
-               else if (htickval == 1)
+               /* Set up timer with host tick period if valid. */
+               if (ret > 1)
+                       xntimer_start(&sched->htimer, ret, ret, XN_RELATIVE);
+               else if (ret == 1)
                        xntimer_start(&sched->htimer, 0, 0, XN_RELATIVE);
 
 #ifdef CONFIG_XENO_OPT_WATCHDOG
@@ -312,7 +320,9 @@ fail:
                xntimer_release_hardware(_cpu);
        }
 
-       return htickval;
+       xntimer_release_ipi();
+
+       return ret;
 }
 
 static __init int sys_init(void)
diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c
index e50c7be..5501962 100644
--- a/kernel/cobalt/timer.c
+++ b/kernel/cobalt/timer.c
@@ -501,6 +501,19 @@ void __xntimer_migrate(struct xntimer *timer, struct 
xnsched *sched)
 }
 EXPORT_SYMBOL_GPL(__xntimer_migrate);
 
+int xntimer_setup_ipi(void)
+{
+       return ipipe_request_irq(&xnarch_machdata.domain,
+                                IPIPE_HRTIMER_IPI,
+                                (ipipe_irq_handler_t)xnintr_core_clock_handler,
+                                NULL, NULL);
+}
+
+void xntimer_release_ipi(void)
+{
+       ipipe_free_irq(&xnarch_machdata.domain, IPIPE_HRTIMER_IPI);
+}
+
 #endif /* CONFIG_SMP */
 
 /**
@@ -728,19 +741,6 @@ int xntimer_grab_hardware(int cpu)
                return ret;
        }
 
-#ifdef CONFIG_SMP
-       if (cpu == 0) {
-               ret = ipipe_request_irq(&xnarch_machdata.domain,
-                                       IPIPE_HRTIMER_IPI,
-                                       
(ipipe_irq_handler_t)xnintr_core_clock_handler,
-                                       NULL, NULL);
-               if (ret) {
-                       ipipe_timer_stop(cpu);
-                       return ret;
-               }
-       }
-#endif
-
        return tickval;
 }
 
@@ -760,10 +760,6 @@ int xntimer_grab_hardware(int cpu)
 void xntimer_release_hardware(int cpu)
 {
        ipipe_timer_stop(cpu);
-#ifdef CONFIG_SMP
-       if (cpu == 0)
-               ipipe_free_irq(&xnarch_machdata.domain, IPIPE_HRTIMER_IPI);
-#endif /* CONFIG_SMP */
 }
 
 #ifdef CONFIG_XENO_OPT_VFILE


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to