]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Oct 2013 18:48:50 +0000 (11:48 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Oct 2013 18:48:50 +0000 (11:48 -0700)
added patches:
0310-ALSA-hda-Fix-mono-speakers-and-headset-mic-on-Dell-V.patch
compiler-gcc4-add-quirk-for-asm-goto-miscompilation-bug.patch
cope-with-potentially-long-d_dname-output-for.patch
drm-i915-only-apply-dpms-to-the-encoder-if-enabled.patch
drm-radeon-fix-hw-contexts-for-sumo2-asics.patch
drm-radeon-fix-typo-in-cp-dma-register-headers.patch
drm-radeon-forever-loop-on-error-in-radeon_do_test_moves.patch
ipc-close-open-coded-spin-lock-calls.patch
ipc-introduce-ipc-object-locking-helpers.patch
ipc-move-locking-out-of-ipcctl_pre_down_nolock.patch
ipc-move-rcu-lock-out-of-ipc_addid.patch
ipc-msg-introduce-lockless-functions-to-obtain-the-ipc-object.patch
ipc-msg-introduce-msgctl_nolock.patch
ipc-msg-make-msgctl_nolock-lockless.patch
ipc-msg-shorten-critical-region-in-msgctl_down.patch
ipc-msg-shorten-critical-region-in-msgrcv.patch
ipc-msg-shorten-critical-region-in-msgsnd.patch
ipc-remove-unused-functions.patch

19 files changed:
queue-3.10/0310-ALSA-hda-Fix-mono-speakers-and-headset-mic-on-Dell-V.patch [new file with mode: 0644]
queue-3.10/compiler-gcc4-add-quirk-for-asm-goto-miscompilation-bug.patch [new file with mode: 0644]
queue-3.10/cope-with-potentially-long-d_dname-output-for.patch [new file with mode: 0644]
queue-3.10/drm-i915-only-apply-dpms-to-the-encoder-if-enabled.patch [new file with mode: 0644]
queue-3.10/drm-radeon-fix-hw-contexts-for-sumo2-asics.patch [new file with mode: 0644]
queue-3.10/drm-radeon-fix-typo-in-cp-dma-register-headers.patch [new file with mode: 0644]
queue-3.10/drm-radeon-forever-loop-on-error-in-radeon_do_test_moves.patch [new file with mode: 0644]
queue-3.10/ipc-close-open-coded-spin-lock-calls.patch [new file with mode: 0644]
queue-3.10/ipc-introduce-ipc-object-locking-helpers.patch [new file with mode: 0644]
queue-3.10/ipc-move-locking-out-of-ipcctl_pre_down_nolock.patch [new file with mode: 0644]
queue-3.10/ipc-move-rcu-lock-out-of-ipc_addid.patch [new file with mode: 0644]
queue-3.10/ipc-msg-introduce-lockless-functions-to-obtain-the-ipc-object.patch [new file with mode: 0644]
queue-3.10/ipc-msg-introduce-msgctl_nolock.patch [new file with mode: 0644]
queue-3.10/ipc-msg-make-msgctl_nolock-lockless.patch [new file with mode: 0644]
queue-3.10/ipc-msg-shorten-critical-region-in-msgctl_down.patch [new file with mode: 0644]
queue-3.10/ipc-msg-shorten-critical-region-in-msgrcv.patch [new file with mode: 0644]
queue-3.10/ipc-msg-shorten-critical-region-in-msgsnd.patch [new file with mode: 0644]
queue-3.10/ipc-remove-unused-functions.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/0310-ALSA-hda-Fix-mono-speakers-and-headset-mic-on-Dell-V.patch b/queue-3.10/0310-ALSA-hda-Fix-mono-speakers-and-headset-mic-on-Dell-V.patch
new file mode 100644 (file)
index 0000000..d9ab587
--- /dev/null
@@ -0,0 +1,89 @@
+From 262b9bf43ad0714531d9f60da141e5173dc808aa Mon Sep 17 00:00:00 2001
+From: David Henningsson <david.henningsson@canonical.com>
+Date: Mon, 7 Oct 2013 10:39:59 +0200
+Subject: ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470
+
+From: David Henningsson <david.henningsson@canonical.com>
+
+This is a backport for stable. The original commit SHA is
+338cae565c53755de9f87d6a801517940d2d56f7.
+
+On this machine, DAC on node 0x03 seems to give mono output.
+
+Also, it needs additional patches for headset mic support.
+It supports CTIA style headsets only.
+
+Alsa-info available at the bug link below.
+
+BugLink: https://bugs.launchpad.net/bugs/1236228
+Signed-off-by: David Henningsson <david.henningsson@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c |   27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -3200,6 +3200,15 @@ static void alc269_fixup_limit_int_mic_b
+       }
+ }
++static void alc290_fixup_mono_speakers(struct hda_codec *codec,
++                                     const struct hda_fixup *fix, int action)
++{
++      if (action == HDA_FIXUP_ACT_PRE_PROBE)
++              /* Remove DAC node 0x03, as it seems to be
++                 giving mono output */
++              snd_hda_override_wcaps(codec, 0x03, 0);
++}
++
+ enum {
+       ALC269_FIXUP_SONY_VAIO,
+       ALC275_FIXUP_SONY_VAIO_GPIO2,
+@@ -3227,6 +3236,8 @@ enum {
+       ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
+       ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+       ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
++      ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
++      ALC290_FIXUP_MONO_SPEAKERS,
+       ALC269_FIXUP_HEADSET_MODE,
+       ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
+       ALC269_FIXUP_ASUS_X101_FUNC,
+@@ -3413,6 +3424,15 @@ static const struct hda_fixup alc269_fix
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
+       },
++      [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
++      },
+       [ALC269_FIXUP_HEADSET_MODE] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_headset_mode,
+@@ -3485,6 +3505,12 @@ static const struct hda_fixup alc269_fix
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_limit_int_mic_boost,
+       },
++      [ALC290_FIXUP_MONO_SPEAKERS] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc290_fixup_mono_speakers,
++              .chained = true,
++              .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -3519,6 +3545,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
++      SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
+       SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+       SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
diff --git a/queue-3.10/compiler-gcc4-add-quirk-for-asm-goto-miscompilation-bug.patch b/queue-3.10/compiler-gcc4-add-quirk-for-asm-goto-miscompilation-bug.patch
new file mode 100644 (file)
index 0000000..65d81ab
--- /dev/null
@@ -0,0 +1,140 @@
+From 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 Mon Sep 17 00:00:00 2001
+From: Ingo Molnar <mingo@kernel.org>
+Date: Thu, 10 Oct 2013 10:16:30 +0200
+Subject: compiler/gcc4: Add quirk for 'asm goto' miscompilation bug
+
+From: Ingo Molnar <mingo@kernel.org>
+
+commit 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 upstream.
+
+Fengguang Wu, Oleg Nesterov and Peter Zijlstra tracked down
+a kernel crash to a GCC bug: GCC miscompiles certain 'asm goto'
+constructs, as outlined here:
+
+  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+
+Implement a workaround suggested by Jakub Jelinek.
+
+Reported-and-tested-by: Fengguang Wu <fengguang.wu@intel.com>
+Reported-by: Oleg Nesterov <oleg@redhat.com>
+Reported-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Suggested-by: Jakub Jelinek <jakub@redhat.com>
+Reviewed-by: Richard Henderson <rth@twiddle.net>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Link: http://lkml.kernel.org/r/20131015062351.GA4666@gmail.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/include/asm/jump_label.h     |    2 +-
+ arch/mips/include/asm/jump_label.h    |    2 +-
+ arch/powerpc/include/asm/jump_label.h |    2 +-
+ arch/s390/include/asm/jump_label.h    |    2 +-
+ arch/sparc/include/asm/jump_label.h   |    2 +-
+ arch/x86/include/asm/cpufeature.h     |    2 +-
+ arch/x86/include/asm/jump_label.h     |    2 +-
+ include/linux/compiler-gcc4.h         |   15 +++++++++++++++
+ 8 files changed, 22 insertions(+), 7 deletions(-)
+
+--- a/arch/arm/include/asm/jump_label.h
++++ b/arch/arm/include/asm/jump_label.h
+@@ -16,7 +16,7 @@
+ static __always_inline bool arch_static_branch(struct static_key *key)
+ {
+-      asm goto("1:\n\t"
++      asm_volatile_goto("1:\n\t"
+                JUMP_LABEL_NOP "\n\t"
+                ".pushsection __jump_table,  \"aw\"\n\t"
+                ".word 1b, %l[l_yes], %c0\n\t"
+--- a/arch/mips/include/asm/jump_label.h
++++ b/arch/mips/include/asm/jump_label.h
+@@ -22,7 +22,7 @@
+ static __always_inline bool arch_static_branch(struct static_key *key)
+ {
+-      asm goto("1:\tnop\n\t"
++      asm_volatile_goto("1:\tnop\n\t"
+               "nop\n\t"
+               ".pushsection __jump_table,  \"aw\"\n\t"
+               WORD_INSN " 1b, %l[l_yes], %0\n\t"
+--- a/arch/powerpc/include/asm/jump_label.h
++++ b/arch/powerpc/include/asm/jump_label.h
+@@ -19,7 +19,7 @@
+ static __always_inline bool arch_static_branch(struct static_key *key)
+ {
+-      asm goto("1:\n\t"
++      asm_volatile_goto("1:\n\t"
+                "nop\n\t"
+                ".pushsection __jump_table,  \"aw\"\n\t"
+                JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
+--- a/arch/s390/include/asm/jump_label.h
++++ b/arch/s390/include/asm/jump_label.h
+@@ -15,7 +15,7 @@
+ static __always_inline bool arch_static_branch(struct static_key *key)
+ {
+-      asm goto("0:    brcl 0,0\n"
++      asm_volatile_goto("0:   brcl 0,0\n"
+               ".pushsection __jump_table, \"aw\"\n"
+               ASM_ALIGN "\n"
+               ASM_PTR " 0b, %l[label], %0\n"
+--- a/arch/sparc/include/asm/jump_label.h
++++ b/arch/sparc/include/asm/jump_label.h
+@@ -9,7 +9,7 @@
+ static __always_inline bool arch_static_branch(struct static_key *key)
+ {
+-              asm goto("1:\n\t"
++              asm_volatile_goto("1:\n\t"
+                        "nop\n\t"
+                        "nop\n\t"
+                        ".pushsection __jump_table,  \"aw\"\n\t"
+--- a/arch/x86/include/asm/cpufeature.h
++++ b/arch/x86/include/asm/cpufeature.h
+@@ -365,7 +365,7 @@ extern const char * const x86_power_flag
+ static __always_inline __pure bool __static_cpu_has(u16 bit)
+ {
+ #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5
+-              asm goto("1: jmp %l[t_no]\n"
++              asm_volatile_goto("1: jmp %l[t_no]\n"
+                        "2:\n"
+                        ".section .altinstructions,\"a\"\n"
+                        " .long 1b - .\n"
+--- a/arch/x86/include/asm/jump_label.h
++++ b/arch/x86/include/asm/jump_label.h
+@@ -13,7 +13,7 @@
+ static __always_inline bool arch_static_branch(struct static_key *key)
+ {
+-      asm goto("1:"
++      asm_volatile_goto("1:"
+               STATIC_KEY_INITIAL_NOP
+               ".pushsection __jump_table,  \"aw\" \n\t"
+               _ASM_ALIGN "\n\t"
+--- a/include/linux/compiler-gcc4.h
++++ b/include/linux/compiler-gcc4.h
+@@ -65,6 +65,21 @@
+ #define __visible __attribute__((externally_visible))
+ #endif
++/*
++ * GCC 'asm goto' miscompiles certain code sequences:
++ *
++ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
++ *
++ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
++ * Fixed in GCC 4.8.2 and later versions.
++ *
++ * (asm goto is automatically volatile - the naming reflects this.)
++ */
++#if GCC_VERSION <= 40801
++# define asm_volatile_goto(x...)      do { asm goto(x); asm (""); } while (0)
++#else
++# define asm_volatile_goto(x...)      do { asm goto(x); } while (0)
++#endif
+ #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+ #if GCC_VERSION >= 40400
diff --git a/queue-3.10/cope-with-potentially-long-d_dname-output-for.patch b/queue-3.10/cope-with-potentially-long-d_dname-output-for.patch
new file mode 100644 (file)
index 0000000..1e3fbec
--- /dev/null
@@ -0,0 +1,93 @@
+From 118b23022512eb2f41ce42db70dc0568d00be4ba Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Sat, 24 Aug 2013 12:08:17 -0400
+Subject: cope with potentially long ->d_dname() output for
+ shmem/hugetlb
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 118b23022512eb2f41ce42db70dc0568d00be4ba upstream.
+
+dynamic_dname() is both too much and too little for those - the
+output may be well in excess of 64 bytes dynamic_dname() assumes
+to be enough (thanks to ashmem feeding really long names to
+shmem_file_setup()) and vsnprintf() is an overkill for those
+guys.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Colin Cross <ccross@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c            |   11 +++++++++++
+ fs/hugetlbfs/inode.c   |    8 +-------
+ include/linux/dcache.h |    1 +
+ mm/shmem.c             |    8 +-------
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -2724,6 +2724,17 @@ char *dynamic_dname(struct dentry *dentr
+       return memcpy(buffer, temp, sz);
+ }
++char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
++{
++      char *end = buffer + buflen;
++      /* these dentries are never renamed, so d_lock is not needed */
++      if (prepend(&end, &buflen, " (deleted)", 11) ||
++          prepend_name(&end, &buflen, &dentry->d_name) ||
++          prepend(&end, &buflen, "/", 1))
++              end = ERR_PTR(-ENAMETOOLONG);
++      return end;
++}
++
+ /*
+  * Write full pathname from the root of the filesystem into the buffer.
+  */
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -916,14 +916,8 @@ static int get_hstate_idx(int page_size_
+       return h - hstates;
+ }
+-static char *hugetlb_dname(struct dentry *dentry, char *buffer, int buflen)
+-{
+-      return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)",
+-                              dentry->d_name.name);
+-}
+-
+ static struct dentry_operations anon_ops = {
+-      .d_dname = hugetlb_dname
++      .d_dname = simple_dname
+ };
+ /*
+--- a/include/linux/dcache.h
++++ b/include/linux/dcache.h
+@@ -332,6 +332,7 @@ extern int d_validate(struct dentry *, s
+  * helper function for dentry_operations.d_dname() members
+  */
+ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
++extern char *simple_dname(struct dentry *, char *, int);
+ extern char *__d_path(const struct path *, const struct path *, char *, int);
+ extern char *d_absolute_path(const struct path *, char *, int);
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -2879,14 +2879,8 @@ EXPORT_SYMBOL_GPL(shmem_truncate_range);
+ /* common code */
+-static char *shmem_dname(struct dentry *dentry, char *buffer, int buflen)
+-{
+-      return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)",
+-                              dentry->d_name.name);
+-}
+-
+ static struct dentry_operations anon_ops = {
+-      .d_dname = shmem_dname
++      .d_dname = simple_dname
+ };
+ /**
diff --git a/queue-3.10/drm-i915-only-apply-dpms-to-the-encoder-if-enabled.patch b/queue-3.10/drm-i915-only-apply-dpms-to-the-encoder-if-enabled.patch
new file mode 100644 (file)
index 0000000..18d7acc
--- /dev/null
@@ -0,0 +1,97 @@
+From c9976dcf55c8aaa7037427b239f15e5acfc01a3a Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Sun, 29 Sep 2013 19:15:07 +0100
+Subject: drm/i915: Only apply DPMS to the encoder if enabled
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit c9976dcf55c8aaa7037427b239f15e5acfc01a3a upstream.
+
+The current test for an attached enabled encoder fails if we have
+multiple connectors aliased to the same encoder - both connectors
+believe they own the enabled encoder and so we attempt to both enable
+and disable DPMS on the encoder, leading to hilarity and an OOPs:
+
+[  354.803064] WARNING: CPU: 0 PID: 482 at
+/usr/src/linux/dist/3.11.2/drivers/gpu/drm/i915/intel_display.c:3869 intel_modeset_check_state+0x764/0x770 [i915]()
+[  354.803064] wrong connector dpms state
+[  354.803084] Modules linked in: nfsd auth_rpcgss oid_registry exportfs nfs lockd sunrpc xt_nat iptable_nat nf_nat_ipv4 nf_nat xt_limit xt_LOG xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 ipt_REJECT ipv6 xt_recent xt_conntrack nf_conntrack iptable_filter ip_tables x_tables snd_hda_codec_realtek snd_hda_codec_hdmi x86_pkg_temp_thermal snd_hda_intel coretemp kvm_intel snd_hda_codec i915 kvm snd_hwdep snd_pcm_oss snd_mixer_oss crc32_pclmul snd_pcm crc32c_intel e1000e intel_agp igb ghash_clmulni_intel intel_gtt aesni_intel cfbfillrect aes_x86_64 cfbimgblt lrw cfbcopyarea drm_kms_helper ptp video thermal processor gf128mul snd_page_alloc drm snd_timer glue_helper 8250_pci snd pps_core ablk_helper agpgart cryptd sg soundcore fan i2c_algo_bit sr_mod thermal_sys 8250 i2c_i801 serial_core
+hwmon cdrom i2c_core evdev button
+[  354.803086] CPU: 0 PID: 482 Comm: kworker/0:1 Not tainted 3.11.2 #1
+[  354.803087] Hardware name: Supermicro X10SAE/X10SAE, BIOS 1.00 05/03/2013 [  354.803091] Workqueue: events console_callback
+[  354.803092]  0000000000000009 ffff88023611db48 ffffffff814048ac ffff88023611db90
+[  354.803093]  ffff88023611db80 ffffffff8103d4e3 ffff880230d82800 ffff880230f9b800
+[  354.803094]  ffff880230f99000 ffff880230f99448 ffff8802351c0e00 ffff88023611dbe0
+[  354.803094] Call Trace:
+[  354.803098]  [<ffffffff814048ac>] dump_stack+0x54/0x8d
+[  354.803101]  [<ffffffff8103d4e3>] warn_slowpath_common+0x73/0x90
+[  354.803103]  [<ffffffff8103d547>] warn_slowpath_fmt+0x47/0x50
+[  354.803109]  [<ffffffffa089f1be>] ? intel_ddi_connector_get_hw_state+0x5e/0x110 [i915]
+[  354.803114]  [<ffffffffa0896974>] intel_modeset_check_state+0x764/0x770 [i915]
+[  354.803117]  [<ffffffffa08969bb>] intel_connector_dpms+0x3b/0x60 [i915]
+[  354.803120]  [<ffffffffa037e1d0>] drm_fb_helper_dpms.isra.11+0x120/0x160 [drm_kms_helper]
+[  354.803122]  [<ffffffffa037e24e>] drm_fb_helper_blank+0x3e/0x80 [drm_kms_helper]
+[  354.803123]  [<ffffffff812116c2>] fb_blank+0x52/0xc0
+[  354.803125]  [<ffffffff8121e04b>] fbcon_blank+0x21b/0x2d0
+[  354.803127]  [<ffffffff81062243>] ? update_rq_clock.part.74+0x13/0x30
+[  354.803129]  [<ffffffff81047486>] ? lock_timer_base.isra.30+0x26/0x50
+[  354.803130]  [<ffffffff810472b2>] ? internal_add_timer+0x12/0x40
+[  354.803131]  [<ffffffff81047f48>] ? mod_timer+0xf8/0x1c0
+[  354.803133]  [<ffffffff81266d61>] do_unblank_screen+0xa1/0x1c0
+[  354.803134]  [<ffffffff81268087>] poke_blanked_console+0xc7/0xd0
+[  354.803136]  [<ffffffff812681cf>] console_callback+0x13f/0x160
+[  354.803137]  [<ffffffff81053258>] process_one_work+0x148/0x3d0
+[  354.803138]  [<ffffffff81053f19>] worker_thread+0x119/0x3a0
+[  354.803140]  [<ffffffff81053e00>] ? manage_workers.isra.30+0x2a0/0x2a0
+[  354.803141]  [<ffffffff8105994b>] kthread+0xbb/0xc0
+[  354.803142]  [<ffffffff81059890>] ? kthread_create_on_node+0x120/0x120
+[  354.803144]  [<ffffffff8140b32c>] ret_from_fork+0x7c/0xb0
+[  354.803145]  [<ffffffff81059890>] ? kthread_create_on_node+0x120/0x120
+
+This regression goes back to the big modeset rework and the conversion
+to the new dpms helpers which started with:
+
+commit 5ab432ef4997ce32c9406721b37ef6e97e57dae1
+Author: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date:   Sat Jun 30 08:59:56 2012 +0200
+
+    drm/i915/hdmi: convert to encoder->disable/enable
+
+Fixes: igt/kms_flip/dpms-off-confusion
+Reported-and-tested-by: Wakko Warner <wakko@animx.eu.org>
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68030
+Link:  http://lkml.kernel.org/r/20130928185023.GA21672@animx.eu.org
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+[danvet: Add regression citation, mention the igt testcase this fixes
+and slap a cc: stable on the patch.]
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -3946,8 +3946,6 @@ static void intel_connector_check_state(
+  * consider. */
+ void intel_connector_dpms(struct drm_connector *connector, int mode)
+ {
+-      struct intel_encoder *encoder = intel_attached_encoder(connector);
+-
+       /* All the simple cases only support two dpms states. */
+       if (mode != DRM_MODE_DPMS_ON)
+               mode = DRM_MODE_DPMS_OFF;
+@@ -3958,10 +3956,8 @@ void intel_connector_dpms(struct drm_con
+       connector->dpms = mode;
+       /* Only need to change hw state when actually enabled */
+-      if (encoder->base.crtc)
+-              intel_encoder_dpms(encoder, mode);
+-      else
+-              WARN_ON(encoder->connectors_active != false);
++      if (connector->encoder)
++              intel_encoder_dpms(to_intel_encoder(connector->encoder), mode);
+       intel_modeset_check_state(connector->dev);
+ }
diff --git a/queue-3.10/drm-radeon-fix-hw-contexts-for-sumo2-asics.patch b/queue-3.10/drm-radeon-fix-hw-contexts-for-sumo2-asics.patch
new file mode 100644 (file)
index 0000000..c4147c6
--- /dev/null
@@ -0,0 +1,33 @@
+From 50b8f5aec04ebec7dbdf2adb17220b9148c99e63 Mon Sep 17 00:00:00 2001
+From: wojciech kapuscinski <wojtask9@wp.pl>
+Date: Tue, 1 Oct 2013 19:54:33 -0400
+Subject: drm/radeon: fix hw contexts for SUMO2 asics
+
+From: wojciech kapuscinski <wojtask9@wp.pl>
+
+commit 50b8f5aec04ebec7dbdf2adb17220b9148c99e63 upstream.
+
+They have 4 rather than 8.
+
+Fixes:
+https://bugs.freedesktop.org/show_bug.cgi?id=63599
+
+Signed-off-by: wojciech kapuscinski <wojtask9@wp.pl>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -2990,7 +2990,7 @@ static void evergreen_gpu_init(struct ra
+               rdev->config.evergreen.sx_max_export_size = 256;
+               rdev->config.evergreen.sx_max_export_pos_size = 64;
+               rdev->config.evergreen.sx_max_export_smx_size = 192;
+-              rdev->config.evergreen.max_hw_contexts = 8;
++              rdev->config.evergreen.max_hw_contexts = 4;
+               rdev->config.evergreen.sq_num_cf_insts = 2;
+               rdev->config.evergreen.sc_prim_fifo_size = 0x40;
diff --git a/queue-3.10/drm-radeon-fix-typo-in-cp-dma-register-headers.patch b/queue-3.10/drm-radeon-fix-typo-in-cp-dma-register-headers.patch
new file mode 100644 (file)
index 0000000..a594df0
--- /dev/null
@@ -0,0 +1,71 @@
+From aa3e146d04b6ae37939daeebaec060562b3db559 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 1 Oct 2013 16:40:45 -0400
+Subject: drm/radeon: fix typo in CP DMA register headers
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit aa3e146d04b6ae37939daeebaec060562b3db559 upstream.
+
+Wrong bit offset for SRC endian swapping.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreend.h |    4 ++--
+ drivers/gpu/drm/radeon/r600d.h      |    2 +-
+ drivers/gpu/drm/radeon/sid.h        |    4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/evergreend.h
++++ b/drivers/gpu/drm/radeon/evergreend.h
+@@ -1104,7 +1104,7 @@
+  * 6. COMMAND [29:22] | BYTE_COUNT [20:0]
+  */
+ #              define PACKET3_CP_DMA_DST_SEL(x)    ((x) << 20)
+-                /* 0 - SRC_ADDR
++                /* 0 - DST_ADDR
+                * 1 - GDS
+                */
+ #              define PACKET3_CP_DMA_ENGINE(x)     ((x) << 27)
+@@ -1119,7 +1119,7 @@
+ #              define PACKET3_CP_DMA_CP_SYNC       (1 << 31)
+ /* COMMAND */
+ #              define PACKET3_CP_DMA_DIS_WC        (1 << 21)
+-#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
++#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22)
+                 /* 0 - none
+                * 1 - 8 in 16
+                * 2 - 8 in 32
+--- a/drivers/gpu/drm/radeon/r600d.h
++++ b/drivers/gpu/drm/radeon/r600d.h
+@@ -1259,7 +1259,7 @@
+  */
+ #              define PACKET3_CP_DMA_CP_SYNC       (1 << 31)
+ /* COMMAND */
+-#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
++#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22)
+                 /* 0 - none
+                * 1 - 8 in 16
+                * 2 - 8 in 32
+--- a/drivers/gpu/drm/radeon/sid.h
++++ b/drivers/gpu/drm/radeon/sid.h
+@@ -928,7 +928,7 @@
+  * 6. COMMAND [30:21] | BYTE_COUNT [20:0]
+  */
+ #              define PACKET3_CP_DMA_DST_SEL(x)    ((x) << 20)
+-                /* 0 - SRC_ADDR
++                /* 0 - DST_ADDR
+                * 1 - GDS
+                */
+ #              define PACKET3_CP_DMA_ENGINE(x)     ((x) << 27)
+@@ -943,7 +943,7 @@
+ #              define PACKET3_CP_DMA_CP_SYNC       (1 << 31)
+ /* COMMAND */
+ #              define PACKET3_CP_DMA_DIS_WC        (1 << 21)
+-#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
++#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 22)
+                 /* 0 - none
+                * 1 - 8 in 16
+                * 2 - 8 in 32
diff --git a/queue-3.10/drm-radeon-forever-loop-on-error-in-radeon_do_test_moves.patch b/queue-3.10/drm-radeon-forever-loop-on-error-in-radeon_do_test_moves.patch
new file mode 100644 (file)
index 0000000..105d2b6
--- /dev/null
@@ -0,0 +1,36 @@
+From 89cd67b326fa95872cc2b4524cd807128db6071d Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 1 Jul 2013 19:39:34 +0300
+Subject: drm/radeon: forever loop on error in radeon_do_test_moves()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 89cd67b326fa95872cc2b4524cd807128db6071d upstream.
+
+The error path does this:
+
+       for (--i; i >= 0; --i) {
+
+which is a forever loop because "i" is unsigned.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_test.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_test.c
++++ b/drivers/gpu/drm/radeon/radeon_test.c
+@@ -37,8 +37,8 @@ static void radeon_do_test_moves(struct
+       struct radeon_bo **gtt_obj = NULL;
+       struct radeon_fence *fence = NULL;
+       uint64_t gtt_addr, vram_addr;
+-      unsigned i, n, size;
+-      int r, ring;
++      unsigned n, size;
++      int i, r, ring;
+       switch (flag) {
+       case RADEON_TEST_COPY_DMA:
diff --git a/queue-3.10/ipc-close-open-coded-spin-lock-calls.patch b/queue-3.10/ipc-close-open-coded-spin-lock-calls.patch
new file mode 100644 (file)
index 0000000..6c73859
--- /dev/null
@@ -0,0 +1,137 @@
+From cf9d5d78d05bca96df7618dfc3a5ee4414dcae58 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:11 -0700
+Subject: ipc: close open coded spin lock calls
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit cf9d5d78d05bca96df7618dfc3a5ee4414dcae58 upstream.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c  |    2 +-
+ ipc/sem.c  |   14 +++++++-------
+ ipc/shm.c  |    4 ++--
+ ipc/util.h |    4 ++--
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -216,7 +216,7 @@ static int newque(struct ipc_namespace *
+       INIT_LIST_HEAD(&msq->q_receivers);
+       INIT_LIST_HEAD(&msq->q_senders);
+-      spin_unlock(&msq->q_perm.lock);
++      ipc_unlock_object(&msq->q_perm);
+       rcu_read_unlock();
+       return msq->q_perm.id;
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -246,7 +246,7 @@ static inline int sem_lock(struct sem_ar
+                * their critical section while the array lock is held.
+                */
+  lock_array:
+-              spin_lock(&sma->sem_perm.lock);
++              ipc_lock_object(&sma->sem_perm);
+               for (i = 0; i < sma->sem_nsems; i++) {
+                       struct sem *sem = sma->sem_base + i;
+                       spin_unlock_wait(&sem->lock);
+@@ -259,7 +259,7 @@ static inline int sem_lock(struct sem_ar
+ static inline void sem_unlock(struct sem_array *sma, int locknum)
+ {
+       if (locknum == -1) {
+-              spin_unlock(&sma->sem_perm.lock);
++              ipc_unlock_object(&sma->sem_perm);
+       } else {
+               struct sem *sem = sma->sem_base + locknum;
+               spin_unlock(&sem->lock);
+@@ -872,7 +872,7 @@ static void freeary(struct ipc_namespace
+       int i;
+       /* Free the existing undo structures for this semaphore set.  */
+-      assert_spin_locked(&sma->sem_perm.lock);
++      ipc_assert_locked_object(&sma->sem_perm);
+       list_for_each_entry_safe(un, tu, &sma->list_id, list_id) {
+               list_del(&un->list_id);
+               spin_lock(&un->ulp->lock);
+@@ -1070,7 +1070,7 @@ static int semctl_setval(struct ipc_name
+       curr = &sma->sem_base[semnum];
+-      assert_spin_locked(&sma->sem_perm.lock);
++      ipc_assert_locked_object(&sma->sem_perm);
+       list_for_each_entry(un, &sma->list_id, list_id)
+               un->semadj[semnum] = 0;
+@@ -1199,7 +1199,7 @@ static int semctl_main(struct ipc_namesp
+               for (i = 0; i < nsems; i++)
+                       sma->sem_base[i].semval = sem_io[i];
+-              assert_spin_locked(&sma->sem_perm.lock);
++              ipc_assert_locked_object(&sma->sem_perm);
+               list_for_each_entry(un, &sma->list_id, list_id) {
+                       for (i = 0; i < nsems; i++)
+                               un->semadj[i] = 0;
+@@ -1496,7 +1496,7 @@ static struct sem_undo *find_alloc_undo(
+       new->semid = semid;
+       assert_spin_locked(&ulp->lock);
+       list_add_rcu(&new->list_proc, &ulp->list_proc);
+-      assert_spin_locked(&sma->sem_perm.lock);
++      ipc_assert_locked_object(&sma->sem_perm);
+       list_add(&new->list_id, &sma->list_id);
+       un = new;
+@@ -1833,7 +1833,7 @@ void exit_sem(struct task_struct *tsk)
+               }
+               /* remove un from the linked lists */
+-              assert_spin_locked(&sma->sem_perm.lock);
++              ipc_assert_locked_object(&sma->sem_perm);
+               list_del(&un->list_id);
+               spin_lock(&ulp->lock);
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -141,7 +141,7 @@ static inline struct shmid_kernel *shm_l
+ static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp)
+ {
+       rcu_read_lock();
+-      spin_lock(&ipcp->shm_perm.lock);
++      ipc_lock_object(&ipcp->shm_perm);
+ }
+ static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns,
+@@ -545,7 +545,7 @@ static int newseg(struct ipc_namespace *
+       ns->shm_tot += numpages;
+       error = shp->shm_perm.id;
+-      spin_unlock(&shp->shm_perm.lock);
++      ipc_unlock_object(&shp->shm_perm);
+       rcu_read_unlock();
+       return error;
+--- a/ipc/util.h
++++ b/ipc/util.h
+@@ -177,12 +177,12 @@ static inline void ipc_assert_locked_obj
+ static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
+ {
+       rcu_read_lock();
+-      spin_lock(&perm->lock);
++      ipc_lock_object(perm);
+ }
+ static inline void ipc_unlock(struct kern_ipc_perm *perm)
+ {
+-      spin_unlock(&perm->lock);
++      ipc_unlock_object(perm);
+       rcu_read_unlock();
+ }
diff --git a/queue-3.10/ipc-introduce-ipc-object-locking-helpers.patch b/queue-3.10/ipc-introduce-ipc-object-locking-helpers.patch
new file mode 100644 (file)
index 0000000..e0d77f6
--- /dev/null
@@ -0,0 +1,64 @@
+From 1ca7003ab41152d673d9e359632283d05294f3d6 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:10 -0700
+Subject: ipc: introduce ipc object locking helpers
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 1ca7003ab41152d673d9e359632283d05294f3d6 upstream.
+
+Simple helpers around the (kern_ipc_perm *)->lock spinlock.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/util.h |   20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/ipc/util.h
++++ b/ipc/util.h
+@@ -159,23 +159,33 @@ static inline int ipc_checkid(struct ker
+       return uid / SEQ_MULTIPLIER != ipcp->seq;
+ }
+-static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
++static inline void ipc_lock_object(struct kern_ipc_perm *perm)
+ {
+-      rcu_read_lock();
+       spin_lock(&perm->lock);
+ }
+-static inline void ipc_unlock(struct kern_ipc_perm *perm)
++static inline void ipc_unlock_object(struct kern_ipc_perm *perm)
+ {
+       spin_unlock(&perm->lock);
+-      rcu_read_unlock();
+ }
+-static inline void ipc_lock_object(struct kern_ipc_perm *perm)
++static inline void ipc_assert_locked_object(struct kern_ipc_perm *perm)
+ {
++      assert_spin_locked(&perm->lock);
++}
++
++static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
++{
++      rcu_read_lock();
+       spin_lock(&perm->lock);
+ }
++static inline void ipc_unlock(struct kern_ipc_perm *perm)
++{
++      spin_unlock(&perm->lock);
++      rcu_read_unlock();
++}
++
+ struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id);
+ struct kern_ipc_perm *ipc_obtain_object_check(struct ipc_ids *ids, int id);
+ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
diff --git a/queue-3.10/ipc-move-locking-out-of-ipcctl_pre_down_nolock.patch b/queue-3.10/ipc-move-locking-out-of-ipcctl_pre_down_nolock.patch
new file mode 100644 (file)
index 0000000..f5183dd
--- /dev/null
@@ -0,0 +1,248 @@
+From 7b4cc5d8411bd4e9d61d8714f53859740cf830c2 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:12 -0700
+Subject: ipc: move locking out of ipcctl_pre_down_nolock
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 7b4cc5d8411bd4e9d61d8714f53859740cf830c2 upstream.
+
+This function currently acquires both the rw_mutex and the rcu lock on
+successful lookups, leaving the callers to explicitly unlock them,
+creating another two level locking situation.
+
+Make the callers (including those that still use ipcctl_pre_down())
+explicitly lock and unlock the rwsem and rcu lock.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c  |   24 +++++++++++++++++-------
+ ipc/sem.c  |   27 ++++++++++++++++-----------
+ ipc/shm.c  |   23 +++++++++++++++++------
+ ipc/util.c |   21 ++++++---------------
+ 4 files changed, 56 insertions(+), 39 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -407,31 +407,38 @@ static int msgctl_down(struct ipc_namesp
+                       return -EFAULT;
+       }
++      down_write(&msg_ids(ns).rw_mutex);
++      rcu_read_lock();
++
+       ipcp = ipcctl_pre_down(ns, &msg_ids(ns), msqid, cmd,
+                              &msqid64.msg_perm, msqid64.msg_qbytes);
+-      if (IS_ERR(ipcp))
+-              return PTR_ERR(ipcp);
++      if (IS_ERR(ipcp)) {
++              err = PTR_ERR(ipcp);
++              /* the ipc lock is not held upon failure */
++              goto out_unlock1;
++      }
+       msq = container_of(ipcp, struct msg_queue, q_perm);
+       err = security_msg_queue_msgctl(msq, cmd);
+       if (err)
+-              goto out_unlock;
++              goto out_unlock0;
+       switch (cmd) {
+       case IPC_RMID:
++              /* freeque unlocks the ipc object and rcu */
+               freeque(ns, ipcp);
+               goto out_up;
+       case IPC_SET:
+               if (msqid64.msg_qbytes > ns->msg_ctlmnb &&
+                   !capable(CAP_SYS_RESOURCE)) {
+                       err = -EPERM;
+-                      goto out_unlock;
++                      goto out_unlock0;
+               }
+               err = ipc_update_perm(&msqid64.msg_perm, ipcp);
+               if (err)
+-                      goto out_unlock;
++                      goto out_unlock0;
+               msq->q_qbytes = msqid64.msg_qbytes;
+@@ -448,8 +455,11 @@ static int msgctl_down(struct ipc_namesp
+       default:
+               err = -EINVAL;
+       }
+-out_unlock:
+-      msg_unlock(msq);
++
++out_unlock0:
++      ipc_unlock_object(&msq->q_perm);
++out_unlock1:
++      rcu_read_unlock();
+ out_up:
+       up_write(&msg_ids(ns).rw_mutex);
+       return err;
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -1289,39 +1289,44 @@ static int semctl_down(struct ipc_namesp
+                       return -EFAULT;
+       }
++      down_write(&sem_ids(ns).rw_mutex);
++      rcu_read_lock();
++
+       ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
+                                     &semid64.sem_perm, 0);
+-      if (IS_ERR(ipcp))
+-              return PTR_ERR(ipcp);
++      if (IS_ERR(ipcp)) {
++              err = PTR_ERR(ipcp);
++              /* the ipc lock is not held upon failure */
++              goto out_unlock1;
++      }
+       sma = container_of(ipcp, struct sem_array, sem_perm);
+       err = security_sem_semctl(sma, cmd);
+-      if (err) {
+-              rcu_read_unlock();
+-              goto out_up;
+-      }
++      if (err)
++              goto out_unlock1;
+-      switch(cmd){
++      switch (cmd) {
+       case IPC_RMID:
+               sem_lock(sma, NULL, -1);
++              /* freeary unlocks the ipc object and rcu */
+               freeary(ns, ipcp);
+               goto out_up;
+       case IPC_SET:
+               sem_lock(sma, NULL, -1);
+               err = ipc_update_perm(&semid64.sem_perm, ipcp);
+               if (err)
+-                      goto out_unlock;
++                      goto out_unlock0;
+               sma->sem_ctime = get_seconds();
+               break;
+       default:
+-              rcu_read_unlock();
+               err = -EINVAL;
+-              goto out_up;
++              goto out_unlock1;
+       }
+-out_unlock:
++out_unlock0:
+       sem_unlock(sma, -1);
++out_unlock1:
+       rcu_read_unlock();
+ out_up:
+       up_write(&sem_ids(ns).rw_mutex);
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -757,31 +757,42 @@ static int shmctl_down(struct ipc_namesp
+                       return -EFAULT;
+       }
++      down_write(&shm_ids(ns).rw_mutex);
++      rcu_read_lock();
++
+       ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd,
+                              &shmid64.shm_perm, 0);
+-      if (IS_ERR(ipcp))
+-              return PTR_ERR(ipcp);
++      if (IS_ERR(ipcp)) {
++              err = PTR_ERR(ipcp);
++              /* the ipc lock is not held upon failure */
++              goto out_unlock1;
++      }
+       shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+       err = security_shm_shmctl(shp, cmd);
+       if (err)
+-              goto out_unlock;
++              goto out_unlock0;
++
+       switch (cmd) {
+       case IPC_RMID:
++              /* do_shm_rmid unlocks the ipc object and rcu */
+               do_shm_rmid(ns, ipcp);
+               goto out_up;
+       case IPC_SET:
+               err = ipc_update_perm(&shmid64.shm_perm, ipcp);
+               if (err)
+-                      goto out_unlock;
++                      goto out_unlock0;
+               shp->shm_ctim = get_seconds();
+               break;
+       default:
+               err = -EINVAL;
+       }
+-out_unlock:
+-      shm_unlock(shp);
++
++out_unlock0:
++      ipc_unlock_object(&shp->shm_perm);
++out_unlock1:
++      rcu_read_unlock();
+ out_up:
+       up_write(&shm_ids(ns).rw_mutex);
+       return err;
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -746,8 +746,10 @@ int ipc_update_perm(struct ipc64_perm *i
+  * It must be called without any lock held and
+  *  - retrieves the ipc with the given id in the given table.
+  *  - performs some audit and permission check, depending on the given cmd
+- *  - returns the ipc with both ipc and rw_mutex locks held in case of success
++ *  - returns the ipc with the ipc lock held in case of success
+  *    or an err-code without any lock held otherwise.
++ *
++ * Call holding the both the rw_mutex and the rcu read lock.
+  */
+ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
+                                     struct ipc_ids *ids, int id, int cmd,
+@@ -772,13 +774,10 @@ struct kern_ipc_perm *ipcctl_pre_down_no
+       int err = -EPERM;
+       struct kern_ipc_perm *ipcp;
+-      down_write(&ids->rw_mutex);
+-      rcu_read_lock();
+-
+       ipcp = ipc_obtain_object_check(ids, id);
+       if (IS_ERR(ipcp)) {
+               err = PTR_ERR(ipcp);
+-              goto out_up;
++              goto err;
+       }
+       audit_ipc_obj(ipcp);
+@@ -789,16 +788,8 @@ struct kern_ipc_perm *ipcctl_pre_down_no
+       euid = current_euid();
+       if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid)  ||
+           ns_capable(ns->user_ns, CAP_SYS_ADMIN))
+-              return ipcp;
+-
+-out_up:
+-      /*
+-       * Unsuccessful lookup, unlock and return
+-       * the corresponding error.
+-       */
+-      rcu_read_unlock();
+-      up_write(&ids->rw_mutex);
+-
++              return ipcp; /* successful lookup */
++err:
+       return ERR_PTR(err);
+ }
diff --git a/queue-3.10/ipc-move-rcu-lock-out-of-ipc_addid.patch b/queue-3.10/ipc-move-rcu-lock-out-of-ipc_addid.patch
new file mode 100644 (file)
index 0000000..f509a13
--- /dev/null
@@ -0,0 +1,106 @@
+From dbfcd91f06f0e2d5564b2fd184e9c2a43675f9ab Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:09 -0700
+Subject: ipc: move rcu lock out of ipc_addid
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit dbfcd91f06f0e2d5564b2fd184e9c2a43675f9ab upstream.
+
+This patchset continues the work that began in the sysv ipc semaphore
+scaling series, see
+
+  https://lkml.org/lkml/2013/3/20/546
+
+Just like semaphores used to be, sysv shared memory and msg queues also
+abuse the ipc lock, unnecessarily holding it for operations such as
+permission and security checks.
+
+This patchset mostly deals with mqueues, and while shared mem can be
+done in a very similar way, I want to get these patches out in the open
+first.  It also does some pending cleanups, mostly focused on the two
+level locking we have in ipc code, taking care of ipc_addid() and
+ipcctl_pre_down_nolock() - yes there are still functions that need to be
+updated as well.
+
+This patch:
+
+Make all callers explicitly take and release the RCU read lock.
+
+This addresses the two level locking seen in newary(), newseg() and
+newqueue().  For the last two, explicitly unlock the ipc object and the
+rcu lock, instead of calling the custom shm_unlock and msg_unlock
+functions.  The next patch will deal with the open coded locking for
+->perm.lock
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c  |    7 +++----
+ ipc/shm.c  |    5 ++++-
+ ipc/util.c |    3 +--
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -199,9 +199,7 @@ static int newque(struct ipc_namespace *
+               return retval;
+       }
+-      /*
+-       * ipc_addid() locks msq
+-       */
++      /* ipc_addid() locks msq upon success. */
+       id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
+       if (id < 0) {
+               security_msg_queue_free(msq);
+@@ -218,7 +216,8 @@ static int newque(struct ipc_namespace *
+       INIT_LIST_HEAD(&msq->q_receivers);
+       INIT_LIST_HEAD(&msq->q_senders);
+-      msg_unlock(msq);
++      spin_unlock(&msq->q_perm.lock);
++      rcu_read_unlock();
+       return msq->q_perm.id;
+ }
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -535,6 +535,7 @@ static int newseg(struct ipc_namespace *
+       shp->shm_nattch = 0;
+       shp->shm_file = file;
+       shp->shm_creator = current;
++
+       /*
+        * shmid gets reported as "inode#" in /proc/pid/maps.
+        * proc-ps tools use this. Changing this will break them.
+@@ -543,7 +544,9 @@ static int newseg(struct ipc_namespace *
+       ns->shm_tot += numpages;
+       error = shp->shm_perm.id;
+-      shm_unlock(shp);
++
++      spin_unlock(&shp->shm_perm.lock);
++      rcu_read_unlock();
+       return error;
+ no_id:
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -246,9 +246,8 @@ int ipc_get_maxid(struct ipc_ids *ids)
+  *    is returned. The 'new' entry is returned in a locked state on success.
+  *    On failure the entry is not locked and a negative err-code is returned.
+  *
+- *    Called with ipc_ids.rw_mutex held as a writer.
++ *    Called with writer ipc_ids.rw_mutex held.
+  */
+- 
+ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
+ {
+       kuid_t euid;
diff --git a/queue-3.10/ipc-msg-introduce-lockless-functions-to-obtain-the-ipc-object.patch b/queue-3.10/ipc-msg-introduce-lockless-functions-to-obtain-the-ipc-object.patch
new file mode 100644 (file)
index 0000000..fe7cd25
--- /dev/null
@@ -0,0 +1,56 @@
+From a5001a0d9768568de5d613c3b3a5b9c7721299da Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:15 -0700
+Subject: ipc,msg: introduce lockless functions to obtain the ipc object
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit a5001a0d9768568de5d613c3b3a5b9c7721299da upstream.
+
+Add msq_obtain_object() and msq_obtain_object_check(), which will allow
+us to get the ipc object without acquiring the lock.  Just as with
+semaphores, these functions are basically wrappers around
+ipc_obtain_object*().
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -166,6 +166,27 @@ static inline struct msg_queue *msg_lock
+       return container_of(ipcp, struct msg_queue, q_perm);
+ }
++static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id)
++{
++      struct kern_ipc_perm *ipcp = ipc_obtain_object(&msg_ids(ns), id);
++
++      if (IS_ERR(ipcp))
++              return ERR_CAST(ipcp);
++
++      return container_of(ipcp, struct msg_queue, q_perm);
++}
++
++static inline struct msg_queue *msq_obtain_object_check(struct ipc_namespace *ns,
++                                                      int id)
++{
++      struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&msg_ids(ns), id);
++
++      if (IS_ERR(ipcp))
++              return ERR_CAST(ipcp);
++
++      return container_of(ipcp, struct msg_queue, q_perm);
++}
++
+ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
+ {
+       ipc_rmid(&msg_ids(ns), &s->q_perm);
diff --git a/queue-3.10/ipc-msg-introduce-msgctl_nolock.patch b/queue-3.10/ipc-msg-introduce-msgctl_nolock.patch
new file mode 100644 (file)
index 0000000..6804854
--- /dev/null
@@ -0,0 +1,117 @@
+From 2cafed30f150f7314f98717b372df8173516cae0 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:14 -0700
+Subject: ipc,msg: introduce msgctl_nolock
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 2cafed30f150f7314f98717b372df8173516cae0 upstream.
+
+Similar to semctl, when calling msgctl, the *_INFO and *_STAT commands
+can be performed without acquiring the ipc object.
+
+Add a msgctl_nolock() function and move the logic of *_INFO and *_STAT
+out of msgctl().  This change still takes the lock and it will be
+properly lockless in the next patch
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   49 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 34 insertions(+), 15 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -467,17 +467,11 @@ out_up:
+       return err;
+ }
+-SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
++static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
++                       int cmd, int version, void __user *buf)
+ {
++      int err;
+       struct msg_queue *msq;
+-      int err, version;
+-      struct ipc_namespace *ns;
+-
+-      if (msqid < 0 || cmd < 0)
+-              return -EINVAL;
+-
+-      version = ipc_parse_version(&cmd);
+-      ns = current->nsproxy->ipc_ns;
+       switch (cmd) {
+       case IPC_INFO:
+@@ -488,6 +482,7 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int,
+               if (!buf)
+                       return -EFAULT;
++
+               /*
+                * We must not return kernel stack data.
+                * due to padding, it's not enough
+@@ -519,7 +514,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int,
+                       return -EFAULT;
+               return (max_id < 0) ? 0 : max_id;
+       }
+-      case MSG_STAT:  /* msqid is an index rather than a msg queue id */
++
++      case MSG_STAT:
+       case IPC_STAT:
+       {
+               struct msqid64_ds tbuf;
+@@ -563,19 +559,42 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int,
+                       return -EFAULT;
+               return success_return;
+       }
+-      case IPC_SET:
+-      case IPC_RMID:
+-              err = msgctl_down(ns, msqid, cmd, buf, version);
+-              return err;
++
+       default:
+-              return  -EINVAL;
++              return -EINVAL;
+       }
++      return err;
+ out_unlock:
+       msg_unlock(msq);
+       return err;
+ }
++SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
++{
++      int version;
++      struct ipc_namespace *ns;
++
++      if (msqid < 0 || cmd < 0)
++              return -EINVAL;
++
++      version = ipc_parse_version(&cmd);
++      ns = current->nsproxy->ipc_ns;
++
++      switch (cmd) {
++      case IPC_INFO:
++      case MSG_INFO:
++      case MSG_STAT:  /* msqid is an index rather than a msg queue id */
++      case IPC_STAT:
++              return msgctl_nolock(ns, msqid, cmd, version, buf);
++      case IPC_SET:
++      case IPC_RMID:
++              return msgctl_down(ns, msqid, cmd, buf, version);
++      default:
++              return  -EINVAL;
++      }
++}
++
+ static int testmsg(struct msg_msg *msg, long type, int mode)
+ {
+       switch(mode)
diff --git a/queue-3.10/ipc-msg-make-msgctl_nolock-lockless.patch b/queue-3.10/ipc-msg-make-msgctl_nolock-lockless.patch
new file mode 100644 (file)
index 0000000..fb3a6bb
--- /dev/null
@@ -0,0 +1,89 @@
+From ac0ba20ea6f2201a1589d6dc26ad1a4f0f967bb8 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:16 -0700
+Subject: ipc,msg: make msgctl_nolock lockless
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit ac0ba20ea6f2201a1589d6dc26ad1a4f0f967bb8 upstream.
+
+While the INFO cmd doesn't take the ipc lock, the STAT commands do
+acquire it unnecessarily.  We can do the permissions and security checks
+only holding the rcu lock.
+
+This function now mimics semctl_nolock().
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -545,17 +545,25 @@ static int msgctl_nolock(struct ipc_name
+               if (!buf)
+                       return -EFAULT;
++              memset(&tbuf, 0, sizeof(tbuf));
++
++              rcu_read_lock();
+               if (cmd == MSG_STAT) {
+-                      msq = msg_lock(ns, msqid);
+-                      if (IS_ERR(msq))
+-                              return PTR_ERR(msq);
++                      msq = msq_obtain_object(ns, msqid);
++                      if (IS_ERR(msq)) {
++                              err = PTR_ERR(msq);
++                              goto out_unlock;
++                      }
+                       success_return = msq->q_perm.id;
+               } else {
+-                      msq = msg_lock_check(ns, msqid);
+-                      if (IS_ERR(msq))
+-                              return PTR_ERR(msq);
++                      msq = msq_obtain_object_check(ns, msqid);
++                      if (IS_ERR(msq)) {
++                              err = PTR_ERR(msq);
++                              goto out_unlock;
++                      }
+                       success_return = 0;
+               }
++
+               err = -EACCES;
+               if (ipcperms(ns, &msq->q_perm, S_IRUGO))
+                       goto out_unlock;
+@@ -564,8 +572,6 @@ static int msgctl_nolock(struct ipc_name
+               if (err)
+                       goto out_unlock;
+-              memset(&tbuf, 0, sizeof(tbuf));
+-
+               kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm);
+               tbuf.msg_stime  = msq->q_stime;
+               tbuf.msg_rtime  = msq->q_rtime;
+@@ -575,7 +581,8 @@ static int msgctl_nolock(struct ipc_name
+               tbuf.msg_qbytes = msq->q_qbytes;
+               tbuf.msg_lspid  = msq->q_lspid;
+               tbuf.msg_lrpid  = msq->q_lrpid;
+-              msg_unlock(msq);
++              rcu_read_unlock();
++
+               if (copy_msqid_to_user(buf, &tbuf, version))
+                       return -EFAULT;
+               return success_return;
+@@ -587,7 +594,7 @@ static int msgctl_nolock(struct ipc_name
+       return err;
+ out_unlock:
+-      msg_unlock(msq);
++      rcu_read_unlock();
+       return err;
+ }
diff --git a/queue-3.10/ipc-msg-shorten-critical-region-in-msgctl_down.patch b/queue-3.10/ipc-msg-shorten-critical-region-in-msgctl_down.patch
new file mode 100644 (file)
index 0000000..e1a3b51
--- /dev/null
@@ -0,0 +1,74 @@
+From 15724ecb7e9bab35fc694c666ad563adba820cc3 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:13 -0700
+Subject: ipc,msg: shorten critical region in msgctl_down
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 15724ecb7e9bab35fc694c666ad563adba820cc3 upstream.
+
+Instead of holding the ipc lock for the entire function, use the
+ipcctl_pre_down_nolock and only acquire the lock for specific commands:
+RMID and SET.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -410,11 +410,10 @@ static int msgctl_down(struct ipc_namesp
+       down_write(&msg_ids(ns).rw_mutex);
+       rcu_read_lock();
+-      ipcp = ipcctl_pre_down(ns, &msg_ids(ns), msqid, cmd,
+-                             &msqid64.msg_perm, msqid64.msg_qbytes);
++      ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
++                                    &msqid64.msg_perm, msqid64.msg_qbytes);
+       if (IS_ERR(ipcp)) {
+               err = PTR_ERR(ipcp);
+-              /* the ipc lock is not held upon failure */
+               goto out_unlock1;
+       }
+@@ -422,10 +421,11 @@ static int msgctl_down(struct ipc_namesp
+       err = security_msg_queue_msgctl(msq, cmd);
+       if (err)
+-              goto out_unlock0;
++              goto out_unlock1;
+       switch (cmd) {
+       case IPC_RMID:
++              ipc_lock_object(&msq->q_perm);
+               /* freeque unlocks the ipc object and rcu */
+               freeque(ns, ipcp);
+               goto out_up;
+@@ -433,9 +433,10 @@ static int msgctl_down(struct ipc_namesp
+               if (msqid64.msg_qbytes > ns->msg_ctlmnb &&
+                   !capable(CAP_SYS_RESOURCE)) {
+                       err = -EPERM;
+-                      goto out_unlock0;
++                      goto out_unlock1;
+               }
++              ipc_lock_object(&msq->q_perm);
+               err = ipc_update_perm(&msqid64.msg_perm, ipcp);
+               if (err)
+                       goto out_unlock0;
+@@ -454,6 +455,7 @@ static int msgctl_down(struct ipc_namesp
+               break;
+       default:
+               err = -EINVAL;
++              goto out_unlock1;
+       }
+ out_unlock0:
diff --git a/queue-3.10/ipc-msg-shorten-critical-region-in-msgrcv.patch b/queue-3.10/ipc-msg-shorten-critical-region-in-msgrcv.patch
new file mode 100644 (file)
index 0000000..16fa2f9
--- /dev/null
@@ -0,0 +1,183 @@
+From 41a0d523d0f626e9da0dc01de47f1b89058033cf Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:18 -0700
+Subject: ipc,msg: shorten critical region in msgrcv
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 41a0d523d0f626e9da0dc01de47f1b89058033cf upstream.
+
+do_msgrcv() is the last msg queue function that abuses the ipc lock Take
+it only when needed when actually updating msq.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   58 ++++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 32 insertions(+), 26 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -886,21 +886,19 @@ static struct msg_msg *find_msg(struct m
+       return found ?: ERR_PTR(-EAGAIN);
+ }
+-
+-long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
+-             int msgflg,
++long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
+              long (*msg_handler)(void __user *, struct msg_msg *, size_t))
+ {
+-      struct msg_queue *msq;
+-      struct msg_msg *msg;
+       int mode;
++      struct msg_queue *msq;
+       struct ipc_namespace *ns;
+-      struct msg_msg *copy = NULL;
++      struct msg_msg *msg, *copy = NULL;
+       ns = current->nsproxy->ipc_ns;
+       if (msqid < 0 || (long) bufsz < 0)
+               return -EINVAL;
++
+       if (msgflg & MSG_COPY) {
+               copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax));
+               if (IS_ERR(copy))
+@@ -908,8 +906,10 @@ long do_msgrcv(int msqid, void __user *b
+       }
+       mode = convert_mode(&msgtyp, msgflg);
+-      msq = msg_lock_check(ns, msqid);
++      rcu_read_lock();
++      msq = msq_obtain_object_check(ns, msqid);
+       if (IS_ERR(msq)) {
++              rcu_read_unlock();
+               free_copy(copy);
+               return PTR_ERR(msq);
+       }
+@@ -919,10 +919,10 @@ long do_msgrcv(int msqid, void __user *b
+               msg = ERR_PTR(-EACCES);
+               if (ipcperms(ns, &msq->q_perm, S_IRUGO))
+-                      goto out_unlock;
++                      goto out_unlock1;
++              ipc_lock_object(&msq->q_perm);
+               msg = find_msg(msq, &msgtyp, mode);
+-
+               if (!IS_ERR(msg)) {
+                       /*
+                        * Found a suitable message.
+@@ -930,7 +930,7 @@ long do_msgrcv(int msqid, void __user *b
+                        */
+                       if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
+                               msg = ERR_PTR(-E2BIG);
+-                              goto out_unlock;
++                              goto out_unlock0;
+                       }
+                       /*
+                        * If we are copying, then do not unlink message and do
+@@ -938,8 +938,9 @@ long do_msgrcv(int msqid, void __user *b
+                        */
+                       if (msgflg & MSG_COPY) {
+                               msg = copy_msg(msg, copy);
+-                              goto out_unlock;
++                              goto out_unlock0;
+                       }
++
+                       list_del(&msg->m_list);
+                       msq->q_qnum--;
+                       msq->q_rtime = get_seconds();
+@@ -948,14 +949,16 @@ long do_msgrcv(int msqid, void __user *b
+                       atomic_sub(msg->m_ts, &ns->msg_bytes);
+                       atomic_dec(&ns->msg_hdrs);
+                       ss_wakeup(&msq->q_senders, 0);
+-                      msg_unlock(msq);
+-                      break;
++
++                      goto out_unlock0;
+               }
++
+               /* No message waiting. Wait for a message */
+               if (msgflg & IPC_NOWAIT) {
+                       msg = ERR_PTR(-ENOMSG);
+-                      goto out_unlock;
++                      goto out_unlock0;
+               }
++
+               list_add_tail(&msr_d.r_list, &msq->q_receivers);
+               msr_d.r_tsk = current;
+               msr_d.r_msgtype = msgtyp;
+@@ -966,8 +969,9 @@ long do_msgrcv(int msqid, void __user *b
+                       msr_d.r_maxsize = bufsz;
+               msr_d.r_msg = ERR_PTR(-EAGAIN);
+               current->state = TASK_INTERRUPTIBLE;
+-              msg_unlock(msq);
++              ipc_unlock_object(&msq->q_perm);
++              rcu_read_unlock();
+               schedule();
+               /* Lockless receive, part 1:
+@@ -978,7 +982,7 @@ long do_msgrcv(int msqid, void __user *b
+                * Prior to destruction, expunge_all(-EIRDM) changes r_msg.
+                * Thus if r_msg is -EAGAIN, then the queue not yet destroyed.
+                * rcu_read_lock() prevents preemption between reading r_msg
+-               * and the spin_lock() inside ipc_lock_by_ptr().
++               * and acquiring the q_perm.lock in ipc_lock_object().
+                */
+               rcu_read_lock();
+@@ -997,32 +1001,34 @@ long do_msgrcv(int msqid, void __user *b
+                * If there is a message or an error then accept it without
+                * locking.
+                */
+-              if (msg != ERR_PTR(-EAGAIN)) {
+-                      rcu_read_unlock();
+-                      break;
+-              }
++              if (msg != ERR_PTR(-EAGAIN))
++                      goto out_unlock1;
+               /* Lockless receive, part 3:
+                * Acquire the queue spinlock.
+                */
+-              ipc_lock_by_ptr(&msq->q_perm);
+-              rcu_read_unlock();
++              ipc_lock_object(&msq->q_perm);
+               /* Lockless receive, part 4:
+                * Repeat test after acquiring the spinlock.
+                */
+               msg = (struct msg_msg*)msr_d.r_msg;
+               if (msg != ERR_PTR(-EAGAIN))
+-                      goto out_unlock;
++                      goto out_unlock0;
+               list_del(&msr_d.r_list);
+               if (signal_pending(current)) {
+                       msg = ERR_PTR(-ERESTARTNOHAND);
+-out_unlock:
+-                      msg_unlock(msq);
+-                      break;
++                      goto out_unlock0;
+               }
++
++              ipc_unlock_object(&msq->q_perm);
+       }
++
++out_unlock0:
++      ipc_unlock_object(&msq->q_perm);
++out_unlock1:
++      rcu_read_unlock();
+       if (IS_ERR(msg)) {
+               free_copy(copy);
+               return PTR_ERR(msg);
diff --git a/queue-3.10/ipc-msg-shorten-critical-region-in-msgsnd.patch b/queue-3.10/ipc-msg-shorten-critical-region-in-msgsnd.patch
new file mode 100644 (file)
index 0000000..afff878
--- /dev/null
@@ -0,0 +1,117 @@
+From 3dd1f784ed6603d7ab1043e51e6371235edf2313 Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:17 -0700
+Subject: ipc,msg: shorten critical region in msgsnd
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 3dd1f784ed6603d7ab1043e51e6371235edf2313 upstream.
+
+do_msgsnd() is another function that does too many things with the ipc
+object lock acquired.  Take it only when needed when actually updating
+msq.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   37 ++++++++++++++++++++++++-------------
+ 1 file changed, 24 insertions(+), 13 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -698,10 +698,11 @@ long do_msgsnd(int msqid, long mtype, vo
+       msg->m_type = mtype;
+       msg->m_ts = msgsz;
+-      msq = msg_lock_check(ns, msqid);
++      rcu_read_lock();
++      msq = msq_obtain_object_check(ns, msqid);
+       if (IS_ERR(msq)) {
+               err = PTR_ERR(msq);
+-              goto out_free;
++              goto out_unlock1;
+       }
+       for (;;) {
+@@ -709,11 +710,11 @@ long do_msgsnd(int msqid, long mtype, vo
+               err = -EACCES;
+               if (ipcperms(ns, &msq->q_perm, S_IWUGO))
+-                      goto out_unlock_free;
++                      goto out_unlock1;
+               err = security_msg_queue_msgsnd(msq, msg, msgflg);
+               if (err)
+-                      goto out_unlock_free;
++                      goto out_unlock1;
+               if (msgsz + msq->q_cbytes <= msq->q_qbytes &&
+                               1 + msq->q_qnum <= msq->q_qbytes) {
+@@ -723,32 +724,41 @@ long do_msgsnd(int msqid, long mtype, vo
+               /* queue full, wait: */
+               if (msgflg & IPC_NOWAIT) {
+                       err = -EAGAIN;
+-                      goto out_unlock_free;
++                      goto out_unlock1;
+               }
++
++              ipc_lock_object(&msq->q_perm);
+               ss_add(msq, &s);
+               if (!ipc_rcu_getref(msq)) {
+                       err = -EIDRM;
+-                      goto out_unlock_free;
++                      goto out_unlock0;
+               }
+-              msg_unlock(msq);
++              ipc_unlock_object(&msq->q_perm);
++              rcu_read_unlock();
+               schedule();
+-              ipc_lock_by_ptr(&msq->q_perm);
++              rcu_read_lock();
++              ipc_lock_object(&msq->q_perm);
++
+               ipc_rcu_putref(msq);
+               if (msq->q_perm.deleted) {
+                       err = -EIDRM;
+-                      goto out_unlock_free;
++                      goto out_unlock0;
+               }
++
+               ss_del(&s);
+               if (signal_pending(current)) {
+                       err = -ERESTARTNOHAND;
+-                      goto out_unlock_free;
++                      goto out_unlock0;
+               }
++
++              ipc_unlock_object(&msq->q_perm);
+       }
++      ipc_lock_object(&msq->q_perm);
+       msq->q_lspid = task_tgid_vnr(current);
+       msq->q_stime = get_seconds();
+@@ -764,9 +774,10 @@ long do_msgsnd(int msqid, long mtype, vo
+       err = 0;
+       msg = NULL;
+-out_unlock_free:
+-      msg_unlock(msq);
+-out_free:
++out_unlock0:
++      ipc_unlock_object(&msq->q_perm);
++out_unlock1:
++      rcu_read_unlock();
+       if (msg != NULL)
+               free_msg(msg);
+       return err;
diff --git a/queue-3.10/ipc-remove-unused-functions.patch b/queue-3.10/ipc-remove-unused-functions.patch
new file mode 100644 (file)
index 0000000..8498080
--- /dev/null
@@ -0,0 +1,69 @@
+From 9ad66ae65fc8d3e7e3344310fb0aa835910264fe Mon Sep 17 00:00:00 2001
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Date: Mon, 8 Jul 2013 16:01:19 -0700
+Subject: ipc: remove unused functions
+
+From: Davidlohr Bueso <davidlohr.bueso@hp.com>
+
+commit 9ad66ae65fc8d3e7e3344310fb0aa835910264fe upstream.
+
+We can now drop the msg_lock and msg_lock_check functions along with a
+bogus comment introduced previously in semctl_down.
+
+Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
+Cc: Andi Kleen <andi@firstfloor.org>
+Cc: Rik van Riel <riel@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/msg.c |   25 -------------------------
+ ipc/sem.c |    1 -
+ 2 files changed, 26 deletions(-)
+
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -141,31 +141,6 @@ void __init msg_init(void)
+                               IPC_MSG_IDS, sysvipc_msg_proc_show);
+ }
+-/*
+- * msg_lock_(check_) routines are called in the paths where the rw_mutex
+- * is not held.
+- */
+-static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id)
+-{
+-      struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id);
+-
+-      if (IS_ERR(ipcp))
+-              return (struct msg_queue *)ipcp;
+-
+-      return container_of(ipcp, struct msg_queue, q_perm);
+-}
+-
+-static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns,
+-                                              int id)
+-{
+-      struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id);
+-
+-      if (IS_ERR(ipcp))
+-              return (struct msg_queue *)ipcp;
+-
+-      return container_of(ipcp, struct msg_queue, q_perm);
+-}
+-
+ static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id)
+ {
+       struct kern_ipc_perm *ipcp = ipc_obtain_object(&msg_ids(ns), id);
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -1296,7 +1296,6 @@ static int semctl_down(struct ipc_namesp
+                                     &semid64.sem_perm, 0);
+       if (IS_ERR(ipcp)) {
+               err = PTR_ERR(ipcp);
+-              /* the ipc lock is not held upon failure */
+               goto out_unlock1;
+       }
index c9485d70a158151c0e6c3e55d133f38a240b7eae..456597e69cc8b45d30d5317af05e5b9dae929cd5 100644 (file)
@@ -20,3 +20,21 @@ arc-workaround-spinlock-livelock-in-smp-systemc-simulation.patch
 arc-fix-signal-frame-management-for-sa_siginfo.patch
 arc-ignore-ptrace-setregset-request-for-synthetic-register-stop_pc.patch
 watchdog-ts72xx_wdt-locking-bug-in-ioctl.patch
+compiler-gcc4-add-quirk-for-asm-goto-miscompilation-bug.patch
+0310-ALSA-hda-Fix-mono-speakers-and-headset-mic-on-Dell-V.patch
+cope-with-potentially-long-d_dname-output-for.patch
+drm-i915-only-apply-dpms-to-the-encoder-if-enabled.patch
+drm-radeon-forever-loop-on-error-in-radeon_do_test_moves.patch
+drm-radeon-fix-typo-in-cp-dma-register-headers.patch
+drm-radeon-fix-hw-contexts-for-sumo2-asics.patch
+ipc-move-rcu-lock-out-of-ipc_addid.patch
+ipc-introduce-ipc-object-locking-helpers.patch
+ipc-close-open-coded-spin-lock-calls.patch
+ipc-move-locking-out-of-ipcctl_pre_down_nolock.patch
+ipc-msg-shorten-critical-region-in-msgctl_down.patch
+ipc-msg-introduce-msgctl_nolock.patch
+ipc-msg-introduce-lockless-functions-to-obtain-the-ipc-object.patch
+ipc-msg-make-msgctl_nolock-lockless.patch
+ipc-msg-shorten-critical-region-in-msgsnd.patch
+ipc-msg-shorten-critical-region-in-msgrcv.patch
+ipc-remove-unused-functions.patch