From 628bdecb85a3a7d591e39402bd61a6d67cd205fb Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 24 Apr 2008 09:58:29 +0100 Subject: [PATCH] trace: Notify dom0 from tasklet context. Avoids deadlocks by avoiding calling into scheduler recursively (__trace_var() is sometimes called with scheduler locks held). Signed-off-by: Naoki Nishiguchi Signed-off-by: Keir Fraser --- xen/common/trace.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/xen/common/trace.c b/xen/common/trace.c index 12ff7a029c..6275f10e27 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -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); } /* -- 2.39.5