WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Extended sedf scheduler (weighted extraqueues), added en

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Extended sedf scheduler (weighted extraqueues), added enhanced scheduling histogramm
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Thu, 17 Feb 2005 18:50:24 +0000
Delivery-date: Mon, 09 May 2005 18:03:49 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1159.170.104, 2005/02/17 18:50:24+00:00, sd386@xxxxxxxxxxxxxxxxx

        Extended sedf scheduler (weighted extraqueues), added enhanced 
scheduling histogramm



 common/sched_sedf.c    |  258 +++++++++++++++++++++++++++++++++++++++----------
 common/schedule.c      |   92 ++++++++++++++++-
 include/xen/sched-if.h |   11 +-
 3 files changed, 302 insertions(+), 59 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:09 -04:00
+++ b/xen/common/sched_sedf.c   2005-05-09 14:04:09 -04:00
@@ -13,14 +13,33 @@
 #include <xen/time.h>
 #include <xen/slab.h>
 
+//#include <xen/adv_sched_hist.h>
+
 #define SEDFLEVEL 2
 #define PRINT(_f, _a...)  \
 if ((_f)<=SEDFLEVEL) printk(_a );
 
+//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 UNBLOCK_BURST
+
+//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_OFF
+
+
 /*
        TODO:
        TESTING!
-       implement stylish features!
        tracing instead of PRINTs
 */
 
@@ -29,15 +48,16 @@
 #define EXTRA_NONE (0)
 #define EXTRA_AWARE (1)
 #define EXTRA_RUNNING (2)
-#define EXTRA_QUANTUM (MICROSECS(1000)) 
+#define EXTRA_QUANTUM (MICROSECS(500)) 
 #define WEIGHT_PERIOD (MILLISECS(100))
 #define WEIGHT_SAFETY (MILLISECS(5))
 
+
 struct sedf_dom_info
 {
        struct domain           *owner;
        struct list_head        list;
-       struct list_head        extralist;
+       struct list_head        extralist[2];
        
        //Parameters for EDF
        s_time_t                period;         //=(relative deadline)
@@ -50,14 +70,17 @@
        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
        s_time_t                absdead;
        s_time_t                sched_start;
        s_time_t                cputime;
-       s_time_t                absblock;
+       s_time_t                absblock;       
+       s_time_t                absunblock;     //time the domain unblocked, 
used by burst mode to determine unblocking intervals
+       int                     score[2];       //scores for {util, block 
penalty}-weighted extratime distribution
+       s_time_t                short_block_lost_tot;
        
        //Statistics
        s_time_t                block_time_tot;
@@ -109,6 +132,37 @@
        return (((EXTRALIST(d))->next != NULL) && (EXTRALIST(d)->next != 
EXTRALIST(d)));
 }
 
