Commit 37790ea1 authored by Philippe Gerum's avatar Philippe Gerum

cobalt/posix/sched-quota: allow force removal of quota group

Sending a sched_quota_force_remove request to the group deletion
service would move all threads still part of the deleted group to the
RT class, then proceed normally.

sched_quota_remove would still return -EBUSY instead.
parent 56adb714
......@@ -44,6 +44,7 @@ struct xnsched_quota_group {
xnticks_t run_start_ns;
xnticks_t run_budget_ns;
xnticks_t run_credit_ns;
struct list_head members;
struct list_head expired;
struct list_head next;
int nr_active;
......@@ -73,6 +74,7 @@ int xnsched_quota_create_group(struct xnsched_quota_group *tg,
int *quota_sum_r);
int xnsched_quota_destroy_group(struct xnsched_quota_group *tg,
int force,
int *quota_sum_r);
void xnsched_quota_set_limit(struct xnsched_quota_group *tg,
......
......@@ -87,6 +87,7 @@ struct xnthread {
#ifdef CONFIG_XENO_OPT_SCHED_QUOTA
struct xnsched_quota_group *quota; /* Quota scheduling group. */
struct list_head quota_expired;
struct list_head quota_next;
#endif
unsigned int idtag; /* Unique ID tag */
......
......@@ -77,6 +77,7 @@ struct __sched_quota_param {
enum {
sched_quota_add,
sched_quota_remove,
sched_quota_force_remove,
sched_quota_set,
sched_quota_get,
};
......
......@@ -401,7 +401,8 @@ int do_quota_config(int cpu, const union sched_config *config, size_t len)
return ret;
}
if (p->op == sched_quota_remove) {
if (p->op == sched_quota_remove ||
p->op == sched_quota_force_remove) {
xnlock_get_irqsave(&nklock, s);
sched = xnsched_struct(cpu);
tg = xnsched_quota_find_group(sched, p->remove.tgid);
......@@ -414,7 +415,9 @@ int do_quota_config(int cpu, const union sched_config *config, size_t len)
xnlock_put_irqrestore(&nklock, s);
return ret;
}
ret = xnsched_quota_destroy_group(tg, &quota_sum);
ret = xnsched_quota_destroy_group(tg,
p->op == sched_quota_force_remove,
&quota_sum);
if (ret) {
xnlock_put_irqrestore(&nklock, s);
return ret;
......@@ -616,7 +619,7 @@ void cobalt_sched_cleanup(struct cobalt_kqueues *q)
group = list_get_entry(&q->schedq, struct cobalt_sched_group, next);
#ifdef CONFIG_XENO_OPT_SCHED_QUOTA
xnsched_quota_destroy_group(&group->quota, &quota_sum);
xnsched_quota_destroy_group(&group->quota, 1, &quota_sum);
#endif
xnlock_put_irqrestore(&nklock, s);
xnfree(group);
......
......@@ -247,14 +247,17 @@ static void xnsched_quota_setparam(struct xnthread *thread,
qs = &thread->sched->quota;
list_for_each_entry(tg, &qs->groups, next) {
if (tg->tgid == p->quota.tgid) {
if (thread->quota)
/* Dequeued earlier by our caller. */
thread->quota->nr_threads--;
thread->quota = tg;
tg->nr_threads++;
return;
if (tg->tgid != p->quota.tgid)
continue;
if (thread->quota) {
/* Dequeued earlier by our caller. */
list_del(&thread->quota_next);
thread->quota->nr_threads--;
}
thread->quota = tg;
list_add(&thread->quota_next, &tg->members);
tg->nr_threads++;
return;
}
XENO_BUG(NUCLEUS);
......@@ -319,6 +322,7 @@ static void xnsched_quota_forget(struct xnthread *thread)
{
thread->quota->nr_threads--;
XENO_BUGON(NUCLEUS, thread->quota->nr_threads < 0);
list_del(&thread->quota_next);
thread->quota = NULL;
}
......@@ -508,6 +512,7 @@ int xnsched_quota_create_group(struct xnsched_quota_group *tg,
tg->quota_peak_ns = qs->period_ns;
tg->nr_active = 0;
tg->nr_threads = 0;
INIT_LIST_HEAD(&tg->members);
INIT_LIST_HEAD(&tg->expired);
if (list_empty(&qs->groups))
......@@ -522,14 +527,23 @@ int xnsched_quota_create_group(struct xnsched_quota_group *tg,
EXPORT_SYMBOL_GPL(xnsched_quota_create_group);
int xnsched_quota_destroy_group(struct xnsched_quota_group *tg,
int *quota_sum_r)
int force, int *quota_sum_r)
{
struct xnsched_quota *qs = &tg->sched->quota;
union xnsched_policy_param param;
struct xnthread *thread;
atomic_only();
if (tg->nr_threads > 0)
return -EBUSY;
if (!list_empty(&tg->members)) {
if (!force)
return -EBUSY;
/* Move group members to the rt class. */
list_for_each_entry(thread, &tg->members, quota_next) {
param.rt.prio = thread->cprio;
xnsched_set_policy(thread, &xnsched_class_rt, &param);
}
}
list_del(&tg->next);
__clear_bit(tg->tgid, group_map);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment