[Xenomai-core] [PATCH] Xenomai 2.1: Add SMP timer support for powerpc
Add SMP timer support code for the powerpc arch in Xenomai 2.1. Still a bit rough, but I'll clean it up as I go. Compiled and tested on G5 UP, SMP (I-pipe 2.6.14 0.9-02) and G4 UP (I-pipe 2.6.14 1.0-07). Doesn't seem to break anything. On a G5, SMP seems to bring a 2-3usec latency penalty. -- Heikki Lindholm diff -Nru xenomai/include/asm-powerpc/hal.h xenomai-devel/include/asm-powerpc/hal.h --- xenomai/include/asm-powerpc/hal.h 2005-12-04 12:21:36.0 +0200 +++ xenomai-devel/include/asm-powerpc/hal.h 2005-12-06 13:15:35.0 +0200 @@ -138,6 +138,10 @@ #define RTHAL_TIMER_IRQ ADEOS_TIMER_VIRQ #else /* !CONFIG_ADEOS_CORE */ #define RTHAL_TIMER_IRQ IPIPE_TIMER_VIRQ +#ifdef CONFIG_SMP +#define RTHAL_TIMER_IPIIPIPE_SERVICE_IPI3 +#define RTHAL_HOST_TIMER_IPI IPIPE_SERVICE_IPI4 +#endif /* CONFIG_SMP */ #endif /* CONFIG_ADEOS_CORE */ #define rthal_irq_descp(irq) (irq_desc[(irq)]) @@ -204,7 +208,7 @@ #ifdef CONFIG_40x mtspr(SPRN_PIT,delay); #else /* !CONFIG_40x */ -set_dec(delay); +set_dec((int)delay); /* decrementer is only 32-bits */ #endif /* CONFIG_40x */ } diff -Nru xenomai/include/asm-powerpc/system.h xenomai-devel/include/asm-powerpc/system.h --- xenomai/include/asm-powerpc/system.h2005-12-04 12:21:36.0 +0200 +++ xenomai-devel/include/asm-powerpc/system.h 2005-12-06 13:18:11.0 +0200 @@ -581,12 +581,11 @@ } static inline int xnarch_send_timer_ipi (xnarch_cpumask_t mask) - { #ifdef CONFIG_SMP -return -1; /* FIXME */ + return rthal_send_ipi(RTHAL_TIMER_IPI, mask); #else /* ! CONFIG_SMP */ -return 0; + return 0; #endif /* CONFIG_SMP */ } @@ -595,9 +594,12 @@ #ifdef XENO_INTR_MODULE static inline void xnarch_relay_tick (void) - { -rthal_irq_host_pend(RTHAL_TIMER_IRQ); +#ifdef CONFIG_SMP + rthal_send_ipi(RTHAL_HOST_TIMER_IPI, cpu_online_map); +#else /* !CONFIG_SMP */ + rthal_irq_host_pend(RTHAL_TIMER_IRQ); +#endif /* CONFIG_SMP */ } static inline void xnarch_announce_tick(void) diff -Nru xenomai/ksrc/arch/powerpc/hal.c xenomai-devel/ksrc/arch/powerpc/hal.c --- xenomai/ksrc/arch/powerpc/hal.c 2005-12-04 12:21:43.0 +0200 +++ xenomai-devel/ksrc/arch/powerpc/hal.c 2005-12-06 13:33:54.0 +0200 @@ -31,6 +31,8 @@ * [EMAIL PROTECTED]/ +#undef DEBUG + #include linux/version.h #include linux/slab.h #include linux/errno.h @@ -51,6 +53,12 @@ #endif /* CONFIG_PROC_FS */ #include stdarg.h +#ifdef DEBUG +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) +#endif + static struct { unsigned long flags; @@ -58,69 +66,215 @@ } rthal_linux_irq[IPIPE_NR_XIRQS]; -static int rthal_periodic_p; +static int rthal_periodic_p[RTHAL_NR_CPUS]; -int rthal_timer_request (void (*handler)(void), -unsigned long nstick) +/* the following two functions are very much alike to the I-pipe tune_timer + * implementation, but tuned for crtitical_enter/exit usage + * + * rthal_set_local_timer might come useful with processor hotplug events + */ +static void rthal_set_local_cpu_timer(void) { -unsigned long flags; -int err; + long ticks; + rthal_declare_cpuid; -flags = rthal_critical_enter(NULL); + rthal_load_cpuid(); -if (nstick 0) - { - /* Periodic setup -- - Use the built-in Adeos service directly. */ - err = rthal_set_timer(nstick); - rthal_periodic_p = 1; - } -else - { - /* Oneshot setup. */ - disarm_decr[rthal_processor_id()] = 1; - rthal_periodic_p = 0; + disarm_decr[cpuid] = (__ipipe_decr_ticks != tb_ticks_per_jiffy); #ifdef CONFIG_40x -mtspr(SPRN_TCR,mfspr(SPRN_TCR) ~TCR_ARE); /* Auto-reload off. */ -#endif /* CONFIG_40x */ - rthal_timer_program_shot(tb_ticks_per_jiffy); + /* Enable and set auto-reload. */ + mtspr(SPRN_TCR, mfspr(SPRN_TCR) | TCR_ARE); + mtspr(SPRN_PIT, __ipipe_decr_ticks); +#else /* !CONFIG_40x */ + ticks = (long)(__ipipe_decr_next[cpuid] - __ipipe_read_timebase()); + set_dec(ticks 0 ? ticks : 0); +#endif /* CONFIG_40x */ + DBG(rthal_set_local_cpu_timer(%d): %ld\n, cpuid, ticks); +} + +static int rthal_set_cpu_timers_unsafe(unsigned long ns) +{ + unsigned long ticks; + unsigned long offset, previous_tb; + int i; + rthal_declare_cpuid; + + DBG(rthal_set_cpu_timers_unsafe: %lu\n, ns); + + if (ns == 0) + ticks = tb_ticks_per_jiffy; + else { + ticks = ns * tb_ticks_per_jiffy / (10 / HZ); + + if (ticks tb_ticks_per_jiffy) { + DBG(rthal_set_cpu_timers_unsafe: -EINVAL (%lu)\n, ticks); + return -EINVAL; + } } -rthal_irq_release(RTHAL_TIMER_IRQ); - -err = rthal_irq_request(RTHAL_TIMER_IRQ, - (rthal_irq_handler_t)handler, -
Re: [Xenomai-core] [PATCH] Xenomai 2.1: Add SMP timer support for powerpc
Heikki Lindholm wrote: Add SMP timer support code for the powerpc arch in Xenomai 2.1. Still a bit rough, but I'll clean it up as I go. Compiled and tested on G5 UP, SMP (I-pipe 2.6.14 0.9-02) and G4 UP (I-pipe 2.6.14 1.0-07). Doesn't seem to break anything. On a G5, SMP seems to bring a 2-3usec latency penalty. Applied, thanks. -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [RFC] rt_task_join?
Hi all, we ran into some issue where we have to wait on the termination of a native real-time userspace thread during cleanup. This can be done in a custom way of course, either via some polling on a flag or by blocking on a standard posix semaphore that are signalled by the terminating real-time thread. But maybe it is more useful to have a generic function available with the native skin. The problem is now that the pthreads underneath the real-time threads are created with PTHREAD_CREATE_DETACHED. Changing this also changes the semantic of other rt_task_xxx functions as posix then requires the creator to call pthread_join (i.e. a new rt_task_join) in any case. A better option might be to introduce a new mode bit T_JOINABLE to decide if the related pthread should be created detached or not. Default would remain PTHREAD_CREATE_DETACHED, if rt_task_join is to be used, T_JOINABLE could be passed to rt_task_create. What do you think, worth the effort? Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [RFC] rt_task_join?
Jan Kiszka wrote: Hi all, we ran into some issue where we have to wait on the termination of a native real-time userspace thread during cleanup. This can be done in a custom way of course, either via some polling on a flag or by blocking on a standard posix semaphore that are signalled by the terminating real-time thread. But maybe it is more useful to have a generic function available with the native skin. The problem is now that the pthreads underneath the real-time threads are created with PTHREAD_CREATE_DETACHED. Changing this also changes the semantic of other rt_task_xxx functions as posix then requires the creator to call pthread_join (i.e. a new rt_task_join) in any case. A better option might be to introduce a new mode bit T_JOINABLE to decide if the related pthread should be created detached or not. Default would remain PTHREAD_CREATE_DETACHED, if rt_task_join is to be used, T_JOINABLE could be passed to rt_task_create. What do you think, worth the effort? Actually, the effort could be as simple as this (+ some docs) - as long as I'm not overseeing some side effect right now. Jan Index: include/native/task.h === --- include/native/task.h (revision 245) +++ include/native/task.h (working copy) @@ -35,18 +35,19 @@ #define T_CPUMASK 0xff00 /* Status/mode flags. */ -#define T_BLOCKED XNPEND -#define T_DELAYED XNDELAY -#define T_READY XNREADY -#define T_DORMANT XNDORMANT -#define T_STARTED XNSTARTED -#define T_BOOST XNBOOST -#define T_LOCKXNLOCK -#define T_RRB XNRRB -#define T_NOSIG XNASDI -#define T_SHIELD XNSHIELD -#define T_WARNSW XNTRAPSW -#define T_PRIMARY XNTHREAD_SPARE0 +#define T_BLOCKED XNPEND +#define T_DELAYED XNDELAY +#define T_READYXNREADY +#define T_DORMANT XNDORMANT +#define T_STARTED XNSTARTED +#define T_BOOSTXNBOOST +#define T_LOCK XNLOCK +#define T_RRB XNRRB +#define T_NOSIGXNASDI +#define T_SHIELD XNSHIELD +#define T_WARNSW XNTRAPSW +#define T_PRIMARY XNTHREAD_SPARE0 +#define T_JOINABLE XNTHREAD_SPARE1 /* Task hook types. */ #define T_HOOK_START XNHOOK_THREAD_START @@ -268,6 +269,8 @@ int rt_task_slice(RT_TASK *task, RTIME quantum); +int rt_task_join(RT_TASK *task); + #ifdef CONFIG_XENO_OPT_NATIVE_MPS ssize_t rt_task_send(RT_TASK *task, Index: src/skins/native/task.c === --- src/skins/native/task.c (revision 245) +++ src/skins/native/task.c (working copy) @@ -127,7 +127,8 @@ stksize = PTHREAD_STACK_MIN; pthread_attr_setstacksize(thattr,stksize); -pthread_attr_setdetachstate(thattr,PTHREAD_CREATE_DETACHED); +if (!(mode T_JOINABLE)) + pthread_attr_setdetachstate(thattr,PTHREAD_CREATE_DETACHED); pthread_attr_setschedpolicy(thattr,SCHED_FIFO); param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_attr_setschedparam(thattr,param); @@ -331,6 +332,11 @@ quantum); } +int rt_task_join (RT_TASK *task) +{ +return -pthread_join((pthread_t)task-opaque2, NULL); +} + #ifdef CONFIG_XENO_OPT_NATIVE_MPS ssize_t rt_task_send (RT_TASK *task, ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] I-pipe ppc64 0.9-02
Updated ppc64 I-pipe patch for 2.6.14. Changes: * sync with ppc 1.0-07 * send IPI to self fixed * additional IPI (#4) for xenomai SMP timer implementation Also at the usual http://www.cs.helsinki.fi/group/nonsto/rtaippc64.html Philippe, please put this in Xenomai 2.1. -- Heikki Lindholm diff -Nru linux-2.6.14/arch/ppc64/Kconfig linux-2.6.14-adeos-ipipe-ppc64-0.9-02-dev/arch/ppc64/Kconfig --- linux-2.6.14/arch/ppc64/Kconfig 2005-10-28 03:02:08.0 +0300 +++ linux-2.6.14-adeos-ipipe-ppc64-0.9-02-dev/arch/ppc64/Kconfig 2005-11-04 08:56:30.0 +0200 @@ -227,6 +227,8 @@ depends on SMP default 32 +source kernel/ipipe/Kconfig + config HMT bool Hardware multithreading depends on SMP PPC_PSERIES BROKEN diff -Nru linux-2.6.14/arch/ppc64/kernel/entry.S linux-2.6.14-adeos-ipipe-ppc64-0.9-02-dev/arch/ppc64/kernel/entry.S --- linux-2.6.14/arch/ppc64/kernel/entry.S 2005-10-28 03:02:08.0 +0300 +++ linux-2.6.14-adeos-ipipe-ppc64-0.9-02-dev/arch/ppc64/kernel/entry.S 2005-11-04 10:28:59.0 +0200 @@ -35,6 +35,14 @@ #define DO_SOFT_DISABLE #endif +#ifdef CONFIG_IPIPE +#define STALL_ROOT_CONDbl __ipipe_stall_root_raw +#define UNSTALL_ROOT_COND bl __ipipe_unstall_root_raw +#else /* !CONFIG_IPIPE */ +#define STALL_ROOT_COND +#define UNSTALL_ROOT_COND +#endif /* CONFIG_IPIPE */ + /* * System calls. */ @@ -108,6 +116,23 @@ ori r11,r11,MSR_EE mtmsrd r11,1 +#ifdef CONFIG_IPIPE + addir3,r1,GPR0 + bl .__ipipe_syscall_root + cmpdi r3,0 + ld r0,GPR0(r1) + ld r3,GPR3(r1) + ld r4,GPR4(r1) + ld r5,GPR5(r1) + ld r6,GPR6(r1) + ld r7,GPR7(r1) + ld r8,GPR8(r1) + ld r9,GPR9(r1) + bgt ipipe_end_syscall + blt syscall_exit + addir9,r1,STACK_FRAME_OVERHEAD +#endif /* CONFIG_IPIPE */ + #ifdef SHOW_SYSCALLS bl .do_show_syscall REST_GPR(0,r1) @@ -196,6 +221,35 @@ rfid b . /* prevent speculative execution */ +#ifdef CONFIG_IPIPE + .globl ipipe_end_syscall +ipipe_end_syscall: + mfmsr r10 + rldicl r10,r10,48,1 + rotldi r10,r10,16 + mtmsrd r10,1 + ld r5,_CCR(r1) + ld r8,_MSR(r1) + ld r7,_NIP(r1) + stdcx. r0,0,r1 /* to clear pending reservations */ + andi. r6,r8,MSR_PR + ld r4,_LINK(r1) + beq-1f /* only restore r13 if */ + ld r13,GPR13(r1) /* returning to usermode */ +1: ld r2,GPR2(r1) + li r12,MSR_RI + mfmsr r10 + andcr10,r10,r12 + mtmsrd r10,1 /* clear MSR.RI */ + ld r1,GPR1(r1) + mtlrr4 + mtcrr5 + mtspr SRR0,r7 + mtspr SRR1,r8 + rfid + b . /* prevent speculative execution */ +#endif /* CONFIG_IPIPE */ + syscall_enosys: li r3,-ENOSYS std r3,RESULT(r1) @@ -470,6 +524,13 @@ rotldi r9,r9,16 mtmsrd r9,1/* Update machine state */ +#ifdef CONFIG_IPIPE + bl .__ipipe_check_root + cmpdi r3,0 + mfmsr r10 /* this is used later, might be messed */ + beq-restore +#endif /* CONFIG_IPIPE */ + #ifdef CONFIG_PREEMPT clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ li r0,_TIF_NEED_RESCHED/* bits to check */ @@ -843,3 +904,11 @@ blr #endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_IPIPE + +_GLOBAL(__ipipe_ret_from_except_lite) + cmpdi r3,0 + bne+.ret_from_except_lite + b restore +#endif /* CONFIG_IPIPE */ diff -Nru linux-2.6.14/arch/ppc64/kernel/head.S linux-2.6.14-adeos-ipipe-ppc64-0.9-02-dev/arch/ppc64/kernel/head.S --- linux-2.6.14/arch/ppc64/kernel/head.S 2005-10-28 03:02:08.0 +0300 +++ linux-2.6.14-adeos-ipipe-ppc64-0.9-02-dev/arch/ppc64/kernel/head.S 2005-11-04 10:36:08.0 +0200 @@ -376,6 +376,18 @@ bl hdlr; \ b .ret_from_except_lite +#ifdef CONFIG_IPIPE +#define IPIPE_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ + .align 7; \ + .globl label##_common; \ +label##_common:\ + EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ + DISABLE_INTS; \ + addir3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b .__ipipe_ret_from_except_lite +#endif /* CONFIG_IPIPE */ + /* * Start of pSeries system interrupt routines */ @@ -685,7 +697,11 @@ bl .machine_check_exception b
Re: [Xenomai-core] [bug] don't try this at home...
Philippe Gerum wrote: Jan Kiszka wrote: Jan Kiszka wrote: Hi Philippe, I'm afraid this one is serious: let the attached migration stress test run on likely any Xenomai since 2.0, preferably with CONFIG_XENO_OPT_DEBUG on. Will give a nice crash sooner or later (I'm trying to set up a serial console now). Confirmed here. My test box went through some nifty triple salto out of the window running this frag for 2mn or so. Actually, the semop handshake is not even needed to cause the crash. At first sight, it looks like a migration issue taking place during the critical phase when a shadow thread switches back to Linux to terminate. As it took some time to persuade my box to not just reboot but to give a message, I'm posting here the kernel dump of the P-III running nat_migration: [...] Xenomai: starting native API services. ce649fb4 ce648000 0b17 0202 c0139246 cdf2819c cdf28070 0b12d310 0037 ce648000 c02f0700 9a28 b7e94a70 bfed63c8 ce648000 c0102fcb b7e94a70 bfed63dc b7faf4b0 bfed63c8 Call Trace: [c0139246] __ipipe_dispatch_event+0x96/0x130 [c0102fcb] work_resched+0x6/0x1c Xenomai: fatal: blocked thread migration[22175] rescheduled?! (status=0x300010, sig=0, prev=watchdog/0[3]) This babe is awaken by Linux while Xeno sees it in a dormant state, likely after it has terminated. No wonder why things are going wild after that... Ok, job queued. Thanks. I think I can explain this warning now: This happens during creation of a new userspace real-time thread. In the context of the newly created Linux pthread that is to become a real-time thread, Xenomai first sets up the real-time part and then calls xnshadow_map. The latter function does further init and then signals via xnshadow_signal_completion to the parent Linux thread (the caller of rt_task_create e.g.) that the thread is up. This happens before xnshadow_harden, i.e. still in preemptible linux context. The signalling should normally do not cause a reschedule as the caller - the to-be-mapped linux pthread - has higher prio than the woken up thread. And Xenomai implicitly assumes with this fatal-test above that there is no preemption! But it can happen: the watchdog thread of linux does preempt here. So, I think it's a false positive. I disabled this particular warning and came a bit further: I-pipe: Domain Xenomai registered. Xenomai: hal/x86 started. Xenomai: real-time nucleus v2.1 (Surfing With The Alien) loaded. Xenomai: starting native API services. Unable to handle kernel paging request at virtual address 75c08732 printing eip: d0acec80 *pde = Oops: [#1] PREEMPT Modules linked in: xeno_native xeno_nucleus eepro100 mii CPU:0 EIP:0060:[d0acec80]Not tainted VLI EFLAGS: 00010086 (2.6.14.3) EIP is at xnpod_schedule+0x790/0xcf0 [xeno_nucleus] eax: 8005003b ebx: d09c1a60 ecx: 75c08500 edx: d0ae441c esi: d0ae4210 edi: ceab1f28 ebp: ceab1f28 esp: ceab1ef4 ds: 007b es: 007b ss: 0068 I-pipe domain Xenomai Stack: 0096 0001 c039cce0 000e ceab1f28 0002 ceab1f20 c010e080 cee1ba90 000e 0004 c0103224 cee0 cee1ba90 cee1ba90 ce86f700 0004 cee1b570 007b cee1007b c028450c Call Trace: [c0103606] show_stack+0x86/0xc0 [c01037a4] show_registers+0x144/0x200 [c01039c7] die+0xd7/0x1e0 [c0286994] do_page_fault+0x1e4/0x667 [c010e094] __ipipe_handle_exception+0x34/0x80 [c0103224] error_code+0x54/0x70 [cee0] 0xcee0 Code: b8 05 e4 01 00 00 39 82 18 02 00 00 74 68 0f 20 c0 83 c8 08 0f 22 c0 8b 4d e8 8b 7d c4 85 ff 8b 49 04 89 4d b8 0f 84 37 fa ff ff f6 81 32 02 00 00 40 0f 84 2a fa ff ff b8 00 e0 ff ff 21 e0 8b scheduling while atomic: migration/0x0002/17646 [c0103655] dump_stack+0x15/0x20 [c02847fb] schedule+0x63b/0x720 [d0ad6573] xnshadow_harden+0x83/0x140 [xeno_nucleus] [d0ad6d7a] xnshadow_wait_barrier+0x7a/0x130 [xeno_nucleus] [d0ad7287] exec_nucleus_syscall+0x77/0xa0 [xeno_nucleus] [d0ad7769] losyscall_event+0x139/0x1a0 [xeno_nucleus] [c0139296] __ipipe_dispatch_event+0x96/0x130 [c010dfb7] __ipipe_syscall_root+0x27/0xc0 [c0102e82] sysenter_past_esp+0x3b/0x67 Xenomai: Switching migration to secondary mode after exception #14 from user-space at 0xc028450c (pid 17646) 3Debug: sleeping function called from invalid context at include/linux/rwsem.h:43 in_atomic():1, irqs_disabled():0 [c0103655] dump_stack+0x15/0x20 [c01120b8] __might_sleep+0x88/0xb0 [c01315ad] futex_wait+0xed/0x2f0 [c0131a35] do_futex+0x45/0x80 [c0131ab0] sys_futex+0x40/0x110 [c0102f28] syscall_call+0x7/0xb Still problems ahead. I got the impression that the migration path is not yet well reviewed. :( Any further ideas welcome! Jan PS: Tests performed with splhigh/splexit removed from __rt_task_create (and splnone from gatekeeper_thread) as Philippe privately acknowledged to be ok. This removes some critical latency source. signature.asc
Re: [Xenomai-core] [bug] don't try this at home...
Jan Kiszka wrote: Philippe Gerum wrote: Jan Kiszka wrote: Jan Kiszka wrote: Hi Philippe, I'm afraid this one is serious: let the attached migration stress test run on likely any Xenomai since 2.0, preferably with CONFIG_XENO_OPT_DEBUG on. Will give a nice crash sooner or later (I'm trying to set up a serial console now). Confirmed here. My test box went through some nifty triple salto out of the window running this frag for 2mn or so. Actually, the semop handshake is not even needed to cause the crash. At first sight, it looks like a migration issue taking place during the critical phase when a shadow thread switches back to Linux to terminate. As it took some time to persuade my box to not just reboot but to give a message, I'm posting here the kernel dump of the P-III running nat_migration: [...] Xenomai: starting native API services. ce649fb4 ce648000 0b17 0202 c0139246 cdf2819c cdf28070 0b12d310 0037 ce648000 c02f0700 9a28 b7e94a70 bfed63c8 ce648000 c0102fcb b7e94a70 bfed63dc b7faf4b0 bfed63c8 Call Trace: [c0139246] __ipipe_dispatch_event+0x96/0x130 [c0102fcb] work_resched+0x6/0x1c Xenomai: fatal: blocked thread migration[22175] rescheduled?! (status=0x300010, sig=0, prev=watchdog/0[3]) This babe is awaken by Linux while Xeno sees it in a dormant state, likely after it has terminated. No wonder why things are going wild after that... Ok, job queued. Thanks. I think I can explain this warning now: This happens during creation of a new userspace real-time thread. In the context of the newly created Linux pthread that is to become a real-time thread, Xenomai first sets up the real-time part and then calls xnshadow_map. The latter function does further init and then signals via xnshadow_signal_completion to the parent Linux thread (the caller of rt_task_create e.g.) that the thread is up. This happens before xnshadow_harden, i.e. still in preemptible linux context. The signalling should normally do not cause a reschedule as the caller - the to-be-mapped linux pthread - has higher prio than the woken up thread. Xeno never assumes this. And Xenomai implicitly assumes with this fatal-test above that there is no preemption! But it can happen: the watchdog thread of linux does preempt here. So, I think it's a false positive. This is wrong. This check is not related to Linux preemption at all; it makes sure that control over any shadow is shared in a strictly _mutually exclusive_ way, so that a thread blocked at Xenomai level may not not be seen as runnable by Linux either. Disabling it only makes things worse since the scheduling state is obviously corrupted when it triggers, and that's the root bug we are chasing right now. You should not draw any conclusion beyond that. Additionally, keep in mind that Xeno has already run over some PREEMPT_RT patches, for which an infinite number of CPUs is assumed over a fine-grained code base, which induces maximum preemption probabilities. I disabled this particular warning and came a bit further: I-pipe: Domain Xenomai registered. Xenomai: hal/x86 started. Xenomai: real-time nucleus v2.1 (Surfing With The Alien) loaded. Xenomai: starting native API services. Unable to handle kernel paging request at virtual address 75c08732 printing eip: d0acec80 *pde = Oops: [#1] PREEMPT Modules linked in: xeno_native xeno_nucleus eepro100 mii CPU:0 EIP:0060:[d0acec80]Not tainted VLI EFLAGS: 00010086 (2.6.14.3) EIP is at xnpod_schedule+0x790/0xcf0 [xeno_nucleus] eax: 8005003b ebx: d09c1a60 ecx: 75c08500 edx: d0ae441c esi: d0ae4210 edi: ceab1f28 ebp: ceab1f28 esp: ceab1ef4 ds: 007b es: 007b ss: 0068 I-pipe domain Xenomai Stack: 0096 0001 c039cce0 000e ceab1f28 0002 ceab1f20 c010e080 cee1ba90 000e 0004 c0103224 cee0 cee1ba90 cee1ba90 ce86f700 0004 cee1b570 007b cee1007b c028450c Call Trace: [c0103606] show_stack+0x86/0xc0 [c01037a4] show_registers+0x144/0x200 [c01039c7] die+0xd7/0x1e0 [c0286994] do_page_fault+0x1e4/0x667 [c010e094] __ipipe_handle_exception+0x34/0x80 [c0103224] error_code+0x54/0x70 [cee0] 0xcee0 Code: b8 05 e4 01 00 00 39 82 18 02 00 00 74 68 0f 20 c0 83 c8 08 0f 22 c0 8b 4d e8 8b 7d c4 85 ff 8b 49 04 89 4d b8 0f 84 37 fa ff ff f6 81 32 02 00 00 40 0f 84 2a fa ff ff b8 00 e0 ff ff 21 e0 8b scheduling while atomic: migration/0x0002/17646 [c0103655] dump_stack+0x15/0x20 [c02847fb] schedule+0x63b/0x720 [d0ad6573] xnshadow_harden+0x83/0x140 [xeno_nucleus] [d0ad6d7a] xnshadow_wait_barrier+0x7a/0x130 [xeno_nucleus] [d0ad7287] exec_nucleus_syscall+0x77/0xa0 [xeno_nucleus] [d0ad7769] losyscall_event+0x139/0x1a0 [xeno_nucleus] [c0139296] __ipipe_dispatch_event+0x96/0x130 [c010dfb7] __ipipe_syscall_root+0x27/0xc0 [c0102e82] sysenter_past_esp+0x3b/0x67 Xenomai: Switching migration to secondary mode after exception #14 from
[Xenomai-core] Re: I-pipe ppc64 0.9-02
Heikki Lindholm wrote: Updated ppc64 I-pipe patch for 2.6.14. Changes: * sync with ppc 1.0-07 * send IPI to self fixed * additional IPI (#4) for xenomai SMP timer implementation Also at the usual http://www.cs.helsinki.fi/group/nonsto/rtaippc64.html Philippe, please put this in Xenomai 2.1. Applied, thanks. -- Philippe.
Re: [Xenomai-core] [PATCH] Xenomai 2.1: Add SMP timer support for powerpc
Heikki Lindholm wrote: Add SMP timer support code for the powerpc arch in Xenomai 2.1. Still a bit rough, but I'll clean it up as I go. Compiled and tested on G5 UP, SMP (I-pipe 2.6.14 0.9-02) and G4 UP (I-pipe 2.6.14 1.0-07). Doesn't seem to break anything. On a G5, SMP seems to bring a 2-3usec latency penalty. Applied, thanks. -- Philippe.
Re: [Xenomai-core] [bug] don't try this at home...
Philippe Gerum wrote: Jan Kiszka wrote: Philippe Gerum wrote: Jan Kiszka wrote: Jan Kiszka wrote: Hi Philippe, I'm afraid this one is serious: let the attached migration stress test run on likely any Xenomai since 2.0, preferably with CONFIG_XENO_OPT_DEBUG on. Will give a nice crash sooner or later (I'm trying to set up a serial console now). Confirmed here. My test box went through some nifty triple salto out of the window running this frag for 2mn or so. Actually, the semop handshake is not even needed to cause the crash. At first sight, it looks like a migration issue taking place during the critical phase when a shadow thread switches back to Linux to terminate. As it took some time to persuade my box to not just reboot but to give a message, I'm posting here the kernel dump of the P-III running nat_migration: [...] Xenomai: starting native API services. ce649fb4 ce648000 0b17 0202 c0139246 cdf2819c cdf28070 0b12d310 0037 ce648000 c02f0700 9a28 b7e94a70 bfed63c8 ce648000 c0102fcb b7e94a70 bfed63dc b7faf4b0 bfed63c8 Call Trace: [c0139246] __ipipe_dispatch_event+0x96/0x130 [c0102fcb] work_resched+0x6/0x1c Xenomai: fatal: blocked thread migration[22175] rescheduled?! (status=0x300010, sig=0, prev=watchdog/0[3]) This babe is awaken by Linux while Xeno sees it in a dormant state, likely after it has terminated. No wonder why things are going wild after that... Ok, job queued. Thanks. I think I can explain this warning now: This happens during creation of a new userspace real-time thread. In the context of the newly created Linux pthread that is to become a real-time thread, Xenomai first sets up the real-time part and then calls xnshadow_map. The latter function does further init and then signals via xnshadow_signal_completion to the parent Linux thread (the caller of rt_task_create e.g.) that the thread is up. This happens before xnshadow_harden, i.e. still in preemptible linux context. The signalling should normally do not cause a reschedule as the caller - the to-be-mapped linux pthread - has higher prio than the woken up thread. Xeno never assumes this. And Xenomai implicitly assumes with this fatal-test above that there is no preemption! But it can happen: the watchdog thread of linux does preempt here. So, I think it's a false positive. This is wrong. This check is not related to Linux preemption at all; it makes sure that control over any shadow is shared in a strictly _mutually exclusive_ way, so that a thread blocked at Xenomai level may not not be seen as runnable by Linux either. Disabling it only makes things worse since the scheduling state is obviously corrupted when it triggers, and that's the root bug we are chasing right now. You should not draw any conclusion beyond that. Additionally, keep in mind that Xeno has already run over some PREEMPT_RT patches, for which an infinite number of CPUs is assumed over a fine-grained code base, which induces maximum preemption probabilities. Ok, may explanation was a quick hack before some meeting here, I should have elaborated it more thoroughly. Let's try to do it step by step so that you can say where I go of the right path: 1. We enter xnshadow_map. The linux thread is happily running, the shadow thread is in XNDORMANT state and not yet linked to its linux mate. Any linux preemption hitting us here and causing a reactivation of this particular linux thread later will not cause any activity of do_schedule_event related to this thread because [1] is NULL. That's important, we will see later why. 2. After some init stuff, xnshadow_map links the shadow to the linux thread [2] and then calls xnshadow_signal_completion. This call would normally wake up the sleeping parent of our linux thread, performing a direct standard linux schedule from the new born thread to the parent. Again, nothing here about which do_schedule_event could complain. 3. Now let's consider some preemption by a third linux task after [2] but before [3]. Scheduling away the new linux thread is no issue. But when it comes back again, we will see those nice xnpod_fatal. The reason: our shadow thread is now linked to its linux mate, thus [1] will evaluate non-NULL, and later also [4] will hit as XNDORMANT is part of XNTHREAD_BLOCK_BITS (and the thread is not ptraced). Ok, this is how I see THIS particular issue so far. For me the question is now: a) I'm right? b) If yes, is this preemption uncritical, thus the warning in the described context a false positive? c) If it is not, can this cause the following crash? Jan [1]http://www.rts.uni-hannover.de/xenomai/lxr/source/ksrc/nucleus/shadow.c?v=SVN-trunk#L1515 [2]http://www.rts.uni-hannover.de/xenomai/lxr/source/ksrc/nucleus/shadow.c?v=SVN-trunk#L765
[Xenomai-core] [RFC] rt_task_join?
Hi all, we ran into some issue where we have to wait on the termination of a native real-time userspace thread during cleanup. This can be done in a custom way of course, either via some polling on a flag or by blocking on a standard posix semaphore that are signalled by the terminating real-time thread. But maybe it is more useful to have a generic function available with the native skin. The problem is now that the pthreads underneath the real-time threads are created with PTHREAD_CREATE_DETACHED. Changing this also changes the semantic of other rt_task_xxx functions as posix then requires the creator to call pthread_join (i.e. a new rt_task_join) in any case. A better option might be to introduce a new mode bit T_JOINABLE to decide if the related pthread should be created detached or not. Default would remain PTHREAD_CREATE_DETACHED, if rt_task_join is to be used, T_JOINABLE could be passed to rt_task_create. What do you think, worth the effort? Jan signature.asc Description: OpenPGP digital signature
Re: [Xenomai-core] [RFC] rt_task_join?
Jan Kiszka wrote: Hi all, we ran into some issue where we have to wait on the termination of a native real-time userspace thread during cleanup. This can be done in a custom way of course, either via some polling on a flag or by blocking on a standard posix semaphore that are signalled by the terminating real-time thread. But maybe it is more useful to have a generic function available with the native skin. The problem is now that the pthreads underneath the real-time threads are created with PTHREAD_CREATE_DETACHED. Changing this also changes the semantic of other rt_task_xxx functions as posix then requires the creator to call pthread_join (i.e. a new rt_task_join) in any case. A better option might be to introduce a new mode bit T_JOINABLE to decide if the related pthread should be created detached or not. Default would remain PTHREAD_CREATE_DETACHED, if rt_task_join is to be used, T_JOINABLE could be passed to rt_task_create. What do you think, worth the effort? Actually, the effort could be as simple as this (+ some docs) - as long as I'm not overseeing some side effect right now. Jan Index: include/native/task.h === --- include/native/task.h (revision 245) +++ include/native/task.h (working copy) @@ -35,18 +35,19 @@ #define T_CPUMASK 0xff00 /* Status/mode flags. */ -#define T_BLOCKED XNPEND -#define T_DELAYED XNDELAY -#define T_READY XNREADY -#define T_DORMANT XNDORMANT -#define T_STARTED XNSTARTED -#define T_BOOST XNBOOST -#define T_LOCKXNLOCK -#define T_RRB XNRRB -#define T_NOSIG XNASDI -#define T_SHIELD XNSHIELD -#define T_WARNSW XNTRAPSW -#define T_PRIMARY XNTHREAD_SPARE0 +#define T_BLOCKED XNPEND +#define T_DELAYED XNDELAY +#define T_READYXNREADY +#define T_DORMANT XNDORMANT +#define T_STARTED XNSTARTED +#define T_BOOSTXNBOOST +#define T_LOCK XNLOCK +#define T_RRB XNRRB +#define T_NOSIGXNASDI +#define T_SHIELD XNSHIELD +#define T_WARNSW XNTRAPSW +#define T_PRIMARY XNTHREAD_SPARE0 +#define T_JOINABLE XNTHREAD_SPARE1 /* Task hook types. */ #define T_HOOK_START XNHOOK_THREAD_START @@ -268,6 +269,8 @@ int rt_task_slice(RT_TASK *task, RTIME quantum); +int rt_task_join(RT_TASK *task); + #ifdef CONFIG_XENO_OPT_NATIVE_MPS ssize_t rt_task_send(RT_TASK *task, Index: src/skins/native/task.c === --- src/skins/native/task.c (revision 245) +++ src/skins/native/task.c (working copy) @@ -127,7 +127,8 @@ stksize = PTHREAD_STACK_MIN; pthread_attr_setstacksize(thattr,stksize); -pthread_attr_setdetachstate(thattr,PTHREAD_CREATE_DETACHED); +if (!(mode T_JOINABLE)) + pthread_attr_setdetachstate(thattr,PTHREAD_CREATE_DETACHED); pthread_attr_setschedpolicy(thattr,SCHED_FIFO); param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_attr_setschedparam(thattr,param); @@ -331,6 +332,11 @@ quantum); } +int rt_task_join (RT_TASK *task) +{ +return -pthread_join((pthread_t)task-opaque2, NULL); +} + #ifdef CONFIG_XENO_OPT_NATIVE_MPS ssize_t rt_task_send (RT_TASK *task,