From: Greg Kroah-Hartman Date: Tue, 15 Oct 2013 18:48:50 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.10.17~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9043e8277c6c391e96d4bfd52fac1c7c25637b0d;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches 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 --- 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 index 00000000000..d9ab5870bad --- /dev/null +++ b/queue-3.10/0310-ALSA-hda-Fix-mono-speakers-and-headset-mic-on-Dell-V.patch @@ -0,0 +1,89 @@ +From 262b9bf43ad0714531d9f60da141e5173dc808aa Mon Sep 17 00:00:00 2001 +From: David Henningsson +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 + +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 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..65d81ab7781 --- /dev/null +++ b/queue-3.10/compiler-gcc4-add-quirk-for-asm-goto-miscompilation-bug.patch @@ -0,0 +1,140 @@ +From 3f0116c3238a96bc18ad4b4acefe4e7be32fa861 Mon Sep 17 00:00:00 2001 +From: Ingo Molnar +Date: Thu, 10 Oct 2013 10:16:30 +0200 +Subject: compiler/gcc4: Add quirk for 'asm goto' miscompilation bug + +From: Ingo Molnar + +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 +Reported-by: Oleg Nesterov +Reported-by: Peter Zijlstra +Suggested-by: Jakub Jelinek +Reviewed-by: Richard Henderson +Cc: Linus Torvalds +Cc: Andrew Morton +Link: http://lkml.kernel.org/r/20131015062351.GA4666@gmail.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1e3fbecc0bd --- /dev/null +++ b/queue-3.10/cope-with-potentially-long-d_dname-output-for.patch @@ -0,0 +1,93 @@ +From 118b23022512eb2f41ce42db70dc0568d00be4ba Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sat, 24 Aug 2013 12:08:17 -0400 +Subject: cope with potentially long ->d_dname() output for + shmem/hugetlb + +From: Al Viro + +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 +Cc: Colin Cross +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..18d7accb8e7 --- /dev/null +++ b/queue-3.10/drm-i915-only-apply-dpms-to-the-encoder-if-enabled.patch @@ -0,0 +1,97 @@ +From c9976dcf55c8aaa7037427b239f15e5acfc01a3a Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Sun, 29 Sep 2013 19:15:07 +0100 +Subject: drm/i915: Only apply DPMS to the encoder if enabled + +From: Chris Wilson + +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] [] dump_stack+0x54/0x8d +[ 354.803101] [] warn_slowpath_common+0x73/0x90 +[ 354.803103] [] warn_slowpath_fmt+0x47/0x50 +[ 354.803109] [] ? intel_ddi_connector_get_hw_state+0x5e/0x110 [i915] +[ 354.803114] [] intel_modeset_check_state+0x764/0x770 [i915] +[ 354.803117] [] intel_connector_dpms+0x3b/0x60 [i915] +[ 354.803120] [] drm_fb_helper_dpms.isra.11+0x120/0x160 [drm_kms_helper] +[ 354.803122] [] drm_fb_helper_blank+0x3e/0x80 [drm_kms_helper] +[ 354.803123] [] fb_blank+0x52/0xc0 +[ 354.803125] [] fbcon_blank+0x21b/0x2d0 +[ 354.803127] [] ? update_rq_clock.part.74+0x13/0x30 +[ 354.803129] [] ? lock_timer_base.isra.30+0x26/0x50 +[ 354.803130] [] ? internal_add_timer+0x12/0x40 +[ 354.803131] [] ? mod_timer+0xf8/0x1c0 +[ 354.803133] [] do_unblank_screen+0xa1/0x1c0 +[ 354.803134] [] poke_blanked_console+0xc7/0xd0 +[ 354.803136] [] console_callback+0x13f/0x160 +[ 354.803137] [] process_one_work+0x148/0x3d0 +[ 354.803138] [] worker_thread+0x119/0x3a0 +[ 354.803140] [] ? manage_workers.isra.30+0x2a0/0x2a0 +[ 354.803141] [] kthread+0xbb/0xc0 +[ 354.803142] [] ? kthread_create_on_node+0x120/0x120 +[ 354.803144] [] ret_from_fork+0x7c/0xb0 +[ 354.803145] [] ? 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 +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 +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 +[danvet: Add regression citation, mention the igt testcase this fixes +and slap a cc: stable on the patch.] +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c4147c6555f --- /dev/null +++ b/queue-3.10/drm-radeon-fix-hw-contexts-for-sumo2-asics.patch @@ -0,0 +1,33 @@ +From 50b8f5aec04ebec7dbdf2adb17220b9148c99e63 Mon Sep 17 00:00:00 2001 +From: wojciech kapuscinski +Date: Tue, 1 Oct 2013 19:54:33 -0400 +Subject: drm/radeon: fix hw contexts for SUMO2 asics + +From: wojciech kapuscinski + +commit 50b8f5aec04ebec7dbdf2adb17220b9148c99e63 upstream. + +They have 4 rather than 8. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=63599 + +Signed-off-by: wojciech kapuscinski +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a594df003cb --- /dev/null +++ b/queue-3.10/drm-radeon-fix-typo-in-cp-dma-register-headers.patch @@ -0,0 +1,71 @@ +From aa3e146d04b6ae37939daeebaec060562b3db559 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 1 Oct 2013 16:40:45 -0400 +Subject: drm/radeon: fix typo in CP DMA register headers + +From: Alex Deucher + +commit aa3e146d04b6ae37939daeebaec060562b3db559 upstream. + +Wrong bit offset for SRC endian swapping. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..105d2b61d64 --- /dev/null +++ b/queue-3.10/drm-radeon-forever-loop-on-error-in-radeon_do_test_moves.patch @@ -0,0 +1,36 @@ +From 89cd67b326fa95872cc2b4524cd807128db6071d Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 1 Jul 2013 19:39:34 +0300 +Subject: drm/radeon: forever loop on error in radeon_do_test_moves() + +From: Dan Carpenter + +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 +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..6c73859f1f7 --- /dev/null +++ b/queue-3.10/ipc-close-open-coded-spin-lock-calls.patch @@ -0,0 +1,137 @@ +From cf9d5d78d05bca96df7618dfc3a5ee4414dcae58 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:11 -0700 +Subject: ipc: close open coded spin lock calls + +From: Davidlohr Bueso + +commit cf9d5d78d05bca96df7618dfc3a5ee4414dcae58 upstream. + +Signed-off-by: Davidlohr Bueso +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e0d77f63320 --- /dev/null +++ b/queue-3.10/ipc-introduce-ipc-object-locking-helpers.patch @@ -0,0 +1,64 @@ +From 1ca7003ab41152d673d9e359632283d05294f3d6 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:10 -0700 +Subject: ipc: introduce ipc object locking helpers + +From: Davidlohr Bueso + +commit 1ca7003ab41152d673d9e359632283d05294f3d6 upstream. + +Simple helpers around the (kern_ipc_perm *)->lock spinlock. + +Signed-off-by: Davidlohr Bueso +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f5183ddd98c --- /dev/null +++ b/queue-3.10/ipc-move-locking-out-of-ipcctl_pre_down_nolock.patch @@ -0,0 +1,248 @@ +From 7b4cc5d8411bd4e9d61d8714f53859740cf830c2 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:12 -0700 +Subject: ipc: move locking out of ipcctl_pre_down_nolock + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f509a13e43c --- /dev/null +++ b/queue-3.10/ipc-move-rcu-lock-out-of-ipc_addid.patch @@ -0,0 +1,106 @@ +From dbfcd91f06f0e2d5564b2fd184e9c2a43675f9ab Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:09 -0700 +Subject: ipc: move rcu lock out of ipc_addid + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..fe7cd254d09 --- /dev/null +++ b/queue-3.10/ipc-msg-introduce-lockless-functions-to-obtain-the-ipc-object.patch @@ -0,0 +1,56 @@ +From a5001a0d9768568de5d613c3b3a5b9c7721299da Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:15 -0700 +Subject: ipc,msg: introduce lockless functions to obtain the ipc object + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..6804854684e --- /dev/null +++ b/queue-3.10/ipc-msg-introduce-msgctl_nolock.patch @@ -0,0 +1,117 @@ +From 2cafed30f150f7314f98717b372df8173516cae0 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:14 -0700 +Subject: ipc,msg: introduce msgctl_nolock + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..fb3a6bbe583 --- /dev/null +++ b/queue-3.10/ipc-msg-make-msgctl_nolock-lockless.patch @@ -0,0 +1,89 @@ +From ac0ba20ea6f2201a1589d6dc26ad1a4f0f967bb8 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:16 -0700 +Subject: ipc,msg: make msgctl_nolock lockless + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e1a3b51be82 --- /dev/null +++ b/queue-3.10/ipc-msg-shorten-critical-region-in-msgctl_down.patch @@ -0,0 +1,74 @@ +From 15724ecb7e9bab35fc694c666ad563adba820cc3 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:13 -0700 +Subject: ipc,msg: shorten critical region in msgctl_down + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..16fa2f970db --- /dev/null +++ b/queue-3.10/ipc-msg-shorten-critical-region-in-msgrcv.patch @@ -0,0 +1,183 @@ +From 41a0d523d0f626e9da0dc01de47f1b89058033cf Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:18 -0700 +Subject: ipc,msg: shorten critical region in msgrcv + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Tested-by: Sedat Dilek +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..afff8784dfe --- /dev/null +++ b/queue-3.10/ipc-msg-shorten-critical-region-in-msgsnd.patch @@ -0,0 +1,117 @@ +From 3dd1f784ed6603d7ab1043e51e6371235edf2313 Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:17 -0700 +Subject: ipc,msg: shorten critical region in msgsnd + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..84980809ce1 --- /dev/null +++ b/queue-3.10/ipc-remove-unused-functions.patch @@ -0,0 +1,69 @@ +From 9ad66ae65fc8d3e7e3344310fb0aa835910264fe Mon Sep 17 00:00:00 2001 +From: Davidlohr Bueso +Date: Mon, 8 Jul 2013 16:01:19 -0700 +Subject: ipc: remove unused functions + +From: Davidlohr Bueso + +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 +Cc: Andi Kleen +Cc: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Mike Galbraith +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-3.10/series b/queue-3.10/series index c9485d70a15..456597e69cc 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -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