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

Reply via email to