[Xenomai-git] Jan Kiszka : cobalt/kernel: Introduce lazy Linux scheduling parameter synchronization

2016-03-08 Thread git repository hosting
Module: xenomai-jki
Branch: for-forge
Commit: bf1b75b6d9633622393526cf1ae4853416a8cdd9
URL:
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=bf1b75b6d9633622393526cf1ae4853416a8cdd9

Author: Jan Kiszka 
Date:   Tue Mar  8 18:22:51 2016 +0100

cobalt/kernel: Introduce lazy Linux scheduling parameter synchronization

We currently require userspace to trigger the synchronization of a
real-time thread's scheduling parameters with Linux by calling
corresponding libc functions. Those usually trigger a migration to
secondary mode. This can be unwanted, specifically for workload that
makes heavy use of manual priority tunings from withing real-time
threads.

To avoid the mode switch, this makes the kernel initiate the parameter
synchronization. As we don't want to do this while the caller of
setschedparam & Co. is in real-time mode, the actual call to Linux'
sched_setscheduler is delegated to helper kernel tasks, one for each
CPU. When a thread received an scheduling parameter update, it is queued
to a per-helper list. The helper task is triggered from primary mode,
but it will only run once we next switch back to Linux on that CPU. Then
it will dequeue all entries from its work list, apply the scheduling
parameters also on the Linux side, and the threads' Linux mates will
then run with the right tunings.

In order to avoid most cases where the Linux parameters could be applied
too late, the helper tasks run with highest priority. One theoretical
case remains: If a thread drops from the very same highest priority
level, the helper may not be executed first, thus the Linux priority
drop may only be applied once the target thread is preempted or
suspended. However, in practice, the helper task is woken up first, and
only afterward the Linux mate. So the Linux scheduler is expected to run
the helper first.

Signed-off-by: Jan Kiszka 

---

 include/cobalt/kernel/sched.h  |6 +++
 include/cobalt/kernel/thread.h |4 ++
 kernel/cobalt/init.c   |9 
 kernel/cobalt/sched.c  |   96 
 kernel/cobalt/thread.c |   41 +
 5 files changed, 156 insertions(+)