+/* adds a domain to the queue of processes which are aware of extra time. List 
is sorted by score,
+   where a lower score means higher priority for an extra slice. It also 
updates the score, by simply subtracting
+   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) 
{
+       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); 
+       //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)
+                       break;
+               else
+                       PRINT(4,"\tbehind domain %i (score= 
%llu)\n",curinf->owner->id,curinf->score);
+       }
+       //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);
+       
+       //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);
+               }
+}
 static inline void extraq_check(struct domain *d) {
        if (extraq_on(d)) {
                PRINT(2,"Dom %i is on extraQ\n",d->id);
@@ -120,11 +174,10 @@
                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_tail(d);
+                       extraq_add_sort_update(d, 0);
                }
        }
 }
-
 static inline void __del_from_queue(struct domain *d)
 {
     struct list_head *list = LIST(d);
@@ -277,29 +330,45 @@
        int                   cpu   = current->processor;
        struct list_head     *runq  = RUNQ(cpu);
        struct list_head     *waitq = WAITQ(cpu);
+       #if (EXTRA > EXTRA_OFF)
        struct list_head     *extraq = EXTRAQ(cpu);
+       #endif
        struct list_head     *cur,*tmp;
        struct sedf_dom_info *curinf;
        task_slice_t          ret;
-
+       #if (EXTRA == EXTRA_SLICE_WEIGHT)
+       unsigned long         oldscore;
+       #endif
        
        //idle tasks don't need any of the following stuf
        if (is_idle_task(inf->owner))
                goto check_waitq;                               //idle task 
doesn't get scheduled on the runq
-       
+
+       #if (EXTRA > EXTRA_OFF)
        if (unlikely(inf->extra == EXTRA_RUNNING)) {
                //special treatment of domains running in extra time
                inf->extra = EXTRA_AWARE;
                inf->cputime=0;
                inf->extra_time_tot += now - inf->sched_start;
                
-               extraq_del(current);                            //remove 
extradomain from head of the queue
-               if (domain_runnable(inf->owner))
-                       extraq_add_tail(current);               //and add to 
the tail if it is runnable => round-robin
+               extraq_del(current);                                    
//remove extradomain from head of the queue
+               
+               #if (EXTRA == EXTRA_ROUNDR)
+               if (domain_runnable(current))
+                       extraq_add_tail(current);                       //and 
add to the tail if it is runnable => round-robin
+               #elif (EXTRA == EXTRA_SLICE_WEIGHT)
+               oldscore   = inf->score;                                
//update the score
+               inf->score = (inf->period << 10) / inf->slice;          //use 
fixed point arithmetic with 10 bits
+               
+               if (domain_runnable(current))
+                       extraq_add_sort_update(current, oldscore);      //add 
according to score: weighted round robin
+               #endif
                else
-                       __del_from_queue(inf->owner);           //if domain 
blocked in extratime remove it from waitq(/runq) as well
+                       __del_from_queue(inf->owner);                   //if 
domain blocked in extratime remove it from waitq(/runq) as well
        }
-       else {
+       else
+       #endif
+       {
                //current domain is running in real time mode
                //update the domains cputime
                inf->cputime += now - inf->sched_start;
@@ -315,13 +384,18 @@
                        inf->cputime -= inf->slice;
                        
                        if (inf->period < inf->period_orig) {
-                               //this domain runs in latency scaling mode
-                               inf->period *= 2;
-                               inf->slice *= 2;
-                               if ((inf->period > inf->period_orig) || 
(inf->slice > inf->slice_orig)) {
-                                       //now switch back to standard timing
-                                       inf->period = inf->period_orig;
-                                       inf->slice = inf->slice_orig;
+                               //this domain runs in latency scaling or burst 
mode
+                               #if (UNBLOCK == UNBLOCK_BURST)
+                               if (now - inf->absunblock >= 2 * inf->period)
+                               #endif
+                               {
+                                       inf->period *= 2;
+                                       inf->slice *= 2;
+                                       if ((inf->period > inf->period_orig) || 
(inf->slice > inf->slice_orig)) {
+                                               //now switch back to standard 
timing
+                                               inf->period = inf->period_orig;
+                                               inf->slice = inf->slice_orig;
+                                       }
                                }
                        }
                        inf->absdead += inf->period;            //set next 
deadline
@@ -333,9 +407,11 @@
                        __add_to_waitqueue_sort(inf->owner);
                else {
                        //we have a blocked realtime task
-                       inf->absblock=now;
+                       inf->absblock = now;
+                       #if (EXTRA > EXTRA_OFF)
                        if (inf->extra == EXTRA_AWARE)
                                extraq_del(inf->owner);         //remove a 
blocked domain from the extraq aswell
+                       #endif
                }
        }
 check_waitq:
@@ -393,13 +469,16 @@
                if (!list_empty(waitq)) {
                        waitinf  = list_entry(waitq->next,struct 
sedf_dom_info,list);
                        //we could not find any suitable domain => look for 
domains that are aware of extratime
+                       #if (EXTRA > EXTRA_OFF)
                        if (!list_empty(extraq) && (PERIOD_BEGIN(waitinf) - now 
>= EXTRA_QUANTUM)) {
                                runinf   = list_entry(extraq->next,struct 
sedf_dom_info,extralist);
                                runinf->extra = EXTRA_RUNNING;
                                ret.task = runinf->owner;
                                ret.time = EXTRA_QUANTUM;
                        }
-                       else {
+                       else
+                       #endif
+                       {
                                //we have an empty run- and extraqueue or too 
less time => idle task!
                                ret.task = IDLETASK(cpu);
                                ret.time = PERIOD_BEGIN(waitinf) - now;
@@ -420,13 +499,19 @@
 
 static void sedf_sleep(struct domain *d) {
        PRINT(2,"sedf_sleep was called, domain-id %i\n",d->id);
-       if ( test_bit(DF_RUNNING, &d->flags) )
+       if ( test_bit(DF_RUNNING, &d->flags) ) {
+#ifdef ADV_SCHED_HISTO
+               adv_sched_hist_start(d->processor);
+#endif
                cpu_raise_softirq(d->processor, SCHEDULE_SOFTIRQ);
+       }
        else  {

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Extended sedf scheduler (weighted extraqueues), added enhanced scheduling histogramm, BitKeeper Bot <=