diff options
-rw-r--r-- | kernel/sched.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index f7dee2029e4d..2d4ff91e0c97 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -5378,8 +5378,7 @@ out_unlock: | |||
5378 | 5378 | ||
5379 | long sched_setaffinity(pid_t pid, const cpumask_t *in_mask) | 5379 | long sched_setaffinity(pid_t pid, const cpumask_t *in_mask) |
5380 | { | 5380 | { |
5381 | cpumask_t cpus_allowed; | 5381 | cpumask_var_t cpus_allowed, new_mask; |
5382 | cpumask_t new_mask = *in_mask; | ||
5383 | struct task_struct *p; | 5382 | struct task_struct *p; |
5384 | int retval; | 5383 | int retval; |
5385 | 5384 | ||
@@ -5401,6 +5400,14 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask) | |||
5401 | get_task_struct(p); | 5400 | get_task_struct(p); |
5402 | read_unlock(&tasklist_lock); | 5401 | read_unlock(&tasklist_lock); |
5403 | 5402 | ||
5403 | if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) { | ||
5404 | retval = -ENOMEM; | ||
5405 | goto out_put_task; | ||
5406 | } | ||
5407 | if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) { | ||
5408 | retval = -ENOMEM; | ||
5409 | goto out_free_cpus_allowed; | ||
5410 | } | ||
5404 | retval = -EPERM; | 5411 | retval = -EPERM; |
5405 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 5412 | if ((current->euid != p->euid) && (current->euid != p->uid) && |
5406 | !capable(CAP_SYS_NICE)) | 5413 | !capable(CAP_SYS_NICE)) |
@@ -5410,24 +5417,28 @@ long sched_setaffinity(pid_t pid, const cpumask_t *in_mask) | |||
5410 | if (retval) | 5417 | if (retval) |
5411 | goto out_unlock; | 5418 | goto out_unlock; |
5412 | 5419 | ||
5413 | cpuset_cpus_allowed(p, &cpus_allowed); | 5420 | cpuset_cpus_allowed(p, cpus_allowed); |
5414 | cpus_and(new_mask, new_mask, cpus_allowed); | 5421 | cpumask_and(new_mask, in_mask, cpus_allowed); |
5415 | again: | 5422 | again: |
5416 | retval = set_cpus_allowed_ptr(p, &new_mask); | 5423 | retval = set_cpus_allowed_ptr(p, new_mask); |
5417 | 5424 | ||
5418 | if (!retval) { | 5425 | if (!retval) { |
5419 | cpuset_cpus_allowed(p, &cpus_allowed); | 5426 | cpuset_cpus_allowed(p, cpus_allowed); |
5420 | if (!cpus_subset(new_mask, cpus_allowed)) { | 5427 | if (!cpumask_subset(new_mask, cpus_allowed)) { |
5421 | /* | 5428 | /* |
5422 | * We must have raced with a concurrent cpuset | 5429 | * We must have raced with a concurrent cpuset |
5423 | * update. Just reset the cpus_allowed to the | 5430 | * update. Just reset the cpus_allowed to the |
5424 | * cpuset's cpus_allowed | 5431 | * cpuset's cpus_allowed |
5425 | */ | 5432 | */ |
5426 | new_mask = cpus_allowed; | 5433 | cpumask_copy(new_mask, cpus_allowed); |
5427 | goto again; | 5434 | goto again; |
5428 | } | 5435 | } |
5429 | } | 5436 | } |
5430 | out_unlock: | 5437 | out_unlock: |
5438 | free_cpumask_var(new_mask); | ||
5439 | out_free_cpus_allowed: | ||
5440 | free_cpumask_var(cpus_allowed); | ||
5441 | out_put_task: | ||
5431 | put_task_struct(p); | 5442 | put_task_struct(p); |
5432 | put_online_cpus(); | 5443 | put_online_cpus(); |
5433 | return retval; | 5444 | return retval; |
@@ -5453,14 +5464,17 @@ static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len, | |||
5453 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, | 5464 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, |
5454 | unsigned long __user *user_mask_ptr) | 5465 | unsigned long __user *user_mask_ptr) |
5455 | { | 5466 | { |
5456 | cpumask_t new_mask; | 5467 | cpumask_var_t new_mask; |
5457 | int retval; | 5468 | int retval; |
5458 | 5469 | ||
5459 | retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask); | 5470 | if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) |
5460 | if (retval) | 5471 | return -ENOMEM; |
5461 | return retval; | ||
5462 | 5472 | ||
5463 | return sched_setaffinity(pid, &new_mask); | 5473 | retval = get_user_cpu_mask(user_mask_ptr, len, new_mask); |
5474 | if (retval == 0) | ||
5475 | retval = sched_setaffinity(pid, new_mask); | ||
5476 | free_cpumask_var(new_mask); | ||
5477 | return retval; | ||
5464 | } | 5478 | } |
5465 | 5479 | ||
5466 | long sched_getaffinity(pid_t pid, cpumask_t *mask) | 5480 | long sched_getaffinity(pid_t pid, cpumask_t *mask) |