Module: xenomai-3 Branch: master Commit: 4beb554db716acad7f5998e56ce2c1350146d98b URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=4beb554db716acad7f5998e56ce2c1350146d98b
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Sep 22 10:41:09 2015 +0200 cobalt/posix/sched: add support for sched_getscheduler(2) --- .../arch/x86/include/asm/xenomai/syscall32-table.h | 1 + kernel/cobalt/posix/sched.c | 41 ++++++++++++++ kernel/cobalt/posix/sched.h | 11 +++- kernel/cobalt/posix/syscall32.c | 29 ++++++++-- kernel/cobalt/posix/syscall32.h | 5 ++ kernel/cobalt/posix/thread.c | 58 +++++++++----------- kernel/cobalt/posix/thread.h | 8 ++- kernel/cobalt/trace/cobalt-posix.h | 5 ++ 8 files changed, 119 insertions(+), 39 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 53aa131..7484c3a 100644 --- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h +++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h @@ -49,6 +49,7 @@ __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(sched_getscheduler_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 ff4fdc9..b73d531 100644 --- a/kernel/cobalt/posix/sched.c +++ b/kernel/cobalt/posix/sched.c @@ -785,6 +785,47 @@ COBALT_SYSCALL(sched_setscheduler_ex, conforming, u_winoff, u_promoted); } +int cobalt_sched_getscheduler_ex(pid_t pid, + int *policy_r, + struct sched_param_ex *param_ex) +{ + struct cobalt_thread *thread; + spl_t s; + + trace_cobalt_sched_getscheduler(pid); + + 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) + return -ESRCH; + + return __cobalt_thread_getschedparam_ex(thread, policy_r, param_ex); +} + +COBALT_SYSCALL(sched_getscheduler_ex, current, + (pid_t pid, + int __user *u_policy, + struct sched_param_ex __user *u_param)) +{ + struct sched_param_ex param_ex; + int ret, policy; + + ret = cobalt_sched_getscheduler_ex(pid, &policy, ¶m_ex); + if (ret) + return ret; + + if (cobalt_copy_to_user(u_param, ¶m_ex, sizeof(param_ex)) || + cobalt_copy_to_user(u_policy, &policy, sizeof(policy))) + return -EFAULT; + + return 0; +} + 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 4ccef3c..2b23be0 100644 --- a/kernel/cobalt/posix/sched.h +++ b/kernel/cobalt/posix/sched.h @@ -63,6 +63,10 @@ int cobalt_sched_setscheduler_ex(pid_t pid, __u32 __user *u_winoff, int __user *u_promoted); +int cobalt_sched_getscheduler_ex(pid_t pid, + int *policy_r, + struct sched_param_ex *param_ex); + struct xnsched_class * cobalt_sched_policy_param(union xnsched_policy_param *param, int u_policy, const struct sched_param_ex *param_ex, @@ -91,10 +95,15 @@ COBALT_SYSCALL_DECL(sched_getconfig_np, COBALT_SYSCALL_DECL(sched_setscheduler_ex, (pid_t pid, int policy, - const struct sched_param_ex *param_ex, + const struct sched_param_ex __user *u_param, __u32 __user *u_winoff, int __user *u_promoted)); +COBALT_SYSCALL_DECL(sched_getscheduler_ex, + (pid_t pid, + int __user *u_policy, + struct sched_param_ex __user *u_param)); + 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 fda93a9..d0af2cc 100644 --- a/kernel/cobalt/posix/syscall32.c +++ b/kernel/cobalt/posix/syscall32.c @@ -77,13 +77,15 @@ COBALT_SYSCALL32emu(thread_getschedparam_ex, current, struct compat_sched_param_ex __user *u_param)) { struct sched_param_ex param_ex; - int policy; + int ret, policy; - policy = __cobalt_thread_getschedparam_ex(pth, u_policy, ¶m_ex); - if (policy < 0) - return policy; + ret = cobalt_thread_getschedparam_ex(pth, &policy, ¶m_ex); + if (ret) + return ret; - return sys32_put_param_ex(policy, u_param, ¶m_ex); + ret = cobalt_copy_to_user(u_policy, &policy, sizeof(policy)); + + return ret ?: sys32_put_param_ex(policy, u_param, ¶m_ex); } static inline int sys32_fetch_timeout(struct timespec *ts, @@ -448,6 +450,23 @@ COBALT_SYSCALL32emu(sched_setscheduler_ex, conforming, u_winoff, u_promoted); } +COBALT_SYSCALL32emu(sched_getscheduler_ex, current, + (compat_pid_t pid, + int __user *u_policy, + struct compat_sched_param_ex __user *u_param)) +{ + struct sched_param_ex param_ex; + int ret, policy; + + ret = cobalt_sched_getscheduler_ex(pid, &policy, ¶m_ex); + if (ret) + return ret; + + ret = cobalt_copy_to_user(u_policy, &policy, sizeof(policy)); + + return ret ?: sys32_put_param_ex(policy, u_param, ¶m_ex); +} + 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 045e6be..64f0958 100644 --- a/kernel/cobalt/posix/syscall32.h +++ b/kernel/cobalt/posix/syscall32.h @@ -121,6 +121,11 @@ COBALT_SYSCALL32emu_DECL(sched_setscheduler_ex, __u32 __user *u_winoff, int __user *u_promoted)); +COBALT_SYSCALL32emu_DECL(sched_getscheduler_ex, + (compat_pid_t pid, + int __user *u_policy, + struct compat_sched_param_ex __user *u_param)); + 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 0fe2088..5886ceb 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -276,9 +276,9 @@ out: return ret; } -static inline int -pthread_getschedparam_ex(struct cobalt_thread *thread, - int *policy_r, struct sched_param_ex *param_ex) +int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread, + int *policy_r, + struct sched_param_ex *param_ex) { struct xnsched_class *base_class; struct xnthread *base_thread; @@ -289,13 +289,14 @@ pthread_getschedparam_ex(struct cobalt_thread *thread, if (!cobalt_obj_active(thread, COBALT_THREAD_MAGIC, struct cobalt_thread)) { xnlock_put_irqrestore(&nklock, s); - return ESRCH; + return -ESRCH; } base_thread = &thread->threadbase; base_class = base_thread->base_class; - param_ex->sched_priority = xnthread_base_priority(base_thread); *policy_r = base_class->policy; + + param_ex->sched_priority = xnthread_base_priority(base_thread); if (param_ex->sched_priority == 0) /* SCHED_FIFO/SCHED_WEAK */ *policy_r = SCHED_NORMAL; @@ -304,14 +305,14 @@ pthread_getschedparam_ex(struct cobalt_thread *thread, ns2ts(¶m_ex->sched_rr_quantum, base_thread->rrperiod); *policy_r = SCHED_RR; } - goto unlock_and_exit; + goto out; } #ifdef CONFIG_XENO_OPT_SCHED_WEAK if (base_class == &xnsched_class_weak) { if (*policy_r != SCHED_WEAK) param_ex->sched_priority = -param_ex->sched_priority; - goto unlock_and_exit; + goto out; } #endif #ifdef CONFIG_XENO_OPT_SCHED_SPORADIC @@ -320,25 +321,24 @@ pthread_getschedparam_ex(struct cobalt_thread *thread, ns2ts(¶m_ex->sched_ss_repl_period, base_thread->pss->param.repl_period); ns2ts(¶m_ex->sched_ss_init_budget, base_thread->pss->param.init_budget); param_ex->sched_ss_max_repl = base_thread->pss->param.max_repl; - goto unlock_and_exit; + goto out; } #endif #ifdef CONFIG_XENO_OPT_SCHED_TP if (base_class == &xnsched_class_tp) { param_ex->sched_tp_partition = base_thread->tps - base_thread->sched->tp.partitions; - goto unlock_and_exit; + goto out; } #endif #ifdef CONFIG_XENO_OPT_SCHED_QUOTA if (base_class == &xnsched_class_quota) { param_ex->sched_quota_group = base_thread->quota->tgid; - goto unlock_and_exit; + goto out; } #endif -unlock_and_exit: - +out: xnlock_put_irqrestore(&nklock, s); return 0; @@ -500,13 +500,13 @@ COBALT_SYSCALL(thread_setschedparam_ex, conforming, u_winoff, u_promoted); } -int __cobalt_thread_getschedparam_ex(unsigned long pth, - int __user *u_policy, - struct sched_param_ex *param_ex) +int cobalt_thread_getschedparam_ex(unsigned long pth, + int *policy_r, + struct sched_param_ex *param_ex) { struct cobalt_local_hkey hkey; struct cobalt_thread *thread; - int policy, ret; + int ret; hkey.u_pth = pth; hkey.mm = current->mm; @@ -514,34 +514,30 @@ int __cobalt_thread_getschedparam_ex(unsigned long pth, if (thread == NULL) return -ESRCH; - ret = pthread_getschedparam_ex(thread, &policy, param_ex); + ret = __cobalt_thread_getschedparam_ex(thread, policy_r, param_ex); if (ret) return ret; - trace_cobalt_pthread_getschedparam(pth, policy, param_ex); - - if (cobalt_copy_to_user(u_policy, &policy, sizeof(int))) - return -EFAULT; + trace_cobalt_pthread_getschedparam(pth, *policy_r, param_ex); - return policy; + return 0; } -/* - * NOTE: there is no cobalt_thread_getschedparam syscall defined by - * the Cobalt ABI. Useland retrieves scheduling parameters only via - * the extended cobalt_thread_getschedparam_ex syscall. - */ COBALT_SYSCALL(thread_getschedparam_ex, current, (unsigned long pth, int __user *u_policy, struct sched_param_ex __user *u_param)) { struct sched_param_ex param_ex; - int policy; + int ret, policy; + + ret = cobalt_thread_getschedparam_ex(pth, &policy, ¶m_ex); + if (ret) + return ret; - policy = __cobalt_thread_getschedparam_ex(pth, u_policy, ¶m_ex); - if (policy < 0) - return policy; + ret = cobalt_copy_to_user(u_policy, &policy, sizeof(policy)); + if (ret) + return ret; return cobalt_copy_to_user(u_param, ¶m_ex, sizeof(param_ex)); } diff --git a/kernel/cobalt/posix/thread.h b/kernel/cobalt/posix/thread.h index 1894774..abbb203 100644 --- a/kernel/cobalt/posix/thread.h +++ b/kernel/cobalt/posix/thread.h @@ -131,8 +131,12 @@ int cobalt_thread_setschedparam_ex(unsigned long pth, __u32 __user *u_winoff, int __user *u_promoted); -int __cobalt_thread_getschedparam_ex(unsigned long pth, - int __user *u_policy, +int cobalt_thread_getschedparam_ex(unsigned long pth, + int *policy_r, + struct sched_param_ex *param_ex); + +int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread, + int *policy_r, struct sched_param_ex *param_ex); struct cobalt_thread *cobalt_thread_find(pid_t pid); diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h index 9c2ae22..536108d 100644 --- a/kernel/cobalt/trace/cobalt-posix.h +++ b/kernel/cobalt/trace/cobalt-posix.h @@ -400,6 +400,11 @@ DEFINE_EVENT(cobalt_posix_scheduler, cobalt_sched_setscheduler, TP_ARGS(pid, policy, param_ex) ); +DEFINE_EVENT(cobalt_posix_pid, cobalt_sched_getscheduler, + TP_PROTO(pid_t pid), + TP_ARGS(pid) +); + 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