[Xenomai-git] Philippe Gerum : cobalt/sched: add start, stop SCHED_TP config operations

2015-08-15 Thread git repository hosting
Module: xenomai-3
Branch: master
Commit: 08af0a3457514230180cce05b3e0eda751a377db
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=08af0a3457514230180cce05b3e0eda751a377db

Author: Philippe Gerum r...@xenomai.org
Date:   Thu Jul 30 14:16:04 2015 +0200

cobalt/sched: add start, stop SCHED_TP config operations

We may want to start/stop a TP schedule without removing it from the
CPU entirely. To this end, this commit introduces the
sched_tp_start/stop requests, processed by sched_config_np().

---

 include/cobalt/kernel/compat.h  |1 +
 include/cobalt/uapi/sched.h |8 +
 kernel/cobalt/posix/sched.c |   30 +---
 kernel/cobalt/posix/syscall32.c |4 +++
 kernel/cobalt/sched-tp.c|9 +++--
 lib/cobalt/thread.c |   72 ---
 6 files changed, 97 insertions(+), 27 deletions(-)

diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index 7420804..b0ef81e 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -61,6 +61,7 @@ struct compat_sched_tp_window {
 };
 
 struct __compat_sched_config_tp {
+   int op;
int nr_windows;
struct compat_sched_tp_window windows[0];
 };
diff --git a/include/cobalt/uapi/sched.h b/include/cobalt/uapi/sched.h
index fc04f49..b672095 100644
--- a/include/cobalt/uapi/sched.h
+++ b/include/cobalt/uapi/sched.h
@@ -57,7 +57,15 @@ struct sched_tp_window {
int ptid;
 };
 
+enum {
+   sched_tp_install,
+   sched_tp_uninstall,
+   sched_tp_start,
+   sched_tp_stop,
+};
+   
 struct __sched_config_tp {
+   int op;
int nr_windows;
struct sched_tp_window windows[0];
 };
diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c
index 0e7d405..be2e441 100644
--- a/kernel/cobalt/posix/sched.c
+++ b/kernel/cobalt/posix/sched.c
@@ -242,14 +242,35 @@ int set_tp_config(int cpu, union sched_config *config, 
size_t len)
if (len  sizeof(config-tp))
return -EINVAL;
 
