Hi, I'm using linux-2.6.26 with Freescale patches and the adeos-ipipe-2.6.26-powerpc-DENX-2.2-04.patch from xenomai-2.4.5 on a Freescale PowerPC MPC8360.
I was calling 'vprintk' (kernel/printk.c) from within a Xenomai task which lead to a Linux freeze. After some investigation, I found out that just 'printk' is "Ipipe aware" (printk is implemented differently if CONFIG_IPIPE is defined) but not 'vprintk'. I rearranged the code (see patch) which actually does the job and makes 'vprintk' "Ipipe aware", too. The original 'vprintk' funktion was renamed '__vprintk'. I tested the code. My kernel boots fine and I can call vprintk from within a Xenomai task. Do you have any concerns with this approach? Andreas
--- linux-source-2.6.26/kernel/printk.c 2008-12-10 18:06:03.000000000 -0500 +++ linux-source-2.6.26.mod/kernel/printk.c 2008-12-17 09:40:24.000000000 -0500 @@ -583,41 +583,6 @@ return 0; } -#ifdef CONFIG_IPIPE - -static ipipe_spinlock_t __ipipe_printk_lock = IPIPE_SPIN_LOCK_UNLOCKED; - -static int __ipipe_printk_fill; - -static char __ipipe_printk_buf[__LOG_BUF_LEN]; - -void __ipipe_flush_printk (unsigned virq, void *cookie) -{ - char *p = __ipipe_printk_buf; - int len, lmax, out = 0; - unsigned long flags; - - goto start; - - do { - spin_unlock_irqrestore(&__ipipe_printk_lock, flags); - start: - lmax = __ipipe_printk_fill; - while (out < lmax) { - len = strlen(p) + 1; - printk("%s",p); - p += len; - out += len; - } - spin_lock_irqsave(&__ipipe_printk_lock, flags); - } - while (__ipipe_printk_fill != lmax); - - __ipipe_printk_fill = 0; - - spin_unlock_irqrestore(&__ipipe_printk_lock, flags); -} - /** * printk - print a kernel message * @fmt: format string @@ -640,48 +605,6 @@ * See also: * printf(3) */ - -asmlinkage int printk(const char *fmt, ...) -{ - int r, fbytes, oldcount, cs = -1; - unsigned long flags; - va_list args; - - va_start(args, fmt); - - if (test_bit(IPIPE_SPRINTK_FLAG,&ipipe_current_domain->flags) || - oops_in_progress) - cs = ipipe_disable_context_check(ipipe_processor_id()); - - if (ipipe_current_domain == ipipe_root_domain || cs != -1) { - r = vprintk(fmt, args); - if (cs != -1) - ipipe_restore_context_check(ipipe_processor_id(), cs); - goto out; - } - - spin_lock_irqsave(&__ipipe_printk_lock, flags); - - oldcount = __ipipe_printk_fill; - fbytes = __LOG_BUF_LEN - oldcount; - - if (fbytes > 1) { - r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, - fbytes, fmt, args) + 1; /* account for the null byte */ - __ipipe_printk_fill += r; - } else - r = 0; - - spin_unlock_irqrestore(&__ipipe_printk_lock, flags); - - if (oldcount == 0) - ipipe_trigger_irq(__ipipe_printk_virq); -out: - va_end(args); - - return r; -} -#else /* !CONFIG_IPIPE */ asmlinkage int printk(const char *fmt, ...) { va_list args; @@ -693,7 +616,6 @@ return r; } -#endif /* CONFIG_IPIPE */ /* cpu currently holding logbuf_lock */ static volatile unsigned int printk_cpu = UINT_MAX; @@ -749,7 +671,11 @@ KERN_CRIT "BUG: recent printk recursion!\n"; static int printk_recursion_bug; +#ifdef CONFIG_IPIPE +asmlinkage int __vprintk(const char *fmt, va_list args) +#else /* !CONFIG_IPIPE */ asmlinkage int vprintk(const char *fmt, va_list args) +#endif /* !CONFIG_IPIPE */ { static int log_level_unknown = 1; static char printk_buf[1024]; @@ -874,6 +800,78 @@ preempt_enable(); return printed_len; } + +#ifdef CONFIG_IPIPE +static ipipe_spinlock_t __ipipe_printk_lock = IPIPE_SPIN_LOCK_UNLOCKED; + +static int __ipipe_printk_fill; + +static char __ipipe_printk_buf[__LOG_BUF_LEN]; + +void __ipipe_flush_printk (unsigned virq, void *cookie) +{ + char *p = __ipipe_printk_buf; + int len, lmax, out = 0; + unsigned long flags; + + goto start; + + do { + spin_unlock_irqrestore(&__ipipe_printk_lock, flags); + start: + lmax = __ipipe_printk_fill; + while (out < lmax) { + len = strlen(p) + 1; + printk("%s",p); + p += len; + out += len; + } + spin_lock_irqsave(&__ipipe_printk_lock, flags); + } + while (__ipipe_printk_fill != lmax); + + __ipipe_printk_fill = 0; + + spin_unlock_irqrestore(&__ipipe_printk_lock, flags); +} + +asmlinkage int vprintk(const char *fmt, va_list args) +{ + int r, fbytes, oldcount, cs = -1; + unsigned long flags; + + if (test_bit(IPIPE_SPRINTK_FLAG,&ipipe_current_domain->flags) || + oops_in_progress) + cs = ipipe_disable_context_check(ipipe_processor_id()); + + if (ipipe_current_domain == ipipe_root_domain || cs != -1) { + r = __vprintk(fmt, args); + if (cs != -1) + ipipe_restore_context_check(ipipe_processor_id(), cs); + goto out; + } + + spin_lock_irqsave(&__ipipe_printk_lock, flags); + + oldcount = __ipipe_printk_fill; + fbytes = __LOG_BUF_LEN - oldcount; + + if (fbytes > 1) { + r = vscnprintf(__ipipe_printk_buf + __ipipe_printk_fill, + fbytes, fmt, args) + 1; /* account for the null byte */ + __ipipe_printk_fill += r; + } else + r = 0; + + spin_unlock_irqrestore(&__ipipe_printk_lock, flags); + + if (oldcount == 0) + ipipe_trigger_irq(__ipipe_printk_virq); +out: + return r; +} +#endif /* CONFIG_IPIPE */ + EXPORT_SYMBOL(printk); EXPORT_SYMBOL(vprintk);
_______________________________________________ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core