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] Fix sched_adjust_global() and clean up su

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Fix sched_adjust_global() and clean up surrounding code.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 21 Jun 2010 10:45:11 -0700
Delivery-date: Mon, 21 Jun 2010 10:45:27 -0700
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.fraser@xxxxxxxxxx>
# Date 1276758147 -3600
# Node ID dab8676e97ce7a95c0777e58eee4b1b03bfc5322
# Parent  0695a5cdcb42d98dcd4bbda35614753787aa7983
Fix sched_adjust_global() and clean up surrounding code.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/common/cpupool.c        |   85 ++++++++++++++++++++++++++++++--------------
 xen/common/schedule.c       |   69 +++++++++++++++++------------------
 xen/include/public/sysctl.h |    5 +-
 xen/include/xen/sched-if.h  |    2 -
 xen/include/xen/sched.h     |    7 ++-
 5 files changed, 98 insertions(+), 70 deletions(-)

diff -r 0695a5cdcb42 -r dab8676e97ce xen/common/cpupool.c
--- a/xen/common/cpupool.c      Thu Jun 17 07:22:06 2010 +0100
+++ b/xen/common/cpupool.c      Thu Jun 17 08:02:27 2010 +0100
@@ -71,6 +71,22 @@ static struct cpupool *cpupool_find_by_i
     return exact ? NULL : *q;
 }
 
+struct cpupool *cpupool_get_by_id(int poolid)
+{
+    struct cpupool *c;
+    /* cpupool_ctl_lock protects against concurrent pool destruction */
+    spin_lock(&cpupool_ctl_lock);
+    c = cpupool_find_by_id(poolid, 1);
+    if ( c == NULL )
+        spin_unlock(&cpupool_ctl_lock);
+    return c;
+}
+
+void cpupool_put(struct cpupool *pool)
+{
+    spin_unlock(&cpupool_ctl_lock);
+}
+
 /*
  * create a new cpupool with specified poolid and scheduler
  * returns pointer to new cpupool structure if okay, NULL else
@@ -79,18 +95,22 @@ static struct cpupool *cpupool_find_by_i
  * - poolid already used
  * - unknown scheduler
  */
-struct cpupool *cpupool_create(int poolid, char *sched)
+static struct cpupool *cpupool_create(
+    int poolid, unsigned int sched_id, int *perr)
 {
     struct cpupool *c;
     struct cpupool **q;
     int last = 0;
 
+    *perr = -ENOMEM;
     if ( (c = alloc_cpupool_struct()) == NULL )
         return NULL;
     memset(c, 0, sizeof(*c));
 
-    cpupool_dprintk("cpupool_create(pool=%d,sched=%s)\n", poolid, sched);
-    spin_lock(&cpupool_lock);
+    cpupool_dprintk("cpupool_create(pool=%d,sched=%u)\n", poolid, sched_id);
+
+    spin_lock(&cpupool_lock);
+
     for_each_cpupool(q)
     {
         last = (*q)->cpupool_id;
@@ -100,26 +120,39 @@ struct cpupool *cpupool_create(int pooli
     if ( *q != NULL )
     {
         if ( (*q)->cpupool_id == poolid )
+        {
+            spin_unlock(&cpupool_lock);
+            free_cpupool_struct(c);
+            *perr = -EEXIST;
+            return NULL;
+        }
+        c->next = *q;
+    }
+
+    c->cpupool_id = (poolid == CPUPOOLID_NONE) ? (last + 1) : poolid;
+    if ( poolid == 0 )
+    {
+        c->sched = scheduler_get_default();
+    }
+    else
+    {
+        c->sched = scheduler_alloc(sched_id, perr);
+        if ( c->sched == NULL )
         {
             spin_unlock(&cpupool_lock);
             free_cpupool_struct(c);
             return NULL;
         }
-        c->next = *q;
-    }
+    }
+
     *q = c;
-    c->cpupool_id = (poolid == CPUPOOLID_NONE) ? (last + 1) : poolid;
-    if ( (c->sched = scheduler_alloc(sched)) == NULL )
-    {
-        spin_unlock(&cpupool_lock);
-        cpupool_destroy(c);
-        return NULL;
-    }
+
     spin_unlock(&cpupool_lock);
 
     cpupool_dprintk("Created cpupool %d with scheduler %s (%s)\n",
                     c->cpupool_id, c->sched->name, c->sched->opt_name);
 
+    *perr = 0;
     return c;
 }
 /*
@@ -130,7 +163,7 @@ struct cpupool *cpupool_create(int pooli
  * - cpus still assigned to pool
  * - pool not in list
  */
-int cpupool_destroy(struct cpupool *c)
+static int cpupool_destroy(struct cpupool *c)
 {
     struct cpupool **q;
 
@@ -138,10 +171,15 @@ int cpupool_destroy(struct cpupool *c)
     for_each_cpupool(q)
         if ( *q == c )
             break;
-    if ( (*q != c) || (c->n_dom != 0) || cpus_weight(c->cpu_valid) )
+    if ( *q != c )
     {
         spin_unlock(&cpupool_lock);
-        return 1;
+        return -ENOENT;
+    }
+    if ( (c->n_dom != 0) || cpus_weight(c->cpu_valid) )
+    {
+        spin_unlock(&cpupool_lock);
+        return -EBUSY;
     }
     *q = c->next;
     spin_unlock(&cpupool_lock);
@@ -365,19 +403,11 @@ int cpupool_do_sysctl(struct xen_sysctl_
     case XEN_SYSCTL_CPUPOOL_OP_CREATE:
     {
         int poolid;
-        const struct scheduler *sched;
 
         poolid = (op->cpupool_id == XEN_SYSCTL_CPUPOOL_PAR_ANY) ?
             CPUPOOLID_NONE: op->cpupool_id;
-        sched = scheduler_get_by_id(op->sched_id);
-        ret = -ENOENT;
-        if ( sched == NULL )
-            break;
-        ret = 0;
-        c = cpupool_create(poolid, sched->opt_name);
-        if ( c == NULL )
-            ret = -EINVAL;
-        else
+        c = cpupool_create(poolid, op->sched_id, &ret);
+        if ( c != NULL )
             op->cpupool_id = c->cpupool_id;
     }
     break;
@@ -388,7 +418,7 @@ int cpupool_do_sysctl(struct xen_sysctl_
         ret = -ENOENT;
         if ( c == NULL )
             break;
-        ret = (cpupool_destroy(c) != 0) ? -EBUSY : 0;
+        ret = cpupool_destroy(c);
     }
     break;
 
@@ -571,8 +601,9 @@ static struct notifier_block cpu_nfb = {
 
 static int __init cpupool_presmp_init(void)
 {
+    int err;
     void *cpu = (void *)(long)smp_processor_id();
-    cpupool0 = cpupool_create(0, NULL);
+    cpupool0 = cpupool_create(0, 0, &err);
     BUG_ON(cpupool0 == NULL);
     cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
     register_cpu_notifier(&cpu_nfb);
diff -r 0695a5cdcb42 -r dab8676e97ce xen/common/schedule.c
--- a/xen/common/schedule.c     Thu Jun 17 07:22:06 2010 +0100
+++ b/xen/common/schedule.c     Thu Jun 17 08:02:27 2010 +0100
@@ -965,17 +965,28 @@ long sched_adjust(struct domain *d, stru
 
 long sched_adjust_global(struct xen_sysctl_scheduler_op *op)
 {
-    const struct scheduler *sched;
-
-    sched = scheduler_get_by_id(op->sched_id);
-    if ( sched == NULL )
-        return -ESRCH;
+    struct cpupool *pool;
+    int rc;
 
     if ( (op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) &&
          (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo) )
         return -EINVAL;
 
-    return SCHED_OP(sched, adjust_global, op);
+    pool = cpupool_get_by_id(op->cpupool_id);
+    if ( pool == NULL )
+        return -ESRCH;
+
+    if ( op->sched_id != pool->sched->sched_id )
+    {
+        cpupool_put(pool);
+        return -EINVAL;
+    }
+
+    rc = SCHED_OP(pool->sched, adjust_global, op);
+
+    cpupool_put(pool);
+
+    return rc;
 }
 
 static void vcpu_periodic_timer_work(struct vcpu *v)
@@ -1152,19 +1163,6 @@ static void poll_timer_fn(void *data)
 
     if ( test_and_clear_bit(v->vcpu_id, v->domain->poll_mask) )
         vcpu_unblock(v);
-}
-
-/* Get scheduler by id */
-const struct scheduler *scheduler_get_by_id(unsigned int id)
-{
-    int i;
-
-    for ( i = 0; schedulers[i] != NULL; i++ )
-    {
-        if ( schedulers[i]->sched_id == id )
-            return schedulers[i];
-    }
-    return NULL;
 }
 
 static int cpu_schedule_up(unsigned int cpu)
@@ -1302,29 +1300,28 @@ void schedule_cpu_switch(unsigned int cp
     SCHED_OP(old_ops, free_pdata, ppriv_old, cpu);
 }
 
-struct scheduler *scheduler_alloc(char *name)
+struct scheduler *scheduler_get_default(void)
+{
+    return &ops;
+}
+
+struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr)
 {
     int i;
-    const struct scheduler *data;
     struct scheduler *sched;
 
-    if ( name == NULL )
-        return &ops;
-
-    data = &ops;
-    for ( i = 0; (schedulers[i] != NULL) && (name != NULL) ; i++ )
-    {
-        if ( strcmp(schedulers[i]->opt_name, name) == 0 )
-        {
-            data = schedulers[i];
-            break;
-        }
-    }
-
+    for ( i = 0; schedulers[i] != NULL; i++ )
+        if ( schedulers[i]->sched_id == sched_id )
+            goto found;
+    *perr = -ENOENT;
+    return NULL;
+
+ found:
+    *perr = -ENOMEM;
     if ( (sched = xmalloc(struct scheduler)) == NULL )
         return NULL;
-    memcpy(sched, data, sizeof(*sched));
-    if ( SCHED_OP(sched, init) != 0 )
+    memcpy(sched, schedulers[i], sizeof(*sched));
+    if ( (*perr = SCHED_OP(sched, init)) != 0 )
     {
         xfree(sched);
         sched = NULL;
diff -r 0695a5cdcb42 -r dab8676e97ce xen/include/public/sysctl.h
--- a/xen/include/public/sysctl.h       Thu Jun 17 07:22:06 2010 +0100
+++ b/xen/include/public/sysctl.h       Thu Jun 17 08:02:27 2010 +0100
@@ -540,8 +540,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpupo
 #define XEN_SYSCTL_SCHEDOP_putinfo 0
 #define XEN_SYSCTL_SCHEDOP_getinfo 1
 struct xen_sysctl_scheduler_op {
-    uint32_t sched_id;  /* XEN_SCHEDULER_* (domctl.h) */
-    uint32_t cmd;       /* XEN_SYSCTL_SCHEDOP_* */
+    uint32_t cpupool_id; /* Cpupool whose scheduler is to be targetted. */
+    uint32_t sched_id;   /* XEN_SCHEDULER_* (domctl.h) */
+    uint32_t cmd;        /* XEN_SYSCTL_SCHEDOP_* */
     union {
     } u;
 };
diff -r 0695a5cdcb42 -r dab8676e97ce xen/include/xen/sched-if.h
--- a/xen/include/xen/sched-if.h        Thu Jun 17 07:22:06 2010 +0100
+++ b/xen/include/xen/sched-if.h        Thu Jun 17 08:02:27 2010 +0100
@@ -133,6 +133,4 @@ struct cpupool
     struct scheduler *sched;
 };
 
-const struct scheduler *scheduler_get_by_id(unsigned int id);
-
 #endif /* __XEN_SCHED_IF_H__ */
diff -r 0695a5cdcb42 -r dab8676e97ce xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Thu Jun 17 07:22:06 2010 +0100
+++ b/xen/include/xen/sched.h   Thu Jun 17 08:02:27 2010 +0100
@@ -592,7 +592,8 @@ void cpu_init(void);
 
 struct scheduler;
 
-struct scheduler *scheduler_alloc(char *name);
+struct scheduler *scheduler_get_default(void);
+struct scheduler *scheduler_alloc(unsigned int sched_id, int *perr);
 void scheduler_free(struct scheduler *sched);
 void schedule_cpu_switch(unsigned int cpu, struct cpupool *c);
 void vcpu_force_reschedule(struct vcpu *v);
@@ -634,8 +635,8 @@ extern enum cpufreq_controller {
 
 #define CPUPOOLID_NONE    -1
 
-struct cpupool *cpupool_create(int poolid, char *sched);
-int cpupool_destroy(struct cpupool *c);
+struct cpupool *cpupool_get_by_id(int poolid);
+void cpupool_put(struct cpupool *pool);
 int cpupool_add_domain(struct domain *d, int poolid);
 void cpupool_rm_domain(struct domain *d);
 int cpupool_do_sysctl(struct xen_sysctl_cpupool_op *op);

_______________________________________________
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] Fix sched_adjust_global() and clean up surrounding code., Xen patchbot-unstable <=