[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Implemented twol level extra-time scheduling and added an advanced scheduling history



ChangeSet 1.1159.170.105, 2005/03/09 14:35:02+00:00, sd386@xxxxxxxxxxxxxxxxx

        Implemented twol level extra-time scheduling and added an advanced 
scheduling history



 common/sched_sedf.c          |  688 ++++++++++++++++++++++++++++---------------
 include/xen/adv_sched_hist.h |   40 ++
 2 files changed, 497 insertions(+), 231 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:21 -04:00
+++ b/xen/common/sched_sedf.c   2005-05-09 14:04:21 -04:00
@@ -5,6 +5,14 @@
  * 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>
@@ -25,8 +33,8 @@
 #define UNBLOCK_ATROPOS 3
 #define UNBLOCK_SHORT_RESUME 4
 #define UNBLOCK_BURST 5
-
-#define UNBLOCK UNBLOCK_BURST
+#define UNBLOCK_EXTRA_SUPPORT 6
+#define UNBLOCK UNBLOCK_EXTRA_SUPPORT
 
 //various ways of treating extra-time
 #define EXTRA_OFF 1
@@ -34,20 +42,19 @@
 #define EXTRA_SLICE_WEIGHT 3
 #define EXTRA_BLOCK_WEIGHT 4
 
-#define EXTRA EXTRA_OFF
+#define EXTRA EXTRA_BLOCK_WEIGHT
 
-
-/*
-       TODO:
-       TESTING!
-       tracing instead of PRINTs
-*/
-
-
-#define TRC_SEDF 0xBEEF0000
 #define EXTRA_NONE (0)
 #define EXTRA_AWARE (1)
-#define EXTRA_RUNNING (2)
+#define EXTRA_RUN_PEN (2)
+#define EXTRA_RUN_UTIL (4)
+#define EXTRA_WANT_PEN_Q (8)
+#define EXTRA_PEN_Q (0)
+#define EXTRA_UTIL_Q (1)
+
+#define extra_runs(inf) ((inf->extra) & 6)
+#define extra_get_cur_q(inf) (((inf->extra & 6) >> 1)-1)
+
 #define EXTRA_QUANTUM (MICROSECS(500)) 
 #define WEIGHT_PERIOD (MILLISECS(100))
 #define WEIGHT_SAFETY (MILLISECS(5))
@@ -70,7 +77,7 @@
        s_time_t                latency;
        //extra-time status of domain
        short                   extra;
-       //weights for "Scheduling for beginners/ lazy/ etc."
+       //weights for "Scheduling for beginners/ lazy/ etc." ;)
        short                   weight;
        
        //Bookkeeping
@@ -90,46 +97,58 @@
        int                     short_block_tot;
        int                     long_block_tot;
        int                     short_cont;
+       int                     pen_extra_blocks;
+       int                     pen_extra_slices;
 };
 
 struct sedf_cpu_info {
        struct list_head runnableq;
        struct list_head waitq;
-       struct list_head extraq;
+       struct list_head extraq[2];
 };
 
 #define DOM_INFO(d)            ((struct sedf_dom_info *)((d)->sched_priv))
 #define CPU_INFO(cpu)          ((struct sedf_cpu_info 
*)schedule_data[cpu].sched_priv)
 #define LIST(d)                        (&DOM_INFO(d)->list)
-#define EXTRALIST(d)           (&DOM_INFO(d)->extralist)
+#define EXTRALIST(d,i)         (&(DOM_INFO(d)->extralist[i]))
 #define RUNQ(cpu)              (&CPU_INFO(cpu)->runnableq)
 #define WAITQ(cpu)             (&CPU_INFO(cpu)->waitq)
-#define EXTRAQ(cpu)            (&CPU_INFO(cpu)->extraq)
+#define EXTRAQ(cpu,i)                  (&(CPU_INFO(cpu)->extraq[i]))
 #define IDLETASK(cpu)          ((struct domain *)schedule_data[cpu].idle)
 
 #define PERIOD_BEGIN(inf)      ((inf)->absdead - (inf)->period)
 
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#define DIV_UP(x,y) (((x) + (y) - 1) / y)
+
 static xmem_cache_t *dom_info_cache;
 
