Module: xenomai-3 Branch: master Commit: 507c4d17abef6feeeb1538c6e28b442fb27c57c4 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=507c4d17abef6feeeb1538c6e28b442fb27c57c4
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Sep 17 00:30:06 2015 +0200 cobalt/posix/sched: add support for sched_setscheduler(2) --- .../arch/x86/include/asm/xenomai/syscall32-table.h | 1 + kernel/cobalt/posix/sched.c | 54 ++++++++++++++++++++ kernel/cobalt/posix/sched.h | 13 +++++ kernel/cobalt/posix/syscall32.c | 22 +++++++- kernel/cobalt/posix/syscall32.h | 7 +++ kernel/cobalt/posix/thread.c | 42 ++++++--------- kernel/cobalt/posix/thread.h | 13 +++-- kernel/cobalt/trace/cobalt-posix.h | 32 ++++++++++++ 8 files changed, 152 insertions(+), 32 deletions(-) diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h index 1dce4e7..53aa131 100644 --- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h +++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h @@ -48,6 +48,7 @@ __COBALT_CALL32x_THUNK(mq_notify) __COBALT_CALL32emu_THUNK(sched_weightprio) __COBALT_CALL32emu_THUNK(sched_setconfig_np) __COBALT_CALL32emu_THUNK(sched_getconfig_np) +__COBALT_CALL32emu_THUNK(sched_setscheduler_ex) __COBALT_CALL32emu_THUNK(timer_create) __COBALT_CALL32x_THUNK(timer_create) __COBALT_CALL32emu_THUNK(timer_settime) diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c index be2e441..ff4fdc9 100644 --- a/kernel/cobalt/posix/sched.c +++ b/kernel/cobalt/posix/sched.c @@ -731,6 +731,60 @@ COBALT_SYSCALL(sched_weightprio, current, return __cobalt_sched_weightprio(policy, ¶m_ex); } +int cobalt_sched_setscheduler_ex(pid_t pid, + int policy, + const struct sched_param_ex *param_ex, + __u32 __user *u_winoff, + int __user *u_promoted) +{ + struct cobalt_local_hkey hkey; + struct cobalt_thread *thread; + int ret, promoted = 0; + spl_t s; + + trace_cobalt_sched_setscheduler(pid, policy, param_ex); + + if (pid) { + xnlock_get_irqsave(&nklock, s); + thread = cobalt_thread_find(pid); + xnlock_put_irqrestore(&nklock, s); + } else + thread = cobalt_current_thread(); + + if (thread == NULL) { + if (u_winoff == NULL) + return -ESRCH; + + thread = cobalt_thread_shadow(current, &hkey, u_winoff); + if (IS_ERR(thread)) + return PTR_ERR(thread); + + promoted = 1; + } + + ret = __cobalt_thread_setschedparam_ex(thread, policy, param_ex); + if (ret) + return ret; + + return cobalt_copy_to_user(u_promoted, &promoted, sizeof(promoted)); +} + +COBALT_SYSCALL(sched_setscheduler_ex, conforming, + (pid_t pid, + int policy, + const struct sched_param_ex __user *u_param, + __u32 __user *u_winoff, + int __user *u_promoted)) +{ + struct sched_param_ex param_ex; + + if (cobalt_copy_from_user(¶m_ex, u_param, sizeof(param_ex))) + return -EFAULT; + + return cobalt_sched_setscheduler_ex(pid, policy, ¶m_ex, + u_winoff, u_promoted); +} + void cobalt_sched_reclaim(struct cobalt_process *process) { struct cobalt_resources *p = &process->resources; diff --git a/kernel/cobalt/posix/sched.h b/kernel/cobalt/posix/sched.h index ae7b618..4ccef3c 100644 --- a/kernel/cobalt/posix/sched.h +++ b/kernel/cobalt/posix/sched.h @@ -57,6 +57,12 @@ ssize_t __cobalt_sched_getconfig_np(int cpu, int policy, void __user *u_config, size_t u_len, const union sched_config *config, size_t len)); +int cobalt_sched_setscheduler_ex(pid_t pid, + int policy, + const struct sched_param_ex *param_ex, + __u32 __user *u_winoff, + int __user *u_promoted); + struct xnsched_class * cobalt_sched_policy_param(union xnsched_policy_param *param, int u_policy, const struct sched_param_ex *param_ex, @@ -82,6 +88,13 @@ COBALT_SYSCALL_DECL(sched_getconfig_np, union sched_config __user *u_config, size_t len)); +COBALT_SYSCALL_DECL(sched_setscheduler_ex, + (pid_t pid, + int policy, + const struct sched_param_ex *param_ex, + __u32 __user *u_winoff, + int __user *u_promoted)); + void cobalt_sched_reclaim(struct cobalt_process *process); #endif /* !_COBALT_POSIX_SCHED_H */ diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c index b3ce8a7..fda93a9 100644 --- a/kernel/cobalt/posix/syscall32.c +++ b/kernel/cobalt/posix/syscall32.c @@ -67,8 +67,8 @@ COBALT_SYSCALL32emu(thread_setschedparam_ex, conforming, if (ret) return ret; - return __cobalt_thread_setschedparam_ex(pth, policy, ¶m_ex, - u_winoff, u_promoted); + return cobalt_thread_setschedparam_ex(pth, policy, ¶m_ex, + u_winoff, u_promoted); } COBALT_SYSCALL32emu(thread_getschedparam_ex, current, @@ -430,6 +430,24 @@ COBALT_SYSCALL32emu(sched_getconfig_np, conformin, sys32_fetch_config, sys32_put_config); } +COBALT_SYSCALL32emu(sched_setscheduler_ex, conforming, + (compat_pid_t pid, + int policy, + const struct compat_sched_param_ex __user *u_param_ex, + __u32 __user *u_winoff, + int __user *u_promoted)) +{ + struct sched_param_ex param_ex; + int ret; + + ret = sys32_get_param_ex(policy, ¶m_ex, u_param_ex); + if (ret) + return ret; + + return cobalt_sched_setscheduler_ex(pid, policy, ¶m_ex, + u_winoff, u_promoted); +} + COBALT_SYSCALL32emu(timer_create, current, (clockid_t clock, const struct compat_sigevent __user *u_sev, diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h index f31448e..045e6be 100644 --- a/kernel/cobalt/posix/syscall32.h +++ b/kernel/cobalt/posix/syscall32.h @@ -114,6 +114,13 @@ COBALT_SYSCALL32emu_DECL(sched_getconfig_np, union compat_sched_config __user *u_config, size_t len)); +COBALT_SYSCALL32emu_DECL(sched_setscheduler_ex, + (compat_pid_t pid, + int policy, + const struct compat_sched_param_ex __user *u_param, + __u32 __user *u_winoff, + int __user *u_promoted)); + COBALT_SYSCALL32emu_DECL(timer_create, (clockid_t clock, const struct compat_sigevent __user *u_sev, diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c index 00397fc..0fe2088 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -239,9 +239,8 @@ struct xnthread_personality *cobalt_thread_finalize(struct xnthread *zombie) return NULL; } -static inline int -pthread_setschedparam_ex(struct cobalt_thread *thread, - int policy, const struct sched_param_ex *param_ex) +int __cobalt_thread_setschedparam_ex(struct cobalt_thread *thread, int policy, + const struct sched_param_ex *param_ex) { struct xnsched_class *sched_class; union xnsched_policy_param param; @@ -452,11 +451,11 @@ static inline int pthread_setmode_np(int clrmask, int setmask, int *mode_r) return 0; } -int __cobalt_thread_setschedparam_ex(unsigned long pth, - int policy, - const struct sched_param_ex *param_ex, - __u32 __user *u_winoff, - int __user *u_promoted) +int cobalt_thread_setschedparam_ex(unsigned long pth, + int policy, + const struct sched_param_ex *param_ex, + __u32 __user *u_winoff, + int __user *u_promoted) { struct cobalt_local_hkey hkey; struct cobalt_thread *thread; @@ -467,7 +466,10 @@ int __cobalt_thread_setschedparam_ex(unsigned long pth, trace_cobalt_pthread_setschedparam(pth, policy, param_ex); thread = thread_lookup(&hkey); - if (thread == NULL && u_winoff) { + if (thread == NULL) { + if (u_winoff == NULL) + return -ESRCH; + thread = cobalt_thread_shadow(current, &hkey, u_winoff); if (IS_ERR(thread)) return PTR_ERR(thread); @@ -475,23 +477,13 @@ int __cobalt_thread_setschedparam_ex(unsigned long pth, promoted = 1; } - if (thread) - ret = pthread_setschedparam_ex(thread, policy, param_ex); - else - ret = -EPERM; - - if (ret == 0 && - cobalt_copy_to_user(u_promoted, &promoted, sizeof(promoted))) - ret = -EFAULT; + ret = __cobalt_thread_setschedparam_ex(thread, policy, param_ex); + if (ret) + return ret; - return ret; + return cobalt_copy_to_user(u_promoted, &promoted, sizeof(promoted)); } -/* - * NOTE: there is no cobalt_thread_setschedparam syscall defined by - * the Cobalt ABI. Useland changes scheduling parameters only via the - * extended cobalt_thread_setschedparam_ex syscall. - */ COBALT_SYSCALL(thread_setschedparam_ex, conforming, (unsigned long pth, int policy, @@ -504,8 +496,8 @@ COBALT_SYSCALL(thread_setschedparam_ex, conforming, if (cobalt_copy_from_user(¶m_ex, u_param, sizeof(param_ex))) return -EFAULT; - return __cobalt_thread_setschedparam_ex(pth, policy, ¶m_ex, - u_winoff, u_promoted); + return cobalt_thread_setschedparam_ex(pth, policy, ¶m_ex, + u_winoff, u_promoted); } int __cobalt_thread_getschedparam_ex(unsigned long pth, diff --git a/kernel/cobalt/posix/thread.h b/kernel/cobalt/posix/thread.h index ffdf612..1894774 100644 --- a/kernel/cobalt/posix/thread.h +++ b/kernel/cobalt/posix/thread.h @@ -122,11 +122,14 @@ int __cobalt_thread_create(unsigned long pth, int policy, struct sched_param_ex __user *u_param, int xid, __u32 __user *u_winoff); -int __cobalt_thread_setschedparam_ex(unsigned long pth, - int policy, - const struct sched_param_ex *param_ex, - __u32 __user *u_winoff, - int __user *u_promoted); +int __cobalt_thread_setschedparam_ex(struct cobalt_thread *thread, int policy, + const struct sched_param_ex *param_ex); + +int cobalt_thread_setschedparam_ex(unsigned long pth, + int policy, + const struct sched_param_ex *param_ex, + __u32 __user *u_winoff, + int __user *u_promoted); int __cobalt_thread_getschedparam_ex(unsigned long pth, int __user *u_policy, diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h index 2382615..9c2ae22 100644 --- a/kernel/cobalt/trace/cobalt-posix.h +++ b/kernel/cobalt/trace/cobalt-posix.h @@ -156,6 +156,32 @@ DECLARE_EVENT_CLASS(cobalt_posix_schedparam, ) ); +DECLARE_EVENT_CLASS(cobalt_posix_scheduler, + TP_PROTO(pid_t pid, int policy, + const struct sched_param_ex *param_ex), + TP_ARGS(pid, policy, param_ex), + + TP_STRUCT__entry( + __field(pid_t, pid) + __field(int, policy) + __dynamic_array(char, param_ex, sizeof(struct sched_param_ex)) + ), + + TP_fast_assign( + __entry->pid = pid; + __entry->policy = policy; + memcpy(__get_dynamic_array(param_ex), param_ex, sizeof(*param_ex)); + ), + + TP_printk("pid=%d policy=%d(%s) param={ %s }", + __entry->pid, __entry->policy, + cobalt_print_sched_policy(__entry->policy), + cobalt_print_sched_params(__entry->policy, + (struct sched_param_ex *) + __get_dynamic_array(param_ex)) + ) +); + DECLARE_EVENT_CLASS(cobalt_void, TP_PROTO(int dummy), TP_ARGS(dummy), @@ -368,6 +394,12 @@ TRACE_EVENT(cobalt_sched_get_config, __entry->rlen) ); +DEFINE_EVENT(cobalt_posix_scheduler, cobalt_sched_setscheduler, + TP_PROTO(pid_t pid, int policy, + const struct sched_param_ex *param_ex), + TP_ARGS(pid, policy, param_ex) +); + DECLARE_EVENT_CLASS(cobalt_posix_prio_bound, TP_PROTO(int policy, int prio), TP_ARGS(policy, prio), _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git