]> xenbits.xensource.com Git - xen.git/commitdiff
trace: Notify dom0 from tasklet context.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 24 Apr 2008 08:58:29 +0000 (09:58 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 24 Apr 2008 08:58:29 +0000 (09:58 +0100)
Avoids deadlocks by avoiding calling into scheduler recursively
(__trace_var() is sometimes called with scheduler locks held).

Signed-off-by: Naoki Nishiguchi <nisiguti@jp.fujitsu.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/trace.c

index 12ff7a029c6efd0663452d67ffab478bab7bea59..6275f10e27c9d0fa0164360e6b49a7433d1ea4ed 100644 (file)
@@ -374,6 +374,15 @@ static inline int insert_lost_records(struct t_buf *buf)
                            (unsigned char *)&ed);
 }
 
+/*
+ * Notification is performed in qtasklet to avoid deadlocks with contexts
+ * which __trace_var() may be called from (e.g., scheduler critical regions).
+ */
+static void trace_notify_dom0(unsigned long unused)
+{
+    send_guest_global_virq(dom0, VIRQ_TBUF);
+}
+static DECLARE_TASKLET(trace_notify_dom0_tasklet, trace_notify_dom0, 0);
 
 /**
  * trace - Enters a trace tuple into the trace buffer for the current CPU.
@@ -506,7 +515,7 @@ void __trace_var(u32 event, int cycles, int extra, unsigned char *extra_data)
     /* Notify trace buffer consumer that we've crossed the high water mark. */
     if ( started_below_highwater &&
          (calc_unconsumed_bytes(buf) >= t_buf_highwater) )
-        send_guest_global_virq(dom0, VIRQ_TBUF);
+        tasklet_schedule(&trace_notify_dom0_tasklet);
 }
 
 /*