Commit 507c4d17 authored by Philippe Gerum's avatar Philippe Gerum
Browse files

cobalt/posix/sched: add support for sched_setscheduler(2)

parent 7594a861
......@@ -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)
......
......@@ -731,6 +731,60 @@ COBALT_SYSCALL(sched_weightprio, current,
return __cobalt_sched_weightprio(policy, &param_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(&param_ex, u_param, sizeof(param_ex)))
return -EFAULT;
return cobalt_sched_setscheduler_ex(pid, policy, &param_ex,
u_winoff, u_promoted);
}
void cobalt_sched_reclaim(struct cobalt_process *process)
{
struct cobalt_resources *p = &process->resources;
......
......@@ -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 */
......@@ -67,8 +67,8 @@ COBALT_SYSCALL32emu(thread_setschedparam_ex, conforming,
if (ret)
return ret;
return __cobalt_thread_setschedparam_ex(pth, policy, &param_ex,
u_winoff, u_promoted);
return cobalt_thread_setschedparam_ex(pth, policy, &param_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, &param_ex, u_param_ex);
if (ret)
return ret;
return cobalt_sched_setscheduler_ex(pid, policy, &param_ex,
u_winoff, u_promoted);
}
COBALT_SYSCALL32emu(timer_create, current,
(clockid_t clock,
const struct compat_sigevent __user *u_sev,
......
......@@ -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,
......
......@@ -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(&param_ex, u_param, sizeof(param_ex)))
return -EFAULT;
return __cobalt_thread_setschedparam_ex(pth, policy, &param_ex,
u_winoff, u_promoted);
return cobalt_thread_setschedparam_ex(pth, policy, &param_ex,
u_winoff, u_promoted);
}
int __cobalt_thread_getschedparam_ex(unsigned long pth,
......
......@@ -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,
......
......@@ -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),
......
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