-static inline void extraq_add_head(struct domain *d)
-{
-    list_add(EXTRALIST(d), EXTRAQ(d->processor));
+static void sedf_dump_cpu_state(int i);
+
+static inline int extraq_on(struct domain *d, int i) {
+       return ((EXTRALIST(d,i)->next != NULL) && (EXTRALIST(d,i)->next != 
EXTRALIST(d,i)));
 }
 
-static inline void extraq_add_tail(struct domain *d)
+static inline void extraq_add_head(struct domain *d, int i)
 {
-    list_add_tail(EXTRALIST(d), EXTRAQ(d->processor));
+    list_add(EXTRALIST(d,i), EXTRAQ(d->processor,i));
 }
 
-static inline void extraq_del(struct domain *d)
+static inline void extraq_add_tail(struct domain *d, int i)
 {
-    struct list_head *list = EXTRALIST(d);
-    list_del(list);
-    list->next = NULL;
+    list_add_tail(EXTRALIST(d,i), EXTRAQ(d->processor,i));
 }
 
-static inline int extraq_on(struct domain *d) {
-       return (((EXTRALIST(d))->next != NULL) && (EXTRALIST(d)->next != 
EXTRALIST(d)));
+static inline void extraq_del(struct domain *d, int i)
+{
+       struct list_head *list = EXTRALIST(d,i);
+       /*if (!extraq_on(d,i)) {
+               PRINT(0,"extraq_del: domain %i is NOT on L%i extraq! 
HALTING\n",d->id,i);
+               sedf_dump_cpu_state(0);(*((int*)0))++;
+       }*/
+       PRINT(3, "Removing domain %i from L%i extraq\n", d->id,i);      
+       list_del(list);
+       list->next = NULL;
 }
 
 /* adds a domain to the queue of processes which are aware of extra time. List 
is sorted by score,
@@ -137,50 +156,57 @@
    a fixed value from 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 domain *d, unsigned long sub) 
{
+static inline void extraq_add_sort_update(struct domain *d, int i, int sub) {
        struct list_head     *cur;
        struct sedf_dom_info *curinf;
        
-       PRINT(3,"Adding domain %i (score= %llu) to 
extraq\n",d->id,DOM_INFO(d)->score); 
+       /*if (extraq_on(d,i)) {
+               PRINT(0,"extraq_add_sort_update: domain %i is already on L%i 
extraq! HALTING\n",d->id,i);
+               sedf_dump_cpu_state(0);(*((int*)0))++;
+       }*/
+       PRINT(3, "Adding domain %i (score= %i, short_pen= %lli) to L%i 
extraq\n", d->id,
+               DOM_INFO(d)->score[i], DOM_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)){
-               curinf         = list_entry(cur,struct sedf_dom_info,extralist);
-               curinf->score -= sub;
-               if (DOM_INFO(d)->score < curinf->score)
+       list_for_each(cur,EXTRAQ(d->processor,i)){
+               curinf            = list_entry(cur,struct 
sedf_dom_info,extralist[i]);
+               curinf->score[i] -= sub;
+               if (DOM_INFO(d)->score[i] < curinf->score[i])
                        break;
                else
-                       PRINT(4,"\tbehind domain %i (score= 
%llu)\n",curinf->owner->id,curinf->score);
+                       PRINT(4,"\tbehind domain %i (score= %i)\n", 
curinf->owner->id, curinf->score[i]);
        }
-       //cur now contains the element, before which we'll enqueue
-       PRINT(3,"\tlist_add to %x\n",cur->prev);
-       list_add(EXTRALIST(d),cur->prev);
+       //cur now contains the element, before which we'll enq  ueue
+       PRINT(3, "\tlist_add to %x\n", cur->prev);
+       list_add(EXTRALIST(d,i),cur->prev);
        
        //continue updating the extraq
-       if ((cur != EXTRAQ(d->processor)) && sub) 
-               for (cur = cur->next; cur != EXTRAQ(d->processor); cur = cur-> 
next) {
-                       curinf         = list_entry(cur,struct 
sedf_dom_info,extralist);
-                       curinf->score -= sub;
-                       PRINT(4,"\tupdating domain %i (score= 
%llu)\n",curinf->owner->id,curinf->score);
+       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_dom_info,extralist[i]);
+                       curinf->score[i] -= sub;
+                       PRINT(4, "\tupdating domain %i (score= %llu)\n", 
curinf->owner->id, curinf->score[i]);
                }
 }
 static inline void extraq_check(struct domain *d) {
-       if (extraq_on(d)) {
+       if (extraq_on(d, EXTRA_UTIL_Q)) {
                PRINT(2,"Dom %i is on extraQ\n",d->id);
-               if (DOM_INFO(d)->extra == EXTRA_NONE) {
-                       extraq_del(d);
-                       PRINT(2,"Removed dom %i from extraQ\n",d->id);
+               if (!(DOM_INFO(d)->extra & EXTRA_AWARE)) {
+                       extraq_del(d, EXTRA_UTIL_Q);
+                       PRINT(2,"Removed dom %i from L1 extraQ\n",d->id);
                }
        } else {
-               PRINT(2,"Dom %i is NOT on extraQ\n",d->id);
-               if (DOM_INFO(d)->extra != EXTRA_NONE) {
-                       PRINT(2,"Added dom %i to extraQ\n",d->id);
-                       extraq_add_sort_update(d, 0);
+               PRINT(2,"Dom %i is NOT on L1 extraQ\n",d->id);
+               if ((DOM_INFO(d)->extra & EXTRA_AWARE) && domain_runnable(d))  {
+                       extraq_add_sort_update(d, EXTRA_UTIL_Q, 0);
+                       PRINT(2,"Added dom %i to L1 extraQ\n",d->id);
+                       //TODO: add extraq_add_tail
                }
        }
 }
 static inline void __del_from_queue(struct domain *d)
 {
     struct list_head *list = LIST(d);
+    PRINT(3,"Removing domain %i (bop= %llu) from 
runq/waitq\n",d->id,PERIOD_BEGIN(DOM_INFO(d)));
     list_del(list);
     list->next = NULL;
 }
@@ -192,7 +218,7 @@
        struct list_head     *cur;
        struct sedf_dom_info *curinf;
        
-       PRINT(3,"Adding domain %i (bop= %llu) to 
waitq\n",d->id,PERIOD_BEGIN(DOM_INFO(d)));     
+       PRINT(3,"Adding domain %i (bop= %llu) to 
waitq\n",d->id,PERIOD_BEGIN(DOM_INFO(d)));
        //iterate through all elements to find our "hole"
        list_for_each(cur,WAITQ(d->processor)){
                curinf = list_entry(cur,struct sedf_dom_info,list);
@@ -243,13 +269,12 @@
                schedule_data[i].sched_priv = xmalloc(sizeof(struct 
sedf_cpu_info));
                if ( schedule_data[i].sched_priv == NULL )
                        return -1;
-               INIT_LIST_HEAD(WAITQ(i));//used for Latency Scaling
+               INIT_LIST_HEAD(WAITQ(i));
                INIT_LIST_HEAD(RUNQ(i));
-               INIT_LIST_HEAD(EXTRAQ(i));
+               INIT_LIST_HEAD(EXTRAQ(i,EXTRA_PEN_Q));
+               INIT_LIST_HEAD(EXTRAQ(i,EXTRA_UTIL_Q));
        }
-                               //we could not find any suitable domain => look 
for domains that are aware of extratime
-       dom_info_cache = xmem_cache_create(
-               "SEDF dom info", sizeof(struct sedf_dom_info), 0, 0, 0, NULL);
+       dom_info_cache = xmem_cache_create("SEDF dom info", sizeof(struct 
sedf_dom_info), 0, 0, 0, NULL);
        if ( dom_info_cache == NULL )
        {
                printk("Could not allocate SLAB cache.\n");

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.