Hi,

as promised, here is the patch to extend the I-ipipe trace so that it
displays also the domain stall flags of the first 4 domains (I don't
expect more in practice yet ;) ). The information is shown if you switch
on the verbose mode (echo 1 > /proc/ipipe/tracer/verbose). Also, more
explanation of the shown columns is given now.

Please apply.

Jan
---
 kernel/ipipe/core.c   |    4 --
 kernel/ipipe/tracer.c |   77 +++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 71 insertions(+), 10 deletions(-)

Index: linux-2.6.15.3-kgdb/kernel/ipipe/core.c
===================================================================
--- linux-2.6.15.3-kgdb.orig/kernel/ipipe/core.c
+++ linux-2.6.15.3-kgdb/kernel/ipipe/core.c
@@ -40,7 +40,7 @@ struct ipipe_domain *ipipe_percpu_domain
 
 ipipe_spinlock_t __ipipe_pipelock = IPIPE_SPIN_LOCK_UNLOCKED;
 
-struct list_head __ipipe_pipeline;
+LIST_HEAD(__ipipe_pipeline);
 
 unsigned long __ipipe_virtual_irq_map = 0;
 
@@ -66,8 +66,6 @@ void ipipe_init(void)
 	 * secondary CPUs are still lost in space.
 	 */
 
-	INIT_LIST_HEAD(&__ipipe_pipeline);
-
 	ipd->name = "Linux";
 	ipd->domid = IPIPE_ROOT_ID;
 	ipd->priority = IPIPE_ROOT_PRIO;
Index: linux-2.6.15.3-kgdb/kernel/ipipe/tracer.c
===================================================================
--- linux-2.6.15.3-kgdb.orig/kernel/ipipe/tracer.c
+++ linux-2.6.15.3-kgdb/kernel/ipipe/tracer.c
@@ -51,6 +51,7 @@
 
 #define IPIPE_TFLG_HWIRQ_OFF        0x0100
 #define IPIPE_TFLG_FREEZING         0x0200
+#define IPIPE_TFLG_DOMSTATE_SHIFT   12   /* bits 12..15: domain stalled? */
 
 
 struct ipipe_trace_point{
@@ -118,6 +119,24 @@ __ipipe_trace_point_type(char *buf, stru
 static void __ipipe_print_symname(struct seq_file *m, unsigned long eip);
 
 
+static notrace void
+__ipipe_store_domain_states(struct ipipe_trace_point *point, int cpu_id)
+{
+	int i = IPIPE_TFLG_DOMSTATE_SHIFT;
+	struct list_head *pos;
+
+	list_for_each_prev(pos, &__ipipe_pipeline) {
+		struct ipipe_domain *ipd =
+			list_entry(pos, struct ipipe_domain, p_link);
+
+		if (test_bit(IPIPE_STALL_FLAG, &ipd->cpudata[cpu_id].status))
+			point->flags |= (1 << i);
+
+		if (++i > IPIPE_TFLG_DOMSTATE_SHIFT+3)
+			break;
+	}
+}
+
 static notrace int __ipipe_get_free_trace_path(int old, int cpu_id)
 {
 	int new_active = old;
@@ -282,6 +301,8 @@ restart:
 	point->v = v;
 	ipipe_read_tsc(point->timestamp);
 
+	__ipipe_store_domain_states(point, cpu_id);
+
 	/* forward to next point buffer */
 	next_pos = WRAP_POINT_NO(pos+1);
 	tp->trace_pos = next_pos;
@@ -617,6 +638,7 @@ __ipipe_print_pathmark(struct seq_file *
 {
 	char mark = ' ';
 	int point_no = point - print_path->point;
+	int i;
 
 	if (print_path->end == point_no)
 		mark = '<';
@@ -626,6 +648,12 @@ __ipipe_print_pathmark(struct seq_file *
 		mark = ':';
 	seq_printf(m, "%c%c", mark,
 	           (point->flags & IPIPE_TFLG_HWIRQ_OFF) ? '|' : ' ');
+
+	if (verbose_trace)
+		for (i = IPIPE_TFLG_DOMSTATE_SHIFT + 3;
+		     i >= IPIPE_TFLG_DOMSTATE_SHIFT; i--)
+			seq_printf(m, "%c",
+			           (point->flags & (1 << i)) ? '*' : ' ');
 }
 
 static void
@@ -695,6 +723,9 @@ static void __ipipe_print_dbgwarning(str
 #ifdef CONFIG_XENO_OPT_DEBUG
 		" o CONFIG_XENO_OPT_DEBUG\n"
 #endif /* CONFIG_XENO_OPT_DEBUG */
+#ifdef CONFIG_XENO_OPT_DEBUG_QUEUES
+		" o CONFIG_XENO_OPT_DEBUG_QUEUES (very costly)\n"
+#endif /* CONFIG_XENO_OPT_DEBUG */
 #ifdef CONFIG_DEBUG_PREEMPT
 		" o CONFIG_DEBUG_PREEMPT\n"
 #endif /* CONFIG_DEBUG_PREEMPT */
@@ -706,9 +737,44 @@ static void __ipipe_print_dbgwarning(str
 
 static void __ipipe_print_headline(struct seq_file *m)
 {
-	seq_puts(m, verbose_trace ?
-		"  Type   User Val.   Time    Delay  Function (Parent)\n" :
-		"  Type    Time   Function (Parent)\n");
+	if (verbose_trace) {
+		const char *name[4] = { [0 ... 3] = "<unused>" };
+		struct list_head *pos;
+		int i = 0;
+
+		list_for_each_prev(pos, &__ipipe_pipeline) {
+			struct ipipe_domain *ipd =
+				list_entry(pos, struct ipipe_domain, p_link);
+
+			name[i] = ipd->name;
+			if (++i > 3)
+				break;
+		}
+
+		seq_printf(m,
+		           " +----- Hard IRQs ('|': locked)\n"
+		           " |+---- %s\n"
+		           " ||+--- %s\n"
+		           " |||+-- %s\n"
+		           " ||||+- %s%s\n"
+		           " |||||                       +---------- "
+		               "Delay flag ('+': > %d us, '!': > %d us)\n"
+		           " |||||                       |        +- "
+		               "NMI noise ('N')\n"
+		           " |||||                       |        |\n"
+		           "      Type   User Val.   Time    Delay  Function "
+		               "(Parent)\n",
+		           name[3], name[2], name[1], name[0],
+		           name[0] ? " ('*': domain stalled)" : "",
+		           IPIPE_DELAY_NOTE/1000, IPIPE_DELAY_WARN/1000);
+	} else
+		seq_printf(m,
+		           " +-------------- Hard IRQs ('|': locked)\n"
+		           " |            +- Delay flag "
+		               "('+': > %d us, '!': > %d us)\n"
+		           " |            |\n"
+		           "  Type    Time   Function (Parent)\n",
+		           IPIPE_DELAY_NOTE/1000, IPIPE_DELAY_WARN/1000);
 }
 
 static void *__ipipe_max_prtrace_start(struct seq_file *m, loff_t *pos)
@@ -914,10 +980,7 @@ static void *__ipipe_frozen_prtrace_star
 		seq_printf(m, "Freeze: %lld cycles, Trace Points: %d (+%d)\n\n",
 			print_path->point[print_path->begin].timestamp,
 			print_pre_trace+1, print_post_trace);
-
-		seq_puts(m, verbose_trace ?
-			"  Type   User Val.   Time    Delay  Function (Parent)\n" :
-			"  Type    Time   Function (Parent)\n");
+		__ipipe_print_headline(m);
 	}
 
 	/* check if we are inside the trace range */

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to