]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.32 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 14 Apr 2010 23:29:44 +0000 (16:29 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 14 Apr 2010 23:29:44 +0000 (16:29 -0700)
queue-2.6.32/sched-fix-sched_getaffinity.patch [new file with mode: 0644]
queue-2.6.32/sched-sched_getaffinity-allow-less-than-nr_cpus-length.patch [new file with mode: 0644]
queue-2.6.32/series

diff --git a/queue-2.6.32/sched-fix-sched_getaffinity.patch b/queue-2.6.32/sched-fix-sched_getaffinity.patch
new file mode 100644 (file)
index 0000000..52ce2d2
--- /dev/null
@@ -0,0 +1,51 @@
+From 84fba5ec91f11c0efb27d0ed6098f7447491f0df Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Tue, 6 Apr 2010 17:02:19 +1000
+Subject: sched: Fix sched_getaffinity()
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 84fba5ec91f11c0efb27d0ed6098f7447491f0df upstream.
+
+taskset on 2.6.34-rc3 fails on one of my ppc64 test boxes with
+the following error:
+
+  sched_getaffinity(0, 16, 0x10029650030) = -1 EINVAL (Invalid argument)
+
+This box has 128 threads and 16 bytes is enough to cover it.
+
+Commit cd3d8031eb4311e516329aee03c79a08333141f1 (sched:
+sched_getaffinity(): Allow less than NR_CPUS length) is
+comparing this 16 bytes agains nr_cpu_ids.
+
+Fix it by comparing nr_cpu_ids to the number of bits in the
+cpumask we pass in.
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Cc: Sharyathi Nagesh <sharyath@in.ibm.com>
+Cc: Ulrich Drepper <drepper@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Russ Anderson <rja@sgi.com>
+Cc: Mike Travis <travis@sgi.com>
+LKML-Reference: <20100406070218.GM5594@kryten>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sched.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -6669,7 +6669,7 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t
+       int ret;
+       cpumask_var_t mask;
+-      if (len < nr_cpu_ids)
++      if ((len * BITS_PER_BYTE) < nr_cpu_ids)
+               return -EINVAL;
+       if (len & (sizeof(unsigned long)-1))
+               return -EINVAL;
diff --git a/queue-2.6.32/sched-sched_getaffinity-allow-less-than-nr_cpus-length.patch b/queue-2.6.32/sched-sched_getaffinity-allow-less-than-nr_cpus-length.patch
new file mode 100644 (file)
index 0000000..42898d1
--- /dev/null
@@ -0,0 +1,120 @@
+From cd3d8031eb4311e516329aee03c79a08333141f1 Mon Sep 17 00:00:00 2001
+From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Date: Fri, 12 Mar 2010 16:15:36 +0900
+Subject: sched: sched_getaffinity(): Allow less than NR_CPUS length
+
+From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+
+commit cd3d8031eb4311e516329aee03c79a08333141f1 upstream.
+
+[ Note, this commit changes the syscall ABI for > 1024 CPUs systems. ]
+
+Recently, some distro decided to use NR_CPUS=4096 for mysterious reasons.
+Unfortunately, glibc sched interface has the following definition:
+
+       # define __CPU_SETSIZE  1024
+       # define __NCPUBITS     (8 * sizeof (__cpu_mask))
+       typedef unsigned long int __cpu_mask;
+       typedef struct
+       {
+         __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
+       } cpu_set_t;
+
+It mean, if NR_CPUS is bigger than 1024, cpu_set_t makes an
+ABI issue ...
+
+More recently, Sharyathi Nagesh reported following test program makes
+misterious syscall failure:
+
+ -----------------------------------------------------------------------
+ #define _GNU_SOURCE
+ #include<stdio.h>
+ #include<errno.h>
+ #include<sched.h>
+
+ int main()
+ {
+     cpu_set_t set;
+     if (sched_getaffinity(0, sizeof(cpu_set_t), &set) < 0)
+         printf("\n Call is failing with:%d", errno);
+ }
+ -----------------------------------------------------------------------
+
+Because the kernel assumes len argument of sched_getaffinity() is bigger
+than NR_CPUS. But now it is not correct.
+
+Now we are faced with the following annoying dilemma, due to
+the limitations of the glibc interface built in years ago:
+
+ (1) if we change glibc's __CPU_SETSIZE definition, we lost
+     binary compatibility of _all_ application.
+
+ (2) if we don't change it, we also lost binary compatibility of
+     Sharyathi's use case.
+
+Then, I would propse to change the rule of the len argument of
+sched_getaffinity().
+
+Old:
+       len should be bigger than NR_CPUS
+New:
+       len should be bigger than maximum possible cpu id
+
+This creates the following behavior:
+
+ (A) In the real 4096 cpus machine, the above test program still
+     return -EINVAL.
+
+ (B) NR_CPUS=4096 but the machine have less than 1024 cpus (almost
+     all machines in the world), the above can run successfully.
+
+Fortunatelly, BIG SGI machine is mainly used for HPC use case. It means
+they can rebuild their programs.
+
+IOW we hope they are not annoyed by this issue ...
+
+Reported-by: Sharyathi Nagesh <sharyath@in.ibm.com>
+Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Acked-by: Ulrich Drepper <drepper@redhat.com>
+Acked-by: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Russ Anderson <rja@sgi.com>
+Cc: Mike Travis <travis@sgi.com>
+LKML-Reference: <20100312161316.9520.A69D9226@jp.fujitsu.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sched.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -6669,7 +6669,9 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t
+       int ret;
+       cpumask_var_t mask;
+-      if (len < cpumask_size())
++      if (len < nr_cpu_ids)
++              return -EINVAL;
++      if (len & (sizeof(unsigned long)-1))
+               return -EINVAL;
+       if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+@@ -6677,10 +6679,12 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t
+       ret = sched_getaffinity(pid, mask);
+       if (ret == 0) {
+-              if (copy_to_user(user_mask_ptr, mask, cpumask_size()))
++              int retlen = min(len, cpumask_size());
++
++              if (copy_to_user(user_mask_ptr, mask, retlen))
+                       ret = -EFAULT;
+               else
+-                      ret = cpumask_size();
++                      ret = retlen;
+       }
+       free_cpumask_var(mask);
index 016f15379ca2858f69ca88b7a3c69fce13604a7e..26ac8973c2855ad006bef79a5d85a669f1e150d1 100644 (file)
@@ -91,3 +91,5 @@ x86-32-resume-do-a-global-tlb-flush-in-s4-resume.patch
 x86-hpet-make-warn_on-understandable.patch
 x86-hpet-erratum-workaround-for-read-after-write-of-hpet-comparator.patch
 x86-fix-double-enable_ir_x2apic-call-on-smp-kernel-on-smp-boards.patch
+sched-sched_getaffinity-allow-less-than-nr_cpus-length.patch
+sched-fix-sched_getaffinity.patch