From: Jan Kiszka <jan.kis...@siemens.com> The approach of using thread_setschedparam_ex with __SCHED_CURRENT failed for policies with complex parameter sets. Therefore, introduce a syscall that is fully aware of how to apply only the priority change to the target thread's scheduling settings.
We need a compat path as well because we are passing down pointers. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- include/cobalt/uapi/syscall.h | 1 + .../arch/x86/include/asm/xenomai/syscall32-table.h | 1 + kernel/cobalt/posix/syscall32.c | 9 ++++++ kernel/cobalt/posix/syscall32.h | 6 ++++ kernel/cobalt/posix/thread.c | 37 ++++++++++++++++++++++ kernel/cobalt/posix/thread.h | 11 +++++++ kernel/cobalt/trace/cobalt-posix.h | 15 +++++++++ 7 files changed, 80 insertions(+) diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h index 1cb22a5936..aa3c308d0b 100644 --- a/include/cobalt/uapi/syscall.h +++ b/include/cobalt/uapi/syscall.h @@ -121,6 +121,7 @@ #define sc_cobalt_recvmmsg 98 #define sc_cobalt_sendmmsg 99 #define sc_cobalt_clock_adjtime 100 +#define sc_cobalt_thread_setschedprio 101 #define __NR_COBALT_SYSCALLS 128 /* Power of 2 */ 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 7484c3a955..4784377b06 100644 --- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h +++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h @@ -27,6 +27,7 @@ __COBALT_CALL32emu_THUNK(thread_create) __COBALT_CALL32emu_THUNK(thread_setschedparam_ex) __COBALT_CALL32emu_THUNK(thread_getschedparam_ex) +__COBALT_CALL32emu_THUNK(thread_setschedprio) __COBALT_CALL32emu_THUNK(sem_open) __COBALT_CALL32x_THUNK(sem_open) __COBALT_CALL32emu_THUNK(sem_timedwait) diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c index a2482b7a00..faa7ef53a6 100644 --- a/kernel/cobalt/posix/syscall32.c +++ b/kernel/cobalt/posix/syscall32.c @@ -88,6 +88,15 @@ COBALT_SYSCALL32emu(thread_getschedparam_ex, current, return ret ?: sys32_put_param_ex(policy, u_param, ¶m_ex); } +COBALT_SYSCALL32emu(thread_setschedprio, conforming, + (compat_ulong_t pth, + int prio, + __u32 __user *u_winoff, + int __user *u_promoted)) +{ + return cobalt_thread_setschedprio(pth, prio, u_winoff, u_promoted); +} + static inline int sys32_fetch_timeout(struct timespec *ts, const void __user *u_ts) { diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h index 5ba6513f38..34904f96bd 100644 --- a/kernel/cobalt/posix/syscall32.h +++ b/kernel/cobalt/posix/syscall32.h @@ -45,6 +45,12 @@ COBALT_SYSCALL32emu_DECL(thread_getschedparam_ex, int __user *u_policy, struct compat_sched_param_ex __user *u_param)); +COBALT_SYSCALL32emu_DECL(thread_setschedprio, + (compat_ulong_t pth, + int prio, + __u32 __user *u_winoff, + int __user *u_promoted)); + COBALT_SYSCALL32emu_DECL(clock_getres, (clockid_t clock_id, struct compat_timespec __user *u_ts)); diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c index 9f1c802b63..c2a9fb46c5 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -568,6 +568,43 @@ COBALT_SYSCALL(thread_getschedparam_ex, current, return cobalt_copy_to_user(u_param, ¶m_ex, sizeof(param_ex)); } +int cobalt_thread_setschedprio(unsigned long pth, + int prio, + __u32 __user *u_winoff, + int __user *u_promoted) +{ + struct sched_param_ex param_ex; + struct cobalt_thread *thread; + int ret, policy, promoted; + + trace_cobalt_pthread_setschedprio(pth, prio); + + thread = thread_lookup_or_shadow(pth, u_winoff, &promoted); + if (IS_ERR(thread)) + return PTR_ERR(thread); + + ret = __cobalt_thread_getschedparam_ex(thread, &policy, ¶m_ex); + if (ret) + return ret; + + param_ex.sched_priority = prio; + + ret = __cobalt_thread_setschedparam_ex(thread, policy, ¶m_ex); + if (ret) + return ret; + + return cobalt_copy_to_user(u_promoted, &promoted, sizeof(promoted)); +} + +COBALT_SYSCALL(thread_setschedprio, conforming, + (unsigned long pth, + int prio, + __u32 __user *u_winoff, + int __user *u_promoted)) +{ + return cobalt_thread_setschedprio(pth, prio, u_winoff, u_promoted); +} + int __cobalt_thread_create(unsigned long pth, int policy, struct sched_param_ex *param_ex, int xid, __u32 __user *u_winoff) diff --git a/kernel/cobalt/posix/thread.h b/kernel/cobalt/posix/thread.h index fec9d17859..51be372a7a 100644 --- a/kernel/cobalt/posix/thread.h +++ b/kernel/cobalt/posix/thread.h @@ -139,6 +139,11 @@ int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread, int *policy_r, struct sched_param_ex *param_ex); +int cobalt_thread_setschedprio(unsigned long pth, + int prio, + __u32 __user *u_winoff, + int __user *u_promoted); + struct cobalt_thread *cobalt_thread_find(pid_t pid); struct cobalt_thread *cobalt_thread_find_local(pid_t pid); @@ -181,6 +186,12 @@ COBALT_SYSCALL_DECL(thread_getschedparam_ex, int __user *u_policy, struct sched_param_ex __user *u_param)); +COBALT_SYSCALL_DECL(thread_setschedprio, + (unsigned long pth, + int prio, + __u32 __user *u_winoff, + int __user *u_promoted)); + void cobalt_thread_map(struct xnthread *curr); struct xnthread_personality *cobalt_thread_exit(struct xnthread *curr); diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h index bda7bdd3c8..83ec748586 100644 --- a/kernel/cobalt/trace/cobalt-posix.h +++ b/kernel/cobalt/trace/cobalt-posix.h @@ -70,6 +70,7 @@ __cobalt_symbolic_syscall(thread_kill), \ __cobalt_symbolic_syscall(thread_setschedparam_ex), \ __cobalt_symbolic_syscall(thread_getschedparam_ex), \ + __cobalt_symbolic_syscall(thread_setschedprio), \ __cobalt_symbolic_syscall(thread_getstat), \ __cobalt_symbolic_syscall(sem_init), \ __cobalt_symbolic_syscall(sem_destroy), \ @@ -311,6 +312,20 @@ DEFINE_EVENT(cobalt_posix_schedparam, cobalt_pthread_getschedparam, TP_ARGS(pth, policy, param_ex) ); +TRACE_EVENT(cobalt_pthread_setschedprio, + TP_PROTO(unsigned long pth, int prio), + TP_ARGS(pth, prio), + TP_STRUCT__entry( + __field(unsigned long, pth) + __field(int, prio) + ), + TP_fast_assign( + __entry->pth = pth; + __entry->prio = prio; + ), + TP_printk("pth=%p prio=%d", (void *)__entry->pth, __entry->prio) +); + #define cobalt_print_thread_mode(__mode) \ __print_flags(__mode, "|", \ {PTHREAD_WARNSW, "warnsw"}, \ -- 2.16.4