Module: xenomai-forge Branch: next Commit: 90d521cedf20eb063113d8cec0d2b854719ab689 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=90d521cedf20eb063113d8cec0d2b854719ab689
Author: Philippe Gerum <r...@xenomai.org> Date: Wed May 28 11:49:06 2014 +0200 cobalt/sched: return overall quota reservation in SCHED_QUOTA ops --- include/cobalt/kernel/sched-quota.h | 11 +++++-- include/cobalt/uapi/sched.h | 1 + kernel/cobalt/posix/thread.c | 40 +++++++++++++++------- kernel/cobalt/sched-quota.c | 62 ++++++++++++++++++++++++++--------- testsuite/unit/sched-quota.c | 7 ++-- 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/include/cobalt/kernel/sched-quota.h b/include/cobalt/kernel/sched-quota.h index 381f8cb..97d2387 100644 --- a/include/cobalt/kernel/sched-quota.h +++ b/include/cobalt/kernel/sched-quota.h @@ -66,16 +66,21 @@ static inline int xnsched_quota_init_thread(struct xnthread *thread) } int xnsched_quota_create_group(struct xnsched_quota_group *tg, - struct xnsched *sched); + struct xnsched *sched, + int *quota_sum_r); -int xnsched_quota_destroy_group(struct xnsched_quota_group *tg); +int xnsched_quota_destroy_group(struct xnsched_quota_group *tg, + int *quota_sum_r); void xnsched_quota_set_limit(struct xnsched_quota_group *tg, - int quota_percent, int quota_peak_percent); + int quota_percent, int quota_peak_percent, + int *quota_sum_r); struct xnsched_quota_group * xnsched_quota_find_group(struct xnsched *sched, int tgid); +int xnsched_quota_sum_all(struct xnsched *sched); + #endif /* !CONFIG_XENO_OPT_SCHED_QUOTA */ #endif /* !_COBALT_KERNEL_SCHED_QUOTA_H */ diff --git a/include/cobalt/uapi/sched.h b/include/cobalt/uapi/sched.h index 11bbc1a..99f0f98 100644 --- a/include/cobalt/uapi/sched.h +++ b/include/cobalt/uapi/sched.h @@ -83,6 +83,7 @@ enum { struct __sched_config_quota { int op; + int *sum_r; struct { int *tgid_r; } add; diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c index 41fcd5d..ecfe256 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -1453,10 +1453,10 @@ get_tp_config(int cpu, union sched_config __user *u_config, #ifdef CONFIG_XENO_OPT_SCHED_QUOTA static inline -int set_quota_config(int cpu, const union sched_config *config, size_t len) +int do_quota_config(int cpu, const union sched_config *config, size_t len) { + int ret = -ESRCH, quota_percent, quota_peak_percent, quota_sum; const struct __sched_config_quota *p = &config->quota; - int ret = -ESRCH, quota_percent, quota_peak_percent; struct xnsched_quota_group *tg; struct xnsched *sched; spl_t s; @@ -1470,13 +1470,17 @@ int set_quota_config(int cpu, const union sched_config *config, size_t len) return -ENOMEM; xnlock_get_irqsave(&nklock, s); sched = xnsched_struct(cpu); - ret = xnsched_quota_create_group(tg, sched); + ret = xnsched_quota_create_group(tg, sched, "a_sum); xnlock_put_irqrestore(&nklock, s); - if (ret == 0) - ret = __xn_safe_copy_to_user(p->add.tgid_r, &tg->tgid, - sizeof(tg->tgid)); if (ret) xnfree(tg); + else { + ret = __xn_safe_copy_to_user(p->add.tgid_r, &tg->tgid, + sizeof(tg->tgid)); + if (ret == 0 && p->sum_r) + ret = __xn_safe_copy_to_user(p->sum_r, "a_sum, + sizeof(quota_sum)); + } return ret; } @@ -1485,10 +1489,14 @@ int set_quota_config(int cpu, const union sched_config *config, size_t len) sched = xnsched_struct(cpu); tg = xnsched_quota_find_group(sched, p->remove.tgid); if (tg) { - ret = xnsched_quota_destroy_group(tg); + ret = xnsched_quota_destroy_group(tg, "a_sum); xnlock_put_irqrestore(&nklock, s); - if (ret == 0) + if (ret == 0) { xnfree(tg); + if (p->sum_r) + ret = __xn_safe_copy_to_user(p->sum_r, "a_sum, + sizeof(quota_sum)); + } return ret; } xnlock_put_irqrestore(&nklock, s); @@ -1502,8 +1510,12 @@ int set_quota_config(int cpu, const union sched_config *config, size_t len) if (tg) { xnsched_quota_set_limit(tg, p->set.quota, - p->set.quota_peak); + p->set.quota_peak, + "a_sum); ret = 0; + if (p->sum_r) + ret = __xn_safe_copy_to_user(p->sum_r, "a_sum, + sizeof(quota_sum)); } xnlock_put_irqrestore(&nklock, s); return ret; @@ -1516,6 +1528,7 @@ int set_quota_config(int cpu, const union sched_config *config, size_t len) if (tg) { quota_percent = tg->quota_percent; quota_peak_percent = tg->quota_peak_percent; + quota_sum = xnsched_quota_sum_all(sched); ret = 0; } xnlock_put_irqrestore(&nklock, s); @@ -1528,6 +1541,9 @@ int set_quota_config(int cpu, const union sched_config *config, size_t len) ret = __xn_safe_copy_to_user(p->get.quota_peak_r, "a_peak_percent, sizeof(quota_peak_percent)); + if (ret == 0 && p->sum_r) + ret = __xn_safe_copy_to_user(p->sum_r, "a_sum, + sizeof(quota_sum)); return ret; } @@ -1545,13 +1561,13 @@ ssize_t get_quota_config(int cpu, union sched_config __user *u_config, buf.quota.op = sched_quota_get; - return set_quota_config(cpu, &buf, len); + return do_quota_config(cpu, &buf, len); } #else /* !CONFIG_XENO_OPT_SCHED_QUOTA */ static inline -int set_quota_config(int cpu, const union sched_config *config, size_t len) +int do_quota_config(int cpu, const union sched_config *config, size_t len) { return -EINVAL; } @@ -1677,7 +1693,7 @@ int cobalt_sched_setconfig_np(int cpu, int policy, ret = set_tp_config(cpu, buf, len); break; case SCHED_QUOTA: - ret = set_quota_config(cpu, buf, len); + ret = do_quota_config(cpu, buf, len); break; default: ret = -EINVAL; diff --git a/kernel/cobalt/sched-quota.c b/kernel/cobalt/sched-quota.c index b12edae..5dd9db8 100644 --- a/kernel/cobalt/sched-quota.c +++ b/kernel/cobalt/sched-quota.c @@ -215,6 +215,21 @@ static void quota_limit_handler(struct xntimer *timer) xnsched_set_self_resched(sched); } +static int quota_sum_all(struct xnsched_quota *qs) +{ + struct xnsched_quota_group *tg; + int sum; + + if (list_empty(&qs->groups)) + return 0; + + sum = 0; + list_for_each_entry(tg, &qs->groups, next) + sum += tg->quota_percent; + + return sum; +} + static void xnsched_quota_init(struct xnsched *sched) { char limiter_name[XNOBJECT_NAME_LEN], refiller_name[XNOBJECT_NAME_LEN]; @@ -469,7 +484,8 @@ static void xnsched_quota_migrate(struct xnthread *thread, struct xnsched *sched } int xnsched_quota_create_group(struct xnsched_quota_group *tg, - struct xnsched *sched) + struct xnsched *sched, + int *quota_sum_r) { int tgid, nr_groups = CONFIG_XENO_OPT_SCHED_QUOTA_NR_GROUPS; struct xnsched_quota *qs = &sched->quota; @@ -498,12 +514,14 @@ int xnsched_quota_create_group(struct xnsched_quota_group *tg, qs->period_ns, qs->period_ns, XN_RELATIVE); list_add(&tg->next, &qs->groups); + *quota_sum_r = quota_sum_all(qs); return 0; } EXPORT_SYMBOL_GPL(xnsched_quota_create_group); -int xnsched_quota_destroy_group(struct xnsched_quota_group *tg) +int xnsched_quota_destroy_group(struct xnsched_quota_group *tg, + int *quota_sum_r) { struct xnsched_quota *qs = &tg->sched->quota; @@ -518,40 +536,42 @@ int xnsched_quota_destroy_group(struct xnsched_quota_group *tg) if (list_empty(&qs->groups)) xntimer_stop(&qs->refill_timer); + *quota_sum_r = quota_sum_all(qs); + return 0; } EXPORT_SYMBOL_GPL(xnsched_quota_destroy_group); void xnsched_quota_set_limit(struct xnsched_quota_group *tg, - int quota_percent, int quota_peak_percent) + int quota_percent, int quota_peak_percent, + int *quota_sum_r) { struct xnsched_quota *qs = &tg->sched->quota; atomic_only(); - if (quota_percent < 0) { /* Quota off. */ - tg->quota_percent = 100; - tg->quota_peak_percent = 100; + if (quota_percent < 0 || quota_percent > 100) { /* Quota off. */ + quota_percent = 100; tg->quota_ns = qs->period_ns; - tg->quota_peak_ns = qs->period_ns; - tg->run_budget_ns = qs->period_ns; - return; - } + } else + tg->quota_ns = xnarch_div64(qs->period_ns * quota_percent, 100); - if (quota_percent > 100) - quota_percent = 100; - if (quota_peak_percent > 100) - quota_peak_percent = 100; if (quota_peak_percent < quota_percent) quota_peak_percent = quota_percent; + if (quota_peak_percent < 0 || quota_peak_percent > 100) { + quota_peak_percent = 100; + tg->quota_peak_ns = qs->period_ns; + } else + tg->quota_peak_ns = xnarch_div64(qs->period_ns * quota_peak_percent, 100); + tg->quota_percent = quota_percent; tg->quota_peak_percent = quota_peak_percent; - tg->quota_ns = xnarch_div64(qs->period_ns * quota_percent, 100); - tg->quota_peak_ns = xnarch_div64(qs->period_ns * quota_peak_percent, 100); tg->run_budget_ns = tg->quota_ns; tg->run_credit_ns = 0; /* Drop accumulated credit. */ + *quota_sum_r = quota_sum_all(qs); + /* * Apply the new budget immediately, in case a member of this * group is currently running. @@ -580,6 +600,16 @@ xnsched_quota_find_group(struct xnsched *sched, int tgid) } EXPORT_SYMBOL_GPL(xnsched_quota_find_group); +int xnsched_quota_sum_all(struct xnsched *sched) +{ + struct xnsched_quota *qs = &sched->quota; + + atomic_only(); + + return quota_sum_all(qs); +} +EXPORT_SYMBOL_GPL(xnsched_quota_sum_all); + #ifdef CONFIG_XENO_OPT_VFILE struct xnvfile_directory sched_quota_vfroot; diff --git a/testsuite/unit/sched-quota.c b/testsuite/unit/sched-quota.c index fef6880..cea6aa0 100644 --- a/testsuite/unit/sched-quota.c +++ b/testsuite/unit/sched-quota.c @@ -154,13 +154,15 @@ static void __create_fifo_thread(pthread_t *tid, const char *name, static double run_quota(int quota) { size_t len = sched_quota_confsz(); + int ret, tgid, n, quota_sum; unsigned long long count; union sched_config cf; struct timespec req; - int ret, tgid, n; double percent; char label[8]; + cf.quota.sum_r = "a_sum; + cf.quota.op = sched_quota_add; cf.quota.add.tgid_r = &tgid; ret = sched_setconfig_np(0, SCHED_QUOTA, &cf, len); @@ -175,7 +177,8 @@ static double run_quota(int quota) if (ret) error(1, ret, "sched_setconfig_np(set-quota, tgid=%d)", tgid); - printf("new thread group #%d on CPU0\n", tgid); + printf("new thread group #%d on CPU0, quota sum is %d%%\n", + tgid, quota_sum); for (n = 0; n < nrthreads; n++) { sprintf(label, "t%d", n); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git