Commit fcbfaf4b authored by Jan Kiszka's avatar Jan Kiszka

cobalt/posix: Add thread_setschedprio

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's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 33e64f41
......@@ -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 */
......
......@@ -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)
......
......@@ -88,6 +88,15 @@ COBALT_SYSCALL32emu(thread_getschedparam_ex, current,
return ret ?: sys32_put_param_ex(policy, u_param, &param_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)
{
......
......@@ -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));
......
......@@ -568,6 +568,43 @@ COBALT_SYSCALL(thread_getschedparam_ex, current,
return cobalt_copy_to_user(u_param, &param_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, &param_ex);
if (ret)
return ret;
param_ex.sched_priority = prio;
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(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)
......
......@@ -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);
......
......@@ -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"}, \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment