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

[Xen-changelog] [xen-unstable] Fix sched_adjust_global() and clean up surrounding code.



# 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


 


Rackspace

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