direct-io.hg

changeset 6445:83c73802f02a

Clean up and fix domain_pause and friends. Synchronous
pause should not only wait for the running flag to clear,
but also for the scheduler lock to be released. Also get
rid of some unused sync_lazy_execstate functions.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Aug 26 09:29:54 2005 +0000 (2005-08-26)
parents 9312a3e8a6f8
children 581be7c5e9e4
files xen/arch/ia64/linux-xen/irq_ia64.c xen/arch/ia64/patch/linux-2.6.11/irq_ia64.c xen/arch/ia64/patch/linux-2.6.7/irq_ia64.c xen/arch/ia64/patch/linux-2.6.7/time.c xen/arch/ia64/xenirq.c xen/arch/ia64/xenmisc.c xen/arch/ia64/xentime.c xen/arch/x86/audit.c xen/arch/x86/domain.c xen/common/domain.c xen/common/schedule.c xen/include/asm-x86/mm.h xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/irq_ia64.c	Fri Aug 26 09:05:43 2005 +0000
     1.2 +++ b/xen/arch/ia64/linux-xen/irq_ia64.c	Fri Aug 26 09:29:54 2005 +0000
     1.3 @@ -265,7 +265,7 @@ vmx_ia64_handle_irq (ia64_vector vector,
     1.4  	 */
     1.5  	vmx_irq_exit();
     1.6  	if ( wake_dom0 && current != dom0 ) 
     1.7 -		domain_wake(dom0->vcpu[0]);
     1.8 +		vcpu_wake(dom0->vcpu[0]);
     1.9  }
    1.10  #endif
    1.11  
     2.1 --- a/xen/arch/ia64/patch/linux-2.6.11/irq_ia64.c	Fri Aug 26 09:05:43 2005 +0000
     2.2 +++ b/xen/arch/ia64/patch/linux-2.6.11/irq_ia64.c	Fri Aug 26 09:29:54 2005 +0000
     2.3 @@ -116,7 +116,7 @@
     2.4  +	 */
     2.5  +	vmx_irq_exit();
     2.6  +	if ( wake_dom0 && current != dom0 ) 
     2.7 -+		domain_wake(dom0->vcpu[0]);
     2.8 ++		vcpu_wake(dom0->vcpu[0]);
     2.9  +}
    2.10  +#endif
    2.11  +
     3.1 --- a/xen/arch/ia64/patch/linux-2.6.7/irq_ia64.c	Fri Aug 26 09:05:43 2005 +0000
     3.2 +++ b/xen/arch/ia64/patch/linux-2.6.7/irq_ia64.c	Fri Aug 26 09:29:54 2005 +0000
     3.3 @@ -73,7 +73,7 @@
     3.4  +#endif
     3.5  +		//FIXME: TEMPORARY HACK!!!!
     3.6  +		vcpu_pend_interrupt(dom0->vcpu[0],vector);
     3.7 -+		domain_wake(dom0->vcpu[0]);
     3.8 ++		vcpu_wake(dom0->vcpu[0]);
     3.9  +	}
    3.10  +	else
    3.11  +#endif
     4.1 --- a/xen/arch/ia64/patch/linux-2.6.7/time.c	Fri Aug 26 09:05:43 2005 +0000
     4.2 +++ b/xen/arch/ia64/patch/linux-2.6.7/time.c	Fri Aug 26 09:29:54 2005 +0000
     4.3 @@ -209,14 +209,14 @@
     4.4  +	if (domain0_ready && vcpu_timer_expired(dom0->vcpu[0])) {
     4.5  +		vcpu_pend_timer(dom0->vcpu[0]);
     4.6  +		//vcpu_set_next_timer(dom0->vcpu[0]);
     4.7 -+		domain_wake(dom0->vcpu[0]);
     4.8 ++		vcpu_wake(dom0->vcpu[0]);
     4.9  +	}
    4.10  +	if (!is_idle_task(current->domain) && current->domain != dom0) {
    4.11  +		if (vcpu_timer_expired(current)) {
    4.12  +			vcpu_pend_timer(current);
    4.13  +			// ensure another timer interrupt happens even if domain doesn't
    4.14  +			vcpu_set_next_timer(current);
    4.15 -+			domain_wake(current);
    4.16 ++			vcpu_wake(current);
    4.17  +		}
    4.18  +	}
    4.19  +	raise_actimer_softirq();
     5.1 --- a/xen/arch/ia64/xenirq.c	Fri Aug 26 09:05:43 2005 +0000
     5.2 +++ b/xen/arch/ia64/xenirq.c	Fri Aug 26 09:29:54 2005 +0000
     5.3 @@ -50,7 +50,7 @@ xen_do_IRQ(ia64_vector vector)
     5.4  #endif
     5.5  		//FIXME: TEMPORARY HACK!!!!
     5.6  		vcpu_pend_interrupt(dom0->vcpu[0],vector);
     5.7 -		domain_wake(dom0->vcpu[0]);
     5.8 +		vcpu_wake(dom0->vcpu[0]);
     5.9  		return(1);
    5.10  	}
    5.11  	return(0);
     6.1 --- a/xen/arch/ia64/xenmisc.c	Fri Aug 26 09:05:43 2005 +0000
     6.2 +++ b/xen/arch/ia64/xenmisc.c	Fri Aug 26 09:29:54 2005 +0000
     6.3 @@ -59,8 +59,6 @@ platform_is_hp_ski(void)
     6.4  /* calls in xen/common code that are unused on ia64 */
     6.5  
     6.6  void sync_lazy_execstate_cpu(unsigned int cpu) {}
     6.7 -void sync_lazy_execstate_mask(cpumask_t mask) {}
     6.8 -void sync_lazy_execstate_all(void) {}
     6.9  
    6.10  #ifdef CONFIG_VTI
    6.11  int grant_table_create(struct domain *d) { return 0; }
     7.1 --- a/xen/arch/ia64/xentime.c	Fri Aug 26 09:05:43 2005 +0000
     7.2 +++ b/xen/arch/ia64/xentime.c	Fri Aug 26 09:29:54 2005 +0000
     7.3 @@ -162,14 +162,14 @@ xen_timer_interrupt (int irq, void *dev_
     7.4  	if (domain0_ready && vcpu_timer_expired(dom0->vcpu[0])) {
     7.5  		vcpu_pend_timer(dom0->vcpu[0]);
     7.6  		//vcpu_set_next_timer(dom0->vcpu[0]);
     7.7 -		domain_wake(dom0->vcpu[0]);
     7.8 +		vcpu_wake(dom0->vcpu[0]);
     7.9  	}
    7.10  	if (!is_idle_task(current->domain) && current->domain != dom0) {
    7.11  		if (vcpu_timer_expired(current)) {
    7.12  			vcpu_pend_timer(current);
    7.13  			// ensure another timer interrupt happens even if domain doesn't
    7.14  			vcpu_set_next_timer(current);
    7.15 -			domain_wake(current);
    7.16 +			vcpu_wake(current);
    7.17  		}
    7.18  	}
    7.19  	raise_actimer_softirq();
     8.1 --- a/xen/arch/x86/audit.c	Fri Aug 26 09:05:43 2005 +0000
     8.2 +++ b/xen/arch/x86/audit.c	Fri Aug 26 09:29:54 2005 +0000
     8.3 @@ -735,7 +735,6 @@ void _audit_domain(struct domain *d, int
     8.4  
     8.5      if ( d != current->domain )
     8.6          domain_pause(d);
     8.7 -    sync_lazy_execstate_all();
     8.8  
     8.9      // Maybe we should just be using BIGLOCK?
    8.10      //
     9.1 --- a/xen/arch/x86/domain.c	Fri Aug 26 09:05:43 2005 +0000
     9.2 +++ b/xen/arch/x86/domain.c	Fri Aug 26 09:29:54 2005 +0000
     9.3 @@ -888,24 +888,14 @@ int __sync_lazy_execstate(void)
     9.4  void sync_lazy_execstate_cpu(unsigned int cpu)
     9.5  {
     9.6      if ( cpu == smp_processor_id() )
     9.7 -        (void)__sync_lazy_execstate();
     9.8 -    else
     9.9 -        flush_tlb_mask(cpumask_of_cpu(cpu));
    9.10 -}
    9.11 -
    9.12 -void sync_lazy_execstate_mask(cpumask_t mask)
    9.13 -{
    9.14 -    if ( cpu_isset(smp_processor_id(), mask) )
    9.15 +    {
    9.16          (void)__sync_lazy_execstate();
    9.17 -    /* Other cpus call __sync_lazy_execstate from flush ipi handler. */
    9.18 -    flush_tlb_mask(mask);
    9.19 -}
    9.20 -
    9.21 -void sync_lazy_execstate_all(void)
    9.22 -{
    9.23 -    __sync_lazy_execstate();
    9.24 -    /* Other cpus call __sync_lazy_execstate from flush ipi handler. */
    9.25 -    flush_tlb_mask(cpu_online_map);
    9.26 +    }
    9.27 +    else
    9.28 +    {
    9.29 +        /* Other cpus call __sync_lazy_execstate from flush ipi handler. */
    9.30 +        flush_tlb_mask(cpumask_of_cpu(cpu));
    9.31 +    }
    9.32  }
    9.33  
    9.34  unsigned long __hypercall_create_continuation(
    10.1 --- a/xen/common/domain.c	Fri Aug 26 09:05:43 2005 +0000
    10.2 +++ b/xen/common/domain.c	Fri Aug 26 09:29:54 2005 +0000
    10.3 @@ -152,10 +152,7 @@ static void domain_shutdown_finalise(voi
    10.4  
    10.5      /* Make sure that every vcpu is descheduled before we finalise. */
    10.6      for_each_vcpu ( d, v )
    10.7 -        while ( test_bit(_VCPUF_running, &v->vcpu_flags) )
    10.8 -            cpu_relax();
    10.9 -
   10.10 -    sync_lazy_execstate_mask(d->cpumask);
   10.11 +        vcpu_sleep_sync(v);
   10.12      BUG_ON(!cpus_empty(d->cpumask));
   10.13  
   10.14      sync_pagetable_state(d);
   10.15 @@ -209,7 +206,7 @@ void domain_shutdown(u8 reason)
   10.16  
   10.17      /* Put every vcpu to sleep, but don't wait (avoids inter-vcpu deadlock). */
   10.18      for_each_vcpu ( d, v )
   10.19 -        domain_sleep_nosync(v);
   10.20 +        vcpu_sleep_nosync(v);
   10.21  }
   10.22  
   10.23  
   10.24 @@ -226,7 +223,7 @@ void domain_pause_for_debugger(void)
   10.25      for_each_vcpu ( d, v )
   10.26      {
   10.27          set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
   10.28 -        domain_sleep_nosync(v);
   10.29 +        vcpu_sleep_nosync(v);
   10.30      }
   10.31  
   10.32      send_guest_virq(dom0->vcpu[0], VIRQ_DEBUGGER);
   10.33 @@ -275,7 +272,7 @@ void vcpu_pause(struct vcpu *v)
   10.34  {
   10.35      BUG_ON(v == current);
   10.36      atomic_inc(&v->pausecnt);
   10.37 -    domain_sleep_sync(v);
   10.38 +    vcpu_sleep_sync(v);
   10.39  }
   10.40  
   10.41  void domain_pause(struct domain *d)
   10.42 @@ -286,7 +283,7 @@ void domain_pause(struct domain *d)
   10.43      {
   10.44          BUG_ON(v == current);
   10.45          atomic_inc(&v->pausecnt);
   10.46 -        domain_sleep_sync(v);
   10.47 +        vcpu_sleep_sync(v);
   10.48      }
   10.49  }
   10.50  
   10.51 @@ -294,7 +291,7 @@ void vcpu_unpause(struct vcpu *v)
   10.52  {
   10.53      BUG_ON(v == current);
   10.54      if ( atomic_dec_and_test(&v->pausecnt) )
   10.55 -        domain_wake(v);
   10.56 +        vcpu_wake(v);
   10.57  }
   10.58  
   10.59  void domain_unpause(struct domain *d)
   10.60 @@ -313,7 +310,7 @@ void domain_pause_by_systemcontroller(st
   10.61      {
   10.62          BUG_ON(v == current);
   10.63          if ( !test_and_set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
   10.64 -            domain_sleep_sync(v);
   10.65 +            vcpu_sleep_sync(v);
   10.66      }
   10.67  }
   10.68  
   10.69 @@ -324,7 +321,7 @@ void domain_unpause_by_systemcontroller(
   10.70      for_each_vcpu ( d, v )
   10.71      {
   10.72          if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
   10.73 -            domain_wake(v);
   10.74 +            vcpu_wake(v);
   10.75      }
   10.76  }
   10.77  
   10.78 @@ -413,7 +410,7 @@ long do_boot_vcpu(unsigned long vcpu, st
   10.79  
   10.80      /* domain_unpause_by_systemcontroller */
   10.81      if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) )
   10.82 -        domain_wake(v);
   10.83 +        vcpu_wake(v);
   10.84  
   10.85      xfree(c);
   10.86      return 0;
    11.1 --- a/xen/common/schedule.c	Fri Aug 26 09:05:43 2005 +0000
    11.2 +++ b/xen/common/schedule.c	Fri Aug 26 09:29:54 2005 +0000
    11.3 @@ -193,7 +193,7 @@ void sched_rem_domain(struct vcpu *v)
    11.4      TRACE_2D(TRC_SCHED_DOM_REM, v->domain->domain_id, v->vcpu_id);
    11.5  }
    11.6  
    11.7 -void domain_sleep_nosync(struct vcpu *v)
    11.8 +void vcpu_sleep_nosync(struct vcpu *v)
    11.9  {
   11.10      unsigned long flags;
   11.11  
   11.12 @@ -205,18 +205,25 @@ void domain_sleep_nosync(struct vcpu *v)
   11.13      TRACE_2D(TRC_SCHED_SLEEP, v->domain->domain_id, v->vcpu_id);
   11.14  } 
   11.15  
   11.16 -void domain_sleep_sync(struct vcpu *v)
   11.17 +void vcpu_sleep_sync(struct vcpu *v)
   11.18  {
   11.19 -    domain_sleep_nosync(v);
   11.20 +    vcpu_sleep_nosync(v);
   11.21  
   11.22 -    while ( test_bit(_VCPUF_running, &v->vcpu_flags) && !domain_runnable(v) )
   11.23 +    /*
   11.24 +     * We can be sure that the VCPU is finally descheduled after the running
   11.25 +     * flag is cleared and the scheduler lock is released.
   11.26 +     */
   11.27 +    while ( test_bit(_VCPUF_running, &v->vcpu_flags)
   11.28 +            && !domain_runnable(v)
   11.29 +            && spin_is_locked(&schedule_data[v->processor].schedule_lock) )
   11.30          cpu_relax();
   11.31  
   11.32 +    /* Counteract lazy context switching. */
   11.33      if ( cpu_isset(v->processor, v->domain->cpumask) )
   11.34          sync_lazy_execstate_cpu(v->processor);
   11.35  }
   11.36  
   11.37 -void domain_wake(struct vcpu *v)
   11.38 +void vcpu_wake(struct vcpu *v)
   11.39  {
   11.40      unsigned long flags;
   11.41  
   11.42 @@ -293,7 +300,7 @@ static long do_vcpu_up(int vcpu)
   11.43          return -ESRCH;
   11.44      clear_bit(_VCPUF_down, &target->vcpu_flags);
   11.45      /* wake vcpu */
   11.46 -    domain_wake(target);
   11.47 +    vcpu_wake(target);
   11.48  
   11.49      return 0;
   11.50  }
   11.51 @@ -457,10 +464,10 @@ long sched_adjdom(struct sched_adjdom_cm
   11.52                  }
   11.53              }
   11.54          }
   11.55 -    } while (!succ);
   11.56 -    //spin_lock_irq(&schedule_data[d->vcpu[0]->processor].schedule_lock);
   11.57 +    } while ( !succ );
   11.58 +
   11.59      SCHED_OP(adjdom, d, cmd);
   11.60 -    //spin_unlock_irq(&schedule_data[d->vcpu[0]->processor].schedule_lock);
   11.61 +
   11.62      for (cpu = 0; cpu < NR_CPUS; cpu++)
   11.63          if (__get_cpu_bit(cpu, have_lock))
   11.64              spin_unlock(&schedule_data[cpu].schedule_lock);
   11.65 @@ -520,7 +527,8 @@ static void __enter_scheduler(void)
   11.66      perfc_incrc(sched_ctx);
   11.67  
   11.68  #if defined(WAKE_HISTO)
   11.69 -    if ( !is_idle_task(next->domain) && next->wokenup ) {
   11.70 +    if ( !is_idle_task(next->domain) && next->wokenup )
   11.71 +    {
   11.72          ulong diff = (ulong)(now - next->wokenup);
   11.73          diff /= (ulong)MILLISECS(1);
   11.74          if (diff <= BUCKETS-2)  schedule_data[cpu].hist[diff]++;
    12.1 --- a/xen/include/asm-x86/mm.h	Fri Aug 26 09:05:43 2005 +0000
    12.2 +++ b/xen/include/asm-x86/mm.h	Fri Aug 26 09:29:54 2005 +0000
    12.3 @@ -370,6 +370,8 @@ int new_guest_cr3(unsigned long pfn);
    12.4  
    12.5  void propagate_page_fault(unsigned long addr, u16 error_code);
    12.6  
    12.7 +extern int __sync_lazy_execstate(void);
    12.8 +
    12.9  /*
   12.10   * Caller must own d's BIGLOCK, is responsible for flushing the TLB, and must 
   12.11   * hold a reference to the page.
    13.1 --- a/xen/include/xen/sched.h	Fri Aug 26 09:05:43 2005 +0000
    13.2 +++ b/xen/include/xen/sched.h	Fri Aug 26 09:29:54 2005 +0000
    13.3 @@ -245,18 +245,15 @@ void sched_rem_domain(struct vcpu *);
    13.4  long sched_ctl(struct sched_ctl_cmd *);
    13.5  long sched_adjdom(struct sched_adjdom_cmd *);
    13.6  int  sched_id();
    13.7 -void domain_wake(struct vcpu *d);
    13.8 -void domain_sleep_nosync(struct vcpu *d);
    13.9 -void domain_sleep_sync(struct vcpu *d);
   13.10 +void vcpu_wake(struct vcpu *d);
   13.11 +void vcpu_sleep_nosync(struct vcpu *d);
   13.12 +void vcpu_sleep_sync(struct vcpu *d);
   13.13  
   13.14  /*
   13.15 - * Force loading of currently-executing domain state on the specified set
   13.16 - * of CPUs. This is used to counteract lazy state switching where required.
   13.17 + * Force loading of currently-executing domain state on the specified CPU.
   13.18 + * This is used to counteract lazy state switching where required.
   13.19   */
   13.20  extern void sync_lazy_execstate_cpu(unsigned int cpu);
   13.21 -extern void sync_lazy_execstate_mask(cpumask_t mask);
   13.22 -extern void sync_lazy_execstate_all(void);
   13.23 -extern int __sync_lazy_execstate(void);
   13.24  
   13.25  /*
   13.26   * Called by the scheduler to switch to another VCPU. On entry, although
   13.27 @@ -268,7 +265,7 @@ extern int __sync_lazy_execstate(void);
   13.28   * The callee must ensure that the local CPU is no longer running in @prev's
   13.29   * context, and that the context is saved to memory, before returning.
   13.30   * Alternatively, if implementing lazy context switching, it suffices to ensure
   13.31 - * that invoking __sync_lazy_execstate() will switch and commit @prev's state.
   13.32 + * that invoking sync_lazy_execstate() will switch and commit @prev's state.
   13.33   */
   13.34  extern void context_switch(
   13.35      struct vcpu *prev, 
   13.36 @@ -287,7 +284,8 @@ extern void context_switch_finalise(
   13.37  extern void continue_running(
   13.38      struct vcpu *same);
   13.39  
   13.40 -int idle_cpu(int cpu); /* Is CPU 'cpu' idle right now? */
   13.41 +/* Is CPU 'cpu' idle right now? */
   13.42 +int idle_cpu(int cpu);
   13.43  
   13.44  void startup_cpu_idle_loop(void);
   13.45  
   13.46 @@ -410,7 +408,7 @@ void cpu_init(void);
   13.47  static inline void vcpu_unblock(struct vcpu *v)
   13.48  {
   13.49      if ( test_and_clear_bit(_VCPUF_blocked, &v->vcpu_flags) )
   13.50 -        domain_wake(v);
   13.51 +        vcpu_wake(v);
   13.52  }
   13.53  
   13.54  #define IS_PRIV(_d)                                         \