Jan Kiszka wrote:
> Jan Kiszka wrote:
> 
>>...
>>Meanwhile I found a solution for the described unterminated trace (put
>>an explicite trace_end at the end of __ipipe_unstall_iret_root),
>>included the irq number in the begin/end report, and stumbled over some
>>other remaining unterminated trace on a different machine. So, no need
>>to hurry with the merge (not the review! ;) ), I will publish a second
>>revision first.
>>
> 
> 
> And here comes this revision finally. Should apply (almost) cleanly
> against latest ipipe versions. Additionally to the changes of the first
> revision this one addresses the following topics:
> 
>  o fix trace overrun handling
>  o report IRQ number to tracer on IRQ entry/exit
>  o fix virtually leaking IRQs-off in __ipipe_unstall_iret_root()
>  o fix another potential NMI race
>  o really trace the maximum IRQs-off time, not the maximum time of
>    consecutive IRQs-off times (that scenario will soon be addressed
>    instead  in the latency benchmark tool => reset&freeze the maximum
>    latency from the user's point of view)

...and it turned out that the existing functions were no sufficient for
this. So here comes an add-on patch to update3:

 o allow ipipe_trace_{frozen|max}_reset from every context
   (well, at least give it a try and just fail on locked traces)
 o mark border between valid and invalid trace points
 o show invalid points border

Apply order:

ipipe_tracer.update3
ipipe_tracer.update3-1

The front-end to the first change, a modified latency+timerbench will
get committed to Xenomai soon. It already works nicely, automatically
creating a freeze of the maximum latency turn the benchmark perceives.

Jan
--- linux-2.6.14.3/kernel/ipipe/tracer.c.orig   2006-01-06 11:13:41.000000000 
+0100
+++ linux-2.6.14.3/kernel/ipipe/tracer.c        2006-01-06 20:11:10.000000000 
+0100
@@ -134,10 +134,14 @@ __ipipe_migrate_pre_trace(struct ipipe_t
        int i;
 
        new_tp->trace_pos = pre_trace+1;
+
        for (i = new_tp->trace_pos; i > 0; i--)
                memcpy(&new_tp->point[WRAP_POINT_NO(new_tp->trace_pos-i)],
                       &old_tp->point[WRAP_POINT_NO(old_pos-i)],
                       sizeof(struct ipipe_trace_point));
+
+       /* mark the end (i.e. the point before point[0]) invalid */
+       new_tp->point[IPIPE_TRACE_POINTS-1].eip = 0;
 }
 
 static notrace struct ipipe_trace_path *
@@ -436,21 +440,23 @@ void notrace ipipe_trace_special(unsigne
 }
 EXPORT_SYMBOL(ipipe_trace_special);
 
-void ipipe_trace_max_reset(void)
+int ipipe_trace_max_reset(void)
 {
        int cpu_id;
        unsigned long flags;
        struct ipipe_trace_path *path;
+       int ret = 0;
 
-       /* only allowed from root domain (we sync with /proc routines) */
-       if (ipipe_current_domain != ipipe_root_domain)
-               return;
-
-       down(&out_mutex);
        flags = __ipipe_global_path_lock();
 
        for_each_cpu(cpu_id) {
                path = &trace_paths[cpu_id][max_path[cpu_id]];
+
+               if (path->dump_lock) {
+                       ret = -EBUSY;
+                       break;
+               }
+
                path->begin     = -1;
                path->end       = -1;
                path->trace_pos = 0;
@@ -458,25 +464,28 @@ void ipipe_trace_max_reset(void)
        }
 
        __ipipe_global_path_unlock(flags);
-       up(&out_mutex);
+
+       return ret;
 }
 EXPORT_SYMBOL(ipipe_trace_max_reset);
 
-void ipipe_trace_frozen_reset(void)
+int ipipe_trace_frozen_reset(void)
 {
        int cpu_id;
        unsigned long flags;
        struct ipipe_trace_path *path;
+       int ret = 0;
 
-       /* only allowed from root domain (we sync with /proc routines) */
-       if (ipipe_current_domain != ipipe_root_domain)
-               return;
-
-       down(&out_mutex);
        flags = __ipipe_global_path_lock();
 
        for_each_cpu(cpu_id) {
                path = &trace_paths[cpu_id][frozen_path[cpu_id]];
+
+               if (path->dump_lock) {
+                       ret = -EBUSY;
+                       break;
+               }
+
                path->begin = -1;
                path->end = -1;
                path->trace_pos = 0;
@@ -484,7 +493,8 @@ void ipipe_trace_frozen_reset(void)
        }
 
        __ipipe_global_path_unlock(flags);
-       up(&out_mutex);
+
+       return ret;
 }
 EXPORT_SYMBOL(ipipe_trace_frozen_reset);
 
@@ -684,8 +694,10 @@ static int __ipipe_prtrace_show(struct s
        unsigned long long abs_delta;
        struct ipipe_trace_point *point = p;
 
-       if (!point->eip)
+       if (!point->eip) {
+               seq_puts(m, "-<invalid>-\n");
                return 0;
+       }
 
        /* ipipe_tsc2us works on unsigned => handle sign separately */
        delta = point->timestamp -
@@ -749,7 +761,10 @@ static ssize_t
 __ipipe_max_reset(struct file *file, const char __user *pbuffer,
                   size_t count, loff_t *data)
 {
+       down(&out_mutex);
        ipipe_trace_max_reset();
+       up(&out_mutex);
+
        return count;
 }
 
@@ -841,7 +856,10 @@ static ssize_t
 __ipipe_frozen_reset(struct file *file, const char __user *pbuffer,
                      size_t count, loff_t *data)
 {
+       down(&out_mutex);
        ipipe_trace_frozen_reset();
+       up(&out_mutex);
+
        return count;
 }
 
--- linux-2.6.14.3/include/linux/ipipe_trace.h.orig     2006-01-06 
11:13:41.000000000 +0100
+++ linux-2.6.14.3/include/linux/ipipe_trace.h  2006-01-06 12:37:19.000000000 
+0100
@@ -28,7 +28,7 @@ void ipipe_trace_end(unsigned long v);
 void ipipe_trace_freeze(unsigned long v);
 void ipipe_trace_special(unsigned char special_id, unsigned long v);
 
-void ipipe_trace_max_reset(void);
-void ipipe_trace_frozen_reset(void);
+int ipipe_trace_max_reset(void);
+int ipipe_trace_frozen_reset(void);
 
 #endif /* !__LINUX_IPIPE_H */

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to