[Xenomai-git] Jan Kiszka : cobalt/kernel: Introduce lazy Linux scheduling parameter synchronization
Module: xenomai-jki Branch: for-forge Commit: bf1b75b6d9633622393526cf1ae4853416a8cdd9 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=bf1b75b6d9633622393526cf1ae4853416a8cdd9 Author: Jan KiszkaDate: 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
Module: xenomai-jki Branch: for-forge Commit: 3c17feb1cc6066e6adca727c2b198546087a8bd8 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=3c17feb1cc6066e6adca727c2b198546087a8bd8 Author: Jan KiszkaDate: 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,
Module: xenomai-jki Branch: for-forge Commit: c0e15af00c4b31ab811d726249562df7c499ef93 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=c0e15af00c4b31ab811d726249562df7c499ef93 Author: Jan KiszkaDate: 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
Module: xenomai-jki Branch: for-forge Commit: 47a69b3ca1041cda3ab8ac69591e625d6992645f URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=47a69b3ca1041cda3ab8ac69591e625d6992645f Author: Jan KiszkaDate: 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