]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Sep 2012 17:24:17 +0000 (10:24 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Sep 2012 17:24:17 +0000 (10:24 -0700)
added patches:
powerpc-fix-dscr-inheritance-in-copy_thread.patch
powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch
powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch
powerpc-restore-correct-dscr-in-context-switch.patch
powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch
remove-user-triggerable-bug-from-mpol_to_str.patch

queue-3.5/powerpc-fix-dscr-inheritance-in-copy_thread.patch [new file with mode: 0644]
queue-3.5/powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch [new file with mode: 0644]
queue-3.5/powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch [new file with mode: 0644]
queue-3.5/powerpc-restore-correct-dscr-in-context-switch.patch [new file with mode: 0644]
queue-3.5/powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch [new file with mode: 0644]
queue-3.5/remove-user-triggerable-bug-from-mpol_to_str.patch [new file with mode: 0644]
queue-3.5/series

diff --git a/queue-3.5/powerpc-fix-dscr-inheritance-in-copy_thread.patch b/queue-3.5/powerpc-fix-dscr-inheritance-in-copy_thread.patch
new file mode 100644 (file)
index 0000000..35b157f
--- /dev/null
@@ -0,0 +1,50 @@
+From 1021cb268b3025573c4811f1dee4a11260c4507b Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 3 Sep 2012 16:49:47 +0000
+Subject: powerpc: Fix DSCR inheritance in copy_thread()
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 1021cb268b3025573c4811f1dee4a11260c4507b upstream.
+
+If the default DSCR is non zero we set thread.dscr_inherit in
+copy_thread() meaning the new thread and all its children will ignore
+future updates to the default DSCR. This is not intended and is
+a change in behaviour that a number of our users have hit.
+
+We just need to inherit thread.dscr and thread.dscr_inherit from
+the parent which ends up being much simpler.
+
+This was found with the following test case:
+
+http://ozlabs.org/~anton/junkcode/dscr_default_test.c
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/process.c |   12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -802,16 +802,8 @@ int copy_thread(unsigned long clone_flag
+ #endif /* CONFIG_PPC_STD_MMU_64 */
+ #ifdef CONFIG_PPC64 
+       if (cpu_has_feature(CPU_FTR_DSCR)) {
+-              if (current->thread.dscr_inherit) {
+-                      p->thread.dscr_inherit = 1;
+-                      p->thread.dscr = current->thread.dscr;
+-              } else if (0 != dscr_default) {
+-                      p->thread.dscr_inherit = 1;
+-                      p->thread.dscr = dscr_default;
+-              } else {
+-                      p->thread.dscr_inherit = 0;
+-                      p->thread.dscr = 0;
+-              }
++              p->thread.dscr_inherit = current->thread.dscr_inherit;
++              p->thread.dscr = current->thread.dscr;
+       }
+ #endif
diff --git a/queue-3.5/powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch b/queue-3.5/powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch
new file mode 100644 (file)
index 0000000..3d586e1
--- /dev/null
@@ -0,0 +1,58 @@
+From 00ca0de02f80924dfff6b4f630e1dff3db005e35 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 3 Sep 2012 16:48:46 +0000
+Subject: powerpc: Keep thread.dscr and thread.dscr_inherit in sync
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 00ca0de02f80924dfff6b4f630e1dff3db005e35 upstream.
+
+When we update the DSCR either via emulation of mtspr(DSCR) or via
+a change to dscr_default in sysfs we don't update thread.dscr.
+We will eventually update it at context switch time but there is
+a period where thread.dscr is incorrect.
+
+If we fork at this point we will copy the old value of thread.dscr
+into the child. To avoid this, always keep thread.dscr in sync with
+reality.
+
+This issue was found with the following testcase:
+
+http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/sysfs.c |    4 +++-
+ arch/powerpc/kernel/traps.c |    3 ++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -196,8 +196,10 @@ static ssize_t show_dscr_default(struct
+ static void update_dscr(void *dummy)
+ {
+-      if (!current->thread.dscr_inherit)
++      if (!current->thread.dscr_inherit) {
++              current->thread.dscr = dscr_default;
+               mtspr(SPRN_DSCR, dscr_default);
++      }
+ }
+ static ssize_t __used store_dscr_default(struct device *dev,
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -972,8 +972,9 @@ static int emulate_instruction(struct pt
+                       cpu_has_feature(CPU_FTR_DSCR)) {
+               PPC_WARN_EMULATED(mtdscr, regs);
+               rd = (instword >> 21) & 0x1f;
+-              mtspr(SPRN_DSCR, regs->gpr[rd]);
++              current->thread.dscr = regs->gpr[rd];
+               current->thread.dscr_inherit = 1;
++              mtspr(SPRN_DSCR, current->thread.dscr);
+               return 0;
+       }
+ #endif
diff --git a/queue-3.5/powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch b/queue-3.5/powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch
new file mode 100644 (file)
index 0000000..e832410
--- /dev/null
@@ -0,0 +1,108 @@
+From 9fb1b36ca1234e64a5d1cc573175303395e3354d Mon Sep 17 00:00:00 2001
+From: Paul Mackerras <paulus@samba.org>
+Date: Tue, 4 Sep 2012 18:33:08 +0000
+Subject: powerpc: Make sure IPI handlers see data written by IPI senders
+
+From: Paul Mackerras <paulus@samba.org>
+
+commit 9fb1b36ca1234e64a5d1cc573175303395e3354d upstream.
+
+We have been observing hangs, both of KVM guest vcpu tasks and more
+generally, where a process that is woken doesn't properly wake up and
+continue to run, but instead sticks in TASK_WAKING state.  This
+happens because the update of rq->wake_list in ttwu_queue_remote()
+is not ordered with the update of ipi_message in
+smp_muxed_ipi_message_pass(), and the reading of rq->wake_list in
+scheduler_ipi() is not ordered with the reading of ipi_message in
+smp_ipi_demux().  Thus it is possible for the IPI receiver not to see
+the updated rq->wake_list and therefore conclude that there is nothing
+for it to do.
+
+In order to make sure that anything done before smp_send_reschedule()
+is ordered before anything done in the resulting call to scheduler_ipi(),
+this adds barriers in smp_muxed_message_pass() and smp_ipi_demux().
+The barrier in smp_muxed_message_pass() is a full barrier to ensure that
+there is a full ordering between the smp_send_reschedule() caller and
+scheduler_ipi().  In smp_ipi_demux(), we use xchg() rather than
+xchg_local() because xchg() includes release and acquire barriers.
+Using xchg() rather than xchg_local() makes sense given that
+ipi_message is not just accessed locally.
+
+This moves the barrier between setting the message and calling the
+cause_ipi() function into the individual cause_ipi implementations.
+Most of them -- those that used outb, out_8 or similar -- already had
+a full barrier because out_8 etc. include a sync before the MMIO
+store.  This adds an explicit barrier in the two remaining cases.
+
+These changes made no measurable difference to the speed of IPIs as
+measured using a simple ping-pong latency test across two CPUs on
+different cores of a POWER7 machine.
+
+The analysis of the reason why processes were not waking up properly
+is due to Milton Miller.
+
+Reported-by: Milton Miller <miltonm@bga.com>
+Signed-off-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/dbell.c       |    2 ++
+ arch/powerpc/kernel/smp.c         |   11 +++++++++--
+ arch/powerpc/sysdev/xics/icp-hv.c |    6 +++++-
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+--- a/arch/powerpc/kernel/dbell.c
++++ b/arch/powerpc/kernel/dbell.c
+@@ -28,6 +28,8 @@ void doorbell_setup_this_cpu(void)
+ void doorbell_cause_ipi(int cpu, unsigned long data)
+ {
++      /* Order previous accesses vs. msgsnd, which is treated as a store */
++      mb();
+       ppc_msgsnd(PPC_DBELL, 0, data);
+ }
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -197,8 +197,15 @@ void smp_muxed_ipi_message_pass(int cpu,
+       struct cpu_messages *info = &per_cpu(ipi_message, cpu);
+       char *message = (char *)&info->messages;
++      /*
++       * Order previous accesses before accesses in the IPI handler.
++       */
++      smp_mb();
+       message[msg] = 1;
+-      mb();
++      /*
++       * cause_ipi functions are required to include a full barrier
++       * before doing whatever causes the IPI.
++       */
+       smp_ops->cause_ipi(cpu, info->data);
+ }
+@@ -210,7 +217,7 @@ irqreturn_t smp_ipi_demux(void)
+       mb();   /* order any irq clear */
+       do {
+-              all = xchg_local(&info->messages, 0);
++              all = xchg(&info->messages, 0);
+ #ifdef __BIG_ENDIAN
+               if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION)))
+--- a/arch/powerpc/sysdev/xics/icp-hv.c
++++ b/arch/powerpc/sysdev/xics/icp-hv.c
+@@ -65,7 +65,11 @@ static inline void icp_hv_set_xirr(unsig
+ static inline void icp_hv_set_qirr(int n_cpu , u8 value)
+ {
+       int hw_cpu = get_hard_smp_processor_id(n_cpu);
+-      long rc = plpar_hcall_norets(H_IPI, hw_cpu, value);
++      long rc;
++
++      /* Make sure all previous accesses are ordered before IPI sending */
++      mb();
++      rc = plpar_hcall_norets(H_IPI, hw_cpu, value);
+       if (rc != H_SUCCESS) {
+               pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x "
+                       "returned %ld\n", __func__, n_cpu, hw_cpu, value, rc);
diff --git a/queue-3.5/powerpc-restore-correct-dscr-in-context-switch.patch b/queue-3.5/powerpc-restore-correct-dscr-in-context-switch.patch
new file mode 100644 (file)
index 0000000..628c0ad
--- /dev/null
@@ -0,0 +1,99 @@
+From 714332858bfd40dcf8f741498336d93875c23aa7 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 3 Sep 2012 16:51:10 +0000
+Subject: powerpc: Restore correct DSCR in context switch
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 714332858bfd40dcf8f741498336d93875c23aa7 upstream.
+
+During a context switch we always restore the per thread DSCR value.
+If we aren't doing explicit DSCR management
+(ie thread.dscr_inherit == 0) and the default DSCR changed while
+the process has been sleeping we end up with the wrong value.
+
+Check thread.dscr_inherit and select the default DSCR or per thread
+DSCR as required.
+
+This was found with the following test case, when running with
+more threads than CPUs (ie forcing context switching):
+
+http://ozlabs.org/~anton/junkcode/dscr_default_test.c
+
+With the four patches applied I can run a combination of all
+test cases successfully at the same time:
+
+http://ozlabs.org/~anton/junkcode/dscr_default_test.c
+http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
+http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/asm-offsets.c |    1 +
+ arch/powerpc/kernel/entry_64.S    |   23 +++++++++++++++++------
+ 2 files changed, 18 insertions(+), 6 deletions(-)
+
+--- a/arch/powerpc/kernel/asm-offsets.c
++++ b/arch/powerpc/kernel/asm-offsets.c
+@@ -76,6 +76,7 @@ int main(void)
+       DEFINE(SIGSEGV, SIGSEGV);
+       DEFINE(NMI_MASK, NMI_MASK);
+       DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr));
++      DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit));
+ #else
+       DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
+ #endif /* CONFIG_PPC64 */
+--- a/arch/powerpc/kernel/entry_64.S
++++ b/arch/powerpc/kernel/entry_64.S
+@@ -369,6 +369,12 @@ _GLOBAL(ret_from_fork)
+       li      r3,0
+       b       syscall_exit
++      .section        ".toc","aw"
++DSCR_DEFAULT:
++      .tc dscr_default[TC],dscr_default
++
++      .section        ".text"
++
+ /*
+  * This routine switches between two different tasks.  The process
+  * state of one is saved on its kernel stack.  Then the state
+@@ -508,9 +514,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG
+       mr      r1,r8           /* start using new stack pointer */
+       std     r7,PACAKSAVE(r13)
+-      ld      r6,_CCR(r1)
+-      mtcrf   0xFF,r6
+-
+ #ifdef CONFIG_ALTIVEC
+ BEGIN_FTR_SECTION
+       ld      r0,THREAD_VRSAVE(r4)
+@@ -519,14 +522,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ #endif /* CONFIG_ALTIVEC */
+ #ifdef CONFIG_PPC64
+ BEGIN_FTR_SECTION
++      lwz     r6,THREAD_DSCR_INHERIT(r4)
++      ld      r7,DSCR_DEFAULT@toc(2)
+       ld      r0,THREAD_DSCR(r4)
+-      cmpd    r0,r25
+-      beq     1f
++      cmpwi   r6,0
++      bne     1f
++      ld      r0,0(r7)
++1:    cmpd    r0,r25
++      beq     2f
+       mtspr   SPRN_DSCR,r0
+-1:    
++2:
+ END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
+ #endif
++      ld      r6,_CCR(r1)
++      mtcrf   0xFF,r6
++
+       /* r3-r13 are destroyed -- Cort */
+       REST_8GPRS(14, r1)
+       REST_10GPRS(22, r1)
diff --git a/queue-3.5/powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch b/queue-3.5/powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch
new file mode 100644 (file)
index 0000000..63cb5b1
--- /dev/null
@@ -0,0 +1,50 @@
+From 1b6ca2a6fe56e7697d57348646e07df08f43b1bb Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 3 Sep 2012 16:47:56 +0000
+Subject: powerpc: Update DSCR on all CPUs when writing sysfs dscr_default
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 1b6ca2a6fe56e7697d57348646e07df08f43b1bb upstream.
+
+Writing to dscr_default in sysfs doesn't actually change the DSCR -
+we rely on a context switch on each CPU to do the work. There is no
+guarantee we will get a context switch in a reasonable amount of time
+so fire off an IPI to force an immediate change.
+
+This issue was found with the following test case:
+
+http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/sysfs.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -194,6 +194,12 @@ static ssize_t show_dscr_default(struct
+       return sprintf(buf, "%lx\n", dscr_default);
+ }
++static void update_dscr(void *dummy)
++{
++      if (!current->thread.dscr_inherit)
++              mtspr(SPRN_DSCR, dscr_default);
++}
++
+ static ssize_t __used store_dscr_default(struct device *dev,
+               struct device_attribute *attr, const char *buf,
+               size_t count)
+@@ -206,6 +212,8 @@ static ssize_t __used store_dscr_default
+               return -EINVAL;
+       dscr_default = val;
++      on_each_cpu(update_dscr, NULL, 1);
++
+       return count;
+ }
diff --git a/queue-3.5/remove-user-triggerable-bug-from-mpol_to_str.patch b/queue-3.5/remove-user-triggerable-bug-from-mpol_to_str.patch
new file mode 100644 (file)
index 0000000..fa8f07b
--- /dev/null
@@ -0,0 +1,42 @@
+From 80de7c3138ee9fd86a98696fd2cf7ad89b995d0a Mon Sep 17 00:00:00 2001
+From: Dave Jones <davej@redhat.com>
+Date: Thu, 6 Sep 2012 12:01:00 -0400
+Subject: Remove user-triggerable BUG from mpol_to_str
+
+From: Dave Jones <davej@redhat.com>
+
+commit 80de7c3138ee9fd86a98696fd2cf7ad89b995d0a upstream.
+
+Trivially triggerable, found by trinity:
+
+  kernel BUG at mm/mempolicy.c:2546!
+  Process trinity-child2 (pid: 23988, threadinfo ffff88010197e000, task ffff88007821a670)
+  Call Trace:
+    show_numa_map+0xd5/0x450
+    show_pid_numa_map+0x13/0x20
+    traverse+0xf2/0x230
+    seq_read+0x34b/0x3e0
+    vfs_read+0xac/0x180
+    sys_pread64+0xa2/0xc0
+    system_call_fastpath+0x1a/0x1f
+  RIP: mpol_to_str+0x156/0x360
+
+Signed-off-by: Dave Jones <davej@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/mempolicy.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -2556,7 +2556,7 @@ int mpol_to_str(char *buffer, int maxlen
+               break;
+       default:
+-              BUG();
++              return -EINVAL;
+       }
+       l = strlen(policy_modes[mode]);
index e77ac88205840895fe785aba040c1a8a47f1256b..35571a9f7694434d69fdb732d229f0b6102de177 100644 (file)
@@ -75,3 +75,9 @@ alsa-snd-usb-use-list_for_each_safe-for-endpoint-resources.patch
 alsa-snd-usb-restore-delay-information.patch
 alsa-snd-usb-fix-calls-to-next_packet_size.patch
 alsa-snd-usb-fix-cross-interface-streaming-devices.patch
+powerpc-update-dscr-on-all-cpus-when-writing-sysfs-dscr_default.patch
+powerpc-keep-thread.dscr-and-thread.dscr_inherit-in-sync.patch
+powerpc-fix-dscr-inheritance-in-copy_thread.patch
+powerpc-restore-correct-dscr-in-context-switch.patch
+powerpc-make-sure-ipi-handlers-see-data-written-by-ipi-senders.patch
+remove-user-triggerable-bug-from-mpol_to_str.patch