Module: xenomai-head
Branch: master
Commit: 8b492681e8f10434fbdd4eca995a32d49bf3ebc7
URL:
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=8b492681e8f10434fbdd4eca995a32d49bf3ebc7
Author: Philippe Gerum
Date: Thu Apr 7 16:49:20 2011 +0200
hal/generic: fix APC trampoline call over -rt kernel
---
ksrc/arch/generic/hal.c | 53 +-
1 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/ksrc/arch/generic/hal.c b/ksrc/arch/generic/hal.c
index b5f5040..f7c5ddb 100644
--- a/ksrc/arch/generic/hal.c
+++ b/ksrc/arch/generic/hal.c
@@ -414,6 +414,55 @@ static void rthal_apc_handler(unsigned virq, void *arg)
rthal_spin_unlock(&rthal_apc_lock);
}
+#ifdef CONFIG_PREEMPT_RT
+
+/* On PREEMPT_RT, we need to invoke the apc handlers over a process
+ context, so that the latter can access non-atomic kernel services
+ properly. So the Adeos virq is only used to kick a per-CPU apc
+ server process which in turns runs the apc dispatcher. A bit
+ twisted, but indeed consistent with the threaded IRQ model of
+ PREEMPT_RT. */
+
+#include
+
+static struct task_struct *rthal_apc_servers[RTHAL_NR_CPUS];
+
+static int rthal_apc_thread(void *data)
+{
+unsigned cpu = (unsigned)(unsigned long)data;
+
+set_cpus_allowed(current, cpumask_of_cpu(cpu));
+sigfillset(¤t->blocked);
+current->flags |= PF_NOFREEZE;
+/* Use highest priority here, since some apc handlers might
+ require to run as soon as possible after the request has been
+ pended. */
+rthal_setsched_root(current, SCHED_FIFO, MAX_RT_PRIO - 1);
+
+while (!kthread_should_stop()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ rthal_apc_handler(0, NULL);
+}
+
+__set_current_state(TASK_RUNNING);
+
+return 0;
+}
+
+void rthal_apc_kicker(unsigned virq, void *cookie)
+{
+wake_up_process(rthal_apc_servers[smp_processor_id()]);
+}
+
+#define rthal_apc_trampoline rthal_apc_kicker
+
+#else /* !CONFIG_PREEMPT_RT */
+
+#define rthal_apc_trampoline rthal_apc_handler
+
+#endif /* CONFIG_PREEMPT_RT */
+
/**
* @fn int rthal_apc_alloc (const char *name,void (*handler)(void
*cookie),void *cookie)
*
@@ -502,7 +551,7 @@ out:
void rthal_apc_free(int apc)
{
BUG_ON(apc < 0 || apc >= RTHAL_NR_APCS);
-clear_bit(apc, &rthal_apc_map);
+ clear_bit(apc, &rthal_apc_map);
}
int rthal_init(void)
@@ -578,7 +627,7 @@ int rthal_init(void)
#endif
printk(KERN_ERR "Xenomai: Domain registration failed (%d).\n", err);
-goto fail;
+ goto fail;
}
return 0;
___
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git