update_schedule_vcpus(ops);
}
-/**
- * This function allocates scheduler-specific data for a domain
- *
- * We do not actually make use of any per-domain data but the hypervisor
- * expects a non-NULL return value
- *
- * @param ops Pointer to this instance of the scheduler structure
- *
- * @return Pointer to the allocated data
- */
-static void *
-a653sched_alloc_domdata(const struct scheduler *ops, struct domain *dom)
-{
- /* return a non-NULL value to keep schedule.c happy */
- return SCHED_PRIV(ops);
-}
-
-/**
- * This function frees scheduler-specific data for a domain
- *
- * @param ops Pointer to this instance of the scheduler structure
- */
-static void
-a653sched_free_domdata(const struct scheduler *ops, void *data)
-{
- /* nop */
-}
-
/**
* Xen scheduler callback function to sleep a VCPU
*
.free_vdata = a653sched_free_vdata,
.alloc_vdata = a653sched_alloc_vdata,
- .free_domdata = a653sched_free_domdata,
- .alloc_domdata = a653sched_alloc_domdata,
-
.init_domain = NULL,
.destroy_domain = NULL,
sdom = xzalloc(struct csched_dom);
if ( sdom == NULL )
- return NULL;
+ return ERR_PTR(-ENOMEM);
/* Initialize credit and weight */
INIT_LIST_HEAD(&sdom->active_vcpu);
sdom->dom = dom;
sdom->weight = CSCHED_DEFAULT_WEIGHT;
- return (void *)sdom;
+ return sdom;
}
static int
return 0;
sdom = csched_alloc_domdata(ops, dom);
- if ( sdom == NULL )
- return -ENOMEM;
+ if ( IS_ERR(sdom) )
+ return PTR_ERR(sdom);
dom->sched_priv = sdom;
sdom = xzalloc(struct csched2_dom);
if ( sdom == NULL )
- return NULL;
+ return ERR_PTR(-ENOMEM);
/* Initialize credit, cap and weight */
INIT_LIST_HEAD(&sdom->sdom_elem);
write_unlock_irqrestore(&prv->lock, flags);
- return (void *)sdom;
+ return sdom;
}
static int
return 0;
sdom = csched2_alloc_domdata(ops, dom);
- if ( sdom == NULL )
- return -ENOMEM;
+ if ( IS_ERR(sdom) )
+ return PTR_ERR(sdom);
dom->sched_priv = sdom;
static void
csched2_free_domdata(const struct scheduler *ops, void *data)
{
- unsigned long flags;
struct csched2_dom *sdom = data;
struct csched2_private *prv = csched2_priv(ops);
- kill_timer(&sdom->repl_timer);
-
- write_lock_irqsave(&prv->lock, flags);
+ if ( sdom )
+ {
+ unsigned long flags;
- list_del_init(&sdom->sdom_elem);
+ kill_timer(&sdom->repl_timer);
- write_unlock_irqrestore(&prv->lock, flags);
+ write_lock_irqsave(&prv->lock, flags);
+ list_del_init(&sdom->sdom_elem);
+ write_unlock_irqrestore(&prv->lock, flags);
- xfree(data);
+ xfree(sdom);
+ }
}
static void
ndom = xzalloc(struct null_dom);
if ( ndom == NULL )
- return NULL;
+ return ERR_PTR(-ENOMEM);
ndom->dom = d;
list_add_tail(&ndom->ndom_elem, &null_priv(ops)->ndom);
spin_unlock_irqrestore(&prv->lock, flags);
- return (void*)ndom;
+ return ndom;
}
static void null_free_domdata(const struct scheduler *ops, void *data)
{
- unsigned long flags;
struct null_dom *ndom = data;
struct null_private *prv = null_priv(ops);
- spin_lock_irqsave(&prv->lock, flags);
- list_del_init(&ndom->ndom_elem);
- spin_unlock_irqrestore(&prv->lock, flags);
+ if ( ndom )
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&prv->lock, flags);
+ list_del_init(&ndom->ndom_elem);
+ spin_unlock_irqrestore(&prv->lock, flags);
- xfree(data);
+ xfree(ndom);
+ }
}
static int null_dom_init(const struct scheduler *ops, struct domain *d)
return 0;
ndom = null_alloc_domdata(ops, d);
- if ( ndom == NULL )
- return -ENOMEM;
+ if ( IS_ERR(ndom) )
+ return PTR_ERR(ndom);
d->sched_priv = ndom;
sdom = xzalloc(struct rt_dom);
if ( sdom == NULL )
- return NULL;
+ return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&sdom->sdom_elem);
sdom->dom = dom;
static void
rt_free_domdata(const struct scheduler *ops, void *data)
{
- unsigned long flags;
struct rt_dom *sdom = data;
struct rt_private *prv = rt_priv(ops);
- spin_lock_irqsave(&prv->lock, flags);
- list_del_init(&sdom->sdom_elem);
- spin_unlock_irqrestore(&prv->lock, flags);
- xfree(data);
+ if ( sdom )
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&prv->lock, flags);
+ list_del_init(&sdom->sdom_elem);
+ spin_unlock_irqrestore(&prv->lock, flags);
+
+ xfree(sdom);
+ }
}
static int
return 0;
sdom = rt_alloc_domdata(ops, dom);
- if ( sdom == NULL )
- return -ENOMEM;
+ if ( IS_ERR(sdom) )
+ return PTR_ERR(sdom);
dom->sched_priv = sdom;
return -EBUSY;
}
- domdata = SCHED_OP(c->sched, alloc_domdata, d);
- if ( domdata == NULL )
- return -ENOMEM;
+ domdata = sched_alloc_domdata(c->sched, d);
+ if ( IS_ERR(domdata) )
+ return PTR_ERR(domdata);
vcpu_priv = xzalloc_array(void *, d->max_vcpus);
if ( vcpu_priv == NULL )
{
- SCHED_OP(c->sched, free_domdata, domdata);
+ sched_free_domdata(c->sched, domdata);
return -ENOMEM;
}
for_each_vcpu ( d, v )
xfree(vcpu_priv[v->vcpu_id]);
xfree(vcpu_priv);
- SCHED_OP(c->sched, free_domdata, domdata);
+ sched_free_domdata(c->sched, domdata);
return -ENOMEM;
}
}
domain_unpause(d);
- SCHED_OP(old_ops, free_domdata, old_domdata);
+ sched_free_domdata(old_ops, old_domdata);
xfree(vcpu_priv);
void * (*alloc_pdata) (const struct scheduler *, int);
void (*init_pdata) (const struct scheduler *, void *, int);
void (*deinit_pdata) (const struct scheduler *, void *, int);
- void (*free_domdata) (const struct scheduler *, void *);
+
+ /* Returns ERR_PTR(-err) for error, NULL for 'nothing needed'. */
void * (*alloc_domdata) (const struct scheduler *, struct domain *);
+ /* Idempotent. */
+ void (*free_domdata) (const struct scheduler *, void *);
void (*switch_sched) (struct scheduler *, unsigned int,
void *, void *);
void (*tick_resume) (const struct scheduler *, unsigned int);
};
+static inline void *sched_alloc_domdata(const struct scheduler *s,
+ struct domain *d)
+{
+ if ( s->alloc_domdata )
+ return s->alloc_domdata(s, d);
+ else
+ return NULL;
+}
+
+static inline void sched_free_domdata(const struct scheduler *s,
+ void *data)
+{
+ if ( s->free_domdata )
+ s->free_domdata(s, data);
+ else
+ /*
+ * Check that if there isn't a free_domdata hook, we haven't got any
+ * data we're expected to deal with.
+ */
+ ASSERT(!data);
+}
+
#define REGISTER_SCHEDULER(x) static const struct scheduler *x##_entry \
__used_section(".data.schedulers") = &x;