All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Fix deadlock in schedule.c at TRACE mode
@ 2008-04-24  4:34 NISHIGUCHI Naoki
  2008-04-24  5:42 ` Atsushi SAKAI
  0 siblings, 1 reply; 4+ messages in thread
From: NISHIGUCHI Naoki @ 2008-04-24  4:34 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 455 bytes --]

Hi,

In schedule.c, schedule() and sched_adjust() call trace functions during
acquiring lock of schedule_lock in each cpu's schedule_data. When trace
buffers are enabled, the trace function (__trace_var()) may call
vcpu_wake() by calling send_guest_global_virq(). In the case, a deadlock
occurs when acquiring lock of schedule_lock.

Attached patch fixes this problem.

Signed-off-by: Naoki Nishiguchi <nisiguti@jp.fujitsu.com>

Regards,
Naoki Nishiguchi

[-- Attachment #2: fix_deadlock.patch --]
[-- Type: text/plain, Size: 2165 bytes --]

diff -r 77dec8732cde xen/common/schedule.c
--- a/xen/common/schedule.c	Wed Apr 23 16:58:44 2008 +0100
+++ b/xen/common/schedule.c	Thu Apr 24 11:19:25 2008 +0900
@@ -605,11 +605,13 @@ long sched_adjust(struct domain *d, stru
     if ( d == current->domain )
         vcpu_schedule_lock_irq(current);
 
-    if ( (ret = SCHED_OP(adjust, d, op)) == 0 )
-        TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
+    ret = SCHED_OP(adjust, d, op);
 
     if ( d == current->domain )
         vcpu_schedule_unlock_irq(current);
+
+    if ( ret == 0 )
+        TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id);
 
     for_each_vcpu ( d, v )
     {
@@ -654,6 +656,7 @@ static void schedule(void)
     struct schedule_data *sd;
     struct task_slice     next_slice;
     s32                   r_time;     /* time for new dom to run */
+    uint64_t              prev_state_time, next_state_time;
 
     ASSERT(!in_irq());
     ASSERT(this_cpu(mc_state).flags == 0);
@@ -682,14 +685,10 @@ static void schedule(void)
         return continue_running(prev);
     }
 
-    TRACE_2D(TRC_SCHED_SWITCH_INFPREV,
-             prev->domain->domain_id,
-             now - prev->runstate.state_entry_time);
-    TRACE_3D(TRC_SCHED_SWITCH_INFNEXT,
-             next->domain->domain_id,
-             (next->runstate.state == RUNSTATE_runnable) ?
-             (now - next->runstate.state_entry_time) : 0,
-             r_time);
+    /* Temporarily save the period of previous runstate. */
+    prev_state_time = now - prev->runstate.state_entry_time;
+    next_state_time = (next->runstate.state == RUNSTATE_runnable) ?
+                      (now - next->runstate.state_entry_time) : 0;
 
     ASSERT(prev->runstate.state == RUNSTATE_running);
     vcpu_runstate_change(
@@ -705,6 +704,12 @@ static void schedule(void)
     next->is_running = 1;
 
     spin_unlock_irq(&sd->schedule_lock);
+
+    /* Avoid deadlock by calling the trace function after unlock. */
+    TRACE_2D(TRC_SCHED_SWITCH_INFPREV,
+             prev->domain->domain_id, prev_state_time);
+    TRACE_3D(TRC_SCHED_SWITCH_INFNEXT,
+             next->domain->domain_id, next_state_time, r_time);
 
     perfc_incr(sched_ctx);
 

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-04-24  7:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-24  4:34 [PATCH] Fix deadlock in schedule.c at TRACE mode NISHIGUCHI Naoki
2008-04-24  5:42 ` Atsushi SAKAI
2008-04-24  7:03   ` NISHIGUCHI Naoki
2008-04-24  7:29     ` Keir Fraser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.