From 5dfb68819166b2328c2b90f456b98d3c3ff552d3 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Sun, 16 Mar 2008 16:27:44 +0000 Subject: [PATCH] Implement sched_setaffinity and get_setaffinity using real cpu affinity setting primitives. Reviewed by: jeff Approved by: kib (mentor) --- sys/amd64/linux32/syscalls.master | 3 +- sys/compat/linux/linux_misc.c | 49 +++++++++++++++++++++++++------ sys/i386/linux/syscalls.master | 3 +- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master index 1dd6e9c964b..86350c91b6e 100644 --- a/sys/amd64/linux32/syscalls.master +++ b/sys/amd64/linux32/syscalls.master @@ -407,7 +407,8 @@ 239 AUE_SENDFILE UNIMPL linux_sendfile64 240 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, int val, \ struct l_timespec *timeout, void *uaddr2, int val3); } -241 AUE_NULL UNIMPL linux_sched_setaffinity +241 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \ + l_ulong *user_mask_ptr); } 242 AUE_NULL STD { int linux_sched_getaffinity(l_pid_t pid, l_uint len, \ l_ulong *user_mask_ptr); } 243 AUE_NULL STD { int linux_set_thread_area(struct l_user_desc *desc); } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index ee06e78463a..1e124484874 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -1730,22 +1731,52 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args) } /* - * XXX: fake one.. waiting for real implementation of affinity mask. + * Get affinity of a process. */ int linux_sched_getaffinity(struct thread *td, struct linux_sched_getaffinity_args *args) { int error; - cpumask_t i = ~0; + struct cpuset_getaffinity_args cga; - if (args->len < sizeof(cpumask_t)) - return (EINVAL); +#ifdef DEBUG + if (ldebug(sched_getaffinity)) + printf(ARGS(sched_getaffinity, "%d, %d, *"), args->pid, + args->len); +#endif - error = copyout(&i, args->user_mask_ptr, sizeof(cpumask_t)); - if (error) - return (EFAULT); + cga.level = CPU_LEVEL_WHICH; + cga.which = CPU_WHICH_PID; + cga.id = args->pid; + cga.cpusetsize = sizeof(cpumask_t); + cga.mask = (long *) args->user_mask_ptr; + + if ((error = cpuset_getaffinity(td, &cga)) == 0) + td->td_retval[0] = sizeof(cpumask_t); - td->td_retval[0] = sizeof(cpumask_t); - return (0); + return (error); +} + +/* + * Set affinity of a process. + */ +int +linux_sched_setaffinity(struct thread *td, + struct linux_sched_setaffinity_args *args) +{ + struct cpuset_setaffinity_args csa; + +#ifdef DEBUG + if (ldebug(sched_setaffinity)) + printf(ARGS(sched_setaffinity, "%d, %d, *"), args->pid, + args->len); +#endif + csa.level = CPU_LEVEL_WHICH; + csa.which = CPU_WHICH_PID; + csa.id = args->pid; + csa.cpusetsize = args->len; + csa.mask = (long *) args->user_mask_ptr; + + return (cpuset_setaffinity(td, &csa)); } diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master index 9692fe4e0e8..af0755aedc5 100644 --- a/sys/i386/linux/syscalls.master +++ b/sys/i386/linux/syscalls.master @@ -409,7 +409,8 @@ 239 AUE_SENDFILE UNIMPL linux_sendfile64 240 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, int val, \ struct l_timespec *timeout, void *uaddr2, int val3); } -241 AUE_NULL UNIMPL linux_sched_setaffinity +241 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \ + l_ulong *user_mask_ptr); } 242 AUE_NULL STD { int linux_sched_getaffinity(l_pid_t pid, l_uint len, \ l_ulong *user_mask_ptr); } 243 AUE_NULL STD { int linux_set_thread_area(struct l_user_desc *desc); }