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] [xen-unstable] credit2: Refactor runqueue initialization

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] credit2: Refactor runqueue initialization
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 24 Dec 2010 15:46:42 -0800
Delivery-date: Fri, 24 Dec 2010 15:52:11 -0800
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/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1293179262 0
# Node ID f33f7a9f9d40046687b50f8f8ed2e5a9981d81d1
# Parent  05377a7969525e140b57a8ea910f396da2355d77
credit2: Refactor runqueue initialization

Several refactorizations:
* Add prv->initialized cpu mask
* Replace prv->runq_count with active_queue mask
* Replace rqd->cpu_min,cpu_mask with  active cpu mask
* Put locks in the runqueue structure, rather than borrowing the
existing cpu locks
* init() initializes all runqueues to NULL, inactive, and maps all
pcpus to runqueue -q
* alloc_pcpu() will add cpus to runqueues, "activating" the runqueue
if necessary.  All cpus are currently assigned to runqueue 0.

End-to-end behavior of the system should remain largely the same.

Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
---
 xen/common/sched_credit2.c |  215 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 153 insertions(+), 62 deletions(-)

diff -r 05377a796952 -r f33f7a9f9d40 xen/common/sched_credit2.c
--- a/xen/common/sched_credit2.c        Fri Dec 24 08:26:59 2010 +0000
+++ b/xen/common/sched_credit2.c        Fri Dec 24 08:27:42 2010 +0000
@@ -176,10 +176,14 @@ integer_param("sched_credit2_migrate_res
  */
 struct csched_runqueue_data {
     int id;
+
+    spinlock_t lock;      /* Lock for this runqueue. */
+    cpumask_t active;      /* CPUs enabled for this runqueue */
+
     struct list_head runq; /* Ordered list of runnable vms */
     struct list_head svc;  /* List of all vcpus assigned to this runqueue */
     int max_weight;
-    int cpu_min, cpu_max;  /* Range of physical cpus this runqueue runs */
+
     cpumask_t idle,        /* Currently idle */
         tickled;           /* Another cpu in the queue is already targeted for 
this one */
 };
@@ -189,12 +193,12 @@ struct csched_runqueue_data {
  */
 struct csched_private {
     spinlock_t lock;
-    uint32_t ncpus;
-
+    cpumask_t initialized; /* CPU is initialized for this pool */
+    
     struct list_head sdom; /* Used mostly for dump keyhandler. */
 
     int runq_map[NR_CPUS];
-    uint32_t runq_count;
+    cpumask_t active_queues; /* Queues which may have active cpus */
     struct csched_runqueue_data rqd[NR_CPUS];
 };
 
@@ -341,7 +345,7 @@ runq_tickle(const struct scheduler *ops,
     int i, ipid=-1;
     s_time_t lowest=(1<<30);
     struct csched_runqueue_data *rqd = RQD(ops, cpu);
-    cpumask_t *online, mask;
+    cpumask_t mask;
     struct csched_vcpu * cur;
 
     d2printk("rqt d%dv%d cd%dv%d\n",
@@ -374,9 +378,7 @@ runq_tickle(const struct scheduler *ops,
 
     /* Otherwise, look for the non-idle cpu with the lowest credit,
      * skipping cpus which have been tickled but not scheduled yet */
-    online = CSCHED_CPUONLINE(per_cpu(cpupool, cpu));
-
-    cpus_andnot(mask, *online, rqd->idle);
+    cpus_andnot(mask, rqd->active, rqd->idle);
     cpus_andnot(mask, mask, rqd->tickled);
 
     for_each_cpu_mask(i, mask)
@@ -997,7 +999,7 @@ csched_schedule(
     const struct scheduler *ops, s_time_t now, bool_t tasklet_work_scheduled)
 {
     const int cpu = smp_processor_id();
-    struct csched_runqueue_data *rqd = RQD(ops, cpu);
+    struct csched_runqueue_data *rqd;
     struct csched_vcpu * const scurr = CSCHED_VCPU(current);
     struct csched_vcpu *snext = NULL;
     struct task_slice ret;
@@ -1010,6 +1012,10 @@ csched_schedule(
              scurr->vcpu->vcpu_id,
              now);
 
+    BUG_ON(!cpu_isset(cpu, CSCHED_PRIV(ops)->initialized));
+
+    rqd = RQD(ops, cpu);
+    BUG_ON(!cpu_isset(cpu, rqd->active));
 
     /* Protected by runqueue lock */
 
@@ -1166,14 +1172,22 @@ csched_dump(const struct scheduler *ops)
 {
     struct list_head *iter_sdom, *iter_svc;
     struct csched_private *prv = CSCHED_PRIV(ops);
-    int loop;
-
-    printk("info:\n"
-           "\tncpus              = %u\n"
+    int i, loop;
+
+    printk("Active queues: %d\n"
            "\tdefault-weight     = %d\n",
-           prv->ncpus,
+           cpus_weight(prv->active_queues),
            CSCHED_DEFAULT_WEIGHT);
-
+    for_each_cpu_mask(i, prv->active_queues)
+    {
+        printk("Runqueue %d:\n"
+               "\tncpus              = %u\n"
+               "\tmax_weight         = %d\n",
+               i,
+               cpus_weight(prv->rqd[i].active),
+               prv->rqd[i].max_weight);
+
+    }
     /* FIXME: Locking! */
 
     printk("Domain info:\n");
@@ -1199,51 +1213,135 @@ csched_dump(const struct scheduler *ops)
     }
 }
 
+static void activate_runqueue(struct csched_private *prv, int rqi)
+{
+    struct csched_runqueue_data *rqd;
+
+    rqd = prv->rqd + rqi;
+
+    BUG_ON(!cpus_empty(rqd->active));
+
+    rqd->max_weight = 1;
+    rqd->id = rqi;
+    INIT_LIST_HEAD(&rqd->svc);
+    INIT_LIST_HEAD(&rqd->runq);
+    spin_lock_init(&rqd->lock);
+
+    cpu_set(rqi, prv->active_queues);
+}
+
+static void deactivate_runqueue(struct csched_private *prv, int rqi)
+{
+    struct csched_runqueue_data *rqd;
+
+    rqd = prv->rqd + rqi;
+
+    BUG_ON(!cpus_empty(rqd->active));
+    
+    rqd->id = -1;
+
+    cpu_clear(rqi, prv->active_queues);
+}
+
+static void init_pcpu(const struct scheduler *ops, int cpu)
+{
+    int rqi, old_rqi, flags;
+    struct csched_private *prv = CSCHED_PRIV(ops);
+    struct csched_runqueue_data *rqd;
+    spinlock_t *old_lock;
+
+    spin_lock_irqsave(&prv->lock, flags);
+
+    if ( cpu_isset(cpu, prv->initialized) )
+    {
+        printk("%s: Strange, cpu %d already initialized!\n", __func__, cpu);
+        spin_unlock_irqrestore(&prv->lock, flags);
+        return;
+    }
+
+    old_rqi = prv->runq_map[cpu];
+
+    /* Figure out which runqueue to put it in */
+    rqi = 0;
+
+    rqd=prv->rqd + rqi;
+
+    printk("Adding cpu %d to runqueue %d\n", cpu, rqi);
+    if ( ! cpu_isset(rqi, prv->active_queues) )
+    {
+        printk(" First cpu on runqueue, activating\n");
+        activate_runqueue(prv, rqi);
+    }
+    
+    /* IRQs already disabled */
+    old_lock=pcpu_schedule_lock(cpu);
+
+    /* Move spinlock to new runq lock.  */
+    per_cpu(schedule_data, cpu).schedule_lock = &rqd->lock;
+
+    /* Set the runqueue map */
+    prv->runq_map[cpu]=rqi;
+    
+    cpu_set(cpu, rqd->idle);
+    cpu_set(cpu, rqd->active);
+
+    spin_unlock(old_lock);
+
+    cpu_set(cpu, prv->initialized);
+
+    spin_unlock_irqrestore(&prv->lock, flags);
+
+    return;
+}
+
+static void *
+csched_alloc_pdata(const struct scheduler *ops, int cpu)
+{
+    init_pcpu(ops, cpu);
+
+    return (void *)1;
+}
+
 static void
 csched_free_pdata(const struct scheduler *ops, void *pcpu, int cpu)
 {
     unsigned long flags;
     struct csched_private *prv = CSCHED_PRIV(ops);
+    struct csched_runqueue_data *rqd;
+    int rqi;
 
     spin_lock_irqsave(&prv->lock, flags);
-    prv->ncpus--;
-    cpu_clear(cpu, RQD(ops, cpu)->idle);
-    printk("Removing cpu %d to pool (%d total)\n", cpu, prv->ncpus);
+
+    BUG_ON( !cpu_isset(cpu, prv->initialized));
+    
+    /* Find the old runqueue and remove this cpu from it */
+    rqi = prv->runq_map[cpu];
+
+    rqd = prv->rqd + rqi;
+
+    /* No need to save IRQs here, they're already disabled */
+    spin_lock(&rqd->lock);
+
+    BUG_ON(!cpu_isset(cpu, rqd->idle));
+
+    printk("Removing cpu %d from runqueue %d\n", cpu, rqi);
+
+    cpu_clear(cpu, rqd->idle);
+    cpu_clear(cpu, rqd->active);
+
+    if ( cpus_empty(rqd->active) )
+    {
+        printk(" No cpus left on runqueue, disabling\n");
+        deactivate_runqueue(prv, rqi);
+    }
+
+    spin_unlock(&rqd->lock);
+
+    cpu_clear(cpu, prv->initialized);
+
     spin_unlock_irqrestore(&prv->lock, flags);
 
     return;
-}
-
-static void *
-csched_alloc_pdata(const struct scheduler *ops, int cpu)
-{
-    spinlock_t *new_lock;
-    spinlock_t *old_lock = per_cpu(schedule_data, cpu).schedule_lock;
-    unsigned long flags;
-    struct csched_private *prv = CSCHED_PRIV(ops);
-
-    spin_lock_irqsave(old_lock, flags);
-    new_lock = &per_cpu(schedule_data, prv->runq_map[cpu])._lock;
-    per_cpu(schedule_data, cpu).schedule_lock = new_lock;
-    spin_unlock_irqrestore(old_lock, flags);
-
-    spin_lock_irqsave(&prv->lock, flags);
-    prv->ncpus++;
-    cpu_set(cpu, RQD(ops, cpu)->idle);
-    printk("Adding cpu %d to pool (%d total)\n", cpu, prv->ncpus);
-    spin_unlock_irqrestore(&prv->lock, flags);
-
-    return (void *)1;
-}
-
-static void
-make_runq_map(struct csched_private *prv)
-{
-    /* FIXME: Read pcpu layout and do this properly */
-    prv->runq_count = 1;
-    prv->rqd[0].cpu_min = 0;
-    prv->rqd[0].cpu_max = NR_CPUS;
-    memset(prv->runq_map, 0, sizeof(prv->runq_map));
 }
 
 static int
@@ -1265,18 +1363,11 @@ csched_init(struct scheduler *ops)
     spin_lock_init(&prv->lock);
     INIT_LIST_HEAD(&prv->sdom);
 
-    prv->ncpus = 0;
-
-    make_runq_map(prv);
-
-    for ( i=0; i<prv->runq_count ; i++ )
-    {
-        struct csched_runqueue_data *rqd = prv->rqd + i;
-
-        rqd->max_weight = 1;
-        rqd->id = i;
-        INIT_LIST_HEAD(&rqd->svc);
-        INIT_LIST_HEAD(&rqd->runq);
+    /* But un-initialize all runqueues */
+    for ( i=0; i<NR_CPUS; i++)
+    {
+        prv->runq_map[i] = -1;
+        prv->rqd[i].id = -1;
     }
 
     return 0;

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] credit2: Refactor runqueue initialization, Xen patchbot-unstable <=