[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fixed weights on SMP machines.
ChangeSet 1.1159.170.106, 2005/03/09 16:10:08+00:00, sd386@xxxxxxxxxxxxxxxxx Fixed weights on SMP machines. sched_sedf.c | 72 +++++++++++++++++++++++++++++++---------------------------- 1 files changed, 38 insertions(+), 34 deletions(-) diff -Nru a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c --- a/xen/common/sched_sedf.c 2005-05-09 14:04:47 -04:00 +++ b/xen/common/sched_sedf.c 2005-05-09 14:04:47 -04:00 @@ -5,14 +5,6 @@ * based on code by Mark Williamson (C) 2004 Intel Research Cambridge */ -/* - TODO: - TESTING! - tracing instead of PRINTs -*/ - - - #include <xen/sched.h> #include <xen/sched-if.h> #include <public/sched_ctl.h> @@ -75,10 +67,9 @@ s_time_t period_orig; s_time_t slice_orig; s_time_t latency; - //extra-time status of domain - short extra; - //weights for "Scheduling for beginners/ lazy/ etc." ;) - short weight; + + short extra; //extra-time status of domain + short weight; //weights for "Scheduling for beginners/ lazy/ etc." ;) //Bookkeeping s_time_t absdead; @@ -197,9 +188,14 @@ } else { PRINT(2,"Dom %i is NOT on L1 extraQ\n",d->id); if ((DOM_INFO(d)->extra & EXTRA_AWARE) && domain_runnable(d)) { + #if (EXTRA == EXTRA_ROUNDR) + extraq_add_tail(d, EXTRA_UTIL_Q); //Favour domains which got short unblocked + #elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT) extraq_add_sort_update(d, EXTRA_UTIL_Q, 0); + #elif + ; + #endif PRINT(2,"Added dom %i to L1 extraQ\n",d->id); - //TODO: add extraq_add_tail } } } @@ -350,9 +346,8 @@ //current domain is running in real time mode inf->cputime += now - inf->sched_start; //update the domains cputime - //scheduling decisions, which don't remove the running domain from the runq - if ((inf->cputime < inf->slice) && domain_runnable(d)) - return; //there is nothing to do with the running task + if ((inf->cputime < inf->slice) && domain_runnable(d)) //scheduling decisions, which don't remove the running domain from the runq + return; //there is nothing to do with the running task __del_from_queue(d); /*if (__task_on_queue(current)) { @@ -388,8 +383,8 @@ #if (EXTRA > EXTRA_OFF) #if (EXTRA == EXTRA_BLOCK_WEIGHT) if (extraq_on(d,EXTRA_PEN_Q)) extraq_del(d,EXTRA_PEN_Q); - if (extraq_on(d,EXTRA_UTIL_Q)) extraq_del(d,EXTRA_UTIL_Q); #endif + if (extraq_on(d,EXTRA_UTIL_Q)) extraq_del(d,EXTRA_UTIL_Q); #endif } } @@ -496,12 +491,14 @@ printf("Oops... We attempt to remove d %i from the waitq, but it is not on :(\n",d->id);*/ __del_from_queue(d); //also remove this blocked domain from the waitq! //make sure that we remove a blocked domain from the other extraq aswell (this caused hours of debugging!) + #if (EXTRA == EXTRA_BLOCK_WEIGHT) if (i == EXTRA_PEN_Q) { if (extraq_on(d,EXTRA_UTIL_Q)) extraq_del(d,EXTRA_UTIL_Q); } else { if (extraq_on(d,EXTRA_PEN_Q)) extraq_del(d,EXTRA_PEN_Q); } + #endif } #endif /*if (!domain_runnable(d)) { @@ -521,7 +518,7 @@ static inline task_slice_t sedf_do_extra_schedule(s_time_t now, s_time_t end_xt, struct list_head *extraq[], int cpu) { task_slice_t ret; struct sedf_dom_info *runinf; - //TODO write this stuff as a loop and pay attention to normal stuff! + //TODO write this stuff as a loop if (end_xt - now < EXTRA_QUANTUM) goto return_idle; @@ -555,7 +552,7 @@ * Reasons for calling this function are: * -timeslice for the current period used up * -domain on waitqueue has started it's period - * -and various others ;) in general: determin which domain to run next*/ + * -and various others ;) in general: determine which domain to run next*/ static task_slice_t sedf_do_schedule(s_time_t now) { int cpu = current->processor; @@ -631,8 +628,10 @@ sched_done: //TODO: Do something USEFUL when this happens and find out, why it still can happen!!! - if (ret.time<0) + if (ret.time<0) { printk("Ouch! We are seriously BEHIND schedule! %lli\n",ret.time); + ret.time = EXTRA_QUANTUM; + } DOM_INFO(ret.task)->sched_start=now; return ret; } @@ -840,7 +839,7 @@ /*Compares two domains in the relation of whether the one is allowed to interrupt the others execution. It returns true (!=0) if a switch to the other domain is good. Current Priority scheme is as follows: - EDF > L0 (penalty based) extra-time > L1 (utilization) extra-time > blocked domain > idle-domain + EDF > L0 (penalty based) extra-time > L1 (utilization) extra-time > idle-domain In the same class priorities are assigned as following: EDF: early deadline > late deadline L0 extra-time: lower score > higher score*/ @@ -933,7 +932,7 @@ #if (EXTRA == EXTRA_OFF) ; #elif (EXTRA == EXTRA_ROUNDR) - extraq_add_head(d); //Favour domains which got short unblocked + extraq_add_head(d, EXTRA_UTIL_Q); //Favour domains which got short unblocked #elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT) extraq_add_sort_update(d, EXTRA_UTIL_Q, 0); #endif @@ -960,7 +959,7 @@ #if (EXTRA == EXTRA_OFF) ; #elif (EXTRA == EXTRA_ROUNDR) - extraq_add_head(d); + extraq_add_head(d, EXTRA_UTIL_Q); #elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT) //PRINT(2,"now try to add domain %i to the extra_util_q\n",d->id); extraq_add_sort_update(d, EXTRA_UTIL_Q, 0); @@ -980,10 +979,10 @@ inf->penalty_time_tot += PERIOD_BEGIN(inf) + inf->cputime - inf->absblock; } //sanity check: make sure each extra-aware domain IS on the util-q! - if (inf->extra & EXTRA_AWARE) { + /*if (inf->extra & EXTRA_AWARE) { if (!extraq_on(d, EXTRA_UTIL_Q)) printf("sedf_wake: domain %i is extra-aware, but NOT on L1 extraq!\n",d->id); - } + }*/ //check whether the awakened task needs to get scheduled before the next sched. decision //and check, whether we are idling and this domain is extratime aware if (should_switch(schedule_data[d->processor].curr, d, now)){ @@ -994,8 +993,7 @@ } } - -/* This could probably be a bit more specific!*/ +/*Print a lot of use-{full, less} information about a domains in the system*/ static void sedf_dump_domain(struct domain *d) { printk("%u has=%c ", d->id, test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); @@ -1017,6 +1015,7 @@ printf("\n"); } +/*dumps all domains on hte specified cpu*/ static void sedf_dump_cpu_state(int i) { struct list_head *list, *queue, *tmp; @@ -1064,7 +1063,7 @@ loop = 0; printk("\nnot on Q\n"); for_each_domain(d) { - if (!extraq_on(d,1) && !__task_on_queue(d)) { + if (!__task_on_queue(d) && (d->processor == i)) { printk("%3d: ",loop++); sedf_dump_domain(d); } @@ -1072,19 +1071,24 @@ } //Adjusts periods and slices of the domains accordingly to their weights static inline int sedf_adjust_weights(struct domain *p, struct sched_adjdom_cmd *cmd) { - int sumw = 0; - s_time_t sumt = 0; - + int sumw[NR_CPUS]; + s_time_t sumt[NR_CPUS]; + int cpu; + + for (cpu=0; cpu < NR_CPUS; cpu++) { + sumw[cpu] = 0; + sumt[cpu] = 0; + } //sum up all weights for_each_domain(p) { if (DOM_INFO(p)->weight) - sumw += DOM_INFO(p)->weight; + sumw[p->processor] += DOM_INFO(p)->weight; else { //don't modify domains who don't have a weight, but sum up //the time they need, projected to a WEIGHT_PERIOD, so that //this time is not given to the weight-driven domains ASSERT((WEIGHT_PERIOD < ULONG_MAX) && (DOM_INFO(p)->slice_orig < ULONG_MAX)); //this results in max. 4s slice/period length - sumt += (WEIGHT_PERIOD * DOM_INFO(p)->slice_orig) / DOM_INFO(p)->period_orig; + sumt[p->processor] += (WEIGHT_PERIOD * DOM_INFO(p)->slice_orig) / DOM_INFO(p)->period_orig; } } //adjust all slices (and periods) to the new weight @@ -1093,7 +1097,7 @@ DOM_INFO(p)->period_orig = DOM_INFO(p)->period = WEIGHT_PERIOD; DOM_INFO(p)->slice_orig = - DOM_INFO(p)->slice = (DOM_INFO(p)->weight * (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt)) / sumw; + DOM_INFO(p)->slice = (DOM_INFO(p)->weight * (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[p->processor])) / sumw[p->processor]; } } return 0; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |