Commit 22e962f9 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] cpu affinity syscalls

This patch implements the following calls to set and retrieve a task's
CPU affinity:

    int sched_setaffinity(pid_t pid, unsigned int len,
    				      unsigned long *new_mask_ptr)
    int ched_getaffinity(pid_t pid, unsigned int len,
    				      unsigned long *user_mask_ptr)
parent b96ad24a
......@@ -779,6 +779,8 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_tkill)
.long SYMBOL_NAME(sys_sendfile64)
.long SYMBOL_NAME(sys_futex) /* 240 */
.long SYMBOL_NAME(sys_sched_setaffinity)
.long SYMBOL_NAME(sys_sched_getaffinity)
.rept NR_syscalls-(.-sys_call_table)/4
.long SYMBOL_NAME(sys_ni_syscall)
......
......@@ -245,6 +245,8 @@
#define __NR_tkill 238
#define __NR_sendfile64 239
#define __NR_futex 240
#define __NR_sched_setaffinity 241
#define __NR_sched_getaffinity 242
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
......
......@@ -1234,6 +1234,96 @@ asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param *param)
return retval;
}
/**
* sys_sched_setaffinity - set the cpu affinity of a process
* @pid: pid of the process
* @len: length of new_mask
* @new_mask: user-space pointer to the new cpu mask
*/
asmlinkage int sys_sched_setaffinity(pid_t pid, unsigned int len,
unsigned long *new_mask_ptr)
{
unsigned long new_mask;
task_t *p;
int retval;
if (len < sizeof(new_mask))
return -EINVAL;
if (copy_from_user(&new_mask, new_mask_ptr, sizeof(new_mask)))
return -EFAULT;
new_mask &= cpu_online_map;
if (!new_mask)
return -EINVAL;
read_lock(&tasklist_lock);
p = find_process_by_pid(pid);
if (!p) {
read_unlock(&tasklist_lock);
return -ESRCH;
}
/*
* It is not safe to call set_cpus_allowed with the
* tasklist_lock held. We will bump the task_struct's
* usage count and then drop tasklist_lock.
*/
get_task_struct(p);
read_unlock(&tasklist_lock);
retval = -EPERM;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
!capable(CAP_SYS_NICE))
goto out_unlock;
retval = 0;
set_cpus_allowed(p, new_mask);
out_unlock:
put_task_struct(p);
return retval;
}
/**
* sys_sched_getaffinity - get the cpu affinity of a process
* @pid: pid of the process
* @len: length of the new mask
* @user_mask_ptr: userspace pointer to the mask
*/
asmlinkage int sys_sched_getaffinity(pid_t pid, unsigned int len,
unsigned long *user_mask_ptr)
{
unsigned long mask;
unsigned int real_len;
task_t *p;
int retval;
real_len = sizeof(mask);
if (len < real_len)
return -EINVAL;
read_lock(&tasklist_lock);
retval = -ESRCH;
p = find_process_by_pid(pid);
if (!p)
goto out_unlock;
retval = 0;
mask = p->cpus_allowed & cpu_online_map;
out_unlock:
read_unlock(&tasklist_lock);
if (retval)
return retval;
if (copy_to_user(user_mask_ptr, &mask, real_len))
return -EFAULT;
return real_len;
}
asmlinkage long sys_sched_yield(void)
{
runqueue_t *rq;
......
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