Module: xenomai-forge
Branch: next
Commit: f16dca16d635a5283b446accb9ef5c4632922051
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=f16dca16d635a5283b446accb9ef5c4632922051

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..b791d59 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, &quota_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, 
&quota_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, &quota_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, 
&quota_sum,
+                                                                    
sizeof(quota_sum));
+                       }
                        return ret;
                }
                xnlock_put_irqrestore(&nklock, s);
@@ -1502,10 +1510,14 @@ 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,
+                                               &quota_sum);
                        ret = 0;
                }
                xnlock_put_irqrestore(&nklock, s);
+               if (ret == 0 && p->sum_r)
+                       ret = __xn_safe_copy_to_user(p->sum_r, &quota_sum,
+                                                    sizeof(quota_sum));
                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,
                                             &quota_peak_percent,
                                             sizeof(quota_peak_percent));
+               if (ret == 0 && p->sum_r)
+                       ret = __xn_safe_copy_to_user(p->sum_r, &quota_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 = &quota_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

Reply via email to