[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |