ia64/xen-unstable

changeset 4045:6bb21b5051a9

bitkeeper revision 1.1159.170.106 (422f1fe04lkSpzGfJ9fkoHS3KOxslw)

Fixed weights on SMP machines.
author sd386@font.cl.cam.ac.uk
date Wed Mar 09 16:10:08 2005 +0000 (2005-03-09)
parents 2d335430f7fc
children 046ad36e241a
files xen/common/sched_sedf.c
line diff
     1.1 --- a/xen/common/sched_sedf.c	Wed Mar 09 14:35:02 2005 +0000
     1.2 +++ b/xen/common/sched_sedf.c	Wed Mar 09 16:10:08 2005 +0000
     1.3 @@ -5,14 +5,6 @@
     1.4   * based on code by Mark Williamson (C) 2004 Intel Research Cambridge
     1.5   */
     1.6  
     1.7 -/*
     1.8 -	TODO:
     1.9 -	TESTING!
    1.10 -	tracing instead of PRINTs
    1.11 -*/
    1.12 -
    1.13 -
    1.14 -
    1.15  #include <xen/sched.h>
    1.16  #include <xen/sched-if.h>
    1.17  #include <public/sched_ctl.h>
    1.18 @@ -75,10 +67,9 @@ struct sedf_dom_info
    1.19  	s_time_t		period_orig;	
    1.20  	s_time_t		slice_orig;
    1.21  	s_time_t		latency;
    1.22 -	//extra-time status of domain
    1.23 -	short			extra;
    1.24 -	//weights for "Scheduling for beginners/ lazy/ etc." ;)
    1.25 -	short			weight;
    1.26 +	
    1.27 +	short			extra;		//extra-time status of domain
    1.28 +	short			weight;		//weights for "Scheduling for beginners/ lazy/ etc." ;)
    1.29  	
    1.30  	//Bookkeeping
    1.31  	s_time_t		absdead;
    1.32 @@ -197,9 +188,14 @@ static inline void extraq_check(struct d
    1.33  	} else {
    1.34  		PRINT(2,"Dom %i is NOT on L1 extraQ\n",d->id);
    1.35  		if ((DOM_INFO(d)->extra & EXTRA_AWARE) && domain_runnable(d))  {
    1.36 +			#if (EXTRA == EXTRA_ROUNDR)
    1.37 +			extraq_add_tail(d, EXTRA_UTIL_Q);			//Favour domains which got short unblocked
    1.38 +			#elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
    1.39  			extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
    1.40 +			#elif
    1.41 +			;
    1.42 +			#endif
    1.43  			PRINT(2,"Added dom %i to L1 extraQ\n",d->id);
    1.44 -			//TODO: add extraq_add_tail
    1.45  		}
    1.46  	}
    1.47  }
    1.48 @@ -350,9 +346,8 @@ static inline void desched_edf_dom (s_ti
    1.49  	
    1.50  	//current domain is running in real time mode
    1.51  	inf->cputime += now - inf->sched_start;				//update the domains cputime
    1.52 -	//scheduling decisions, which don't remove the running domain from the runq
    1.53 -	if ((inf->cputime < inf->slice) && domain_runnable(d))
    1.54 -		return;						//there is nothing to do with the running task
    1.55 +	if ((inf->cputime < inf->slice) && domain_runnable(d))		//scheduling decisions, which don't remove the running domain from the runq
    1.56 +		return;							//there is nothing to do with the running task
    1.57  		
    1.58  	__del_from_queue(d);
    1.59  	/*if (__task_on_queue(current)) {
    1.60 @@ -388,9 +383,9 @@ static inline void desched_edf_dom (s_ti
    1.61  		#if (EXTRA > EXTRA_OFF)
    1.62  		#if (EXTRA == EXTRA_BLOCK_WEIGHT)
    1.63  		if (extraq_on(d,EXTRA_PEN_Q)) extraq_del(d,EXTRA_PEN_Q);
    1.64 +		#endif
    1.65  		if (extraq_on(d,EXTRA_UTIL_Q)) extraq_del(d,EXTRA_UTIL_Q);
    1.66  		#endif
    1.67 -		#endif
    1.68  	}
    1.69  }
    1.70  
    1.71 @@ -496,12 +491,14 @@ static inline void desched_extra_dom(s_t
    1.72  			printf("Oops... We attempt to remove d %i from the waitq, but it is not on :(\n",d->id);*/
    1.73  		__del_from_queue(d);				//also remove this blocked domain from the waitq!
    1.74  		//make sure that we remove a blocked domain from the other extraq aswell (this caused hours of debugging!)
    1.75 +		#if (EXTRA == EXTRA_BLOCK_WEIGHT)
    1.76  		if (i == EXTRA_PEN_Q) {
    1.77  			if (extraq_on(d,EXTRA_UTIL_Q)) extraq_del(d,EXTRA_UTIL_Q);
    1.78  		}
    1.79  		else {
    1.80  			if (extraq_on(d,EXTRA_PEN_Q)) extraq_del(d,EXTRA_PEN_Q);
    1.81  		}
    1.82 +		#endif
    1.83  	}
    1.84  	#endif
    1.85  	/*if (!domain_runnable(d)) {
    1.86 @@ -521,7 +518,7 @@ static inline void desched_extra_dom(s_t
    1.87  static inline task_slice_t sedf_do_extra_schedule(s_time_t now, s_time_t end_xt, struct list_head *extraq[], int cpu) {
    1.88  	task_slice_t 		ret;
    1.89  	struct sedf_dom_info	*runinf;
    1.90 -	//TODO write this stuff as a loop and pay attention to normal stuff!
    1.91 +	//TODO write this stuff as a loop
    1.92  	
    1.93  	if (end_xt - now < EXTRA_QUANTUM)
    1.94  		goto return_idle;
    1.95 @@ -555,7 +552,7 @@ return_idle:
    1.96   * Reasons for calling this function are:
    1.97   * -timeslice for the current period used up
    1.98   * -domain on waitqueue has started it's period
    1.99 - * -and various others ;) in general: determin which domain to run next*/
   1.100 + * -and various others ;) in general: determine which domain to run next*/
   1.101  static task_slice_t sedf_do_schedule(s_time_t now)
   1.102  {
   1.103  	int                   cpu      = current->processor;
   1.104 @@ -631,8 +628,10 @@ check_waitq:
   1.105  
   1.106  sched_done:	
   1.107  	//TODO: Do something USEFUL when this happens and find out, why it still can happen!!!
   1.108 -	if (ret.time<0)
   1.109 +	if (ret.time<0) {
   1.110  		printk("Ouch! We are seriously BEHIND schedule! %lli\n",ret.time);
   1.111 +		ret.time = EXTRA_QUANTUM;
   1.112 +	}
   1.113  	DOM_INFO(ret.task)->sched_start=now;
   1.114  	return ret;
   1.115  }
   1.116 @@ -840,7 +839,7 @@ static inline int get_run_type(struct do
   1.117  /*Compares two domains in the relation of whether the one is allowed to interrupt the others execution.
   1.118    It returns true (!=0) if a switch to the other domain is good.
   1.119    Current Priority scheme is as follows:
   1.120 -  	EDF > L0 (penalty based) extra-time > L1 (utilization) extra-time > blocked domain > idle-domain
   1.121 +  	EDF > L0 (penalty based) extra-time > L1 (utilization) extra-time > idle-domain
   1.122    In the same class priorities are assigned as following:
   1.123    	EDF: early deadline > late deadline
   1.124    	L0 extra-time: lower score > higher score*/
   1.125 @@ -933,7 +932,7 @@ void sedf_wake(struct domain *d) {
   1.126  				#if (EXTRA == EXTRA_OFF)
   1.127  				;
   1.128  				#elif (EXTRA == EXTRA_ROUNDR)
   1.129 -				extraq_add_head(d);			//Favour domains which got short unblocked
   1.130 +				extraq_add_head(d, EXTRA_UTIL_Q);	//Favour domains which got short unblocked
   1.131  				#elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
   1.132  				extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
   1.133  				#endif
   1.134 @@ -960,7 +959,7 @@ void sedf_wake(struct domain *d) {
   1.135  				#if (EXTRA == EXTRA_OFF)
   1.136  				;
   1.137  				#elif (EXTRA == EXTRA_ROUNDR)
   1.138 -				extraq_add_head(d);
   1.139 +				extraq_add_head(d, EXTRA_UTIL_Q);
   1.140  				#elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
   1.141  				//PRINT(2,"now try to add domain %i to the extra_util_q\n",d->id);
   1.142  				extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
   1.143 @@ -980,10 +979,10 @@ void sedf_wake(struct domain *d) {
   1.144  		inf->penalty_time_tot += PERIOD_BEGIN(inf) + inf->cputime - inf->absblock;
   1.145  	}
   1.146  	//sanity check: make sure each extra-aware domain IS on the util-q!
   1.147 -	if (inf->extra & EXTRA_AWARE) {
   1.148 +	/*if (inf->extra & EXTRA_AWARE) {
   1.149  		if (!extraq_on(d, EXTRA_UTIL_Q))
   1.150  			printf("sedf_wake: domain %i is extra-aware, but NOT on L1 extraq!\n",d->id);
   1.151 -	}
   1.152 +	}*/
   1.153  	//check whether the awakened task needs to get scheduled before the next sched. decision
   1.154  	//and check, whether we are idling and this domain is extratime aware
   1.155  	if (should_switch(schedule_data[d->processor].curr, d, now)){
   1.156 @@ -994,8 +993,7 @@ void sedf_wake(struct domain *d) {
   1.157  	}
   1.158  }
   1.159  
   1.160 -
   1.161 -/* This could probably be a bit more specific!*/
   1.162 +/*Print a lot of use-{full, less} information about a domains in the system*/
   1.163  static void sedf_dump_domain(struct domain *d) {
   1.164  	printk("%u has=%c ", d->id,
   1.165  		test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
   1.166 @@ -1017,6 +1015,7 @@ static void sedf_dump_domain(struct doma
   1.167  	printf("\n");
   1.168  }
   1.169  
   1.170 +/*dumps all domains on hte specified cpu*/
   1.171  static void sedf_dump_cpu_state(int i)
   1.172  {
   1.173  	struct list_head *list, *queue, *tmp;
   1.174 @@ -1064,7 +1063,7 @@ static void sedf_dump_cpu_state(int i)
   1.175  	loop = 0;
   1.176  	printk("\nnot on Q\n");
   1.177  	for_each_domain(d) {
   1.178 -		if (!extraq_on(d,1) && !__task_on_queue(d)) {
   1.179 +		if (!__task_on_queue(d) && (d->processor == i)) {
   1.180  			printk("%3d: ",loop++);
   1.181  			sedf_dump_domain(d);
   1.182  		}
   1.183 @@ -1072,19 +1071,24 @@ static void sedf_dump_cpu_state(int i)
   1.184  }
   1.185  //Adjusts periods and slices of the domains accordingly to their weights
   1.186  static inline int sedf_adjust_weights(struct domain *p, struct sched_adjdom_cmd *cmd) {
   1.187 -	int sumw      = 0;
   1.188 -	s_time_t sumt = 0;
   1.189 +	int sumw[NR_CPUS];
   1.190 +	s_time_t sumt[NR_CPUS];
   1.191 +	int cpu;
   1.192  	
   1.193 +	for (cpu=0; cpu < NR_CPUS; cpu++) {
   1.194 +		sumw[cpu] = 0;
   1.195 +		sumt[cpu] = 0;
   1.196 +	}
   1.197  	//sum up all weights
   1.198  	for_each_domain(p) {
   1.199  		if (DOM_INFO(p)->weight)
   1.200 -			sumw += DOM_INFO(p)->weight;
   1.201 +			sumw[p->processor] += DOM_INFO(p)->weight;
   1.202  		else {
   1.203  			//don't modify domains who don't have a weight, but sum up
   1.204  			//the time they need, projected to a WEIGHT_PERIOD, so that
   1.205  			//this time is not given to the weight-driven domains
   1.206  			ASSERT((WEIGHT_PERIOD < ULONG_MAX) && (DOM_INFO(p)->slice_orig < ULONG_MAX));	//this results in max. 4s slice/period length
   1.207 -			sumt += (WEIGHT_PERIOD * DOM_INFO(p)->slice_orig) / DOM_INFO(p)->period_orig;
   1.208 +			sumt[p->processor] += (WEIGHT_PERIOD * DOM_INFO(p)->slice_orig) / DOM_INFO(p)->period_orig;
   1.209  		}
   1.210  	}
   1.211  	//adjust all slices (and periods) to the new weight
   1.212 @@ -1093,7 +1097,7 @@ static inline int sedf_adjust_weights(st
   1.213  			DOM_INFO(p)->period_orig = 
   1.214  			     DOM_INFO(p)->period = WEIGHT_PERIOD;
   1.215  			DOM_INFO(p)->slice_orig  =
   1.216 -			      DOM_INFO(p)->slice = (DOM_INFO(p)->weight * (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt)) / sumw;
   1.217 +			      DOM_INFO(p)->slice = (DOM_INFO(p)->weight * (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[p->processor])) / sumw[p->processor];
   1.218  		}
   1.219  	}
   1.220  	return 0;