# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 81bc9e9fb40ddd5c4366da8f7b667363005b1f92
# Parent 886594fa3aef2dd2f1ae56c690de62f5c81bf977
Remove various compile-time options from SEDF scheduler and
clean up formatting.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 886594fa3aef -r 81bc9e9fb40d xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c Sat Apr 8 11:10:04 2006
+++ b/xen/common/sched_sedf.c Sun Apr 9 17:23:16 2006
@@ -15,34 +15,23 @@
/*verbosity settings*/
#define SEDFLEVEL 0
-#define PRINT(_f, _a...) \
- if ((_f)<=SEDFLEVEL) printk(_a );
+#define PRINT(_f, _a...) \
+ do { \
+ if ( (_f) <= SEDFLEVEL ) \
+ printk(_a ); \
+ } while ( 0 )
#ifndef NDEBUG
#define SEDF_STATS
-#define CHECK(_p) if ( !(_p) ) \
- { printk("Check '%s' failed, line %d, file %s\n", #_p , __LINE__,\
- __FILE__);}
+#define CHECK(_p) \
+ do { \
+ if ( !(_p) ) \
+ printk("Check '%s' failed, line %d, file %s\n", \
+ #_p , __LINE__, __FILE__); \
+ } while ( 0 )
#else
#define CHECK(_p) ((void)0)
#endif
-
-/*various ways of unblocking domains*/
-#define UNBLOCK_ISOCHRONOUS_EDF 1
-#define UNBLOCK_EDF 2
-#define UNBLOCK_ATROPOS 3
-#define UNBLOCK_SHORT_RESUME 4
-#define UNBLOCK_BURST 5
-#define UNBLOCK_EXTRA_SUPPORT 6
-#define UNBLOCK UNBLOCK_EXTRA_SUPPORT
-
-/*various ways of treating extra-time*/
-#define EXTRA_OFF 1
-#define EXTRA_ROUNDR 2
-#define EXTRA_SLICE_WEIGHT 3
-#define EXTRA_BLOCK_WEIGHT 4
-
-#define EXTRA EXTRA_BLOCK_WEIGHT
#define EXTRA_NONE (0)
#define EXTRA_AWARE (1)
@@ -68,8 +57,8 @@
struct sedf_dom_info {
struct domain *domain;
};
-struct sedf_vcpu_info
-{
+
+struct sedf_vcpu_info {
struct vcpu *vcpu;
struct list_head list;
struct list_head extralist[2];
@@ -85,10 +74,10 @@
s_time_t latency;
/*status of domain*/
- int status;
+ int status;
/*weights for "Scheduling for beginners/ lazy/ etc." ;)*/
- short weight;
- short extraweight;
+ short weight;
+ short extraweight;
/*Bookkeeping*/
s_time_t deadl_abs;
s_time_t sched_start_abs;
@@ -123,28 +112,29 @@
s_time_t current_slice_expires;
};
-#define EDOM_INFO(d) ((struct sedf_vcpu_info *)((d)->sched_priv))
-#define CPU_INFO(cpu) ((struct sedf_cpu_info *)schedule_data[cpu].sched_priv)
-#define LIST(d) (&EDOM_INFO(d)->list)
-#define EXTRALIST(d,i) (&(EDOM_INFO(d)->extralist[i]))
-#define RUNQ(cpu) (&CPU_INFO(cpu)->runnableq)
+#define EDOM_INFO(d) ((struct sedf_vcpu_info *)((d)->sched_priv))
+#define CPU_INFO(cpu) ((struct sedf_cpu_info *)schedule_data[cpu].sched_priv)
+#define LIST(d) (&EDOM_INFO(d)->list)
+#define EXTRALIST(d,i) (&(EDOM_INFO(d)->extralist[i]))
+#define RUNQ(cpu) (&CPU_INFO(cpu)->runnableq)
#define WAITQ(cpu) (&CPU_INFO(cpu)->waitq)
-#define EXTRAQ(cpu,i) (&(CPU_INFO(cpu)->extraq[i]))
+#define EXTRAQ(cpu,i) (&(CPU_INFO(cpu)->extraq[i]))
#define IDLETASK(cpu) ((struct vcpu *)schedule_data[cpu].idle)
#define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period)
-#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MIN(x,y) (((x)<(y))?(x):(y))
#define DIV_UP(x,y) (((x) + (y) - 1) / y)
-#define extra_runs(inf) ((inf->status) & 6)
+#define extra_runs(inf) ((inf->status) & 6)
#define extra_get_cur_q(inf) (((inf->status & 6) >> 1)-1)
-#define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP))
+#define sedf_runnable(edom) (!(EDOM_INFO(edom)->status & SEDF_ASLEEP))
static void sedf_dump_cpu_state(int i);
-static inline int extraq_on(struct vcpu *d, int i) {
+static inline int extraq_on(struct vcpu *d, int i)
+{
return ((EXTRALIST(d,i)->next != NULL) &&
(EXTRALIST(d,i)->next != EXTRALIST(d,i)));
}
@@ -165,8 +155,8 @@
{
struct list_head *list = EXTRALIST(d,i);
ASSERT(extraq_on(d,i));
- PRINT(3, "Removing domain %i.%i from L%i extraq\n", d->domain->domain_id,
- d->vcpu_id, i);
+ PRINT(3, "Removing domain %i.%i from L%i extraq\n",
+ d->domain->domain_id, d->vcpu_id, i);
list_del(list);
list->next = NULL;
ASSERT(!extraq_on(d, i));
@@ -178,94 +168,96 @@
each entry, in order to avoid overflow. The algorithm works by simply
charging each domain that recieved extratime with an inverse of its weight.
*/
-static inline void extraq_add_sort_update(struct vcpu *d, int i, int sub) {
+static inline void extraq_add_sort_update(struct vcpu *d, int i, int sub)
+{
struct list_head *cur;
struct sedf_vcpu_info *curinf;
ASSERT(!extraq_on(d,i));
+
PRINT(3, "Adding domain %i.%i (score= %i, short_pen= %"PRIi64")"
" to L%i extraq\n",
d->domain->domain_id, d->vcpu_id, EDOM_INFO(d)->score[i],
EDOM_INFO(d)->short_block_lost_tot, i);
- /*iterate through all elements to find our "hole" and on our way
- update all the other scores*/
- list_for_each(cur,EXTRAQ(d->processor,i)){
+
+ /*
+ * Iterate through all elements to find our "hole" and on our way
+ * update all the other scores.
+ */
+ list_for_each ( cur, EXTRAQ(d->processor, i) )
+ {
curinf = list_entry(cur,struct sedf_vcpu_info,extralist[i]);
curinf->score[i] -= sub;
- if (EDOM_INFO(d)->score[i] < curinf->score[i])
+ if ( EDOM_INFO(d)->score[i] < curinf->score[i] )
break;
- else
- PRINT(4,"\tbehind domain %i.%i (score= %i)\n",
- curinf->vcpu->domain->domain_id,
- curinf->vcpu->vcpu_id, curinf->score[i]);
- }
- /*cur now contains the element, before which we'll enqueue*/
+ PRINT(4,"\tbehind domain %i.%i (score= %i)\n",
+ curinf->vcpu->domain->domain_id,
+ curinf->vcpu->vcpu_id, curinf->score[i]);
+ }
+
+ /* cur now contains the element, before which we'll enqueue. */
PRINT(3, "\tlist_add to %p\n", cur->prev);
list_add(EXTRALIST(d,i),cur->prev);
- /*continue updating the extraq*/
- if ((cur != EXTRAQ(d->processor,i)) && sub)
- for (cur = cur->next; cur != EXTRAQ(d->processor,i);
- cur = cur-> next) {
- curinf = list_entry(cur,struct sedf_vcpu_info,
- extralist[i]);
+ /* Continue updating the extraq. */
+ if ( (cur != EXTRAQ(d->processor,i)) && sub )
+ {
+ for ( cur = cur->next; cur != EXTRAQ(d->processor,i); cur = cur->next )
+ {
+ curinf = list_entry(cur,struct sedf_vcpu_info, extralist[i]);
curinf->score[i] -= sub;
PRINT(4, "\tupdating domain %i.%i (score= %u)\n",
curinf->vcpu->domain->domain_id,
curinf->vcpu->vcpu_id, curinf->score[i]);
}
+ }
+
ASSERT(extraq_on(d,i));
}
-static inline void extraq_check(struct vcpu *d) {
- if (extraq_on(d, EXTRA_UTIL_Q)) {
- PRINT(2,"Dom %i.%i is on L1 extraQ\n",d->domain->domain_id,
d->vcpu_id);
- if (!(EDOM_INFO(d)->status & EXTRA_AWARE) &&
- !extra_runs(EDOM_INFO(d))) {
+static inline void extraq_check(struct vcpu *d)
+{
+ if ( extraq_on(d, EXTRA_UTIL_Q) )
+ {
+ PRINT(2,"Dom %i.%i is on L1 extraQ\n",
+ d->domain->domain_id, d->vcpu_id);
+
+ if ( !(EDOM_INFO(d)->status & EXTRA_AWARE) &&
+ !extra_runs(EDOM_INFO(d)) )
+ {
extraq_del(d, EXTRA_UTIL_Q);
PRINT(2,"Removed dom %i.%i from L1 extraQ\n",
d->domain->domain_id, d->vcpu_id);
}
- } else {
- PRINT(2,"Dom %i.%i is NOT on L1 extraQ\n",d->domain->domain_id,
+ }
+ else
+ {
+ PRINT(2, "Dom %i.%i is NOT on L1 extraQ\n",
+ d->domain->domain_id,
d->vcpu_id);
- if ((EDOM_INFO(d)->status & EXTRA_AWARE) && sedf_runnable(d))
- {
-#if (EXTRA == EXTRA_ROUNDR)
- extraq_add_tail(d, EXTRA_UTIL_Q);
-#elif (EXTRA == EXTRA_SLICE_WEIGHT || \
- EXTRA == EXTRA_BLOCK_WEIGHT)
+
+ if ( (EDOM_INFO(d)->status & EXTRA_AWARE) && sedf_runnable(d) )
+ {
extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
-#elif
- ;
-#endif
- PRINT(2,"Added dom %i.%i to L1 extraQ\n",d->domain->domain_id,
- d->vcpu_id);
- }
- }
-}
-
-static inline void extraq_check_add_unblocked(struct vcpu *d,
- int priority) {
+ PRINT(2,"Added dom %i.%i to L1 extraQ\n",
+ d->domain->domain_id, d->vcpu_id);
+ }
+ }
+}
+
+static inline void extraq_check_add_unblocked(struct vcpu *d, int priority)
+{
struct sedf_vcpu_info *inf = EDOM_INFO(d);
- if (inf->status & EXTRA_AWARE)
-#if (EXTRA == EXTRA_ROUNDR)
- if (priority)
- extraq_add_head(d,EXTRA_UTIL_Q);
- else
- extraq_add_tail(d,EXTRA_UTIL_Q);
-#elif (EXTRA == EXTRA_SLICE_WEIGHT \
- || EXTRA == EXTRA_BLOCK_WEIGHT)
- /*put in on the weighted extraq,
- without updating any scores*/
- extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
-#else
- ;
-#endif
-}
-
-static inline int __task_on_queue(struct vcpu *d) {
+
+ if ( inf->status & EXTRA_AWARE )
+ /* Put on the weighted extraq without updating any scores. */
+ extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
+}
+
+static inline int __task_on_queue(struct vcpu *d)
+{
return (((LIST(d))->next != NULL) && (LIST(d)->next != LIST(d)));
}
+
static inline void __del_from_queue(struct vcpu *d)
{
struct list_head *list = LIST(d);
@@ -279,42 +271,47 @@
typedef int(*list_comparer)(struct list_head* el1, struct list_head* el2);
-static inline void list_insert_sort(struct list_head *list,
- struct list_head *element, list_comparer
comp) {
+static inline void list_insert_sort(
+ struct list_head *list, struct list_head *element, list_comparer comp)
+{
struct list_head *cur;
- /*iterate through all elements to find our "hole"*/
- list_for_each(cur,list){
- if (comp(element, cur) < 0)
+
+ /* Iterate through all elements to find our "hole". */
+ list_for_each( cur, list )
+ if ( comp(element, cur) < 0 )
break;
- }
- /*cur now contains the element, before which we'll enqueue*/
+
+ /* cur now contains the element, before which we'll enqueue. */
PRINT(3,"\tlist_add to %p\n",cur->prev);
list_add(element, cur->prev);
-}
+}
+
#define DOMAIN_COMPARER(name, field, comp1, comp2) \
int name##_comp(struct list_head* el1, struct list_head* el2) \
{ \
- struct sedf_vcpu_info *d1, *d2; \
- d1 = list_entry(el1,struct sedf_vcpu_info, field); \
- d2 = list_entry(el2,struct sedf_vcpu_info, field); \
- if ((comp1) == (comp2)) \
- return 0; \
- if ((comp1) < (comp2)) \
- return -1; \
- else \
- return 1; \
-}
+ struct sedf_vcpu_info *d1, *d2; \
+ d1 = list_entry(el1,struct sedf_vcpu_info, field); \
+ d2 = list_entry(el2,struct sedf_vcpu_info, field); \
+ if ( (comp1) == (comp2) ) \
+ return 0; \
+ if ( (comp1) < (comp2) ) \
+ return -1; \
+ else \
+ return 1; \
+}
+
/* adds a domain to the queue of processes which wait for the beginning of the
next period; this list is therefore sortet by this time, which is simply
absol. deadline - period
*/
-DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2))
- static inline void __add_to_waitqueue_sort(struct vcpu *d) {
- ASSERT(!__task_on_queue(d));
+DOMAIN_COMPARER(waitq, list, PERIOD_BEGIN(d1), PERIOD_BEGIN(d2));
+static inline void __add_to_waitqueue_sort(struct vcpu *v)
+{
+ ASSERT(!__task_on_queue(v));
PRINT(3,"Adding domain %i.%i (bop= %"PRIu64") to waitq\n",
- d->domain->domain_id, d->vcpu_id, PERIOD_BEGIN(EDOM_INFO(d)));
- list_insert_sort(WAITQ(d->processor), LIST(d), waitq_comp);
- ASSERT(__task_on_queue(d));
+ v->domain->domain_id, v->vcpu_id, PERIOD_BEGIN(EDOM_INFO(v)));
+ list_insert_sort(WAITQ(v->processor), LIST(v), waitq_comp);
+ ASSERT(__task_on_queue(v));
}
/* adds a domain to the queue of processes which have started their current
@@ -322,60 +319,62 @@
on this list is running on the processor, if the list is empty the idle
task will run. As we are implementing EDF, this list is sorted by deadlines.
*/
-DOMAIN_COMPARER(runq, list, d1->deadl_abs, d2->deadl_abs)
- static inline void __add_to_runqueue_sort(struct vcpu *d) {
+DOMAIN_COMPARER(runq, list, d1->deadl_abs, d2->deadl_abs);
+static inline void __add_to_runqueue_sort(struct vcpu *v)
+{
PRINT(3,"Adding domain %i.%i (deadl= %"PRIu64") to runq\n",
- d->domain->domain_id, d->vcpu_id, EDOM_INFO(d)->deadl_abs);
- list_insert_sort(RUNQ(d->processor), LIST(d), runq_comp);
+ v->domain->domain_id, v->vcpu_id, EDOM_INFO(v)->deadl_abs);
+ list_insert_sort(RUNQ(v->processor), LIST(v), runq_comp);
}
/* Allocates memory for per domain private scheduling data*/
-static int sedf_alloc_task(struct vcpu *d)
+static int sedf_alloc_task(struct vcpu *v)
{
PRINT(2, "sedf_alloc_task was called, domain-id %i.%i\n",
- d->domain->domain_id, d->vcpu_id);
-
- if ( d->domain->sched_priv == NULL )
- {
- d->domain->sched_priv = xmalloc(struct sedf_dom_info);
- if ( d->domain->sched_priv == NULL )
+ v->domain->domain_id, v->vcpu_id);
+
+ if ( v->domain->sched_priv == NULL )
+ {
+ v->domain->sched_priv = xmalloc(struct sedf_dom_info);
+ if ( v->domain->sched_priv == NULL )
return -1;
- memset(d->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
- }
-
- if ( (d->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
+ memset(v->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
+ }
+
+ if ( (v->sched_priv = xmalloc(struct sedf_vcpu_info)) == NULL )
return -1;
- memset(d->sched_priv, 0, sizeof(struct sedf_vcpu_info));
+ memset(v->sched_priv, 0, sizeof(struct sedf_vcpu_info));
return 0;
}
/* Setup the sedf_dom_info */
-static void sedf_add_task(struct vcpu *d)
-{
- struct sedf_vcpu_info *inf = EDOM_INFO(d);
- inf->vcpu = d;
-
- PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",d->domain->domain_id,
- d->vcpu_id);
+static void sedf_add_task(struct vcpu *v)
+{
+ struct sedf_vcpu_info *inf = EDOM_INFO(v);
+
+ inf->vcpu = v;
+
+ PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",
+ v->domain->domain_id, v->vcpu_id);
/* Allocate per-CPU context if this is the first domain to be added. */
- if ( unlikely(schedule_data[d->processor].sched_priv == NULL) )
- {
- schedule_data[d->processor].sched_priv =
+ if ( unlikely(schedule_data[v->processor].sched_priv == NULL) )
+ {
+ schedule_data[v->processor].sched_priv =
xmalloc(struct sedf_cpu_info);
- BUG_ON(schedule_data[d->processor].sched_priv == NULL);
- memset(CPU_INFO(d->processor), 0, sizeof(*CPU_INFO(d->processor)));
- INIT_LIST_HEAD(WAITQ(d->processor));
- INIT_LIST_HEAD(RUNQ(d->processor));
- INIT_LIST_HEAD(EXTRAQ(d->processor,EXTRA_PEN_Q));
- INIT_LIST_HEAD(EXTRAQ(d->processor,EXTRA_UTIL_Q));
+ BUG_ON(schedule_data[v->processor].sched_priv == NULL);
+ memset(CPU_INFO(v->processor), 0, sizeof(*CPU_INFO(v->processor)));
+ INIT_LIST_HEAD(WAITQ(v->processor));
+ INIT_LIST_HEAD(RUNQ(v->processor));
+ INIT_LIST_HEAD(EXTRAQ(v->processor,EXTRA_PEN_Q));
+ INIT_LIST_HEAD(EXTRAQ(v->processor,EXTRA_UTIL_Q));
}
- if ( d->domain->domain_id == 0 )
+ if ( v->domain->domain_id == 0 )
{
/*set dom0 to something useful to boot the machine*/
inf->period = MILLISECS(20);
@@ -400,14 +399,14 @@
INIT_LIST_HEAD(&(inf->extralist[EXTRA_PEN_Q]));
INIT_LIST_HEAD(&(inf->extralist[EXTRA_UTIL_Q]));
- if ( !is_idle_vcpu(d) )
- {
- extraq_check(d);
+ if ( !is_idle_vcpu(v) )
+ {
+ extraq_check(v);
}
else
{
- EDOM_INFO(d)->deadl_abs = 0;
- EDOM_INFO(d)->status &= ~SEDF_ASLEEP;
+ EDOM_INFO(v)->deadl_abs = 0;
+ EDOM_INFO(v)->status &= ~SEDF_ASLEEP;
}
}
@@ -418,17 +417,11 @@
PRINT(2,"sedf_free_task was called, domain-id %i\n",d->domain_id);
- ASSERT(d->sched_priv != NULL);
xfree(d->sched_priv);
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
- {
if ( d->vcpu[i] )
- {
- ASSERT(d->vcpu[i]->sched_priv != NULL);
xfree(d->vcpu[i]->sched_priv);
- }
- }
}
/*
@@ -438,64 +431,60 @@
static void desched_edf_dom(s_time_t now, struct vcpu* d)
{
struct sedf_vcpu_info* inf = EDOM_INFO(d);
- /*current domain is running in real time mode*/
-
+
+ /* Current domain is running in real time mode. */
ASSERT(__task_on_queue(d));
- /*update the domains cputime*/
+
+ /* Update the domain's cputime. */
inf->cputime += now - inf->sched_start_abs;
- /*scheduling decisions, which don't remove the running domain
- from the runq*/
+ /*
+ * Scheduling decisions which don't remove the running domain from the
+ * runq.
+ */
if ( (inf->cputime < inf->slice) && sedf_runnable(d) )
return;
__del_from_queue(d);
- /*manage bookkeeping (i.e. calculate next deadline,
- memorize overun-time of slice) of finished domains*/
+ /*
+ * Manage bookkeeping (i.e. calculate next deadline, memorise
+ * overrun-time of slice) of finished domains.
+ */
if ( inf->cputime >= inf->slice )
{
inf->cputime -= inf->slice;
if ( inf->period < inf->period_orig )
{
- /*this domain runs in latency scaling or burst mode*/
-#if (UNBLOCK == UNBLOCK_BURST)
- /*if we are runnig in burst scaling wait for two periods
- before scaling periods up again*/
- if ( (now - inf->unblock_abs) >= (2 * inf->period) )
-#endif
+ /* This domain runs in latency scaling or burst mode. */
+ inf->period *= 2;
+ inf->slice *= 2;
+ if ( (inf->period > inf->period_orig) ||
+ (inf->slice > inf->slice_orig) )
{
- inf->period *= 2; inf->slice *= 2;
- if ( (inf->period > inf->period_orig) ||
- (inf->slice > inf->slice_orig) )
- {
- /*reset slice & period*/
- inf->period = inf->period_orig;
- inf->slice = inf->slice_orig;
- }
+ /* Reset slice and period. */
+ inf->period = inf->period_orig;
+ inf->slice = inf->slice_orig;
}
}
- /*set next deadline*/
+
+ /* Set next deadline. */
inf->deadl_abs += inf->period;
}
- /*add a runnable domain to the waitqueue*/
+ /* Add a runnable domain to the waitqueue. */
if ( sedf_runnable(d) )
{
__add_to_waitqueue_sort(d);
}
else
{
- /*we have a blocked realtime task -> remove it from exqs too*/
-#if (EXTRA > EXTRA_OFF)
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
+ /* We have a blocked realtime task -> remove it from exqs too. */
if ( extraq_on(d, EXTRA_PEN_Q) )
extraq_del(d, EXTRA_PEN_Q);
-#endif
if ( extraq_on(d, EXTRA_UTIL_Q) )
extraq_del(d, EXTRA_UTIL_Q);
-#endif
}
ASSERT(EQ(sedf_runnable(d), __task_on_queue(d)));
@@ -513,58 +502,57 @@
PRINT(3,"Updating waitq..\n");
- /*check for the first elements of the waitqueue, whether their
- next period has already started*/
- list_for_each_safe(cur, tmp, waitq) {
+ /*
+ * Check for the first elements of the waitqueue, whether their
+ * next period has already started.
+ */
+ list_for_each_safe ( cur, tmp, waitq )
+ {
curinf = list_entry(cur, struct sedf_vcpu_info, list);
PRINT(4,"\tLooking @ dom %i.%i\n",
curinf->vcpu->domain->domain_id, curinf->vcpu->vcpu_id);
- if ( PERIOD_BEGIN(curinf) <= now )
- {
- __del_from_queue(curinf->vcpu);
- __add_to_runqueue_sort(curinf->vcpu);
- }
- else
+ if ( PERIOD_BEGIN(curinf) > now )
break;
+ __del_from_queue(curinf->vcpu);
+ __add_to_runqueue_sort(curinf->vcpu);
}
PRINT(3,"Updating runq..\n");
- /*process the runq, find domains that are on
- the runqueue which shouldn't be there*/
- list_for_each_safe(cur, tmp, runq) {
+ /* Process the runq, find domains that are on the runq that shouldn't. */
+ list_for_each_safe ( cur, tmp, runq )
+ {
curinf = list_entry(cur,struct sedf_vcpu_info,list);
PRINT(4,"\tLooking @ dom %i.%i\n",
curinf->vcpu->domain->domain_id, curinf->vcpu->vcpu_id);
if ( unlikely(curinf->slice == 0) )
{
- /*ignore domains with empty slice*/
+ /* Ignore domains with empty slice. */
PRINT(4,"\tUpdating zero-slice domain %i.%i\n",
curinf->vcpu->domain->domain_id,
curinf->vcpu->vcpu_id);
__del_from_queue(curinf->vcpu);
- /*move them to their next period*/
+ /* Move them to their next period. */
curinf->deadl_abs += curinf->period;
- /*ensure that the start of the next period is in the future*/
+
+ /* Ensure that the start of the next period is in the future. */
if ( unlikely(PERIOD_BEGIN(curinf) < now) )
- {
curinf->deadl_abs +=
(DIV_UP(now - PERIOD_BEGIN(curinf),
- curinf->period)) * curinf->period;
- }
- /*and put them back into the queue*/
+ curinf->period)) * curinf->period;
+
+ /* Put them back into the queue. */
__add_to_waitqueue_sort(curinf->vcpu);
- continue;
- }
-
- if ( unlikely((curinf->deadl_abs < now) ||
- (curinf->cputime > curinf->slice)) )
- {
- /*we missed the deadline or the slice was
- already finished... might hapen because
- of dom_adj.*/
+ }
+ else if ( unlikely((curinf->deadl_abs < now) ||
+ (curinf->cputime > curinf->slice)) )
+ {
+ /*
+ * We missed the deadline or the slice was already finished.
+ * Might hapen because of dom_adj.
+ */
PRINT(4,"\tDomain %i.%i exceeded it's deadline/"
"slice (%"PRIu64" / %"PRIu64") now: %"PRIu64
" cputime: %"PRIu64"\n",
@@ -573,20 +561,23 @@
curinf->deadl_abs, curinf->slice, now,
curinf->cputime);
__del_from_queue(curinf->vcpu);
- /*common case: we miss one period!*/
+
+ /* Common case: we miss one period. */
curinf->deadl_abs += curinf->period;
- /*if we are still behind: modulo arithmetic,
- force deadline to be in future and
- aligned to period borders!*/
- if (unlikely(curinf->deadl_abs < now))
+ /*
+ * If we are still behind: modulo arithmetic, force deadline
+ * to be in future and aligned to period borders.
+ */
+ if ( unlikely(curinf->deadl_abs < now) )
curinf->deadl_abs +=
DIV_UP(now - curinf->deadl_abs,
curinf->period) * curinf->period;
ASSERT(curinf->deadl_abs >= now);
- /*give a fresh slice*/
+
+ /* Give a fresh slice. */
curinf->cputime = 0;
- if (PERIOD_BEGIN(curinf) > now)
+ if ( PERIOD_BEGIN(curinf) > now )
__add_to_waitqueue_sort(curinf->vcpu);
else
__add_to_runqueue_sort(curinf->vcpu);
@@ -594,43 +585,36 @@
else
break;
}
+
PRINT(3,"done updating the queues\n");
}
-#if (EXTRA > EXTRA_OFF)
/* removes a domain from the head of the according extraQ and
requeues it at a specified position:
round-robin extratime: end of extraQ
weighted ext.: insert in sorted list by score
if the domain is blocked / has regained its short-block-loss
time it is not put on any queue */
-static void desched_extra_dom(s_time_t now, struct vcpu* d)
+static void desched_extra_dom(s_time_t now, struct vcpu *d)
{
struct sedf_vcpu_info *inf = EDOM_INFO(d);
int i = extra_get_cur_q(inf);
-
-#if (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
- unsigned long oldscore;
-#endif
+ unsigned long oldscore;
+
ASSERT(extraq_on(d, i));
- /*unset all running flags*/
+
+ /* Unset all running flags. */
inf->status &= ~(EXTRA_RUN_PEN | EXTRA_RUN_UTIL);
- /*fresh slice for the next run*/
+ /* Fresh slice for the next run. */
inf->cputime = 0;
- /*accumulate total extratime*/
+ /* Accumulate total extratime. */
inf->extra_time_tot += now - inf->sched_start_abs;
- /*remove extradomain from head of the queue*/
+ /* Remove extradomain from head of the queue. */
extraq_del(d, i);
-#if (EXTRA == EXTRA_ROUNDR)
- if ( sedf_runnable(d) && (inf->status & EXTRA_AWARE) )
- /*add to the tail if it is runnable => round-robin*/
- extraq_add_tail(d, EXTRA_UTIL_Q);
-#elif (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
- /*update the score*/
+ /* Update the score. */
oldscore = inf->score[i];
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( i == EXTRA_PEN_Q )
{
/*domain was running in L0 extraq*/
@@ -640,7 +624,8 @@
PRINT(3,"Domain %i.%i: Short_block_loss: %"PRIi64"\n",
inf->vcpu->domain->domain_id, inf->vcpu->vcpu_id,
inf->short_block_lost_tot);
- if (inf->short_block_lost_tot <= 0) {
+ if ( inf->short_block_lost_tot <= 0 )
+ {
PRINT(4,"Domain %i.%i compensated short block loss!\n",
inf->vcpu->domain->domain_id, inf->vcpu->vcpu_id);
/*we have (over-)compensated our block penalty*/
@@ -649,6 +634,7 @@
inf->status &= ~EXTRA_WANT_PEN_Q;
goto check_extra_queues;
}
+
/*we have to go again for another try in the block-extraq,
the score is not used incremantally here, as this is
already done by recalculating the block_lost*/
@@ -657,7 +643,6 @@
oldscore = 0;
}
else
-#endif
{
/*domain was running in L1 extraq => score is inverse of
utilization and is used somewhat incremental!*/
@@ -684,7 +669,6 @@
{
/*remove this blocked domain from the waitq!*/
__del_from_queue(d);
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
/*make sure that we remove a blocked domain from the other
extraq too*/
if ( i == EXTRA_PEN_Q )
@@ -697,14 +681,12 @@
if ( extraq_on(d, EXTRA_PEN_Q) )
extraq_del(d, EXTRA_PEN_Q);
}
-#endif
- }
-#endif
+ }
+
ASSERT(EQ(sedf_runnable(d), __task_on_queue(d)));
ASSERT(IMPLY(extraq_on(d, EXTRA_UTIL_Q) || extraq_on(d, EXTRA_PEN_Q),
sedf_runnable(d)));
}
-#endif
static struct task_slice sedf_do_extra_schedule(
@@ -718,7 +700,6 @@
if ( end_xt - now < EXTRA_QUANTUM )
goto return_idle;
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( !list_empty(extraq[EXTRA_PEN_Q]) )
{
/*we still have elements on the level 0 extraq
@@ -733,7 +714,6 @@
#endif
}
else
-#endif
{
if ( !list_empty(extraq[EXTRA_UTIL_Q]) )
{
@@ -772,11 +752,9 @@
int cpu = smp_processor_id();
struct list_head *runq = RUNQ(cpu);
struct list_head *waitq = WAITQ(cpu);
-#if (EXTRA > EXTRA_OFF)
struct sedf_vcpu_info *inf = EDOM_INFO(current);
struct list_head *extraq[] = {
EXTRAQ(cpu, EXTRA_PEN_Q), EXTRAQ(cpu, EXTRA_UTIL_Q)};
-#endif
struct sedf_vcpu_info *runinf, *waitinf;
struct task_slice ret;
@@ -793,14 +771,12 @@
if ( inf->status & SEDF_ASLEEP )
inf->block_abs = now;
-#if (EXTRA > EXTRA_OFF)
if ( unlikely(extra_runs(inf)) )
{
/*special treatment of domains running in extra time*/
desched_extra_dom(now, current);
}
else
-#endif
{
desched_edf_dom(now, current);
}
@@ -837,13 +813,8 @@
waitinf = list_entry(waitq->next,struct sedf_vcpu_info, list);
/*we could not find any suitable domain
=> look for domains that are aware of extratime*/
-#if (EXTRA > EXTRA_OFF)
ret = sedf_do_extra_schedule(now, PERIOD_BEGIN(waitinf),
extraq, cpu);
-#else
- ret.task = IDLETASK(cpu);
- ret.time = PERIOD_BEGIN(waitinf) - now;
-#endif
CHECK(ret.time > 0);
}
else
@@ -891,14 +862,10 @@
{
if ( __task_on_queue(d) )
__del_from_queue(d);
-#if (EXTRA > EXTRA_OFF)
if ( extraq_on(d, EXTRA_UTIL_Q) )
extraq_del(d, EXTRA_UTIL_Q);
-#endif
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( extraq_on(d, EXTRA_PEN_Q) )
extraq_del(d, EXTRA_PEN_Q);
-#endif
}
}
@@ -939,7 +906,7 @@
* -addition: experiments have shown that this may have a HUGE impact on
* performance of other domains, becaus it can lead to excessive context
* switches
-
+ *
* Part2: Long Unblocking
* Part 2a
* -it is obvious that such accounting of block time, applied when
@@ -974,32 +941,6 @@
* -either behaviour can lead to missed deadlines in other domains as
* opposed to approaches 1,2a,2b
*/
-#if (UNBLOCK <= UNBLOCK_SHORT_RESUME)
-static void unblock_short_vcons(struct sedf_vcpu_info* inf, s_time_t now)
-{
- inf->deadl_abs += inf->period;
- inf->cputime = 0;
-}
-#endif
-
-#if (UNBLOCK == UNBLOCK_SHORT_RESUME)
-static void unblock_short_cons(struct sedf_vcpu_info* inf, s_time_t now)
-{
- /*treat blocked time as consumed by the domain*/
- inf->cputime += now - inf->block_abs;
- if ( (inf->cputime + EXTRA_QUANTUM) > inf->slice )
- {
- /*we don't have a reasonable amount of time in
- our slice left :( => start in next period!*/
- unblock_short_vcons(inf, now);
- }
-#ifdef SEDF_STATS
- else
- inf->short_cont++;
-#endif
-}
-#endif
-
static void unblock_short_extra_support(
struct sedf_vcpu_info* inf, s_time_t now)
{
@@ -1051,33 +992,6 @@
}
-#if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF)
-static void unblock_long_vcons(struct sedf_vcpu_info* inf, s_time_t now)
-{
- /* align to next future period */
- inf->deadl_abs += (DIV_UP(now - inf->deadl_abs, inf->period) +1)
- * inf->period;
- inf->cputime = 0;
-}
-#endif
-
-
-#if 0
-static void unblock_long_cons_a (struct sedf_vcpu_info* inf, s_time_t now)
-{
- /*treat the time the domain was blocked in the
- CURRENT period as consumed by the domain*/
- inf->cputime = (now - inf->deadl_abs) % inf->period;
- if ( (inf->cputime + EXTRA_QUANTUM) > inf->slice )
- {
- /*we don't have a reasonable amount of time in our slice
- left :( => start in next period!*/
- unblock_long_vcons(inf, now);
- }
-}
-#endif
-
-
static void unblock_long_cons_b(struct sedf_vcpu_info* inf,s_time_t now)
{
/*Conservative 2b*/
@@ -1085,110 +999,6 @@
inf->deadl_abs = now + inf->period;
inf->cputime = 0;
}
-
-
-#if (UNBLOCK == UNBLOCK_ATROPOS)
-static void unblock_long_cons_c(struct sedf_vcpu_info* inf,s_time_t now)
-{
- if ( likely(inf->latency) )
- {
- /*scale the slice and period accordingly to the latency hint*/
- /*reduce period temporarily to the latency hint*/
- inf->period = inf->latency;
- /*this results in max. 4s slice/period length*/
- ASSERT((inf->period < ULONG_MAX)
- && (inf->slice_orig < ULONG_MAX));
- /*scale slice accordingly, so that utilisation stays the same*/
- inf->slice = (inf->period * inf->slice_orig)
- / inf->period_orig;
- inf->deadl_abs = now + inf->period;
- inf->cputime = 0;
- }
- else
- {
- /*we don't have a latency hint.. use some other technique*/
- unblock_long_cons_b(inf, now);
- }
-}
-#endif
-
-
-#if (UNBLOCK == UNBLOCK_BURST)
-/*a new idea of dealing with short blocks: burst period scaling*/
-static void unblock_short_burst(struct sedf_vcpu_info* inf, s_time_t now)
-{
- /*treat blocked time as consumed by the domain*/
- inf->cputime += now - inf->block_abs;
-
- if ( (inf->cputime + EXTRA_QUANTUM) <= inf->slice )
- {
- /*if we can still use some time in the current slice
- then use it!*/
-#ifdef SEDF_STATS
- /*we let the domain run in the current period*/
- inf->short_cont++;
-#endif
- }
- else
- {
- /*we don't have a reasonable amount of time in
- our slice left => switch to burst mode*/
- if ( likely(inf->unblock_abs) )
- {
- /*set the period-length to the current blocking
- interval, possible enhancements: average over last
- blocking intervals, user-specified minimum,...*/
- inf->period = now - inf->unblock_abs;
- /*check for overflow on multiplication*/
- ASSERT((inf->period < ULONG_MAX)
- && (inf->slice_orig < ULONG_MAX));
- /*scale slice accordingly, so that utilisation
- stays the same*/
- inf->slice = (inf->period * inf->slice_orig)
- / inf->period_orig;
- /*set new (shorter) deadline*/
- inf->deadl_abs += inf->period;
- }
- else
- {
- /*in case we haven't unblocked before
- start in next period!*/
- inf->cputime=0;
- inf->deadl_abs += inf->period;
- }
- }
-
- inf->unblock_abs = now;
-}
-
-
-static void unblock_long_burst(struct sedf_vcpu_info* inf, s_time_t now)
-{
- if ( unlikely(inf->latency && (inf->period > inf->latency)) )
- {
- /*scale the slice and period accordingly to the latency hint*/
- inf->period = inf->latency;
- /*check for overflows on multiplication*/
- ASSERT((inf->period < ULONG_MAX)
- && (inf->slice_orig < ULONG_MAX));
- /*scale slice accordingly, so that utilisation stays the same*/
- inf->slice = (inf->period * inf->slice_orig)
- / inf->period_orig;
- inf->deadl_abs = now + inf->period;
- inf->cputime = 0;
- }
- else
- {
- /*we don't have a latency hint.. or we are currently in
- "burst mode": use some other technique
- NB: this should be in fact the normal way of operation,
- when we are in sync with the device!*/
- unblock_long_cons_b(inf, now);
- }
-
- inf->unblock_abs = now;
-}
-#endif /* UNBLOCK == UNBLOCK_BURST */
#define DOMAIN_EDF 1
@@ -1225,32 +1035,31 @@
cur_inf = EDOM_INFO(cur);
other_inf = EDOM_INFO(other);
- /*check whether we need to make an earlier sched-decision*/
- if (PERIOD_BEGIN(other_inf) <
- CPU_INFO(other->processor)->current_slice_expires)
+ /* Check whether we need to make an earlier scheduling decision. */
+ if ( PERIOD_BEGIN(other_inf) <
+ CPU_INFO(other->processor)->current_slice_expires )
return 1;
- /*no timing-based switches need to be taken into account here*/
- switch (get_run_type(cur)) {
+
+ /* No timing-based switches need to be taken into account here. */
+ switch ( get_run_type(cur) )
+ {
case DOMAIN_EDF:
- /* do not interrupt a running EDF domain */
+ /* Do not interrupt a running EDF domain. */
return 0;
case DOMAIN_EXTRA_PEN:
- /*check whether we also want
- the L0 ex-q with lower score*/
- if ((other_inf->status & EXTRA_WANT_PEN_Q)
- && (other_inf->score[EXTRA_PEN_Q] <
- cur_inf->score[EXTRA_PEN_Q]))
- return 1;
- else return 0;
+ /* Check whether we also want the L0 ex-q with lower score. */
+ return ((other_inf->status & EXTRA_WANT_PEN_Q) &&
+ (other_inf->score[EXTRA_PEN_Q] <
+ cur_inf->score[EXTRA_PEN_Q]));
case DOMAIN_EXTRA_UTIL:
- /*check whether we want the L0 extraq, don't
- switch if both domains want L1 extraq */
- if (other_inf->status & EXTRA_WANT_PEN_Q)
- return 1;
- else return 0;
+ /* Check whether we want the L0 extraq. Don't
+ * switch if both domains want L1 extraq.
+ */
+ return !!(other_inf->status & EXTRA_WANT_PEN_Q);
case DOMAIN_IDLE:
return 1;
}
+
return 1;
}
@@ -1295,7 +1104,6 @@
{
PRINT(4,"extratime unblock\n");
/* unblocking in extra-time! */
-#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if ( inf->status & EXTRA_WANT_PEN_Q )
{
/*we have a domain that wants compensation
@@ -1304,7 +1112,6 @@
chance!*/
extraq_add_sort_update(d, EXTRA_PEN_Q, 0);
}
-#endif
extraq_check_add_unblocked(d, 0);
}
else
@@ -1316,15 +1123,7 @@
#ifdef SEDF_STATS
inf->short_block_tot++;
#endif
-#if (UNBLOCK <= UNBLOCK_ATROPOS)
- unblock_short_vcons(inf, now);
-#elif (UNBLOCK == UNBLOCK_SHORT_RESUME)
- unblock_short_cons(inf, now);
-#elif (UNBLOCK == UNBLOCK_BURST)
- unblock_short_burst(inf, now);
-#elif (UNBLOCK == UNBLOCK_EXTRA_SUPPORT)
unblock_short_extra_support(inf, now);
-#endif
extraq_check_add_unblocked(d, 1);
}
@@ -1335,18 +1134,7 @@
#ifdef SEDF_STATS
inf->long_block_tot++;
#endif
-#if (UNBLOCK == UNBLOCK_ISOCHRONOUS_EDF)
- unblock_long_vcons(inf, now);
-#elif (UNBLOCK == UNBLOCK_EDF \
- || UNBLOCK == UNBLOCK_EXTRA_SUPPORT)
unblock_long_cons_b(inf, now);
-#elif (UNBLOCK == UNBLOCK_ATROPOS)
- unblock_long_cons_c(inf, now);
-#elif (UNBLOCK == UNBLOCK_SHORT_RESUME)
- unblock_long_cons_b(inf, now);
-#elif (UNBLOCK == UNBLOCK_BURST)
- unblock_long_burst(inf, now);
-#endif
extraq_check_add_unblocked(d, 1);
}
@@ -1528,7 +1316,7 @@
sumt[cpu] = 0;
}
- /* sum up all weights */
+ /* Sum across all weights. */
for_each_domain( d )
{
for_each_vcpu( d, p )
@@ -1553,7 +1341,7 @@
}
}
- /* adjust all slices (and periods) to the new weight */
+ /* Adjust all slices (and periods) to the new weight. */
for_each_domain( d )
{
for_each_vcpu ( d, p )
@@ -1580,35 +1368,42 @@
{
struct vcpu *v;
- PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" "\
+ PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" "
"new slice %"PRIu64"\nlatency %"PRIu64" extra:%s\n",
p->domain_id, cmd->u.sedf.period, cmd->u.sedf.slice,
cmd->u.sedf.latency, (cmd->u.sedf.extratime)?"yes":"no");
if ( cmd->direction == SCHED_INFO_PUT )
{
- /*check for sane parameters*/
- if (!cmd->u.sedf.period && !cmd->u.sedf.weight)
+ /* Check for sane parameters. */
+ if ( !cmd->u.sedf.period && !cmd->u.sedf.weight )
return -EINVAL;
- if (cmd->u.sedf.weight) {
- if ((cmd->u.sedf.extratime & EXTRA_AWARE) &&
- (! cmd->u.sedf.period)) {
- /*weight driven domains with xtime ONLY!*/
- for_each_vcpu(p, v) {
+ if ( cmd->u.sedf.weight )
+ {
+ if ( (cmd->u.sedf.extratime & EXTRA_AWARE) &&
+ (!cmd->u.sedf.period) )
+ {
+ /* Weight-driven domains with extratime only. */
+ for_each_vcpu ( p, v )
+ {
EDOM_INFO(v)->extraweight = cmd->u.sedf.weight;
EDOM_INFO(v)->weight = 0;
EDOM_INFO(v)->slice = 0;
EDOM_INFO(v)->period = WEIGHT_PERIOD;
}
- } else {
- /*weight driven domains with real-time execution*/
- for_each_vcpu(p, v)
+ }
+ else
+ {
+ /* Weight-driven domains with real-time execution. */
+ for_each_vcpu ( p, v )
EDOM_INFO(v)->weight = cmd->u.sedf.weight;
}
}
- else {
- /*time driven domains*/
- for_each_vcpu(p, v) {
+ else
+ {
+ /* Time-driven domains. */
+ for_each_vcpu ( p, v )
+ {
/*
* Sanity checking: note that disabling extra weight requires
* that we set a non-zero slice.
@@ -1626,10 +1421,12 @@
EDOM_INFO(v)->slice = cmd->u.sedf.slice;
}
}
- if (sedf_adjust_weights(cmd))
+
+ if ( sedf_adjust_weights(cmd) )
return -EINVAL;
-
- for_each_vcpu(p, v) {
+
+ for_each_vcpu ( p, v )
+ {
EDOM_INFO(v)->status =
(EDOM_INFO(v)->status &
~EXTRA_AWARE) | (cmd->u.sedf.extratime & EXTRA_AWARE);
@@ -1641,11 +1438,11 @@
{
cmd->u.sedf.period = EDOM_INFO(p->vcpu[0])->period;
cmd->u.sedf.slice = EDOM_INFO(p->vcpu[0])->slice;
- cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status
- & EXTRA_AWARE;
+ cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE;
cmd->u.sedf.latency = EDOM_INFO(p->vcpu[0])->latency;
cmd->u.sedf.weight = EDOM_INFO(p->vcpu[0])->weight;
}
+
PRINT(2,"sedf_adjdom_finished\n");
return 0;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|