diff --git a/include/cobalt/kernel/sched.h b/include/cobalt/kernel/sched.h
index d5d93c2..a2f7b8c 100644
--- a/include/cobalt/kernel/sched.h
+++ b/include/cobalt/kernel/sched.h
@@ -93,6 +93,10 @@ struct xnsched {
struct xntimer rrbtimer;
/*!< Root thread control block. */
struct xnthread rootcb;
+   /*!< Worker kthread to apply Linux scheduling parameters. */
+   struct task_struct *setsched_worker;
+   /*!< List of pending Linux scheduling parameter updates. */
+   struct list_head setsched_list;
 #ifdef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
struct xnthread *last;
 #endif
@@ -380,6 +384,8 @@ void xnsched_cleanup_proc(void);
 
 void xnsched_register_classes(void);
 
+int xnsched_init_setsched(struct xnsched *sched);
+
 void xnsched_init(struct xnsched *sched, int cpu);
 
 void xnsched_destroy(struct xnsched *sched);
diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index b45de8e..4ffc632 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -188,6 +188,8 @@ struct xnthread {
const char *exe_path;   /* Executable path */
u32 proghash;   /* Hash value for exe_path */
 #endif
+
+   struct list_head setsched_link;
 };
 
 static inline int xnthread_get_state(const struct xnthread *thread)
@@ -541,6 +543,8 @@ static inline void xnthread_migrate_passive(struct xnthread 
*thread,
 
 #endif
 
+void __xnthread_post_setsched_root(struct xnthread *thread);
+
 int __xnthread_set_schedparam(struct xnthread *thread,
  struct xnsched_class *sched_class,
  const union xnsched_policy_param *sched_param);
diff --git a/kernel/cobalt/init.c b/kernel/cobalt/init.c
index 5a6fdbf..dc484a4 100644
--- a/kernel/cobalt/init.c
+++ b/kernel/cobalt/init.c
@@ -309,6 +309,15 @@ static __init int sys_init(void)
 
xnregistry_init();
 
+   for_each_online_cpu(cpu) {
+   sched = _cpu(nksched, cpu);
+   ret = xnsched_init_setsched(sched);
+   if (ret) {
+   sys_shutdown();
+   return ret;
+   }
+   }
+
/*
 * If starting in stopped mode, do all initializations, but do
 * not enable the core timer.
diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c
index d124f79..f13fd83 100644
--- a/kernel/cobalt/sched.c
+++ b/kernel/cobalt/sched.c
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  * 02111-1307, USA.
  */
+#include 
 #include 
 #include 
 #include 
@@ -143,6 +144,84 @@ static void watchdog_handler(struct xntimer *timer)
 
 #endif /* CONFIG_XENO_OPT_WATCHDOG */
 
+static int do_setsched_work(void *data)
+{
+   

[Xenomai-git] Jan Kiszka : lib/cobalt: Wrap pthread_setschedprio for proper real-time support

2016-03-08 Thread git repository hosting
Module: xenomai-jki
Branch: for-forge
Commit: 3c17feb1cc6066e6adca727c2b198546087a8bd8
URL:
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=3c17feb1cc6066e6adca727c2b198546087a8bd8

Author: Jan Kiszka 
Date:   Tue Mar  8 14:46:59 2016 +0100

lib/cobalt: Wrap pthread_setschedprio for proper real-time support

Implement pthread_setschedprio on top of pthread_setschedparam_ex with
the help of the new __SCHED_CURRENT policy. This ensures that prio
changes are directly applied to the real-time core, and that with just
a single syscall.

Signed-off-by: Jan Kiszka 

---

 include/cobalt/pthread.h   |2 ++
 lib/cobalt/cobalt.wrappers |1 +
 lib/cobalt/thread.c|9 +
 lib/cobalt/wrappers.c  |6 ++
 4 files changed, 18 insertions(+)

diff --git a/include/cobalt/pthread.h b/include/cobalt/pthread.h
index 386c337..ea5210e 100644
--- a/include/cobalt/pthread.h
+++ b/include/cobalt/pthread.h
@@ -53,6 +53,8 @@ COBALT_DECL(int, pthread_setschedparam(pthread_t thread,
   int policy,
   const struct sched_param *param));
 
+COBALT_DECL(int, pthread_setschedprio(pthread_t thread, int prio));
+
 COBALT_DECL(int, pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr));
 
diff --git a/lib/cobalt/cobalt.wrappers b/lib/cobalt/cobalt.wrappers
index 9480f34..6a5db57 100644
--- a/lib/cobalt/cobalt.wrappers
+++ b/lib/cobalt/cobalt.wrappers
@@ -2,6 +2,7 @@
 --wrap pthread_create
 --wrap pthread_setschedparam
 --wrap pthread_getschedparam
+--wrap pthread_setschedprio
 --wrap pthread_yield
 --wrap sched_yield
 --wrap sched_get_priority_min
diff --git a/lib/cobalt/thread.c b/lib/cobalt/thread.c
index aab2c81..567972d 100644
--- a/lib/cobalt/thread.c
+++ b/lib/cobalt/thread.c
@@ -674,6 +674,15 @@ int pthread_setschedparam_ex(pthread_t thread,
return ret;
 }
 
+COBALT_IMPL(int, pthread_setschedprio, (pthread_t thread, int prio))
+{
+   struct sched_param_ex param_ex = {
+   .sched_priority = prio,
+   };
+
+   return pthread_setschedparam_ex(thread, __SCHED_CURRENT, _ex);
+}
+
 /**
  * Get the scheduling policy and parameters of the specified thread.
  *
diff --git a/lib/cobalt/wrappers.c b/lib/cobalt/wrappers.c
index 09c74e5..1f1664e 100644
--- a/lib/cobalt/wrappers.c
+++ b/lib/cobalt/wrappers.c
@@ -60,6 +60,12 @@ int __real_pthread_getschedparam(pthread_t thread,
 }
 
 __weak
+int __real_pthread_setschedprio(pthread_t thread, int prio)
+{
+   return pthread_setschedprio(thread, prio);
+}
+
+__weak
 int __real_sched_yield(void)
 {
return sched_yield();


___
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git


[Xenomai-git] Jan Kiszka : testsuite/smokey: Add test case for setschedparam & Co,

2016-03-08 Thread git repository hosting
Module: xenomai-jki
Branch: for-forge
Commit: c0e15af00c4b31ab811d726249562df7c499ef93
URL:
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=c0e15af00c4b31ab811d726249562df7c499ef93

Author: Jan Kiszka 
Date:   Mon Feb 29 16:54:26 2016 +0100

testsuite/smokey: Add test case for setschedparam & Co,

This performs basic checks on the correct execution of scheduling
parameter changes from primary mode.

Signed-off-by: Jan Kiszka 

---

 configure.ac  |1 +
 testsuite/smokey/Makefile.am  |1 +
 testsuite/smokey/setsched/Makefile.am |9 +++
 testsuite/smokey/setsched/setsched.c  |  137 +
 4 files changed, 148 insertions(+)

diff --git a/configure.ac b/configure.ac
index d71aa38..ecabc8d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -890,6 +890,7 @@ AC_CONFIG_FILES([ \
testsuite/smokey/arith/Makefile \
testsuite/smokey/sched-quota/Makefile \
testsuite/smokey/sched-tp/Makefile \
+   testsuite/smokey/setsched/Makefile \
testsuite/smokey/rtdm/Makefile \
testsuite/smokey/vdso-access/Makefile \
testsuite/smokey/posix-cond/Makefile \
diff --git a/testsuite/smokey/Makefile.am b/testsuite/smokey/Makefile.am
index 51292f1..e253d6f 100644
--- a/testsuite/smokey/Makefile.am
+++ b/testsuite/smokey/Makefile.am
@@ -24,6 +24,7 @@ COBALT_SUBDIRS =  \
rtdm\
sched-quota \
sched-tp\
+   setsched\
sigdebug\
timerfd \
tsc \
diff --git a/testsuite/smokey/setsched/Makefile.am 
b/testsuite/smokey/setsched/Makefile.am
new file mode 100644
index 000..8c0a59b
--- /dev/null
+++ b/testsuite/smokey/setsched/Makefile.am
@@ -0,0 +1,9 @@
+
+noinst_LIBRARIES = libsetsched.a
+
+libsetsched_a_SOURCES = setsched.c
+
+libsetsched_a_CPPFLAGS =   \
+   @XENO_USER_CFLAGS@  \
+   -I$(top_srcdir) \
+   -I$(top_srcdir)/include
diff --git a/testsuite/smokey/setsched/setsched.c 
b/testsuite/smokey/setsched/setsched.c
new file mode 100644
index 000..b4b4066
--- /dev/null
+++ b/testsuite/smokey/setsched/setsched.c
@@ -0,0 +1,137 @@
+/*
+ * Scheduler live-adjustment test.
+ *
+ * Copyright (c) Siemens AG 2016
+ *
+ * Authors:
+ *  Jan Kiszka 
+ *
+ * Released under the terms of GPLv2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+smokey_test_plugin(setsched, SMOKEY_NOARGS,
+   "Validate correct application of scheduling parameters to running threads."
+);
+
+static pid_t thread_pid;
+
+static void __check_linux_schedparams(int expected_policy, int expected_prio,
+ int line)
+{
+   struct sched_param linux_param;
+   int linux_policy;
+
+   linux_policy = syscall(SYS_sched_getscheduler, thread_pid);
+   if (smokey_check_status(syscall(SYS_sched_getparam, thread_pid,
+   _param)))
+   exit(-EINVAL);
+
+   if (!smokey_assert(linux_policy == expected_policy) ||
+   !smokey_assert(linux_param.sched_priority == expected_prio)) {
+   smokey_warning("called from line %d", line);
+   exit(-EINVAL);
+   }
+}
+
+#define check_linux_schedparams(pol, prio) \
+   __check_linux_schedparams(pol, prio, __LINE__)
+
+static void __check_rt_schedparams(int expected_policy, int expected_prio,
+  int line)
+{
+   struct sched_param cobalt_param;
+   int cobalt_policy;
+
+   if (smokey_check_status(pthread_getschedparam(pthread_self(),
+ _policy,
+ _param)))
+   exit(-EINVAL);
+
+   if (!smokey_assert(cobalt_policy == expected_policy) ||
+   !smokey_assert(cobalt_param.sched_priority == expected_prio)) {
+   smokey_warning("called from line %d", line);
+   exit(-EINVAL);
+   }
+}
+
+#define check_rt_schedparams(pol, prio)\
+   __check_rt_schedparams(pol, prio, __LINE__)
+
+static void *thread_body(void *arg)
+{
+   struct cobalt_threadstat stats;
+   struct sched_param param;
+   unsigned long long msw;
+
+   thread_pid = syscall(SYS_gettid);
+
+   check_rt_schedparams(SCHED_FIFO, 1);
+   check_linux_schedparams(SCHED_FIFO, 1);
+
+   if (smokey_check_status(cobalt_thread_stat(thread_pid, )))
+   exit(-EINVAL);
+   msw = stats.msw;
+
+   param.sched_priority = 2;
+   if (smokey_check_status(pthread_setschedparam(pthread_self(),
+ SCHED_FIFO, )))
+   exit(-EINVAL);
+
+   check_rt_schedparams(SCHED_FIFO, 2);
+
+   if (smokey_check_status(cobalt_thread_stat(thread_pid, )) ||
+   

[Xenomai-git] Jan Kiszka : boilerplate: Allow for enabling Xenomai only in shared libs

2016-03-08 Thread git repository hosting
Module: xenomai-jki
Branch: for-forge
Commit: 47a69b3ca1041cda3ab8ac69591e625d6992645f
URL:
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=47a69b3ca1041cda3ab8ac69591e625d6992645f

Author: Jan Kiszka 
Date:   Fri Feb  5 17:33:18 2016 +0100

boilerplate: Allow for enabling Xenomai only in shared libs

Normally, one builds shared libraries with Xenomai awareness by adding
--no-auto-init to xeno-config. This drops bootstrap.o from the linking
steps because - normally - the main application performs the
initialization.

However, if the main application is Xenomai-free and only dlopen() would
pull in Xenomai services via a shared library, we face two problems:

- bootstrap.o is not built with position-independence support

- libboilerplate contains __real_main that expects the main symbol which
  cannot be found from a shared library

This patch solves both issues.

Signed-off-by: Jan Kiszka 

---

 lib/boilerplate/init/Makefile.am |1 +
 lib/boilerplate/wrappers.c   |5 -
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/boilerplate/init/Makefile.am b/lib/boilerplate/init/Makefile.am
index 7a58f54..8c09e28 100644
--- a/lib/boilerplate/init/Makefile.am
+++ b/lib/boilerplate/init/Makefile.am
@@ -4,6 +4,7 @@ libbootstrap_a_SOURCES = bootstrap.c
 
 libbootstrap_a_CPPFLAGS =  \
@XENO_USER_CFLAGS@  \
+   -fPIC   \
-I$(top_srcdir)/include \
-I$(top_srcdir)/lib
 
diff --git a/lib/boilerplate/wrappers.c b/lib/boilerplate/wrappers.c
index 9d2490c..db8d5f7 100644
--- a/lib/boilerplate/wrappers.c
+++ b/lib/boilerplate/wrappers.c
@@ -17,7 +17,10 @@
  */
 #include 
 
-int main(int argc, char *const argv[]);
+__weak int main(int argc, char *const argv[])
+{
+   return 0;
+}
 
 int __real_main(int argc, char *const argv[]);
 


___
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git