Module: xenomai-2.5 Branch: master Commit: 7b7054e59e50d44bffc6e0aa52af6eb737ea7cc7 URL: http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=7b7054e59e50d44bffc6e0aa52af6eb737ea7cc7
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Oct 5 15:47:58 2010 +0200 blackfin: upgrade I-pipe support to 2.6.34-blackfin-1.15-01, 2.6.35.7-blackfin-1.15-01 --- ...h => adeos-ipipe-2.6.34-blackfin-1.15-01.patch} | 186 ++++---- ...=> adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch} | 464 ++++++++++++++++---- 2 files changed, 479 insertions(+), 171 deletions(-) diff --git a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.14-02.patch b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.15-01.patch similarity index 98% rename from ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.14-02.patch rename to ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.15-01.patch index 1668422..0af5f58 100644 --- a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.14-02.patch +++ b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.34-blackfin-1.15-01.patch @@ -12,7 +12,7 @@ index c078849..799b1c0 100644 choice diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h -index d3b4044..4530dfa 100644 +index d3b4044..70b409f 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h @@ -34,11 +34,12 @@ @@ -22,12 +22,12 @@ index d3b4044..4530dfa 100644 +#include <asm/bitsperlong.h> -#define IPIPE_ARCH_STRING "1.12-00" -+#define IPIPE_ARCH_STRING "1.14-02" ++#define IPIPE_ARCH_STRING "1.15-01" #define IPIPE_MAJOR_NUMBER 1 -#define IPIPE_MINOR_NUMBER 12 -#define IPIPE_PATCH_NUMBER 0 -+#define IPIPE_MINOR_NUMBER 14 -+#define IPIPE_PATCH_NUMBER 2 ++#define IPIPE_MINOR_NUMBER 15 ++#define IPIPE_PATCH_NUMBER 1 #ifdef CONFIG_SMP #error "I-pipe/blackfin: SMP not implemented" @@ -36,7 +36,7 @@ index d3b4044..4530dfa 100644 #define __ipipe_sync_pipeline ___ipipe_sync_pipeline -void ___ipipe_sync_pipeline(unsigned long syncmask); -+void ___ipipe_sync_pipeline(int dovirt); ++void ___ipipe_sync_pipeline(void); void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs); @@ -136,7 +136,7 @@ index 813a1af..325e532 100644 } while (0) diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c -index 1a496cd..d953572 100644 +index 1a496cd..aa96aa2 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) @@ -148,7 +148,7 @@ index 1a496cd..d953572 100644 goto out; __ipipe_walk_pipeline(head); -@@ -185,11 +185,13 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +@@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) } EXPORT_SYMBOL(__ipipe_disable_irqdesc); @@ -164,22 +164,27 @@ index 1a496cd..d953572 100644 + WARN_ON_ONCE(irqs_disabled_hw()); /* - * We need to run the IRQ tail hook whenever we don't -@@ -197,12 +199,9 @@ int __ipipe_syscall_root(struct pt_regs *regs) - * important operations might be pending there (e.g. Xenomai - * deferred rescheduling). +- * We need to run the IRQ tail hook whenever we don't +- * propagate a syscall to higher domains, because we know that +- * important operations might be pending there (e.g. Xenomai +- * deferred rescheduling). ++ * We need to run the IRQ tail hook each time we intercept a ++ * syscall, because we know that important operations might be ++ * pending there (e.g. Xenomai deferred rescheduling). */ - - if (regs->orig_p0 < NR_syscalls) { +- if (regs->orig_p0 < NR_syscalls) { - void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; -+ hook = (__typeof__(hook))__ipipe_irq_tail_hook; - hook(); +- hook(); - if ((current->flags & PF_EVNOTIFY) == 0) - return 0; - } +- } ++ hook = (__typeof__(hook))__ipipe_irq_tail_hook; ++ hook(); /* -@@ -214,23 +213,32 @@ int __ipipe_syscall_root(struct pt_regs *regs) + * This routine either returns: +@@ -214,23 +210,32 @@ int __ipipe_syscall_root(struct pt_regs *regs) * tail work has to be performed (for handling signals etc). */ @@ -214,7 +219,7 @@ index 1a496cd..d953572 100644 + else { + p = ipipe_root_cpudom_ptr(); + if (__ipipe_ipending_p(p)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOVIRT); ++ __ipipe_sync_pipeline(); + } - local_irq_restore_hw(flags); @@ -222,7 +227,7 @@ index 1a496cd..d953572 100644 return -ret; } -@@ -289,6 +297,7 @@ int ipipe_trigger_irq(unsigned irq) +@@ -289,6 +294,7 @@ int ipipe_trigger_irq(unsigned irq) asmlinkage void __ipipe_sync_root(void) { void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; @@ -230,7 +235,7 @@ index 1a496cd..d953572 100644 unsigned long flags; BUG_ON(irqs_disabled()); -@@ -300,19 +309,20 @@ asmlinkage void __ipipe_sync_root(void) +@@ -300,19 +306,20 @@ asmlinkage void __ipipe_sync_root(void) clear_thread_flag(TIF_IRQ_SYNC); @@ -238,20 +243,20 @@ index 1a496cd..d953572 100644 - __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY); + p = ipipe_root_cpudom_ptr(); + if (__ipipe_ipending_p(p)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); local_irq_restore_hw(flags); } -void ___ipipe_sync_pipeline(unsigned long syncmask) -+void ___ipipe_sync_pipeline(int dovirt) ++void ___ipipe_sync_pipeline(void) { if (__ipipe_root_domain_p && test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) return; - __ipipe_sync_stage(syncmask); -+ __ipipe_sync_stage(dovirt); ++ __ipipe_sync_stage(); } void __ipipe_disable_root_irqs_hw(void) @@ -619,10 +624,10 @@ index d5b3876..010aa8b 100644 #endif /* LINUX_HARDIRQ_H */ diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h new file mode 100644 -index 0000000..c458883 +index 0000000..9af86be --- /dev/null +++ b/include/linux/ipipe.h -@@ -0,0 +1,715 @@ +@@ -0,0 +1,724 @@ +/* -*- linux-c -*- + * include/linux/ipipe.h + * @@ -654,6 +659,7 @@ index 0000000..c458883 +#include <linux/linkage.h> +#include <linux/ipipe_base.h> +#include <asm/ipipe.h> ++#include <asm/bug.h> + +#ifdef CONFIG_IPIPE_DEBUG_CONTEXT + @@ -690,6 +696,14 @@ index 0000000..c458883 + +#endif /* !CONFIG_IPIPE_DEBUG_CONTEXT */ + ++#ifdef CONFIG_IPIPE_DEBUG_INTERNAL ++#define IPIPE_WARN(c) WARN_ON(c) ++#define IPIPE_WARN_ONCE(c) WARN_ON_ONCE(c) ++#else ++#define IPIPE_WARN(c) do { (void)(c); } while (0) ++#define IPIPE_WARN_ONCE(c) do { (void)(c); } while (0) ++#endif ++ +#ifdef CONFIG_IPIPE + +#define IPIPE_VERSION_STRING IPIPE_ARCH_STRING @@ -848,7 +862,7 @@ index 0000000..c458883 + +void __ipipe_dispatch_wired(struct ipipe_domain *head, unsigned irq); + -+void __ipipe_sync_stage(int dovirt); ++void __ipipe_sync_stage(void); + +void __ipipe_set_irq_pending(struct ipipe_domain *ipd, unsigned irq); + @@ -871,7 +885,7 @@ index 0000000..c458883 +} + +#ifndef __ipipe_sync_pipeline -+#define __ipipe_sync_pipeline(dovirt) __ipipe_sync_stage(dovirt) ++#define __ipipe_sync_pipeline() __ipipe_sync_stage() +#endif + +#ifndef __ipipe_run_irqtail @@ -1340,10 +1354,10 @@ index 0000000..c458883 +#endif /* !__LINUX_IPIPE_H */ diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h new file mode 100644 -index 0000000..fa1a951 +index 0000000..4167616 --- /dev/null +++ b/include/linux/ipipe_base.h -@@ -0,0 +1,133 @@ +@@ -0,0 +1,130 @@ +/* -*- linux-c -*- + * include/linux/ipipe_base.h + * @@ -1397,9 +1411,6 @@ index 0000000..fa1a951 +#define __IPIPE_2LEVEL_IRQMAP 1 +#endif + -+#define IPIPE_IRQ_DOALL 0 -+#define IPIPE_IRQ_DOVIRT 1 -+ +/* Per-cpu pipeline status */ +#define IPIPE_STALL_FLAG 0 /* Stalls a pipeline stage -- guaranteed at bit #0 */ +#define IPIPE_SYNC_FLAG 1 /* The interrupt syncer is running for the domain */ @@ -1479,10 +1490,10 @@ index 0000000..fa1a951 +#endif /* !__LINUX_IPIPE_BASE_H */ diff --git a/include/linux/ipipe_lock.h b/include/linux/ipipe_lock.h new file mode 100644 -index 0000000..73ed46a +index 0000000..032080f --- /dev/null +++ b/include/linux/ipipe_lock.h -@@ -0,0 +1,215 @@ +@@ -0,0 +1,230 @@ +/* -*- linux-c -*- + * include/linux/ipipe_lock.h + * @@ -1548,6 +1559,19 @@ index 0000000..73ed46a + __ret__; \ + }) + ++#define PICK_SPINTRYLOCK_IRQ(lock) \ ++ ({ \ ++ int __ret__; \ ++ if (ipipe_spinlock_p(lock)) \ ++ __ret__ = __ipipe_spin_trylock_irq(ipipe_spinlock(lock)); \ ++ else if (std_spinlock_raw_p(lock)) \ ++ __ret__ = __real_raw_spin_trylock_irq(std_spinlock_raw(lock)); \ ++ else if (std_spinlock_p(lock)) \ ++ __ret__ = __real_raw_spin_trylock_irq(&std_spinlock(lock)->rlock); \ ++ else __bad_lock_type(); \ ++ __ret__; \ ++ }) ++ +#define PICK_SPINUNLOCK_IRQRESTORE(lock, flags) \ + do { \ + if (ipipe_spinlock_p(lock)) \ @@ -1643,6 +1667,8 @@ index 0000000..73ed46a + +void __ipipe_spin_lock_irq(ipipe_spinlock_t *lock); + ++int __ipipe_spin_trylock_irq(ipipe_spinlock_t *lock); ++ +void __ipipe_spin_unlock_irq(ipipe_spinlock_t *lock); + +unsigned long __ipipe_spin_lock_irqsave(ipipe_spinlock_t *lock); @@ -1700,7 +1726,7 @@ index 0000000..73ed46a +#endif /* !__LINUX_IPIPE_LOCK_H */ diff --git a/include/linux/ipipe_percpu.h b/include/linux/ipipe_percpu.h new file mode 100644 -index 0000000..f6727e3 +index 0000000..0b42e8c --- /dev/null +++ b/include/linux/ipipe_percpu.h @@ -0,0 +1,89 @@ @@ -1779,7 +1805,7 @@ index 0000000..f6727e3 +DECLARE_PER_CPU(int, ipipe_saved_context_check_state); +#endif + -+#define ipipe_root_cpudom_ptr(var) \ ++#define ipipe_root_cpudom_ptr() \ + (&__ipipe_get_cpu_var(ipipe_percpu_darray)[IPIPE_ROOT_SLOT]) + +#define ipipe_root_cpudom_var(var) ipipe_root_cpudom_ptr()->var @@ -2179,7 +2205,7 @@ index 2b7b81d..05cbf77 100644 * tasks can access tsk->flags in readonly mode for example * with tsk_used_math (like during threaded core dumping). diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h -index 89fac6a..771e701 100644 +index 89fac6a..6135280 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -88,10 +88,12 @@ @@ -2280,7 +2306,7 @@ index 89fac6a..771e701 100644 + __real_raw_spin_trylock(lock) ? \ 1 : ({ local_irq_enable(); 0; }); \ }) -+#define raw_spin_trylock_irq(lock) PICK_SPINOP(_trylock_irq, lock) ++#define raw_spin_trylock_irq(lock) PICK_SPINTRYLOCK_IRQ(lock) -#define raw_spin_trylock_irqsave(lock, flags) \ +#define __real_raw_spin_trylock_irqsave(lock, flags) \ @@ -2700,10 +2726,10 @@ index 0000000..6257dfa +obj-$(CONFIG_IPIPE_TRACE) += tracer.o diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c new file mode 100644 -index 0000000..e2503bd +index 0000000..539ec20 --- /dev/null +++ b/kernel/ipipe/core.c -@@ -0,0 +1,1977 @@ +@@ -0,0 +1,1960 @@ +/* -*- linux-c -*- + * linux/kernel/ipipe/core.c + * @@ -2737,7 +2763,6 @@ index 0000000..e2503bd +#include <linux/interrupt.h> +#include <linux/bitops.h> +#include <linux/tick.h> -+#include <linux/prefetch.h> +#ifdef CONFIG_PROC_FS +#include <linux/proc_fs.h> +#include <linux/seq_file.h> @@ -3022,7 +3047,7 @@ index 0000000..e2503bd + __clear_bit(IPIPE_STALL_FLAG, &p->status); + + if (unlikely(__ipipe_ipending_p(p))) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + + local_irq_enable_hw(); +} @@ -3115,7 +3140,7 @@ index 0000000..e2503bd + if (unlikely(__ipipe_ipending_p(p))) { + head_domain = __ipipe_pipeline_head(); + if (likely(head_domain == __ipipe_current_domain)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + else + __ipipe_walk_pipeline(&head_domain->p_link); + } @@ -3152,7 +3177,7 @@ index 0000000..e2503bd + if (unlikely(__ipipe_ipending_p(p))) { + head_domain = __ipipe_pipeline_head(); + if (likely(head_domain == __ipipe_current_domain)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + else + __ipipe_walk_pipeline(&head_domain->p_link); + } @@ -3254,9 +3279,10 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(ipd); + int l0b, l1b; + ++ IPIPE_WARN_ONCE(!irqs_disabled_hw()); ++ + l0b = irq / (BITS_PER_LONG * BITS_PER_LONG); + l1b = irq / BITS_PER_LONG; -+ prefetchw(p); + + if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) { + __set_bit(irq, p->irqpend_lomap); @@ -3274,6 +3300,8 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p; + int l0b, l1b; + ++ IPIPE_WARN_ONCE(!irqs_disabled_hw()); ++ + /* Wired interrupts cannot be locked (it is useless). */ + if (test_bit(IPIPE_WIRED_FLAG, &ipd->irqs[irq].control) || + test_and_set_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control)) @@ -3299,6 +3327,8 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p; + int l0b, l1b, cpu; + ++ IPIPE_WARN_ONCE(!irqs_disabled_hw()); ++ + if (unlikely(!test_and_clear_bit(IPIPE_LOCK_FLAG, + &ipd->irqs[irq].control))) + return; @@ -3317,36 +3347,18 @@ index 0000000..e2503bd + } +} + -+static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p, -+ int dovirt) ++static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p) +{ -+ unsigned long l0m, l1m, l2m, himask, mdmask; + int l0b, l1b, l2b, vl0b, vl1b; ++ unsigned long l0m, l1m, l2m; + unsigned int irq; + -+ if (dovirt) { -+ /* -+ * All virtual IRQs are mapped by a single long word. -+ * There is exactly BITS_PER_LONG virqs, and they are -+ * always last in the interrupt map, starting at -+ * IPIPE_VIRQ_BASE. Therefore, we only need to test a -+ * single bit within the high and middle maps to check -+ * whether a virtual IRQ is pending (the computations -+ * below are constant). -+ */ -+ vl0b = IPIPE_VIRQ_BASE / (BITS_PER_LONG * BITS_PER_LONG); -+ himask = (1L << vl0b); -+ vl1b = IPIPE_VIRQ_BASE / BITS_PER_LONG; -+ mdmask = (1L << (vl1b & (BITS_PER_LONG-1))); -+ } else -+ himask = mdmask = ~0L; -+ -+ l0m = p->irqpend_himap & himask; ++ l0m = p->irqpend_himap; + if (unlikely(l0m == 0)) + return -1; + + l0b = __ipipe_ffnz(l0m); -+ l1m = p->irqpend_mdmap[l0b] & mdmask; ++ l1m = p->irqpend_mdmap[l0b]; + if (unlikely(l1m == 0)) + return -1; + @@ -3384,7 +3396,7 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(ipd); + int l0b = irq / BITS_PER_LONG; + -+ prefetchw(p); ++ IPIPE_WARN_ONCE(!irqs_disabled_hw()); + + if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) { + __set_bit(irq, p->irqpend_lomap); @@ -3401,6 +3413,8 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p; + int l0b = irq / BITS_PER_LONG; + ++ IPIPE_WARN_ONCE(!irqs_disabled_hw()); ++ + /* Wired interrupts cannot be locked (it is useless). */ + if (test_bit(IPIPE_WIRED_FLAG, &ipd->irqs[irq].control) || + test_and_set_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control)) @@ -3420,6 +3434,8 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p; + int l0b = irq / BITS_PER_LONG, cpu; + ++ IPIPE_WARN_ONCE(!irqs_disabled_hw()); ++ + if (unlikely(!test_and_clear_bit(IPIPE_LOCK_FLAG, + &ipd->irqs[irq].control))) + return; @@ -3434,15 +3450,12 @@ index 0000000..e2503bd + } +} + -+static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p, -+ int dovirt) ++static inline int __ipipe_next_irq(struct ipipe_percpu_domain_data *p) +{ -+ unsigned long l0m, l1m, himask = ~0L; ++ unsigned long l0m, l1m; + int l0b, l1b; + -+ himask <<= dovirt ? IPIPE_VIRQ_BASE/BITS_PER_LONG : 0; -+ -+ l0m = p->irqpend_himap & himask; ++ l0m = p->irqpend_himap; + if (unlikely(l0m == 0)) + return -1; + @@ -3482,7 +3495,7 @@ index 0000000..e2503bd + + if (__ipipe_ipending_p(np)) { + if (next_domain == this_domain) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + else { + + p->evsync = 0; @@ -3499,7 +3512,7 @@ index 0000000..e2503bd + + if (__ipipe_ipending_p(p) && + !test_bit(IPIPE_STALL_FLAG, &p->status)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + } + break; + } else if (next_domain == this_domain) @@ -3546,7 +3559,7 @@ index 0000000..e2503bd + + __ipipe_current_domain = next_domain; +sync_stage: -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + + if (__ipipe_current_domain != next_domain) + /* @@ -3648,7 +3661,7 @@ index 0000000..e2503bd + ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK | + IPIPE_EXCLUSIVE_MASK | IPIPE_WIRED_MASK); + -+ if (acknowledge == NULL && !ipipe_virtual_irq_p(irq)) ++ if (acknowledge == NULL) + /* + * Acknowledge handler unspecified for a hw interrupt: + * use the Linux-defined handler instead. @@ -3798,7 +3811,7 @@ index 0000000..e2503bd + __ipipe_ipending_p(np) && + !test_bit(IPIPE_STALL_FLAG, &np->status)) { + __ipipe_current_domain = next_domain; -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + if (__ipipe_current_domain != next_domain) + this_domain = __ipipe_current_domain; + } @@ -3842,8 +3855,6 @@ index 0000000..e2503bd +{ + struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head); + -+ prefetchw(p); -+ + if (test_bit(IPIPE_STALL_FLAG, &p->status)) { + __ipipe_set_irq_pending(head, irq); + return; @@ -3857,8 +3868,6 @@ index 0000000..e2503bd + struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head); + struct ipipe_domain *old; + -+ prefetchw(p); -+ + old = __ipipe_current_domain; + __ipipe_current_domain = head; /* Switch to the head domain. */ + @@ -3872,7 +3881,7 @@ index 0000000..e2503bd + __ipipe_current_domain = old; + if (old == head) { + if (__ipipe_ipending_p(p)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + return; + } + } @@ -3891,7 +3900,7 @@ index 0000000..e2503bd + * + * This routine must be called with hw interrupts off. + */ -+void __ipipe_sync_stage(int dovirt) ++void __ipipe_sync_stage(void) +{ + struct ipipe_percpu_domain_data *p; + struct ipipe_domain *ipd; @@ -3914,7 +3923,7 @@ index 0000000..e2503bd + cpu = ipipe_processor_id(); + + for (;;) { -+ irq = __ipipe_next_irq(p, dovirt); ++ irq = __ipipe_next_irq(p); + if (irq < 0) + break; + /* @@ -4074,7 +4083,7 @@ index 0000000..e2503bd + + if (__ipipe_ipending_p(p) && + !test_bit(IPIPE_STALL_FLAG, &p->status)) -+ __ipipe_sync_pipeline(IPIPE_IRQ_DOALL); ++ __ipipe_sync_pipeline(); + + local_irq_restore_hw(flags); + @@ -4683,10 +4692,10 @@ index 0000000..e2503bd +EXPORT_SYMBOL(ipipe_get_sysinfo); diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c new file mode 100644 -index 0000000..001a83e +index 0000000..f013ef4 --- /dev/null +++ b/kernel/ipipe/tracer.c -@@ -0,0 +1,1441 @@ +@@ -0,0 +1,1442 @@ +/* -*- linux-c -*- + * kernel/ipipe/tracer.c + * @@ -6093,6 +6102,7 @@ index 0000000..001a83e +#ifdef CONFIG_IPIPE_TRACE_ENABLE + ipipe_trace_enable = 1; +#ifdef CONFIG_IPIPE_TRACE_MCOUNT ++ ftrace_enabled = 1; + register_ftrace_function(&ipipe_trace_ops); +#endif /* CONFIG_IPIPE_TRACE_MCOUNT */ +#endif /* CONFIG_IPIPE_TRACE_ENABLE */ diff --git a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.2-blackfin-1.15-00.patch b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch similarity index 95% rename from ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.2-blackfin-1.15-00.patch rename to ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch index 7bf07f3..2c67b19 100644 --- a/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.2-blackfin-1.15-00.patch +++ b/ksrc/arch/blackfin/patches/adeos-ipipe-2.6.35.7-blackfin-1.15-01.patch @@ -12,23 +12,25 @@ index f66294b..5bad536 100644 choice diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h -index d3b4044..bb310c5 100644 +index d3b4044..9d910bd 100644 --- a/arch/blackfin/include/asm/ipipe.h +++ b/arch/blackfin/include/asm/ipipe.h -@@ -34,10 +34,11 @@ +@@ -34,11 +34,12 @@ #include <asm/bitops.h> #include <asm/atomic.h> #include <asm/traps.h> +#include <asm/bitsperlong.h> -#define IPIPE_ARCH_STRING "1.12-00" -+#define IPIPE_ARCH_STRING "1.15-00" ++#define IPIPE_ARCH_STRING "1.15-01" #define IPIPE_MAJOR_NUMBER 1 -#define IPIPE_MINOR_NUMBER 12 +-#define IPIPE_PATCH_NUMBER 0 +#define IPIPE_MINOR_NUMBER 15 - #define IPIPE_PATCH_NUMBER 0 ++#define IPIPE_PATCH_NUMBER 1 #ifdef CONFIG_SMP + #error "I-pipe/blackfin: SMP not implemented" @@ -64,16 +65,11 @@ do { \ struct ipipe_domain; @@ -163,7 +165,7 @@ index 813a1af..325e532 100644 } while (0) diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c -index 1a496cd..1c20192 100644 +index 1a496cd..dbbe1d4 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs) @@ -175,7 +177,7 @@ index 1a496cd..1c20192 100644 goto out; __ipipe_walk_pipeline(head); -@@ -185,11 +185,13 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) +@@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) } EXPORT_SYMBOL(__ipipe_disable_irqdesc); @@ -191,22 +193,27 @@ index 1a496cd..1c20192 100644 + WARN_ON_ONCE(irqs_disabled_hw()); /* - * We need to run the IRQ tail hook whenever we don't -@@ -197,12 +199,9 @@ int __ipipe_syscall_root(struct pt_regs *regs) - * important operations might be pending there (e.g. Xenomai - * deferred rescheduling). +- * We need to run the IRQ tail hook whenever we don't +- * propagate a syscall to higher domains, because we know that +- * important operations might be pending there (e.g. Xenomai +- * deferred rescheduling). ++ * We need to run the IRQ tail hook each time we intercept a ++ * syscall, because we know that important operations might be ++ * pending there (e.g. Xenomai deferred rescheduling). */ - - if (regs->orig_p0 < NR_syscalls) { +- if (regs->orig_p0 < NR_syscalls) { - void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; -+ hook = (__typeof__(hook))__ipipe_irq_tail_hook; - hook(); +- hook(); - if ((current->flags & PF_EVNOTIFY) == 0) - return 0; - } +- } ++ hook = (__typeof__(hook))__ipipe_irq_tail_hook; ++ hook(); /* -@@ -214,23 +213,32 @@ int __ipipe_syscall_root(struct pt_regs *regs) + * This routine either returns: +@@ -214,51 +210,47 @@ int __ipipe_syscall_root(struct pt_regs *regs) * tail work has to be performed (for handling signals etc). */ @@ -249,7 +256,24 @@ index 1a496cd..1c20192 100644 return -ret; } -@@ -255,10 +263,11 @@ static void __ipipe_no_irqtail(void) + +-unsigned long ipipe_critical_enter(void (*syncfn) (void)) +-{ +- unsigned long flags; +- +- local_irq_save_hw(flags); +- +- return flags; +-} +- +-void ipipe_critical_exit(unsigned long flags) +-{ +- local_irq_restore_hw(flags); +-} +- + static void __ipipe_no_irqtail(void) + { + } int ipipe_get_sysinfo(struct ipipe_sysinfo *info) { @@ -265,7 +289,7 @@ index 1a496cd..1c20192 100644 return 0; } -@@ -289,6 +298,7 @@ int ipipe_trigger_irq(unsigned irq) +@@ -289,6 +281,7 @@ int ipipe_trigger_irq(unsigned irq) asmlinkage void __ipipe_sync_root(void) { void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; @@ -273,7 +297,7 @@ index 1a496cd..1c20192 100644 unsigned long flags; BUG_ON(irqs_disabled()); -@@ -300,19 +310,20 @@ asmlinkage void __ipipe_sync_root(void) +@@ -300,19 +293,20 @@ asmlinkage void __ipipe_sync_root(void) clear_thread_flag(TIF_IRQ_SYNC); @@ -376,10 +400,10 @@ index 98abf8b..7cb0a86 100644 struct ht_irq_cfg { struct pci_dev *dev; diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c -index 891e1dd..c24f9f6 100644 +index 891e1dd..95f42db 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c -@@ -3051,6 +3051,51 @@ static int serial8250_resume(struct platform_device *dev) +@@ -3051,6 +3051,53 @@ static int serial8250_resume(struct platform_device *dev) return 0; } @@ -426,6 +450,8 @@ index 891e1dd..c24f9f6 100644 + local_irq_restore_hw(flags); +} + ++EXPORT_SYMBOL(__ipipe_serial_debug); ++ +#endif + static struct platform_driver serial8250_isa_driver = { @@ -662,10 +688,10 @@ index d5b3876..010aa8b 100644 #endif /* LINUX_HARDIRQ_H */ diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h new file mode 100644 -index 0000000..9af86be +index 0000000..8d82852 --- /dev/null +++ b/include/linux/ipipe.h -@@ -0,0 +1,724 @@ +@@ -0,0 +1,769 @@ +/* -*- linux-c -*- + * include/linux/ipipe.h + * @@ -863,8 +889,15 @@ index 0000000..9af86be + +extern int __ipipe_event_monitors[]; + ++typedef void (*ipipe_root_preempt_handler_t)(void *cookie); ++ ++DECLARE_PER_CPU(ipipe_root_preempt_handler_t, __ipipe_root_preempt_handler); ++DECLARE_PER_CPU(void *, __ipipe_root_preempt_cookie); ++ +/* Private interface */ + ++void ipipe_init_early(void); ++ +void ipipe_init(void); + +#ifdef CONFIG_PROC_FS @@ -1195,7 +1228,10 @@ index 0000000..9af86be + +static inline void ipipe_restore_pipeline_head(unsigned long x) +{ -+ local_irq_disable_hw(); ++#ifdef CONFIG_IPIPE_DEBUG ++ if (WARN_ON_ONCE(!irqs_disabled_hw())) ++ local_irq_disable_hw(); ++#endif + if ((x ^ test_bit(IPIPE_STALL_FLAG, &ipipe_head_cpudom_var(status))) & 1) + __ipipe_restore_pipeline_head(x); +} @@ -1222,10 +1258,14 @@ index 0000000..9af86be + +int ipipe_get_sysinfo(struct ipipe_sysinfo *sysinfo); + ++void __ipipe_do_critical_sync(unsigned irq, void *cookie); ++ +unsigned long ipipe_critical_enter(void (*syncfn) (void)); + +void ipipe_critical_exit(unsigned long flags); + ++void ipipe_prepare_panic(void); ++ +static inline void ipipe_set_printk_sync(struct ipipe_domain *ipd) +{ + set_bit(IPIPE_SPRINTK_FLAG, &ipd->flags); @@ -1339,8 +1379,35 @@ index 0000000..9af86be + (p)->ipipe_flags |= PF_EVTRET; \ + } while (0) + ++static inline void ++ipipe_register_root_preempt_handler(ipipe_root_preempt_handler_t handler, ++ void *cookie) ++{ ++ int cpu = ipipe_processor_id(); ++ ++ per_cpu(__ipipe_root_preempt_cookie, cpu) = cookie; ++ barrier(); ++ per_cpu(__ipipe_root_preempt_handler, cpu) = handler; ++} ++ ++static inline void ipipe_unregister_root_preempt_handler(void) ++{ ++ per_cpu(__ipipe_root_preempt_handler, ipipe_processor_id()) = NULL; ++} ++ ++static inline void ipipe_root_preempt_notify(void) ++{ ++ ipipe_root_preempt_handler_t handler; ++ int cpu = ipipe_processor_id(); ++ ++ handler = per_cpu(__ipipe_root_preempt_handler, cpu); ++ if (unlikely(handler)) ++ handler(per_cpu(__ipipe_root_preempt_cookie, cpu)); ++} ++ +#else /* !CONFIG_IPIPE */ + ++#define ipipe_init_early() do { } while(0) +#define ipipe_init() do { } while(0) +#define ipipe_suspend_domain() do { } while(0) +#define ipipe_sigwake_notify(p) do { } while(0) @@ -1351,6 +1418,10 @@ index 0000000..9af86be +#define ipipe_trap_notify(t,r) 0 +#define ipipe_init_proc() do { } while(0) + ++#define ipipe_register_root_preempt_handler(h, c) do { } while (0) ++#define ipipe_unregister_root_preempt_handler() do { } while (0) ++#define ipipe_root_preempt_notify() do { } while (0) ++ +static inline void __ipipe_pin_range_globally(unsigned long start, + unsigned long end) +{ @@ -1373,7 +1444,7 @@ index 0000000..9af86be + +#define __ipipe_root_domain_p 1 +#define ipipe_root_domain_p 1 -+#define ipipe_safe_current current ++#define ipipe_safe_current() current +#define ipipe_processor_id() smp_processor_id() + +#define ipipe_nmi_enter() do { } while (0) @@ -1392,10 +1463,10 @@ index 0000000..9af86be +#endif /* !__LINUX_IPIPE_H */ diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h new file mode 100644 -index 0000000..4167616 +index 0000000..5260e8b --- /dev/null +++ b/include/linux/ipipe_base.h -@@ -0,0 +1,130 @@ +@@ -0,0 +1,135 @@ +/* -*- linux-c -*- + * include/linux/ipipe_base.h + * @@ -1498,12 +1569,17 @@ index 0000000..4167616 +/* Generic features */ + +#ifdef CONFIG_GENERIC_CLOCKEVENTS -+#define __IPIPE_FEATURE_REQUEST_TICKDEV 1 ++#define __IPIPE_FEATURE_REQUEST_TICKDEV 1 ++#endif ++#define __IPIPE_FEATURE_DELAYED_ATOMICSW 1 ++#define __IPIPE_FEATURE_FASTPEND_IRQ 1 ++#define __IPIPE_FEATURE_TRACE_EVENT 1 ++#define __IPIPE_FEATURE_ENABLE_NOTIFIER 1 ++#ifdef CONFIG_HAVE_IPIPE_HOSTRT ++#define __IPIPE_FEATURE_HOSTRT 1 +#endif -+#define __IPIPE_FEATURE_DELAYED_ATOMICSW 1 -+#define __IPIPE_FEATURE_FASTPEND_IRQ 1 -+#define __IPIPE_FEATURE_TRACE_EVENT 1 -+#define __IPIPE_FEATURE_ENABLE_NOTIFIER 1 ++#define __IPIPE_FEATURE_PREPARE_PANIC 1 ++#define __IPIPE_FEATURE_ROOT_PREEMPT_NOTIFIER 1 + +#else /* !CONFIG_IPIPE */ + @@ -1859,10 +1935,10 @@ index 0000000..0b42e8c +#endif /* !__LINUX_IPIPE_PERCPU_H */ diff --git a/include/linux/ipipe_tickdev.h b/include/linux/ipipe_tickdev.h new file mode 100644 -index 0000000..4a1cb1b +index 0000000..df17444 --- /dev/null +++ b/include/linux/ipipe_tickdev.h -@@ -0,0 +1,58 @@ +@@ -0,0 +1,83 @@ +/* -*- linux-c -*- + * include/linux/ipipe_tickdev.h + * @@ -1890,6 +1966,7 @@ index 0000000..4a1cb1b +#if defined(CONFIG_IPIPE) && defined(CONFIG_GENERIC_CLOCKEVENTS) + +#include <linux/clockchips.h> ++#include <linux/clocksource.h> + +struct tick_device; + @@ -1909,6 +1986,22 @@ index 0000000..4a1cb1b + int real_shift; +}; + ++/* ++ * NOTE: When modifying this structure, make sure to keep the Xenomai ++ * definition include/nucleus/vdso.h in sync. ++ */ ++struct ipipe_hostrt_data { ++ short live; ++ seqcount_t seqcount; ++ time_t wall_time_sec; ++ u32 wall_time_nsec; ++ struct timespec wall_to_monotonic; ++ cycle_t cycle_last; ++ cycle_t mask; ++ u32 mult; ++ u32 shift; ++}; ++ +int ipipe_request_tickdev(const char *devname, + void (*emumode)(enum clock_event_mode mode, + struct clock_event_device *cdev), @@ -1920,6 +2013,14 @@ index 0000000..4a1cb1b + +#endif /* CONFIG_IPIPE && CONFIG_GENERIC_CLOCKEVENTS */ + ++#ifdef CONFIG_HAVE_IPIPE_HOSTRT ++void ipipe_update_hostrt(struct timespec *wall_time, ++ struct clocksource *clock); ++#else /* !CONFIG_IPIPE_HOSTRT */ ++static inline void ++ipipe_update_hostrt(struct timespec *wall_time, struct clocksource *clock) {}; ++#endif ++ +#endif /* !__LINUX_IPIPE_TICKDEV_H */ diff --git a/include/linux/ipipe_trace.h b/include/linux/ipipe_trace.h new file mode 100644 @@ -2518,7 +2619,7 @@ index 5cff9a9..6ce2285 100644 Append an extra string to the end of your kernel version. This will show up when you type uname, for example. diff --git a/init/main.c b/init/main.c -index a42fdf4..d00419b 100644 +index a42fdf4..149d8ea 100644 --- a/init/main.c +++ b/init/main.c @@ -557,7 +557,7 @@ asmlinkage void __init start_kernel(void) @@ -2530,7 +2631,15 @@ index a42fdf4..d00419b 100644 early_boot_irqs_off(); early_init_irq_lock_class(); -@@ -621,6 +621,11 @@ asmlinkage void __init start_kernel(void) +@@ -592,6 +592,7 @@ asmlinkage void __init start_kernel(void) + pidhash_init(); + vfs_caches_init_early(); + sort_main_extable(); ++ ipipe_init_early(); + trap_init(); + mm_init(); + /* +@@ -621,6 +622,11 @@ asmlinkage void __init start_kernel(void) softirq_init(); timekeeping_init(); time_init(); @@ -2542,7 +2651,7 @@ index a42fdf4..d00419b 100644 profile_init(); if (!irqs_disabled()) printk(KERN_CRIT "start_kernel(): bug: interrupts were " -@@ -802,6 +807,7 @@ static void __init do_basic_setup(void) +@@ -802,6 +808,7 @@ static void __init do_basic_setup(void) init_tmpfs(); driver_init(); init_irq_proc(); @@ -2563,7 +2672,7 @@ index 057472f..c456c33 100644 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o diff --git a/kernel/exit.c b/kernel/exit.c -index ceffc67..2710991 100644 +index ac90425..a491bc3 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -966,6 +966,7 @@ NORET_TYPE void do_exit(long code) @@ -2575,10 +2684,10 @@ index ceffc67..2710991 100644 exit_files(tsk); exit_fs(tsk); diff --git a/kernel/fork.c b/kernel/fork.c -index b6cce14..9f70852 100644 +index e96c0cd..9be0e42 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -537,6 +537,7 @@ void mmput(struct mm_struct *mm) +@@ -540,6 +540,7 @@ void mmput(struct mm_struct *mm) exit_aio(mm); ksm_exit(mm); exit_mmap(mm); @@ -2586,7 +2695,7 @@ index b6cce14..9f70852 100644 set_mm_exe_file(mm, NULL); if (!list_empty(&mm->mmlist)) { spin_lock(&mmlist_lock); -@@ -907,7 +908,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) +@@ -910,7 +911,7 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) { unsigned long new_flags = p->flags; @@ -2595,7 +2704,7 @@ index b6cce14..9f70852 100644 new_flags |= PF_FORKNOEXEC; new_flags |= PF_STARTING; p->flags = new_flags; -@@ -1283,6 +1284,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, +@@ -1286,6 +1287,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, write_unlock_irq(&tasklist_lock); proc_fork_connector(p); cgroup_post_fork(p); @@ -2606,7 +2715,7 @@ index b6cce14..9f70852 100644 perf_event_fork(p); return p; -@@ -1685,11 +1690,14 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) +@@ -1688,11 +1693,14 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) } if (new_mm) { @@ -2623,10 +2732,10 @@ index b6cce14..9f70852 100644 diff --git a/kernel/ipipe/Kconfig b/kernel/ipipe/Kconfig new file mode 100644 -index 0000000..8ff9d37 +index 0000000..693a7d2 --- /dev/null +++ b/kernel/ipipe/Kconfig -@@ -0,0 +1,23 @@ +@@ -0,0 +1,26 @@ +config IPIPE + bool "Interrupt pipeline" + default y @@ -2650,6 +2759,9 @@ index 0000000..8ff9d37 + bool + depends on IPIPE + default n ++ ++config HAVE_IPIPE_HOSTRT ++ bool diff --git a/kernel/ipipe/Kconfig.debug b/kernel/ipipe/Kconfig.debug new file mode 100644 index 0000000..32160fc @@ -2762,10 +2874,10 @@ index 0000000..6257dfa +obj-$(CONFIG_IPIPE_TRACE) += tracer.o diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c new file mode 100644 -index 0000000..cd4952c +index 0000000..17479dc --- /dev/null +++ b/kernel/ipipe/core.c -@@ -0,0 +1,1968 @@ +@@ -0,0 +1,2153 @@ +/* -*- linux-c -*- + * linux/kernel/ipipe/core.c + * @@ -2799,7 +2911,6 @@ index 0000000..cd4952c +#include <linux/interrupt.h> +#include <linux/bitops.h> +#include <linux/tick.h> -+#include <linux/prefetch.h> +#ifdef CONFIG_PROC_FS +#include <linux/proc_fs.h> +#include <linux/seq_file.h> @@ -2816,7 +2927,26 @@ index 0000000..cd4952c + +struct ipipe_domain ipipe_root; + -+#ifndef CONFIG_SMP ++#ifdef CONFIG_SMP ++ ++#define IPIPE_CRITICAL_TIMEOUT 1000000 ++ ++static cpumask_t __ipipe_cpu_sync_map; ++ ++static cpumask_t __ipipe_cpu_lock_map; ++ ++static cpumask_t __ipipe_cpu_pass_map; ++ ++static unsigned long __ipipe_critical_lock; ++ ++static IPIPE_DEFINE_SPINLOCK(__ipipe_cpu_barrier); ++ ++static atomic_t __ipipe_critical_count = ATOMIC_INIT(0); ++ ++static void (*__ipipe_cpu_sync) (void); ++ ++#else /* !CONFIG_SMP */ ++ +/* + * Create an alias to the unique root status, so that arch-dep code + * may get simple and easy access to this percpu variable. We also @@ -2864,6 +2994,12 @@ index 0000000..cd4952c + +int __ipipe_event_monitors[IPIPE_NR_EVENTS]; + ++DEFINE_PER_CPU(ipipe_root_preempt_handler_t, __ipipe_root_preempt_handler); ++EXPORT_PER_CPU_SYMBOL_GPL(__ipipe_root_preempt_handler); ++ ++DEFINE_PER_CPU(void *, __ipipe_root_preempt_cookie); ++EXPORT_PER_CPU_SYMBOL_GPL(__ipipe_root_preempt_cookie); ++ +#ifdef CONFIG_GENERIC_CLOCKEVENTS + +DECLARE_PER_CPU(struct tick_device, tick_cpu_device); @@ -2973,15 +3109,15 @@ index 0000000..cd4952c + +#endif /* CONFIG_GENERIC_CLOCKEVENTS */ + -+/* -+ * ipipe_init() -- Initialization routine of the IPIPE layer. Called -+ * by the host kernel early during the boot procedure. -+ */ -+void __init ipipe_init(void) ++void __init ipipe_init_early(void) +{ + struct ipipe_domain *ipd = &ipipe_root; + -+ __ipipe_check_platform(); /* Do platform dependent checks first. */ ++ /* ++ * Do the early init stuff. At this point, the kernel does not ++ * provide much services yet: be careful. ++ */ ++ __ipipe_check_platform(); /* Do platform dependent checks first. */ + + /* + * A lightweight registration code for the root domain. We are @@ -2999,7 +3135,6 @@ index 0000000..cd4952c + + __ipipe_init_stage(ipd); + -+ INIT_LIST_HEAD(&ipd->p_link); + list_add_tail(&ipd->p_link, &__ipipe_pipeline); + + __ipipe_init_platform(); @@ -3011,7 +3146,11 @@ index 0000000..cd4952c + ipd->irqs[__ipipe_printk_virq].acknowledge = NULL; + ipd->irqs[__ipipe_printk_virq].control = IPIPE_HANDLE_MASK; +#endif /* CONFIG_PRINTK */ ++} + ++void __init ipipe_init(void) ++{ ++ /* Now we may engage the pipeline. */ + __ipipe_enable_pipeline(); + + printk(KERN_INFO "I-pipe %s: pipeline enabled.\n", @@ -3074,10 +3213,8 @@ index 0000000..cd4952c + + local_irq_disable_hw(); + -+#ifdef CONFIG_IPIPE_DEBUG_INTERNAL + /* This helps catching bad usage from assembly call sites. */ -+ BUG_ON(!__ipipe_root_domain_p); -+#endif ++ ipipe_check_context(ipipe_root_domain); + + p = ipipe_root_cpudom_ptr(); + @@ -3091,9 +3228,7 @@ index 0000000..cd4952c + +void __ipipe_restore_root(unsigned long x) +{ -+#ifdef CONFIG_IPIPE_DEBUG_INTERNAL -+ BUG_ON(!ipipe_root_domain_p); -+#endif ++ ipipe_check_context(ipipe_root_domain); + + if (x) + __ipipe_stall_root(); @@ -3320,7 +3455,6 @@ index 0000000..cd4952c + + l0b = irq / (BITS_PER_LONG * BITS_PER_LONG); + l1b = irq / BITS_PER_LONG; -+ prefetchw(p); + + if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) { + __set_bit(irq, p->irqpend_lomap); @@ -3435,8 +3569,6 @@ index 0000000..cd4952c + int l0b = irq / BITS_PER_LONG; + + IPIPE_WARN_ONCE(!irqs_disabled_hw()); -+ -+ prefetchw(p); + + if (likely(!test_bit(IPIPE_LOCK_FLAG, &ipd->irqs[irq].control))) { + __set_bit(irq, p->irqpend_lomap); @@ -3701,7 +3833,7 @@ index 0000000..cd4952c + ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK | + IPIPE_EXCLUSIVE_MASK | IPIPE_WIRED_MASK); + -+ if (acknowledge == NULL && !ipipe_virtual_irq_p(irq)) ++ if (acknowledge == NULL) + /* + * Acknowledge handler unspecified for a hw interrupt: + * use the Linux-defined handler instead. @@ -3895,8 +4027,6 @@ index 0000000..cd4952c +{ + struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head); + -+ prefetchw(p); -+ + if (test_bit(IPIPE_STALL_FLAG, &p->status)) { + __ipipe_set_irq_pending(head, irq); + return; @@ -3910,8 +4040,6 @@ index 0000000..cd4952c + struct ipipe_percpu_domain_data *p = ipipe_cpudom_ptr(head); + struct ipipe_domain *old; + -+ prefetchw(p); -+ + old = __ipipe_current_domain; + __ipipe_current_domain = head; /* Switch to the head domain. */ + @@ -4357,12 +4485,172 @@ index 0000000..cd4952c + +{ +#ifdef CONFIG_SMP ++ if (!ipipe_ipi_p(ipi)) ++ return -EINVAL; + return __ipipe_send_ipi(ipi,cpumask); +#else /* !CONFIG_SMP */ + return -EINVAL; +#endif /* CONFIG_SMP */ +} + ++#ifdef CONFIG_SMP ++ ++/* Always called with hw interrupts off. */ ++void __ipipe_do_critical_sync(unsigned irq, void *cookie) ++{ ++ int cpu = ipipe_processor_id(); ++ ++ cpu_set(cpu, __ipipe_cpu_sync_map); ++ ++ /* Now we are in sync with the lock requestor running on another ++ CPU. Enter a spinning wait until he releases the global ++ lock. */ ++ spin_lock(&__ipipe_cpu_barrier); ++ ++ /* Got it. Now get out. */ ++ ++ if (__ipipe_cpu_sync) ++ /* Call the sync routine if any. */ ++ __ipipe_cpu_sync(); ++ ++ cpu_set(cpu, __ipipe_cpu_pass_map); ++ ++ spin_unlock(&__ipipe_cpu_barrier); ++ ++ cpu_clear(cpu, __ipipe_cpu_sync_map); ++} ++#endif /* CONFIG_SMP */ ++ ++/* ++ * ipipe_critical_enter() -- Grab the superlock excluding all CPUs but ++ * the current one from a critical section. This lock is used when we ++ * must enforce a global critical section for a single CPU in a ++ * possibly SMP system whichever context the CPUs are running. ++ */ ++unsigned long ipipe_critical_enter(void (*syncfn)(void)) ++{ ++ unsigned long flags; ++ ++ local_irq_save_hw(flags); ++ ++#ifdef CONFIG_SMP ++ if (num_online_cpus() > 1) { ++ int cpu = ipipe_processor_id(); ++ cpumask_t allbutself; ++ unsigned long loops; ++ ++ if (!cpu_test_and_set(cpu, __ipipe_cpu_lock_map)) { ++ while (test_and_set_bit(0, &__ipipe_critical_lock)) { ++ int n = 0; ++ ++ local_irq_enable_hw(); ++ ++ do { ++ cpu_relax(); ++ } while (++n < cpu); ++ ++ local_irq_disable_hw(); ++ } ++ ++restart: ++ spin_lock(&__ipipe_cpu_barrier); ++ ++ __ipipe_cpu_sync = syncfn; ++ ++ cpus_clear(__ipipe_cpu_pass_map); ++ cpu_set(cpu, __ipipe_cpu_pass_map); ++ ++ /* ++ * Send the sync IPI to all processors but the current ++ * one. ++ */ ++ cpus_andnot(allbutself, cpu_online_map, ++ __ipipe_cpu_pass_map); ++ __ipipe_send_ipi(IPIPE_CRITICAL_IPI, allbutself); ++ ++ loops = IPIPE_CRITICAL_TIMEOUT; ++ ++ while (!cpus_equal(__ipipe_cpu_sync_map, allbutself)) { ++ cpu_relax(); ++ ++ if (--loops == 0) { ++ /* ++ * We ran into a deadlock due to a ++ * contended rwlock. Cancel this round ++ * and retry. ++ */ ++ __ipipe_cpu_sync = NULL; ++ ++ spin_unlock(&__ipipe_cpu_barrier); ++ ++ /* ++ * Ensure all CPUs consumed the IPI to ++ * avoid running __ipipe_cpu_sync ++ * prematurely. This usually resolves ++ * the deadlock reason too. ++ */ ++ while (!cpus_equal(cpu_online_map, ++ __ipipe_cpu_pass_map)) ++ cpu_relax(); ++ ++ goto restart; ++ } ++ } ++ } ++ ++ atomic_inc(&__ipipe_critical_count); ++ } ++#endif /* CONFIG_SMP */ ++ ++ return flags; ++} ++ ++/* ipipe_critical_exit() -- Release the superlock. */ ++ ++void ipipe_critical_exit(unsigned long flags) ++{ ++#ifdef CONFIG_SMP ++ if (num_online_cpus() > 1 && ++ atomic_dec_and_test(&__ipipe_critical_count)) { ++ spin_unlock(&__ipipe_cpu_barrier); ++ ++ while (!cpus_empty(__ipipe_cpu_sync_map)) ++ cpu_relax(); ++ ++ cpu_clear(ipipe_processor_id(), __ipipe_cpu_lock_map); ++ clear_bit(0, &__ipipe_critical_lock); ++ smp_mb__after_clear_bit(); ++ } ++#endif /* CONFIG_SMP */ ++ ++ local_irq_restore_hw(flags); ++} ++ ++#ifdef CONFIG_HAVE_IPIPE_HOSTRT ++/* ++ * NOTE: The architecture specific code must only call this function ++ * when a clocksource suitable for CLOCK_HOST_REALTIME is enabled. ++ */ ++void ipipe_update_hostrt(struct timespec *wall_time, struct clocksource *clock) ++{ ++ struct ipipe_hostrt_data hostrt_data; ++ ++ hostrt_data.live = 1; ++ hostrt_data.cycle_last = clock->cycle_last; ++ hostrt_data.mask = clock->mask; ++ hostrt_data.mult = clock->mult; ++ hostrt_data.shift = clock->shift; ++ hostrt_data.wall_time_sec = wall_time->tv_sec; ++ hostrt_data.wall_time_nsec = wall_time->tv_nsec; ++ hostrt_data.wall_to_monotonic = wall_to_monotonic; ++ ++ /* Note: The event receiver is responsible for providing ++ proper locking */ ++ if (__ipipe_event_monitored_p(IPIPE_EVENT_HOSTRT)) ++ __ipipe_dispatch_event(IPIPE_EVENT_HOSTRT, &hostrt_data); ++} ++#endif /* CONFIG_HAVE_IPIPE_HOSTRT */ ++ +int ipipe_alloc_ptdkey (void) +{ + unsigned long flags; @@ -4684,6 +4972,15 @@ index 0000000..cd4952c + +#endif /* CONFIG_IPIPE_DEBUG_INTERNAL && CONFIG_SMP */ + ++ ++void ipipe_prepare_panic(void) ++{ ++ ipipe_set_printk_sync(ipipe_current_domain); ++ ipipe_context_check_off(); ++} ++ ++EXPORT_SYMBOL_GPL(ipipe_prepare_panic); ++ +EXPORT_SYMBOL(ipipe_virtualize_irq); +EXPORT_SYMBOL(ipipe_control_irq); +EXPORT_SYMBOL(ipipe_suspend_domain); @@ -4736,10 +5033,10 @@ index 0000000..cd4952c +EXPORT_SYMBOL(ipipe_get_sysinfo); diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c new file mode 100644 -index 0000000..001a83e +index 0000000..f013ef4 --- /dev/null +++ b/kernel/ipipe/tracer.c -@@ -0,0 +1,1441 @@ +@@ -0,0 +1,1442 @@ +/* -*- linux-c -*- + * kernel/ipipe/tracer.c + * @@ -6146,6 +6443,7 @@ index 0000000..001a83e +#ifdef CONFIG_IPIPE_TRACE_ENABLE + ipipe_trace_enable = 1; +#ifdef CONFIG_IPIPE_TRACE_MCOUNT ++ ftrace_enabled = 1; + register_ftrace_function(&ipipe_trace_ops); +#endif /* CONFIG_IPIPE_TRACE_MCOUNT */ +#endif /* CONFIG_IPIPE_TRACE_ENABLE */ @@ -6635,7 +6933,7 @@ index 444b770..60e2a08 100644 /* cpu currently holding logbuf_lock */ static volatile unsigned int printk_cpu = UINT_MAX; diff --git a/kernel/sched.c b/kernel/sched.c -index 63b4a14..7812a8c 100644 +index 4fa520b..c5cabba 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2283,7 +2283,8 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, @@ -6762,7 +7060,7 @@ index 63b4a14..7812a8c 100644 } EXPORT_SYMBOL(schedule); -@@ -3729,7 +3754,8 @@ asmlinkage void __sched preempt_schedule(void) +@@ -3737,7 +3762,8 @@ asmlinkage void __sched preempt_schedule(void) do { add_preempt_count(PREEMPT_ACTIVE); @@ -6772,7 +7070,7 @@ index 63b4a14..7812a8c 100644 sub_preempt_count(PREEMPT_ACTIVE); /* -@@ -4514,6 +4540,7 @@ recheck: +@@ -4522,6 +4548,7 @@ recheck: oldprio = p->prio; prev_class = p->sched_class; __setscheduler(rq, p, policy, param->sched_priority); @@ -6780,7 +7078,7 @@ index 63b4a14..7812a8c 100644 if (running) p->sched_class->set_curr_task(rq); -@@ -5170,6 +5197,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) +@@ -5178,6 +5205,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) #else task_thread_info(idle)->preempt_count = 0; #endif @@ -6788,7 +7086,7 @@ index 63b4a14..7812a8c 100644 /* * The idle tasks have their own, simple scheduling class: */ -@@ -8969,3 +8997,65 @@ void synchronize_sched_expedited(void) +@@ -8977,3 +9005,65 @@ void synchronize_sched_expedited(void) EXPORT_SYMBOL_GPL(synchronize_sched_expedited); #endif /* #else #ifndef CONFIG_SMP */ @@ -6958,7 +7256,7 @@ index ee305c8..f595adb 100644 * This function runs timers and the timer-tq in bottom half context. */ diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c -index 6d2cb14..016a0a2 100644 +index 6b316b3..ad342e8 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -29,6 +29,7 @@ @@ -6969,7 +7267,7 @@ index 6d2cb14..016a0a2 100644 #include <trace/events/sched.h> -@@ -1150,6 +1151,9 @@ static int __ftrace_modify_code(void *data) +@@ -1157,6 +1158,9 @@ static int __ftrace_modify_code(void *data) static void ftrace_run_update_code(int command) { @@ -6979,7 +7277,7 @@ index 6d2cb14..016a0a2 100644 int ret; ret = ftrace_arch_code_modify_prepare(); -@@ -1157,7 +1161,13 @@ static void ftrace_run_update_code(int command) +@@ -1164,7 +1168,13 @@ static void ftrace_run_update_code(int command) if (ret) return; @@ -6993,7 +7291,7 @@ index 6d2cb14..016a0a2 100644 ret = ftrace_arch_code_modify_post_process(); FTRACE_WARN_ON(ret); -@@ -2675,9 +2685,9 @@ static int ftrace_process_locs(struct module *mod, +@@ -2684,9 +2694,9 @@ static int ftrace_process_locs(struct module *mod, } /* disable interrupts to prevent kstop machine */ @@ -7005,7 +7303,7 @@ index 6d2cb14..016a0a2 100644 mutex_unlock(&ftrace_lock); return 0; -@@ -2756,9 +2766,9 @@ void __init ftrace_init(void) +@@ -2765,9 +2775,9 @@ void __init ftrace_init(void) /* Keep the ftrace pointer to the stub */ addr = (unsigned long)ftrace_stub; @@ -7085,7 +7383,7 @@ index 4689cb0..3d12764 100644 /* diff --git a/mm/memory.c b/mm/memory.c -index aaaedbd..4fa38b5 100644 +index 7550758..e96effb 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -642,6 +642,32 @@ out: @@ -7244,7 +7542,7 @@ index aaaedbd..4fa38b5 100644 /* * This routine handles present pages, when users try to write * to a shared page. It is done by copying the page to a new address -@@ -3545,3 +3591,111 @@ void might_fault(void) +@@ -3589,3 +3635,111 @@ void might_fault(void) } EXPORT_SYMBOL(might_fault); #endif _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git