ia64/xen-unstable
changeset 4372:046ad36e241a
bitkeeper revision 1.1159.170.107 (42497af7aXKR1tJnN7XlLoXsYCxABQ)
cleaned up some statistics code,
new domains are now best effort by default,
fixed possible bug for best effort domains
cleaned up some statistics code,
new domains are now best effort by default,
fixed possible bug for best effort domains
author | sd386@font.cl.cam.ac.uk |
---|---|
date | Tue Mar 29 15:57:43 2005 +0000 (2005-03-29) |
parents | 6bb21b5051a9 |
children | af870801ba62 |
files | xen/common/sched_sedf.c |
line diff
1.1 --- a/xen/common/sched_sedf.c Wed Mar 09 16:10:08 2005 +0000 1.2 +++ b/xen/common/sched_sedf.c Tue Mar 29 15:57:43 2005 +0000 1.3 @@ -15,10 +15,15 @@ 1.4 1.5 //#include <xen/adv_sched_hist.h> 1.6 1.7 -#define SEDFLEVEL 2 1.8 +//verbosity settings 1.9 +#define SEDFLEVEL 0 1.10 #define PRINT(_f, _a...) \ 1.11 if ((_f)<=SEDFLEVEL) printk(_a ); 1.12 1.13 +#ifdef DEBUG 1.14 + #define SEDF_STATS 1.15 +#endif 1.16 + 1.17 //various ways of unblocking domains 1.18 #define UNBLOCK_ISOCHRONOUS_EDF 1 1.19 #define UNBLOCK_EDF 2 1.20 @@ -81,15 +86,18 @@ struct sedf_dom_info 1.21 s_time_t short_block_lost_tot; 1.22 1.23 //Statistics 1.24 + s_time_t extra_time_tot; 1.25 + 1.26 +#ifdef SEDF_STATS 1.27 s_time_t block_time_tot; 1.28 s_time_t penalty_time_tot; 1.29 - s_time_t extra_time_tot; 1.30 int block_tot; 1.31 int short_block_tot; 1.32 int long_block_tot; 1.33 int short_cont; 1.34 int pen_extra_blocks; 1.35 int pen_extra_slices; 1.36 +#endif 1.37 }; 1.38 1.39 struct sedf_cpu_info { 1.40 @@ -181,7 +189,7 @@ static inline void extraq_add_sort_updat 1.41 static inline void extraq_check(struct domain *d) { 1.42 if (extraq_on(d, EXTRA_UTIL_Q)) { 1.43 PRINT(2,"Dom %i is on extraQ\n",d->id); 1.44 - if (!(DOM_INFO(d)->extra & EXTRA_AWARE)) { 1.45 + if (!(DOM_INFO(d)->extra & EXTRA_AWARE) && !extra_runs(DOM_INFO(d))) { 1.46 extraq_del(d, EXTRA_UTIL_Q); 1.47 PRINT(2,"Removed dom %i from L1 extraQ\n",d->id); 1.48 } 1.49 @@ -306,12 +314,12 @@ static void sedf_add_task(struct domain 1.50 inf->extra = EXTRA_NONE;//EXTRA_AWARE; 1.51 } 1.52 else { 1.53 - //other domains don't get any execution time at all in the beginning! 1.54 + //other domains run in best effort mode 1.55 inf->period = MILLISECS(20); 1.56 inf->slice = 0; 1.57 inf->absdead = 0; 1.58 inf->latency = 0; 1.59 - inf->extra = EXTRA_NONE;//EXTRA_AWARE 1.60 + inf->extra = EXTRA_AWARE; 1.61 } 1.62 inf->period_orig = inf->period; inf->slice_orig = inf->slice; 1.63 INIT_LIST_HEAD(&(inf->list)); 1.64 @@ -481,7 +489,10 @@ static inline void desched_extra_dom(s_t 1.65 #endif 1.66 { 1.67 //domain was running in L1 extraq => score is inverse of utilization and is used somewhat incremental! 1.68 - inf->score[EXTRA_UTIL_Q] = (inf->period << 10) / inf->slice;//use fixed point arithmetic with 10 bits 1.69 + if (inf->slice) 1.70 + inf->score[EXTRA_UTIL_Q] = (inf->period << 10) / inf->slice;//use fixed point arithmetic with 10 bits 1.71 + else 1.72 + inf->score[EXTRA_UTIL_Q] = 2^10; 1.73 } 1.74 if (domain_runnable(d)) 1.75 extraq_add_sort_update(d, i, oldscore); //add according to score: weighted round robin 1.76 @@ -529,7 +540,9 @@ static inline task_slice_t sedf_do_extra 1.77 runinf->extra |= EXTRA_RUN_PEN; 1.78 ret.task = runinf->owner; 1.79 ret.time = EXTRA_QUANTUM; 1.80 +#ifdef SEDF_STATS 1.81 runinf->pen_extra_slices++; 1.82 +#endif 1.83 } 1.84 else if (!list_empty(extraq[EXTRA_UTIL_Q])) { 1.85 //use elements from the normal extraqueue 1.86 @@ -729,8 +742,10 @@ static inline void unblock_short_cons(st 1.87 //we don't have a reasonable amount of time in our slice left :( 1.88 unblock_short_vcons(inf, now); //start in next period! 1.89 } 1.90 +#ifdef SEDF_STATS 1.91 else 1.92 inf->short_cont++; //we let the domain run in the current period 1.93 +#endif 1.94 } 1.95 static inline void unblock_short_extra_support(struct sedf_dom_info* inf, s_time_t now) { 1.96 /*this unblocking scheme tries to support the domain, by assigning it a priority in extratime distribution 1.97 @@ -747,7 +762,9 @@ static inline void unblock_short_extra_s 1.98 1.99 if (inf->short_block_lost_tot) { 1.100 inf->score[0] = (inf->period << 10) / inf->short_block_lost_tot; 1.101 +#ifdef SEDF_STATS 1.102 inf->pen_extra_blocks++; 1.103 +#endif 1.104 if (extraq_on(inf->owner, EXTRA_PEN_Q)) 1.105 extraq_del(inf->owner, EXTRA_PEN_Q); //remove domain for possible resorting! 1.106 else //remember that we want to be on the penalty queue, 1.107 @@ -791,7 +808,9 @@ static inline void unblock_short_burst(s 1.108 inf->cputime += now - inf->absblock; //treat blocked time as consumed by the domain 1.109 1.110 if (inf->cputime + EXTRA_QUANTUM <= inf->slice) { 1.111 +#ifdef SEDF_STATS 1.112 inf->short_cont++; //we let the domain run in the current period 1.113 +#endif 1.114 } 1.115 else { 1.116 //we don't have a reasonable amount of time in our slice left => switch to burst mode 1.117 @@ -851,8 +870,7 @@ static inline int should_switch(struct d 1.118 switch (get_run_type(cur)) { 1.119 case DOMAIN_EDF: 1.120 //check whether we need to make an earlier sched-decision 1.121 - if ((PERIOD_BEGIN(other_inf) < schedule_data[other->processor].s_timer.expires) 1.122 - && (other_inf->absdead < cur_inf->absdead)) 1.123 + if ((PERIOD_BEGIN(other_inf) < schedule_data[other->processor].s_timer.expires)) 1.124 return 1; 1.125 else return 0; 1.126 case DOMAIN_EXTRA_PEN: 1.127 @@ -892,8 +910,9 @@ void sedf_wake(struct domain *d) { 1.128 inf->absdead = now + inf->slice; //initial setup of the deadline 1.129 1.130 PRINT(3,"waking up domain %i (deadl= %llu period= %llu now= %llu)\n",d->id,inf->absdead,inf->period,now); 1.131 - 1.132 +#ifdef SEDF_STATS 1.133 inf->block_tot++; 1.134 +#endif 1.135 if (unlikely(now< PERIOD_BEGIN(inf))) { 1.136 PRINT(4,"extratime unblock\n"); 1.137 //this might happen, imagine unblocking in extra-time! 1.138 @@ -917,7 +936,9 @@ void sedf_wake(struct domain *d) { 1.139 if (now < inf->absdead) { 1.140 PRINT(4,"short unblocking\n"); 1.141 //short blocking 1.142 +#ifdef SEDF_STATS 1.143 inf->short_block_tot++; 1.144 +#endif 1.145 #if (UNBLOCK <= UNBLOCK_ATROPOS) 1.146 unblock_short_vcons(inf, now); 1.147 #elif (UNBLOCK == UNBLOCK_SHORT_RESUME) 1.148 @@ -940,7 +961,9 @@ void sedf_wake(struct domain *d) { 1.149 else { 1.150 PRINT(4,"long unblocking\n"); 1.151 //long blocking 1.152 +#ifdef SEDF_STATS 1.153 inf->long_block_tot++; 1.154 +#endif 1.155 //PRINT(3,"old=%llu ",inf->absdead); 1.156 #if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF) 1.157 unblock_long_vcons(inf, now); 1.158 @@ -973,18 +996,22 @@ void sedf_wake(struct domain *d) { 1.159 __add_to_waitqueue_sort(d); 1.160 PRINT(3,"added to waitq\n"); 1.161 1.162 +#ifdef SEDF_STATS 1.163 //do some statistics here... 1.164 if (inf->absblock != 0) { 1.165 inf->block_time_tot += now - inf->absblock; 1.166 inf->penalty_time_tot += PERIOD_BEGIN(inf) + inf->cputime - inf->absblock; 1.167 } 1.168 +#endif 1.169 //sanity check: make sure each extra-aware domain IS on the util-q! 1.170 /*if (inf->extra & EXTRA_AWARE) { 1.171 if (!extraq_on(d, EXTRA_UTIL_Q)) 1.172 printf("sedf_wake: domain %i is extra-aware, but NOT on L1 extraq!\n",d->id); 1.173 }*/ 1.174 + 1.175 //check whether the awakened task needs to get scheduled before the next sched. decision 1.176 //and check, whether we are idling and this domain is extratime aware 1.177 + //Save approximation: Always switch to scheduler! 1.178 if (should_switch(schedule_data[d->processor].curr, d, now)){ 1.179 #ifdef ADV_SCHED_HISTO 1.180 adv_sched_hist_start(d->processor); 1.181 @@ -1002,6 +1029,7 @@ static void sedf_dump_domain(struct doma 1.182 DOM_INFO(d)->score[EXTRA_UTIL_Q], (DOM_INFO(d)->extra & EXTRA_AWARE) ? "yes" : "no", DOM_INFO(d)->extra_time_tot); 1.183 if (d->cpu_time !=0) 1.184 printf(" (%lu%)", (DOM_INFO(d)->extra_time_tot * 100) / d->cpu_time); 1.185 +#ifdef SEDF_STATS 1.186 if (DOM_INFO(d)->block_time_tot!=0) 1.187 printf(" pen=%lu%", (DOM_INFO(d)->penalty_time_tot * 100) / DOM_INFO(d)->block_time_tot); 1.188 if (DOM_INFO(d)->block_tot!=0) 1.189 @@ -1012,6 +1040,7 @@ static void sedf_dump_domain(struct doma 1.190 DOM_INFO(d)->long_block_tot, (DOM_INFO(d)->long_block_tot * 100) / DOM_INFO(d)->block_tot, 1.191 (DOM_INFO(d)->block_time_tot) / DOM_INFO(d)->block_tot, 1.192 (DOM_INFO(d)->penalty_time_tot) / DOM_INFO(d)->block_tot); 1.193 +#endif 1.194 printf("\n"); 1.195 } 1.196