Jan Kiszka wrote:
> ...
> This patch is an RFC as the following issues need to be resolved:
>
> o The might be parts of I-pipe remaining that make use of
>preemp_disable even over non-root contexts. Philippe indicated the
>PPC PIC code would be one example.
Mmpf, first test, then post. Looks like there are more subtle scenarios
hidden:
> <3>[ 121.256585] I-pipe: Detected illicit call from domain 'Xenomai'
> <4>[ 121.256616] into a service reserved for domain 'Linux' and
> below.
> <4>[ 121.256695] I-pipe tracer log (30 points):
> <4>[ 121.256729] func0 ipipe_trace_panic_freeze+0x8
> (ipipe_check_context+0x36)
> <4>[ 121.256863] func -1 ipipe_check_context+0x9
> (__switch_to+0x34)
> <4>[ 121.256951] func -2 __switch_to+0xe
> (xnpod_schedule+0x69b)
> <4>[ 121.257039] [ 79] gatekee -1-16 xnpod_schedule+0x84
> (xnintr_irq_handler+0xa1)
> <4>[ 121.257129] func -19 xnpod_schedule+0xe
> (xnintr_irq_handler+0xa1)
> <4>[ 121.257213] [ 868] Odometr 19-26 xnpod_resume_thread+0x48
> (xnthread_timeout_handler+0x21)
> <4>[ 121.257448] func -28 xnpod_resume_thread+0xe
> (xnthread_timeout_handler+0x21)
> <4>[ 121.257607] func -30 xnthread_timeout_handler+0x8
> (xntimer_do_tick_aperiodic+0x7b)
> <4>[ 121.257779] func -33 xntimer_do_tick_aperiodic+0xe
> (xnpod_announce_tick+0x17)
> <4>[ 121.257948] func -34 xnpod_announce_tick+0xa
> (xnintr_irq_handler+0x2a)
Namely, __switch_to->__unlazy_fpu->save_init_fpu->preempt_disable.
Philippe, looks like killing the ipipe_preempt_guard is not trivial...
Anyway, attached version 2 of this patch enables both stack dump and
ipipe-backtrace.
Jan
---
arch/i386/kernel/ipipe-root.c |9 ++---
include/linux/ipipe.h |6 ++
include/linux/kernel.h| 16 ++--
include/linux/preempt.h | 11 ++-
kernel/ipipe/Kconfig.debug|9 +
kernel/ipipe/generic.c| 31 +++
6 files changed, 76 insertions(+), 6 deletions(-)
Index: linux-2.6.17.13/include/linux/ipipe.h
===
--- linux-2.6.17.13.orig/include/linux/ipipe.h
+++ linux-2.6.17.13/include/linux/ipipe.h
@@ -694,6 +694,12 @@ int fastcall ipipe_set_ptd(int key,
void fastcall *ipipe_get_ptd(int key);
+#ifdef CONFIG_IPIPE_DEBUG_CONTEXT
+void fastcall ipipe_check_context(struct ipipe_domain *border_ipd);
+#else /* !CONFIG_IPIPE_DEBUG_CONTEXT */
+#define ipipe_check_context(border_ipd) do { } while (0)
+#endif /* CONFIG_IPIPE_DEBUG_CONTEXT */
+
#define local_irq_enable_hw_cond() local_irq_enable_hw()
#define local_irq_disable_hw_cond()local_irq_disable_hw()
#define local_irq_save_hw_cond(flags) local_irq_save_hw(flags)
Index: linux-2.6.17.13/kernel/ipipe/Kconfig.debug
===
--- linux-2.6.17.13.orig/kernel/ipipe/Kconfig.debug
+++ linux-2.6.17.13/kernel/ipipe/Kconfig.debug
@@ -2,6 +2,15 @@ config IPIPE_DEBUG
bool "I-pipe debugging"
depends on IPIPE
+config IPIPE_DEBUG_CONTEXT
+ bool "Check for illicit cross-domain calls"
+ depends on IPIPE_DEBUG
+ ---help---
+ Enable this feature to arm checkpoints in the kernel that
+ verify the correct invocation context. On entry of critical
+ Linux services a warning is issued if the caller is not
+ running over the root domain.
+
config IPIPE_TRACE
bool "Latency tracing"
depends on IPIPE_DEBUG
Index: linux-2.6.17.13/kernel/ipipe/generic.c
===
--- linux-2.6.17.13.orig/kernel/ipipe/generic.c
+++ linux-2.6.17.13/kernel/ipipe/generic.c
@@ -29,6 +29,9 @@
#ifdef CONFIG_PROC_FS
#include
#endif /* CONFIG_PROC_FS */
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+#include
+#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
MODULE_DESCRIPTION("I-pipe");
MODULE_LICENSE("GPL");
@@ -410,6 +413,34 @@ void fastcall *ipipe_get_ptd (int key)
return current->ptd[key];
}
+#ifdef CONFIG_IPIPE_DEBUG_CONTEXT
+void fastcall ipipe_check_context(struct ipipe_domain *border_ipd)
+{
+ static int check_hit;
+
+ if (likely(ipipe_current_domain->priority <= border_ipd->priority) ||
+ check_hit)
+ return;
+
+ check_hit = 1;
+
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+ ipipe_trace_panic_freeze();
+#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
+ ipipe_set_printk_sync(ipipe_current_domain);
+ printk(KERN_ERR "I-pipe: Detected illicit call from domain '%s'\n"
+ KERN_ERR "into a service reserved for domain '%s' and "
+ "below.\n",
+ ipipe_current_domain->name, border_ipd->name);
+ show_stack(NULL, NULL);
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+ ipipe_