ia64/xen-unstable

changeset 2886:7d76c53dcca9

bitkeeper revision 1.1159.163.1 (418a492cLmf4ERioALCFwIiwi2Qh4g)

Fix idle loop to play nicely with RCU. Gets rid of annoying delays
during xenU boot. Also cleaned up the idle code in XenLinux.
author kaf24@freefall.cl.cam.ac.uk
date Thu Nov 04 15:22:20 2004 +0000 (2004-11-04)
parents 9813d8e70a3b
children e17af491ba26
files .rootkeys linux-2.6.9-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile linux-2.6.9-xen-sparse/arch/xen/kernel/process.c
line diff
     1.1 --- a/.rootkeys	Thu Nov 04 11:27:56 2004 +0000
     1.2 +++ b/.rootkeys	Thu Nov 04 15:22:20 2004 +0000
     1.3 @@ -175,7 +175,6 @@ 40f56239pYRq5yshPTkv3ujXKc8K6g linux-2.6
     1.4  40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c
     1.5  4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.9-xen-sparse/arch/xen/kernel/fixup.c
     1.6  412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.9-xen-sparse/arch/xen/kernel/gnttab.c
     1.7 -40f56239sFcjHiIRmnObRIDF-zaeKQ linux-2.6.9-xen-sparse/arch/xen/kernel/process.c
     1.8  40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.9-xen-sparse/arch/xen/kernel/reboot.c
     1.9  414c113396tK1HTVeUalm3u-1DF16g linux-2.6.9-xen-sparse/arch/xen/kernel/skbuff.c
    1.10  3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.9-xen-sparse/arch/xen/kernel/xen_proc.c
     2.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/process.c	Thu Nov 04 11:27:56 2004 +0000
     2.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/process.c	Thu Nov 04 15:22:20 2004 +0000
     2.3 @@ -86,50 +86,25 @@ void enable_hlt(void)
     2.4  
     2.5  EXPORT_SYMBOL(enable_hlt);
     2.6  
     2.7 -/*
     2.8 - * We use this if we don't have any better
     2.9 - * idle routine..
    2.10 - */
    2.11 -void default_idle(void)
    2.12 -{
    2.13 -	if (!hlt_counter && current_cpu_data.hlt_works_ok) {
    2.14 -		local_irq_disable();
    2.15 -		if (!need_resched())
    2.16 -			safe_halt();
    2.17 -		else
    2.18 -			local_irq_enable();
    2.19 -	}
    2.20 -}
    2.21 -
    2.22 -/*
    2.23 - * On SMP it's slightly faster (but much more power-consuming!)
    2.24 - * to poll the ->work.need_resched flag instead of waiting for the
    2.25 - * cross-CPU IPI to arrive. Use this option with caution.
    2.26 - */
    2.27 -static void poll_idle (void)
    2.28 +/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
    2.29 +extern int set_timeout_timer(void);
    2.30 +void xen_idle(void)
    2.31  {
    2.32 -	int oldval;
    2.33 -
    2.34 -	local_irq_enable();
    2.35 +	int cpu = smp_processor_id();
    2.36  
    2.37 -	/*
    2.38 -	 * Deal with another CPU just having chosen a thread to
    2.39 -	 * run here:
    2.40 -	 */
    2.41 -	oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
    2.42 +	local_irq_disable();
    2.43 +
    2.44 +	if (rcu_pending(cpu))
    2.45 +		rcu_check_callbacks(cpu, 0);
    2.46  
    2.47 -	if (!oldval) {
    2.48 -		set_thread_flag(TIF_POLLING_NRFLAG);
    2.49 -		asm volatile(
    2.50 -			"2:"
    2.51 -			"testl %0, %1;"
    2.52 -			"rep; nop;"
    2.53 -			"je 2b;"
    2.54 -			: : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
    2.55 -
    2.56 -		clear_thread_flag(TIF_POLLING_NRFLAG);
    2.57 +	if (need_resched()) {
    2.58 +		local_irq_enable();
    2.59 +	} else if (set_timeout_timer() == 0) {
    2.60 +		/* NB. Blocking reenable events in a race-free manner. */
    2.61 +		HYPERVISOR_block();
    2.62  	} else {
    2.63 -		set_need_resched();
    2.64 +		local_irq_enable();
    2.65 +		HYPERVISOR_yield();
    2.66  	}
    2.67  }
    2.68  
    2.69 @@ -144,82 +119,23 @@ void cpu_idle (void)
    2.70  	/* endless idle loop with no priority at all */
    2.71  	while (1) {
    2.72  		while (!need_resched()) {
    2.73 -			void (*idle)(void);
    2.74  			/*
    2.75  			 * Mark this as an RCU critical section so that
    2.76  			 * synchronize_kernel() in the unload path waits
    2.77  			 * for our completion.
    2.78  			 */
    2.79  			rcu_read_lock();
    2.80 -			idle = pm_idle;
    2.81 -
    2.82 -			if (!idle)
    2.83 -				idle = default_idle;
    2.84 -
    2.85  			irq_stat[smp_processor_id()].idle_timestamp = jiffies;
    2.86 -			idle();
    2.87 +			xen_idle();
    2.88  			rcu_read_unlock();
    2.89  		}
    2.90  		schedule();
    2.91  	}
    2.92  }
    2.93  
    2.94 -/*
    2.95 - * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
    2.96 - * which can obviate IPI to trigger checking of need_resched.
    2.97 - * We execute MONITOR against need_resched and enter optimized wait state
    2.98 - * through MWAIT. Whenever someone changes need_resched, we would be woken
    2.99 - * up from MWAIT (without an IPI).
   2.100 - */
   2.101 -static void mwait_idle(void)
   2.102 -{
   2.103 -	local_irq_enable();
   2.104 -
   2.105 -	if (!need_resched()) {
   2.106 -		set_thread_flag(TIF_POLLING_NRFLAG);
   2.107 -		do {
   2.108 -			__monitor((void *)&current_thread_info()->flags, 0, 0);
   2.109 -			if (need_resched())
   2.110 -				break;
   2.111 -			__mwait(0, 0);
   2.112 -		} while (!need_resched());
   2.113 -		clear_thread_flag(TIF_POLLING_NRFLAG);
   2.114 -	}
   2.115 -}
   2.116 -
   2.117 -void __init select_idle_routine(const struct cpuinfo_x86 *c)
   2.118 -{
   2.119 -	if (cpu_has(c, X86_FEATURE_MWAIT)) {
   2.120 -		printk("monitor/mwait feature present.\n");
   2.121 -		/*
   2.122 -		 * Skip, if setup has overridden idle.
   2.123 -		 * One CPU supports mwait => All CPUs supports mwait
   2.124 -		 */
   2.125 -		if (!pm_idle) {
   2.126 -			printk("using mwait in idle threads.\n");
   2.127 -			pm_idle = mwait_idle;
   2.128 -		}
   2.129 -	}
   2.130 -}
   2.131 -
   2.132 -static int __init idle_setup (char *str)
   2.133 -{
   2.134 -	if (!strncmp(str, "poll", 4)) {
   2.135 -		printk("using polling idle threads.\n");
   2.136 -		pm_idle = poll_idle;
   2.137 -#ifdef CONFIG_X86_SMP
   2.138 -		if (smp_num_siblings > 1)
   2.139 -			printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
   2.140 -#endif
   2.141 -	} else if (!strncmp(str, "halt", 4)) {
   2.142 -		printk("using halt in idle threads.\n");
   2.143 -		pm_idle = default_idle;
   2.144 -	}
   2.145 -
   2.146 -	return 1;
   2.147 -}
   2.148 -
   2.149 -__setup("idle=", idle_setup);
   2.150 +/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
   2.151 +/* Always use xen_idle() instead. */
   2.152 +void __init select_idle_routine(const struct cpuinfo_x86 *c) {}
   2.153  
   2.154  void show_regs(struct pt_regs * regs)
   2.155  {
     3.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c	Thu Nov 04 11:27:56 2004 +0000
     3.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c	Thu Nov 04 15:22:20 2004 +0000
     3.3 @@ -350,8 +350,6 @@ int nr_multicall_ents = 0;
     3.4  /* Raw start-of-day parameters from the hypervisor. */
     3.5  union xen_start_info_union xen_start_info_union;
     3.6  
     3.7 -extern void (*pm_idle)(void);
     3.8 -
     3.9  static void __init limit_regions(unsigned long long size)
    3.10  {
    3.11  	unsigned long long current_addr = 0;
    3.12 @@ -1324,8 +1322,6 @@ void __init setup_arch(char **cmdline_p)
    3.13  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
    3.14  			     VMASST_TYPE_4gb_segments);
    3.15  
    3.16 -	pm_idle = xen_cpu_idle;
    3.17 -
    3.18  	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
    3.19  	early_cpu_init();
    3.20  
     4.1 --- a/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile	Thu Nov 04 11:27:56 2004 +0000
     4.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile	Thu Nov 04 15:22:20 2004 +0000
     4.3 @@ -9,5 +9,5 @@ XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
     4.4  
     4.5  extra-y += vmlinux.lds
     4.6  
     4.7 -obj-y	:= ctrl_if.o evtchn.o fixup.o process.o reboot.o xen_proc.o empty.o \
     4.8 +obj-y	:= ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o empty.o \
     4.9             gnttab.o skbuff.o
     5.1 --- a/linux-2.6.9-xen-sparse/arch/xen/kernel/process.c	Thu Nov 04 11:27:56 2004 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,29 +0,0 @@
     5.4 -
     5.5 -#include <stdarg.h>
     5.6 -
     5.7 -#include <linux/errno.h>
     5.8 -#include <linux/sched.h>
     5.9 -#include <linux/init.h>
    5.10 -#include <linux/platform.h>
    5.11 -#include <linux/pm.h>
    5.12 -#include <linux/rcupdate.h>
    5.13 -
    5.14 -extern int set_timeout_timer(void);
    5.15 -
    5.16 -void xen_cpu_idle (void)
    5.17 -{
    5.18 -	struct rcu_data *rdp = &__get_cpu_var(rcu_bh_data);
    5.19 -
    5.20 -	local_irq_disable();
    5.21 -	if (need_resched() || rdp->curlist) {
    5.22 -		local_irq_enable();
    5.23 -		return;
    5.24 -	}
    5.25 -	if (set_timeout_timer() == 0) {
    5.26 -		/* NB. Blocking reenable events in a race-free manner. */
    5.27 -		HYPERVISOR_block();
    5.28 -		return;
    5.29 -	}
    5.30 -	local_irq_enable();
    5.31 -	HYPERVISOR_yield();
    5.32 -}