-   if (config-tp.nr_windows == 0) {
+   sched = xnsched_struct(cpu);
+
+   switch (config-tp.op) {
+   case sched_tp_install:
+   if (config-tp.nr_windows  0)
+   break;
+   /* Fallback wanted. */
+   case sched_tp_uninstall:
gps = NULL;
goto set_schedule;
+   case sched_tp_start:
+   xnlock_get_irqsave(nklock, s);
+   xnsched_tp_start_schedule(sched);
+   xnlock_put_irqrestore(nklock, s);
+   return 0;
+   case sched_tp_stop:
+   xnlock_get_irqsave(nklock, s);
+   xnsched_tp_stop_schedule(sched);
+   xnlock_put_irqrestore(nklock, s);
+   return 0;
+   default:
+   return -EINVAL;
}
 
+   /* Install a new TP schedule on CPU. */
+
gps = xnmalloc(sizeof(*gps) + config-tp.nr_windows * sizeof(*w));
if (gps == NULL)
-   goto fail;
+   return -ENOMEM;
 
for (n = 0, p = config-tp.windows, w = gps-pwins, next_offset = 0;
 n  config-tp.nr_windows; n++, p++, w++) {
@@ -279,10 +300,8 @@ int set_tp_config(int cpu, union sched_config *config, 
size_t len)
gps-pwin_nr = n;
gps-tf_duration = next_offset;
 set_schedule:
-   sched = xnsched_struct(cpu);
xnlock_get_irqsave(nklock, s);
ogps = xnsched_tp_set_schedule(sched, gps);
-   xnsched_tp_start_schedule(sched);
xnlock_put_irqrestore(nklock, s);
 
if (ogps)
@@ -292,7 +311,7 @@ set_schedule:
 
 cleanup_and_fail:
xnfree(gps);
-fail:
+
return -EINVAL;
 }
 
@@ -333,6 +352,7 @@ ssize_t get_tp_config(int cpu, void __user *u_config, 
size_t len,
goto out;
}
 
+   config-tp.op = sched_tp_install;
config-tp.nr_windows = gps-pwin_nr;
for (n = 0, pp = p = config-tp.windows, pw = w = gps-pwins;
 n  gps-pwin_nr; pp = p, p++, pw = w, w++, n++) {
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 78d3c57..b3ce8a7 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -341,6 +341,7 @@ sys32_fetch_config(int policy, const void __user *u_config, 
size_t *len)
if (policy == SCHED_QUOTA)
memcpy(buf-quota, cbuf-quota, sizeof(cbuf-quota));
else {
+   buf-tp.op = cbuf-tp.op;
buf-tp.nr_windows = cbuf-tp.nr_windows;
for (n = 0; n  buf-tp.nr_windows; n++) {
buf-tp.windows[n].ptid = cbuf-tp.windows[n].ptid;
@@ -387,9 +388,12 @@ static ssize_t sys32_put_config(int policy,
sizeof(u_p-quota.info);
}
 
+   /* SCHED_TP */
+
if (u_len  compat_sched_tp_confsz(config-tp.nr_windows))
return -ENOSPC;
 
+   __xn_put_user(config-tp.op, u_p-tp.op);

[Xenomai-git] Philippe Gerum : cobalt/sched: add start, stop SCHED_TP config operations

2015-07-31 Thread git repository hosting
Module: xenomai-3
Branch: next
Commit: 08af0a3457514230180cce05b3e0eda751a377db
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=08af0a3457514230180cce05b3e0eda751a377db

Author: Philippe Gerum r...@xenomai.org
Date:   Thu Jul 30 14:16:04 2015 +0200

cobalt/sched: add start, stop SCHED_TP config operations

We may want to start/stop a TP schedule without removing it from the
CPU entirely. To this end, this commit introduces the
sched_tp_start/stop requests, processed by sched_config_np().

---

 include/cobalt/kernel/compat.h  |1 +
 include/cobalt/uapi/sched.h |8 +
 kernel/cobalt/posix/sched.c |   30 +---
 kernel/cobalt/posix/syscall32.c |4 +++
 kernel/cobalt/sched-tp.c|9 +++--
 lib/cobalt/thread.c |   72 ---
 6 files changed, 97 insertions(+), 27 deletions(-)

diff --git a/include/cobalt/kernel/compat.h b/include/cobalt/kernel/compat.h
index 7420804..b0ef81e 100644
--- a/include/cobalt/kernel/compat.h
+++ b/include/cobalt/kernel/compat.h
@@ -61,6 +61,7 @@ struct compat_sched_tp_window {
 };
 
 struct __compat_sched_config_tp {
+   int op;
int nr_windows;
struct compat_sched_tp_window windows[0];
 };
diff --git a/include/cobalt/uapi/sched.h b/include/cobalt/uapi/sched.h
index fc04f49..b672095 100644
--- a/include/cobalt/uapi/sched.h
+++ b/include/cobalt/uapi/sched.h
@@ -57,7 +57,15 @@ struct sched_tp_window {
int ptid;
 };
 
+enum {
+   sched_tp_install,
+   sched_tp_uninstall,
+   sched_tp_start,
+   sched_tp_stop,
+};
+   
 struct __sched_config_tp {
+   int op;
int nr_windows;
struct sched_tp_window windows[0];
 };
diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c
index 0e7d405..be2e441 100644
--- a/kernel/cobalt/posix/sched.c
+++ b/kernel/cobalt/posix/sched.c
@@ -242,14 +242,35 @@ int set_tp_config(int cpu, union sched_config *config, 
size_t len)
if (len  sizeof(config-tp))
return -EINVAL;
 
-   if (config-tp.nr_windows == 0) {
+   sched = xnsched_struct(cpu);
+
+   switch (config-tp.op) {
+   case sched_tp_install:
+   if (config-tp.nr_windows  0)
+   break;
+   /* Fallback wanted. */
+   case sched_tp_uninstall:
gps = NULL;
goto set_schedule;
+   case sched_tp_start:
+   xnlock_get_irqsave(nklock, s);
+   xnsched_tp_start_schedule(sched);
+   xnlock_put_irqrestore(nklock, s);
+   return 0;
+   case sched_tp_stop:
+   xnlock_get_irqsave(nklock, s);
+   xnsched_tp_stop_schedule(sched);
+   xnlock_put_irqrestore(nklock, s);
+   return 0;
+   default:
+   return -EINVAL;
}
 
+   /* Install a new TP schedule on CPU. */
+
gps = xnmalloc(sizeof(*gps) + config-tp.nr_windows * sizeof(*w));
if (gps == NULL)
-   goto fail;
+   return -ENOMEM;
 
for (n = 0, p = config-tp.windows, w = gps-pwins, next_offset = 0;
 n  config-tp.nr_windows; n++, p++, w++) {
@@ -279,10 +300,8 @@ int set_tp_config(int cpu, union sched_config *config, 
size_t len)
gps-pwin_nr = n;
gps-tf_duration = next_offset;
 set_schedule:
-   sched = xnsched_struct(cpu);
xnlock_get_irqsave(nklock, s);
ogps = xnsched_tp_set_schedule(sched, gps);
-   xnsched_tp_start_schedule(sched);
xnlock_put_irqrestore(nklock, s);
 
if (ogps)
@@ -292,7 +311,7 @@ set_schedule:
 
 cleanup_and_fail:
xnfree(gps);
-fail:
+
return -EINVAL;
 }
 
@@ -333,6 +352,7 @@ ssize_t get_tp_config(int cpu, void __user *u_config, 
size_t len,
goto out;
}
 
+   config-tp.op = sched_tp_install;
config-tp.nr_windows = gps-pwin_nr;
for (n = 0, pp = p = config-tp.windows, pw = w = gps-pwins;
 n  gps-pwin_nr; pp = p, p++, pw = w, w++, n++) {
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index 78d3c57..b3ce8a7 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -341,6 +341,7 @@ sys32_fetch_config(int policy, const void __user *u_config, 
size_t *len)
if (policy == SCHED_QUOTA)
memcpy(buf-quota, cbuf-quota, sizeof(cbuf-quota));
else {
+   buf-tp.op = cbuf-tp.op;
buf-tp.nr_windows = cbuf-tp.nr_windows;
for (n = 0; n  buf-tp.nr_windows; n++) {
buf-tp.windows[n].ptid = cbuf-tp.windows[n].ptid;
@@ -387,9 +388,12 @@ static ssize_t sys32_put_config(int policy,
sizeof(u_p-quota.info);
}
 
+   /* SCHED_TP */
+
if (u_len  compat_sched_tp_confsz(config-tp.nr_windows))
return -ENOSPC;
 
+   __xn_put_user(config-tp.op, u_p-tp.op);