* [ 00/69] 3.10.17-stable review
@ 2013-10-16 17:44 Greg Kroah-Hartman
2013-10-16 17:44 ` [ 01/69] ALSA: snd-usb-usx2y: remove bogus frame checks Greg Kroah-Hartman
` (70 more replies)
0 siblings, 71 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, torvalds, akpm, stable
This is the start of the stable review cycle for the 3.10.17 release.
There are 69 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
You might notice a bunch of ipc patches in this series. That is to
resolve some reported ipc bugs / scalabity issues. Additional testing
of these code paths would be greatly appreciated.
Responses should be made by Fri Oct 18 17:41:53 UTC 2013.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.10.17-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Linux 3.10.17-rc1
Linn Crosetto <linn@hp.com>
x86: avoid remapping data in parse_setup_data()
Davidlohr Bueso <davidlohr@hp.com>
ipc,msg: prevent race with rmid in msgsnd,msgrcv
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: update sem_otime for all operations
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: synchronize the proc interface
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: optimize sem_lock()
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: fix race in sem_lock()
Davidlohr Bueso <davidlohr@hp.com>
ipc: fix race with LSMs
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: drop ipc_lock_check
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc, shm: drop shm_lock_check
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: drop ipc_lock_by_ptr
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc, shm: guard against non-existant vma in shmdt(2)
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: document general ipc locking scheme
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: drop msg_unlock
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: rename ids->rw_mutex
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: shorten critical region for shmat
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: cleanup do_shmat pasta
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: shorten critical region for shmctl
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: make shmctl_nolock lockless
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: introduce shmctl_nolock
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: drop ipcctl_pre_down
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: shorten critical region in shmctl_down
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,shm: introduce lockless functions to obtain the ipc object
Manfred Spraul <manfred@colorfullife.com>
ipc/msg.c: Fix lost wakeup in msgsnd().
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: rename try_atomic_semop() to perform_atomic_semop(), docu update
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: replace shared sem_otime with per-semaphore value
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: always use only one queue for alter operations
Manfred Spraul <manfred@colorfullife.com>
ipc/sem: separate wait-for-zero and alter tasks into seperate queues
Manfred Spraul <manfred@colorfullife.com>
ipc/sem.c: cacheline align the semaphore structures
Manfred Spraul <manfred@colorfullife.com>
ipc/util.c, ipc_rcu_alloc: cacheline align allocation
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: remove unused functions
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: shorten critical region in msgrcv
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: shorten critical region in msgsnd
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: make msgctl_nolock lockless
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: introduce lockless functions to obtain the ipc object
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: introduce msgctl_nolock
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc,msg: shorten critical region in msgctl_down
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: move locking out of ipcctl_pre_down_nolock
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: close open coded spin lock calls
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: introduce ipc object locking helpers
Davidlohr Bueso <davidlohr.bueso@hp.com>
ipc: move rcu lock out of ipc_addid
wojciech kapuscinski <wojtask9@wp.pl>
drm/radeon: fix hw contexts for SUMO2 asics
Alex Deucher <alexander.deucher@amd.com>
drm/radeon: fix typo in CP DMA register headers
Dan Carpenter <dan.carpenter@oracle.com>
drm/radeon: forever loop on error in radeon_do_test_moves()
Chris Wilson <chris@chris-wilson.co.uk>
drm/i915: Only apply DPMS to the encoder if enabled
Al Viro <viro@zeniv.linux.org.uk>
cope with potentially long ->d_dname() output for shmem/hugetlb
David Henningsson <david.henningsson@canonical.com>
ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470
Ingo Molnar <mingo@kernel.org>
compiler/gcc4: Add quirk for 'asm goto' miscompilation bug
Dan Carpenter <dan.carpenter@oracle.com>
watchdog: ts72xx_wdt: locking bug in ioctl
Vineet Gupta <vgupta@synopsys.com>
ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc"
Christian Ruppert <christian.ruppert@abilis.com>
ARC: Fix signal frame management for SA_SIGINFO
Vineet Gupta <vgupta@synopsys.com>
ARC: Workaround spinlock livelock in SMP SystemC simulation
Vineet Gupta <vgupta@synopsys.com>
ARC: Fix 32-bit wrap around in access_ok()
Mischa Jonker <mjonker@synopsys.com>
ARC: Handle zero-overhead-loop in unaligned access handler
Mischa Jonker <mjonker@synopsys.com>
ARC: Fix __udelay calculation
Noam Camus <noamc@ezchip.com>
ARC: SMP failed to boot due to missing IVT setup
Vineet Gupta <vgupta@synopsys.com>
ARC: Setup Vector Table Base in early boot
Russell King <rmk+kernel@arm.linux.org.uk>
ARM: Fix the world famous typo with is_gate_vma()
Helge Deller <deller@gmx.de>
parisc: fix interruption handler to respect pagefault_disable()
Paul Mackerras <paulus@samba.org>
KVM: PPC: Book3S HV: Fix typo in saving DSCR
Dave Jones <davej@redhat.com>
ext4: fix memory leak in xattr
Josef Bacik <jbacik@fusionio.com>
Btrfs: use right root when checking for hash collision
Henrik Rydberg <rydberg@euromail.se>
hwmon: (applesmc) Always read until end of data
Taras Kondratiuk <taras.kondratiuk@linaro.org>
i2c: omap: Clear ARDY bit twice
Linus Torvalds <torvalds@linux-foundation.org>
vfs: allow O_PATH file descriptors for fstatfs()
Theodore Ts'o <tytso@mit.edu>
random: run random_int_secret_init() run after all late_initcalls
David Henningsson <david.henningsson@canonical.com>
ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model)
Takashi Iwai <tiwai@suse.de>
ALSA: hda - Add fixup for ASUS N56VZ
Anssi Hannula <anssi.hannula@iki.fi>
ALSA: hda - hdmi: Fix channel map switch not taking effect
Daniel Mack <zonque@gmail.com>
ALSA: snd-usb-usx2y: remove bogus frame checks
-------------
Diffstat:
Makefile | 4 +-
arch/arc/include/asm/delay.h | 5 +-
arch/arc/include/asm/sections.h | 1 -
arch/arc/include/asm/spinlock.h | 9 +-
arch/arc/include/asm/uaccess.h | 4 +-
arch/arc/kernel/head.S | 7 +
arch/arc/kernel/irq.c | 3 -
arch/arc/kernel/ptrace.c | 2 +-
arch/arc/kernel/setup.c | 3 -
arch/arc/kernel/signal.c | 25 +-
arch/arc/kernel/unaligned.c | 6 +
arch/arm/include/asm/jump_label.h | 2 +-
arch/arm/kernel/process.c | 2 +-
arch/mips/include/asm/jump_label.h | 2 +-
arch/parisc/kernel/traps.c | 6 +-
arch/powerpc/include/asm/jump_label.h | 2 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 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/e820.h | 2 +-
arch/x86/include/asm/jump_label.h | 2 +-
arch/x86/kernel/e820.c | 5 +-
arch/x86/kernel/setup.c | 19 +-
drivers/char/random.c | 3 +-
drivers/gpu/drm/i915/intel_display.c | 8 +-
drivers/gpu/drm/radeon/evergreen.c | 2 +-
drivers/gpu/drm/radeon/evergreend.h | 4 +-
drivers/gpu/drm/radeon/r600d.h | 2 +-
drivers/gpu/drm/radeon/radeon_test.c | 4 +-
drivers/gpu/drm/radeon/sid.h | 4 +-
drivers/hwmon/applesmc.c | 13 +
drivers/i2c/busses/i2c-omap.c | 3 +
drivers/watchdog/ts72xx_wdt.c | 3 +-
fs/btrfs/inode.c | 2 +-
fs/dcache.c | 11 +
fs/ext4/xattr.c | 2 +
fs/hugetlbfs/inode.c | 8 +-
fs/statfs.c | 2 +-
include/linux/compiler-gcc4.h | 15 +
include/linux/dcache.h | 1 +
include/linux/ipc_namespace.h | 2 +-
include/linux/random.h | 1 +
include/linux/sem.h | 6 +-
init/main.c | 2 +
ipc/msg.c | 281 ++++++++------
ipc/namespace.c | 7 +-
ipc/sem.c | 660 ++++++++++++++++++++++----------
ipc/shm.c | 288 ++++++++------
ipc/util.c | 140 +++----
ipc/util.h | 34 +-
mm/shmem.c | 8 +-
sound/pci/hda/patch_hdmi.c | 18 +-
sound/pci/hda/patch_realtek.c | 37 ++
sound/usb/usx2y/usbusx2yaudio.c | 22 +-
sound/usb/usx2y/usx2yhwdeppcm.c | 7 +-
56 files changed, 1062 insertions(+), 657 deletions(-)
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 01/69] ALSA: snd-usb-usx2y: remove bogus frame checks
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 02/69] ALSA: hda - hdmi: Fix channel map switch not taking effect Greg Kroah-Hartman
` (69 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Dr Nicholas J Bailey, Takashi Iwai,
Daniel Mack, fzu
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Mack <zonque@gmail.com>
commit a9d14bc0b188a822e42787d01e56c06fe9750162 upstream.
The frame check in i_usX2Y_urb_complete() and
i_usX2Y_usbpcm_urb_complete() is bogus and produces false positives as
described in this LAU thread:
http://linuxaudio.org/mailarchive/lau/2013/5/20/200177
This patch removes the check code entirely.
Cc: fzu@wemgehoertderstaat.de
Reported-by: Dr Nicholas J Bailey <nicholas.bailey@glasgow.ac.uk>
Suggested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/usx2y/usbusx2yaudio.c | 22 +++-------------------
sound/usb/usx2y/usx2yhwdeppcm.c | 7 +------
2 files changed, 4 insertions(+), 25 deletions(-)
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -299,19 +299,6 @@ static void usX2Y_error_urb_status(struc
usX2Y_clients_stop(usX2Y);
}
-static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- snd_printk(KERN_ERR
-"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-"Most probably some urb of usb-frame %i is still missing.\n"
-"Cause could be too long delays in usb-hcd interrupt handling.\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
- usX2Y_clients_stop(usX2Y);
-}
-
static void i_usX2Y_urb_complete(struct urb *urb)
{
struct snd_usX2Y_substream *subs = urb->context;
@@ -328,12 +315,9 @@ static void i_usX2Y_urb_complete(struct
usX2Y_error_urb_status(usX2Y, subs, urb);
return;
}
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
+
+ subs->completed_urb = urb;
+
{
struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -244,13 +244,8 @@ static void i_usX2Y_usbpcm_urb_complete(
usX2Y_error_urb_status(usX2Y, subs, urb);
return;
}
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
+ subs->completed_urb = urb;
capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 02/69] ALSA: hda - hdmi: Fix channel map switch not taking effect
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
2013-10-16 17:44 ` [ 01/69] ALSA: snd-usb-usx2y: remove bogus frame checks Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 03/69] ALSA: hda - Add fixup for ASUS N56VZ Greg Kroah-Hartman
` (68 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Anssi Hannula, Takashi Iwai
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anssi Hannula <anssi.hannula@iki.fi>
commit 39edac70e9aedf451fccaa851b273ace9fcca0bd upstream.
Currently hdmi_setup_audio_infoframe() reprograms the HDA channel
mapping only when the infoframe is not up-to-date or the non-PCM flag
has changed.
However, when just the channel map has been changed, the infoframe may
still be up-to-date and non-PCM flag may not have changed, so the new
channel map is not actually programmed into the HDA codec.
Notably, this failing case is also always triggered when the device is
already in a prepared state and a new channel map is configured while
changing only the channel positions (for example, plain
"speaker-test -c2 -m FR,FL").
Fix that by always programming the channel map in
hdmi_setup_audio_infoframe(). Tested on Intel HDMI.
Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/pci/hda/patch_hdmi.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -930,6 +930,14 @@ static void hdmi_setup_audio_infoframe(s
}
/*
+ * always configure channel mapping, it may have been changed by the
+ * user in the meantime
+ */
+ hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
+ channels, per_pin->chmap,
+ per_pin->chmap_set);
+
+ /*
* sizeof(ai) is used instead of sizeof(*hdmi_ai) or
* sizeof(*dp_ai) to avoid partial match/update problems when
* the user switches between HDMI/DP monitors.
@@ -940,20 +948,10 @@ static void hdmi_setup_audio_infoframe(s
"pin=%d channels=%d\n",
pin_nid,
channels);
- hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
- channels, per_pin->chmap,
- per_pin->chmap_set);
hdmi_stop_infoframe_trans(codec, pin_nid);
hdmi_fill_audio_infoframe(codec, pin_nid,
ai.bytes, sizeof(ai));
hdmi_start_infoframe_trans(codec, pin_nid);
- } else {
- /* For non-pcm audio switch, setup new channel mapping
- * accordingly */
- if (per_pin->non_pcm != non_pcm)
- hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
- channels, per_pin->chmap,
- per_pin->chmap_set);
}
per_pin->non_pcm = non_pcm;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 03/69] ALSA: hda - Add fixup for ASUS N56VZ
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
2013-10-16 17:44 ` [ 01/69] ALSA: snd-usb-usx2y: remove bogus frame checks Greg Kroah-Hartman
2013-10-16 17:44 ` [ 02/69] ALSA: hda - hdmi: Fix channel map switch not taking effect Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 04/69] ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model) Greg Kroah-Hartman
` (67 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Takashi Iwai
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit c6cc3d58b4042f5cadae653ff8d3df26af1a0169 upstream.
ASUS N56VZ needs a fixup for the bass speaker pin, which was already
provided via model=asus-mode4.
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=841645
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/pci/hda/patch_realtek.c | 1 +
1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4216,6 +4216,7 @@ static const struct snd_pci_quirk alc662
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
+ SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_ASUS_MODE4),
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 04/69] ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model)
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (2 preceding siblings ...)
2013-10-16 17:44 ` [ 03/69] ALSA: hda - Add fixup for ASUS N56VZ Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 05/69] random: run random_int_secret_init() run after all late_initcalls Greg Kroah-Hartman
` (66 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, David Henningsson, Takashi Iwai
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Henningsson <david.henningsson@canonical.com>
commit 88cfcf86aa3ada84d97195bcad74f4dadb4ae23b upstream.
The external mic showed up with a precense detect of "always present",
essentially disabling the internal mic. Therefore turn off presence
detection for this pin.
Note: The external mic seems not yet working, but an internal mic is
certainly better than no mic at all.
BugLink: https://bugs.launchpad.net/bugs/1227093
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 | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3223,6 +3223,7 @@ enum {
ALC269_FIXUP_HP_GPIO_LED,
ALC269_FIXUP_INV_DMIC,
ALC269_FIXUP_LENOVO_DOCK,
+ ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
@@ -3420,6 +3421,13 @@ static const struct hda_fixup alc269_fix
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode_no_hp_mic,
},
+ [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
+ { }
+ },
+ },
[ALC269_FIXUP_ASUS_X101_FUNC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_x101_headset_mic,
@@ -3529,6 +3537,7 @@ static const struct snd_pci_quirk alc269
SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
+ SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 05/69] random: run random_int_secret_init() run after all late_initcalls
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (3 preceding siblings ...)
2013-10-16 17:44 ` [ 04/69] ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model) Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 06/69] vfs: allow O_PATH file descriptors for fstatfs() Greg Kroah-Hartman
` (65 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Theodore Tso
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <tytso@mit.edu>
commit 47d06e532e95b71c0db3839ebdef3fe8812fca2c upstream.
The some platforms (e.g., ARM) initializes their clocks as
late_initcalls for some unknown reason. So make sure
random_int_secret_init() is run after all of the late_initcalls are
run.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/char/random.c | 3 +--
include/linux/random.h | 1 +
init/main.c | 2 ++
3 files changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1462,12 +1462,11 @@ ctl_table random_table[] = {
static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
-static int __init random_int_secret_init(void)
+int random_int_secret_init(void)
{
get_random_bytes(random_int_secret, sizeof(random_int_secret));
return 0;
}
-late_initcall(random_int_secret_init);
/*
* Get a random word for internal kernel use only. Similar to urandom but
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -17,6 +17,7 @@ extern void add_interrupt_randomness(int
extern void get_random_bytes(void *buf, int nbytes);
extern void get_random_bytes_arch(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
+extern int random_int_secret_init(void);
#ifndef MODULE
extern const struct file_operations random_fops, urandom_fops;
--- a/init/main.c
+++ b/init/main.c
@@ -74,6 +74,7 @@
#include <linux/ptrace.h>
#include <linux/blkdev.h>
#include <linux/elevator.h>
+#include <linux/random.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -777,6 +778,7 @@ static void __init do_basic_setup(void)
do_ctors();
usermodehelper_enable();
do_initcalls();
+ random_int_secret_init();
}
static void __init do_pre_smp_initcalls(void)
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 06/69] vfs: allow O_PATH file descriptors for fstatfs()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (4 preceding siblings ...)
2013-10-16 17:44 ` [ 05/69] random: run random_int_secret_init() run after all late_initcalls Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 07/69] i2c: omap: Clear ARDY bit twice Greg Kroah-Hartman
` (64 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Al Viro, Linus Torvalds
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <torvalds@linux-foundation.org>
commit 9d05746e7b16d8565dddbe3200faa1e669d23bbf upstream.
Olga reported that file descriptors opened with O_PATH do not work with
fstatfs(), found during further development of ksh93's thread support.
There is no reason to not allow O_PATH file descriptors here (fstatfs is
very much a path operation), so use "fdget_raw()". See commit
55815f70147d ("vfs: make O_PATH file descriptors usable for 'fstat()'")
for a very similar issue reported for fstat() by the same team.
Reported-and-tested-by: ольга крыжановская <olga.kryzhanovska@gmail.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/statfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -94,7 +94,7 @@ retry:
int fd_statfs(int fd, struct kstatfs *st)
{
- struct fd f = fdget(fd);
+ struct fd f = fdget_raw(fd);
int error = -EBADF;
if (f.file) {
error = vfs_statfs(&f.file->f_path, st);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 07/69] i2c: omap: Clear ARDY bit twice
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (5 preceding siblings ...)
2013-10-16 17:44 ` [ 06/69] vfs: allow O_PATH file descriptors for fstatfs() Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 08/69] hwmon: (applesmc) Always read until end of data Greg Kroah-Hartman
` (63 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Grygorii Strashko, Taras Kondratiuk,
Wolfram Sang
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taras Kondratiuk <taras.kondratiuk@linaro.org>
commit 4cdbf7d346e7461c3b93a26707c852e2c9db3753 upstream.
Initially commit cb527ede1bf6ff2008a025606f25344b8ed7b4ac
"i2c-omap: Double clear of ARDY status in IRQ handler"
added a workaround for undocumented errata ProDB0017052.
But then commit 1d7afc95946487945cc7f5019b41255b72224b70
"i2c: omap: ack IRQ in parts" refactored code and missed
one of ARDY clearings. So current code violates errata.
It causes often i2c bus timeouts on my Pandaboard.
This patch adds a second clearing in place.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/busses/i2c-omap.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -941,6 +941,9 @@ omap_i2c_isr_thread(int this_irq, void *
/*
* ProDB0017052: Clear ARDY bit twice
*/
+ if (stat & OMAP_I2C_STAT_ARDY)
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY);
+
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 08/69] hwmon: (applesmc) Always read until end of data
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (6 preceding siblings ...)
2013-10-16 17:44 ` [ 07/69] i2c: omap: Clear ARDY bit twice Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 09/69] Btrfs: use right root when checking for hash collision Greg Kroah-Hartman
` (62 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Chris Murphy, Henrik Rydberg,
Guenter Roeck
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henrik Rydberg <rydberg@euromail.se>
commit 25f2bd7f5add608c1d1405938f39c96927b275ca upstream.
The crash reported and investigated in commit 5f4513 turned out to be
caused by a change to the read interface on newer (2012) SMCs.
Tests by Chris show that simply reading the data valid line is enough
for the problem to go away. Additional tests show that the newer SMCs
no longer wait for the number of requested bytes, but start sending
data right away. Apparently the number of bytes to read is no longer
specified as before, but instead found out by reading until end of
data. Failure to read until end of data confuses the state machine,
which eventually causes the crash.
As a remedy, assuming bit0 is the read valid line, make sure there is
nothing more to read before leaving the read function.
Tested to resolve the original problem, and runtested on MBA3,1,
MBP4,1, MBP8,2, MBP10,1, MBP10,2. The patch seems to have no effect on
machines before 2012.
Tested-by: Chris Murphy <chris@cmurf.com>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/applesmc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -230,6 +230,7 @@ static int send_argument(const char *key
static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
{
+ u8 status, data = 0;
int i;
if (send_command(cmd) || send_argument(key)) {
@@ -237,6 +238,7 @@ static int read_smc(u8 cmd, const char *
return -EIO;
}
+ /* This has no effect on newer (2012) SMCs */
if (send_byte(len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: read len fail\n", key);
return -EIO;
@@ -250,6 +252,17 @@ static int read_smc(u8 cmd, const char *
buffer[i] = inb(APPLESMC_DATA_PORT);
}
+ /* Read the data port until bit0 is cleared */
+ for (i = 0; i < 16; i++) {
+ udelay(APPLESMC_MIN_WAIT);
+ status = inb(APPLESMC_CMD_PORT);
+ if (!(status & 0x01))
+ break;
+ data = inb(APPLESMC_DATA_PORT);
+ }
+ if (i)
+ pr_warn("flushed %d bytes, last value is: %d\n", i, data);
+
return 0;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 09/69] Btrfs: use right root when checking for hash collision
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (7 preceding siblings ...)
2013-10-16 17:44 ` [ 08/69] hwmon: (applesmc) Always read until end of data Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 10/69] ext4: fix memory leak in xattr Greg Kroah-Hartman
` (61 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Chris Murphy, Josef Bacik,
Chris Mason
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <jbacik@fusionio.com>
commit 4871c1588f92c6c13f4713a7009f25f217055807 upstream.
btrfs_rename was using the root of the old dir instead of the root of the new
dir when checking for a hash collision, so if you tried to move a file into a
subvol it would freak out because it would see the file you are trying to move
in its current root. This fixes the bug where this would fail
btrfs subvol create test1
btrfs subvol create test2
mv test1 test2.
Thanks to Chris Murphy for catching this,
Reported-by: Chris Murphy <lists@colorremedies.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/btrfs/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8146,7 +8146,7 @@ static int btrfs_rename(struct inode *ol
/* check for collisions, even if the name isn't there */
- ret = btrfs_check_dir_item_collision(root, new_dir->i_ino,
+ ret = btrfs_check_dir_item_collision(dest, new_dir->i_ino,
new_dentry->d_name.name,
new_dentry->d_name.len);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 10/69] ext4: fix memory leak in xattr
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (8 preceding siblings ...)
2013-10-16 17:44 ` [ 09/69] Btrfs: use right root when checking for hash collision Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 11/69] KVM: PPC: Book3S HV: Fix typo in saving DSCR Greg Kroah-Hartman
` (60 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Dave Jones, Theodore Tso,
Eric Sandeen
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jones <davej@redhat.com>
commit 6e4ea8e33b2057b85d75175dd89b93f5e26de3bc upstream.
If we take the 2nd retry path in ext4_expand_extra_isize_ea, we
potentionally return from the function without having freed these
allocations. If we don't do the return, we over-write the previous
allocation pointers, so we leak either way.
Spotted with Coverity.
[ Fixed by tytso to set is and bs to NULL after freeing these
pointers, in case in the retry loop we later end up triggering an
error causing a jump to cleanup, at which point we could have a double
free bug. -- Ted ]
Signed-off-by: Dave Jones <davej@fedoraproject.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ext4/xattr.c | 2 ++
1 file changed, 2 insertions(+)
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1350,6 +1350,8 @@ retry:
s_min_extra_isize) {
tried_min_extra_isize++;
new_extra_isize = s_min_extra_isize;
+ kfree(is); is = NULL;
+ kfree(bs); bs = NULL;
goto retry;
}
error = -1;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 11/69] KVM: PPC: Book3S HV: Fix typo in saving DSCR
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (9 preceding siblings ...)
2013-10-16 17:44 ` [ 10/69] ext4: fix memory leak in xattr Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 12/69] parisc: fix interruption handler to respect pagefault_disable() Greg Kroah-Hartman
` (59 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Paul Mackerras, Alexander Graf,
Paolo Bonzini
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Mackerras <paulus@samba.org>
commit cfc860253abd73e1681696c08ea268d33285a2c4 upstream.
This fixes a typo in the code that saves the guest DSCR (Data Stream
Control Register) into the kvm_vcpu_arch struct on guest exit. The
effect of the typo was that the DSCR value was saved in the wrong place,
so changes to the DSCR by the guest didn't persist across guest exit
and entry, and some host kernel memory got corrupted.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1054,7 +1054,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
BEGIN_FTR_SECTION
mfspr r8, SPRN_DSCR
ld r7, HSTATE_DSCR(r13)
- std r8, VCPU_DSCR(r7)
+ std r8, VCPU_DSCR(r9)
mtspr SPRN_DSCR, r7
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 12/69] parisc: fix interruption handler to respect pagefault_disable()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (10 preceding siblings ...)
2013-10-16 17:44 ` [ 11/69] KVM: PPC: Book3S HV: Fix typo in saving DSCR Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 13/69] ARM: Fix the world famous typo with is_gate_vma() Greg Kroah-Hartman
` (58 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Helge Deller, John David Anglin
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <deller@gmx.de>
commit 59b33f148cc08fb33cbe823fca1e34f7f023765e upstream.
Running an "echo t > /proc/sysrq-trigger" crashes the parisc kernel. The
problem is, that in print_worker_info() we try to read the workqueue info via
the probe_kernel_read() functions which use pagefault_disable() to avoid
crashes like this:
probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq));
probe_kernel_read(&wq, &pwq->wq, sizeof(wq));
probe_kernel_read(name, wq->name, sizeof(name) - 1);
The problem here is, that the first probe_kernel_read(&pwq) might return zero
in pwq and as such the following probe_kernel_reads() try to access contents of
the page zero which is read protected and generate a kernel segfault.
With this patch we fix the interruption handler to call parisc_terminate()
directly only if pagefault_disable() was not called (in which case
preempt_count()==0). Otherwise we hand over to the pagefault handler which
will try to look up the faulting address in the fixup tables.
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/parisc/kernel/traps.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -805,14 +805,14 @@ void notrace handle_interruption(int cod
else {
/*
- * The kernel should never fault on its own address space.
+ * The kernel should never fault on its own address space,
+ * unless pagefault_disable() was called before.
*/
- if (fault_space == 0)
+ if (fault_space == 0 && !in_atomic())
{
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
parisc_terminate("Kernel Fault", regs, code, fault_address);
-
}
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 13/69] ARM: Fix the world famous typo with is_gate_vma()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (11 preceding siblings ...)
2013-10-16 17:44 ` [ 12/69] parisc: fix interruption handler to respect pagefault_disable() Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 14/69] ARC: Setup Vector Table Base in early boot Greg Kroah-Hartman
` (57 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Russell King, Colin Cross
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King <rmk+kernel@arm.linux.org.uk>
commit 1d0bbf428924f94867542d49d436cf254b9dbd06 upstream.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Colin Cross <ccross@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm/kernel/process.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -466,7 +466,7 @@ int in_gate_area_no_mm(unsigned long add
{
return in_gate_area(NULL, addr);
}
-#define is_gate_vma(vma) ((vma) = &gate_vma)
+#define is_gate_vma(vma) ((vma) == &gate_vma)
#else
#define is_gate_vma(vma) 0
#endif
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 14/69] ARC: Setup Vector Table Base in early boot
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (12 preceding siblings ...)
2013-10-16 17:44 ` [ 13/69] ARM: Fix the world famous typo with is_gate_vma() Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 15/69] ARC: SMP failed to boot due to missing IVT setup Greg Kroah-Hartman
` (56 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Vineet Gupta, Guenter Roeck
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <vgupta@synopsys.com>
commit 05b016ecf5e7a8c24409d8e9effb5d2ec9107708 upstream.
Otherwise early boot exceptions such as instructions errors due to
configuration mismatch between kernel and hardware go off to la-la land,
as opposed to hitting the handler and panic()'ing properly.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/kernel/head.S | 2 ++
arch/arc/kernel/irq.c | 2 --
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arc/kernel/head.S
+++ b/arch/arc/kernel/head.S
@@ -27,6 +27,8 @@ stext:
; Don't clobber r0-r4 yet. It might have bootloader provided info
;-------------------------------------------------------------------
+ sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
+
#ifdef CONFIG_SMP
; Only Boot (Master) proceeds. Others wait in platform dependent way
; IDENTITY Reg [ 3 2 1 0 ]
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -32,8 +32,6 @@ void __cpuinit arc_init_IRQ(void)
{
int level_mask = 0;
- write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds);
-
/* Disable all IRQs: enable them as devices request */
write_aux_reg(AUX_IENABLE, 0);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 15/69] ARC: SMP failed to boot due to missing IVT setup
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (13 preceding siblings ...)
2013-10-16 17:44 ` [ 14/69] ARC: Setup Vector Table Base in early boot Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 16/69] ARC: Fix __udelay calculation Greg Kroah-Hartman
` (55 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Gilad Ben-Yossef, Noam Camus,
Vineet Gupta, Linus Torvalds
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Noam Camus <noamc@ezchip.com>
commit c3567f8a359b7917dcffa442301f88ed0a75211f upstream.
Commit 05b016ecf5e7a "ARC: Setup Vector Table Base in early boot" moved
the Interrupt vector Table setup out of arc_init_IRQ() which is called
for all CPUs, to entry point of boot cpu only, breaking booting of others.
Fix by adding the same to entry point of non-boot CPUs too.
read_arc_build_cfg_regs() printing IVT Base Register didn't help the
casue since it prints a synthetic value if zero which is totally bogus,
so fix that to print the exact Register.
[vgupta: Remove the now stale comment from header of arc_init_IRQ and
also added the commentary for halt-on-reset]
Cc: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Noam Camus <noamc@ezchip.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/include/asm/sections.h | 1 -
arch/arc/kernel/head.S | 5 +++++
arch/arc/kernel/irq.c | 1 -
arch/arc/kernel/setup.c | 3 ---
4 files changed, 5 insertions(+), 5 deletions(-)
--- a/arch/arc/include/asm/sections.h
+++ b/arch/arc/include/asm/sections.h
@@ -11,7 +11,6 @@
#include <asm-generic/sections.h>
-extern char _int_vec_base_lds[];
extern char __arc_dccm_base[];
extern char __dtb_start[];
--- a/arch/arc/kernel/head.S
+++ b/arch/arc/kernel/head.S
@@ -34,6 +34,9 @@ stext:
; IDENTITY Reg [ 3 2 1 0 ]
; (cpu-id) ^^^ => Zero for UP ARC700
; => #Core-ID if SMP (Master 0)
+ ; Note that non-boot CPUs might not land here if halt-on-reset and
+ ; instead breath life from @first_lines_of_secondary, but we still
+ ; need to make sure only boot cpu takes this path.
GET_CPU_ID r5
cmp r5, 0
jnz arc_platform_smp_wait_to_boot
@@ -98,6 +101,8 @@ stext:
first_lines_of_secondary:
+ sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
+
; setup per-cpu idle task as "current" on this CPU
ld r0, [@secondary_idle_tsk]
SET_CURR_TASK_ON_CPU r0, r1
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -24,7 +24,6 @@
* -Needed for each CPU (hence not foldable into init_IRQ)
*
* what it does ?
- * -setup Vector Table Base Reg - in case Linux not linked at 0x8000_0000
* -Disable all IRQs (on CPU side)
* -Optionally, setup the High priority Interrupts as Level 2 IRQs
*/
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -47,10 +47,7 @@ void __cpuinit read_arc_build_cfg_regs(v
READ_BCR(AUX_IDENTITY, cpu->core);
cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR);
-
cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE);
- if (cpu->vec_base == 0)
- cpu->vec_base = (unsigned int)_int_vec_base_lds;
READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space);
cpu->uncached_base = uncached_space.start << 24;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 16/69] ARC: Fix __udelay calculation
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (14 preceding siblings ...)
2013-10-16 17:44 ` [ 15/69] ARC: SMP failed to boot due to missing IVT setup Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 17/69] ARC: Handle zero-overhead-loop in unaligned access handler Greg Kroah-Hartman
` (54 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Mischa Jonker, Vineet Gupta
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mischa Jonker <mjonker@synopsys.com>
commit 7efd0da2d17360e1cef91507dbe619db0ee2c691 upstream.
Cast usecs to u64, to ensure that the (usecs * 4295 * HZ)
multiplication is 64 bit.
Initially, the (usecs * 4295 * HZ) part was done as a 32 bit
multiplication, with the result casted to 64 bit. This led to some bits
falling off, causing a "DMA initialization error" in the stmmac Ethernet
driver, due to a premature timeout.
Signed-off-by: Mischa Jonker <mjonker@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/include/asm/delay.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/arch/arc/include/asm/delay.h
+++ b/arch/arc/include/asm/delay.h
@@ -53,11 +53,10 @@ static inline void __udelay(unsigned lon
{
unsigned long loops;
- /* (long long) cast ensures 64 bit MPY - real or emulated
+ /* (u64) cast ensures 64 bit MPY - real or emulated
* HZ * 4295 is pre-evaluated by gcc - hence only 2 mpy ops
*/
- loops = ((long long)(usecs * 4295 * HZ) *
- (long long)(loops_per_jiffy)) >> 32;
+ loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32;
__delay(loops);
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 17/69] ARC: Handle zero-overhead-loop in unaligned access handler
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (15 preceding siblings ...)
2013-10-16 17:44 ` [ 16/69] ARC: Fix __udelay calculation Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 18/69] ARC: Fix 32-bit wrap around in access_ok() Greg Kroah-Hartman
` (53 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Mischa Jonker, Vineet Gupta
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mischa Jonker <mjonker@synopsys.com>
commit c11eb222fd7d4db91196121dbf854178505d2751 upstream.
If a load or store is the last instruction in a zero-overhead-loop, and
it's misaligned, the loop would execute only once.
This fixes that problem.
Signed-off-by: Mischa Jonker <mjonker@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/kernel/unaligned.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/arc/kernel/unaligned.c
+++ b/arch/arc/kernel/unaligned.c
@@ -233,6 +233,12 @@ int misaligned_fixup(unsigned long addre
regs->status32 &= ~STATUS_DE_MASK;
} else {
regs->ret += state.instr_len;
+
+ /* handle zero-overhead-loop */
+ if ((regs->ret == regs->lp_end) && (regs->lp_count)) {
+ regs->ret = regs->lp_start;
+ regs->lp_count--;
+ }
}
return 0;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 18/69] ARC: Fix 32-bit wrap around in access_ok()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (16 preceding siblings ...)
2013-10-16 17:44 ` [ 17/69] ARC: Handle zero-overhead-loop in unaligned access handler Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 19/69] ARC: Workaround spinlock livelock in SMP SystemC simulation Greg Kroah-Hartman
` (52 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Anton Kolesov, Vineet Gupta
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <vgupta@synopsys.com>
commit 0752adfda15f0eca9859a76da3db1800e129ad43 upstream.
Anton reported
| LTP tests syscalls/process_vm_readv01 and process_vm_writev01 fail
| similarly in one testcase test_iov_invalid -> lvec->iov_base.
| Testcase expects errno EFAULT and return code -1,
| but it gets return code 1 and ERRNO is 0 what means success.
Essentially test case was passing a pointer of -1 which access_ok()
was not catching. It was doing [@addr + @sz <= TASK_SIZE] which would
pass for @addr == -1
Fixed that by rewriting as [@addr <= TASK_SIZE - @sz]
Reported-by: Anton Kolesov <Anton.Kolesov@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/include/asm/uaccess.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arc/include/asm/uaccess.h
+++ b/arch/arc/include/asm/uaccess.h
@@ -43,7 +43,7 @@
* Because it essentially checks if buffer end is within limit and @len is
* non-ngeative, which implies that buffer start will be within limit too.
*
- * The reason for rewriting being, for majorit yof cases, @len is generally
+ * The reason for rewriting being, for majority of cases, @len is generally
* compile time constant, causing first sub-expression to be compile time
* subsumed.
*
@@ -53,7 +53,7 @@
*
*/
#define __user_ok(addr, sz) (((sz) <= TASK_SIZE) && \
- (((addr)+(sz)) <= get_fs()))
+ ((addr) <= (get_fs() - (sz))))
#define __access_ok(addr, sz) (unlikely(__kernel_ok) || \
likely(__user_ok((addr), (sz))))
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 19/69] ARC: Workaround spinlock livelock in SMP SystemC simulation
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (17 preceding siblings ...)
2013-10-16 17:44 ` [ 18/69] ARC: Fix 32-bit wrap around in access_ok() Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 20/69] ARC: Fix signal frame management for SA_SIGINFO Greg Kroah-Hartman
` (51 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Vineet Gupta
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <vgupta@synopsys.com>
commit 6c00350b573c0bd3635436e43e8696951dd6e1b6 upstream.
Some ARC SMP systems lack native atomic R-M-W (LLOCK/SCOND) insns and
can only use atomic EX insn (reg with mem) to build higher level R-M-W
primitives. This includes a SystemC based SMP simulation model.
So rwlocks need to use a protecting spinlock for atomic cmp-n-exchange
operation to update reader(s)/writer count.
The spinlock operation itself looks as follows:
mov reg, 1 ; 1=locked, 0=unlocked
retry:
EX reg, [lock] ; load existing, store 1, atomically
BREQ reg, 1, rety ; if already locked, retry
In single-threaded simulation, SystemC alternates between the 2 cores
with "N" insn each based scheduling. Additionally for insn with global
side effect, such as EX writing to shared mem, a core switch is
enforced too.
Given that, 2 cores doing a repeated EX on same location, Linux often
got into a livelock e.g. when both cores were fiddling with tasklist
lock (gdbserver / hackbench) for read/write respectively as the
sequence diagram below shows:
core1 core2
-------- --------
1. spin lock [EX r=0, w=1] - LOCKED
2. rwlock(Read) - LOCKED
3. spin unlock [ST 0] - UNLOCKED
spin lock [EX r=0,w=1] - LOCKED
-- resched core 1----
5. spin lock [EX r=1] - ALREADY-LOCKED
-- resched core 2----
6. rwlock(Write) - READER-LOCKED
7. spin unlock [ST 0]
8. rwlock failed, retry again
9. spin lock [EX r=0, w=1]
-- resched core 1----
10 spinlock locked in #9, retry #5
11. spin lock [EX gets 1]
-- resched core 2----
...
...
The fix was to unlock using the EX insn too (step 7), to trigger another
SystemC scheduling pass which would let core1 proceed, eliding the
livelock.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/include/asm/spinlock.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -45,7 +45,14 @@ static inline int arch_spin_trylock(arch
static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
- lock->slock = __ARCH_SPIN_LOCK_UNLOCKED__;
+ unsigned int tmp = __ARCH_SPIN_LOCK_UNLOCKED__;
+
+ __asm__ __volatile__(
+ " ex %0, [%1] \n"
+ : "+r" (tmp)
+ : "r"(&(lock->slock))
+ : "memory");
+
smp_mb();
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 20/69] ARC: Fix signal frame management for SA_SIGINFO
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (18 preceding siblings ...)
2013-10-16 17:44 ` [ 19/69] ARC: Workaround spinlock livelock in SMP SystemC simulation Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 21/69] ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc" Greg Kroah-Hartman
` (50 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Christian Ruppert, Vineet Gupta
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Ruppert <christian.ruppert@abilis.com>
commit 10469350e345599dfef3fa78a7c19fb230e674c1 upstream.
Previously, when a signal was registered with SA_SIGINFO, parameters 2
and 3 of the signal handler were written to registers r1 and r2 before
the register set was saved. This led to corruption of these two
registers after returning from the signal handler (the wrong values were
restored).
With this patch, registers are now saved before any parameters are
passed, thus maintaining the processor state from before signal entry.
Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/kernel/signal.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
--- a/arch/arc/kernel/signal.c
+++ b/arch/arc/kernel/signal.c
@@ -101,7 +101,6 @@ SYSCALL_DEFINE0(rt_sigreturn)
{
struct rt_sigframe __user *sf;
unsigned int magic;
- int err;
struct pt_regs *regs = current_pt_regs();
/* Always make any pending restarted system calls return -EINTR */
@@ -119,15 +118,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
goto badframe;
- err = restore_usr_regs(regs, sf);
- err |= __get_user(magic, &sf->sigret_magic);
- if (err)
+ if (__get_user(magic, &sf->sigret_magic))
goto badframe;
if (unlikely(is_do_ss_needed(magic)))
if (restore_altstack(&sf->uc.uc_stack))
goto badframe;
+ if (restore_usr_regs(regs, sf))
+ goto badframe;
+
/* Don't restart from sigreturn */
syscall_wont_restart(regs);
@@ -191,6 +191,15 @@ setup_rt_frame(int signo, struct k_sigac
return 1;
/*
+ * w/o SA_SIGINFO, struct ucontext is partially populated (only
+ * uc_mcontext/uc_sigmask) for kernel's normal user state preservation
+ * during signal handler execution. This works for SA_SIGINFO as well
+ * although the semantics are now overloaded (the same reg state can be
+ * inspected by userland: but are they allowed to fiddle with it ?
+ */
+ err |= stash_usr_regs(sf, regs, set);
+
+ /*
* SA_SIGINFO requires 3 args to signal handler:
* #1: sig-no (common to any handler)
* #2: struct siginfo
@@ -213,14 +222,6 @@ setup_rt_frame(int signo, struct k_sigac
magic = MAGIC_SIGALTSTK;
}
- /*
- * w/o SA_SIGINFO, struct ucontext is partially populated (only
- * uc_mcontext/uc_sigmask) for kernel's normal user state preservation
- * during signal handler execution. This works for SA_SIGINFO as well
- * although the semantics are now overloaded (the same reg state can be
- * inspected by userland: but are they allowed to fiddle with it ?
- */
- err |= stash_usr_regs(sf, regs, set);
err |= __put_user(magic, &sf->sigret_magic);
if (err)
return err;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 21/69] ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc"
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (19 preceding siblings ...)
2013-10-16 17:44 ` [ 20/69] ARC: Fix signal frame management for SA_SIGINFO Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 22/69] watchdog: ts72xx_wdt: locking bug in ioctl Greg Kroah-Hartman
` (49 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Anton Kolesov, Vineet Gupta
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <vgupta@synopsys.com>
commit 5b24282846c064ee90d40fcb3a8f63b8e754fd28 upstream.
ARCompact TRAP_S insn used for breakpoints, commits before exception is
taken (updating architectural PC). So ptregs->ret contains next-PC and
not the breakpoint PC itself. This is different from other restartable
exceptions such as TLB Miss where ptregs->ret has exact faulting PC.
gdb needs to know exact-PC hence ARC ptrace GETREGSET provides for
@stop_pc which returns ptregs->ret vs. EFA depending on the
situation.
However, writing stop_pc (SETREGSET request), which updates ptregs->ret
doesn't makes sense stop_pc doesn't always correspond to that reg as
described above.
This was not an issue so far since user_regs->ret / user_regs->stop_pc
had same value and both writing to ptregs->ret was OK, needless, but NOT
broken, hence not observed.
With gdb "jump", they diverge, and user_regs->ret updating ptregs is
overwritten immediately with stop_pc, which this patch fixes.
Reported-by: Anton Kolesov <akolesov@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arc/kernel/ptrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arc/kernel/ptrace.c
+++ b/arch/arc/kernel/ptrace.c
@@ -92,7 +92,7 @@ static int genregs_set(struct task_struc
REG_IN_CHUNK(scratch, callee, ptregs); /* pt_regs[bta..orig_r8] */
REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */
REG_IGNORE_ONE(efa); /* efa update invalid */
- REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */
+ REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */
return ret;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 22/69] watchdog: ts72xx_wdt: locking bug in ioctl
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (20 preceding siblings ...)
2013-10-16 17:44 ` [ 21/69] ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc" Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 23/69] compiler/gcc4: Add quirk for asm goto miscompilation bug Greg Kroah-Hartman
` (48 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Dan Carpenter, Guenter Roeck,
Wim Van Sebroeck, Jonghwan Choi
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <dan.carpenter@oracle.com>
commit 8612ed0d97abcf1c016d34755b7cf2060de71963 upstream.
Calling the WDIOC_GETSTATUS & WDIOC_GETBOOTSTATUS and twice will cause a
interruptible deadlock.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Cc: Jonghwan Choi <jhbird.choi@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/ts72xx_wdt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/watchdog/ts72xx_wdt.c
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -310,7 +310,8 @@ static long ts72xx_wdt_ioctl(struct file
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, p);
+ error = put_user(0, p);
+ break;
case WDIOC_KEEPALIVE:
ts72xx_wdt_kick(wdt);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 23/69] compiler/gcc4: Add quirk for asm goto miscompilation bug
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (21 preceding siblings ...)
2013-10-16 17:44 ` [ 22/69] watchdog: ts72xx_wdt: locking bug in ioctl Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 24/69] ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470 Greg Kroah-Hartman
` (47 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Oleg Nesterov, Peter Zijlstra,
Jakub Jelinek, Richard Henderson, Linus Torvalds, Andrew Morton,
Ingo Molnar
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 24/69] ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (22 preceding siblings ...)
2013-10-16 17:44 ` [ 23/69] compiler/gcc4: Add quirk for asm goto miscompilation bug Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 25/69] cope with potentially long ->d_dname() output for shmem/hugetlb Greg Kroah-Hartman
` (46 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, David Henningsson, Takashi Iwai
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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),
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 25/69] cope with potentially long ->d_dname() output for shmem/hugetlb
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (23 preceding siblings ...)
2013-10-16 17:44 ` [ 24/69] ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470 Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 26/69] drm/i915: Only apply DPMS to the encoder if enabled Greg Kroah-Hartman
` (45 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Al Viro, Colin Cross
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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
};
/**
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 26/69] drm/i915: Only apply DPMS to the encoder if enabled
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (24 preceding siblings ...)
2013-10-16 17:44 ` [ 25/69] cope with potentially long ->d_dname() output for shmem/hugetlb Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 27/69] drm/radeon: forever loop on error in radeon_do_test_moves() Greg Kroah-Hartman
` (44 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Chris Wilson, Daniel Vetter
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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);
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 27/69] drm/radeon: forever loop on error in radeon_do_test_moves()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (25 preceding siblings ...)
2013-10-16 17:44 ` [ 26/69] drm/i915: Only apply DPMS to the encoder if enabled Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 28/69] drm/radeon: fix typo in CP DMA register headers Greg Kroah-Hartman
` (43 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Dan Carpenter, Alex Deucher
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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:
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 28/69] drm/radeon: fix typo in CP DMA register headers
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (26 preceding siblings ...)
2013-10-16 17:44 ` [ 27/69] drm/radeon: forever loop on error in radeon_do_test_moves() Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 29/69] drm/radeon: fix hw contexts for SUMO2 asics Greg Kroah-Hartman
` (42 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, stable, Alex Deucher
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 29/69] drm/radeon: fix hw contexts for SUMO2 asics
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (27 preceding siblings ...)
2013-10-16 17:44 ` [ 28/69] drm/radeon: fix typo in CP DMA register headers Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 30/69] ipc: move rcu lock out of ipc_addid Greg Kroah-Hartman
` (41 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, wojciech kapuscinski, Alex Deucher
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 30/69] ipc: move rcu lock out of ipc_addid
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (28 preceding siblings ...)
2013-10-16 17:44 ` [ 29/69] drm/radeon: fix hw contexts for SUMO2 asics Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 31/69] ipc: introduce ipc object locking helpers Greg Kroah-Hartman
` (40 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 31/69] ipc: introduce ipc object locking helpers
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (29 preceding siblings ...)
2013-10-16 17:44 ` [ 30/69] ipc: move rcu lock out of ipc_addid Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 32/69] ipc: close open coded spin lock calls Greg Kroah-Hartman
` (39 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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,
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 32/69] ipc: close open coded spin lock calls
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (30 preceding siblings ...)
2013-10-16 17:44 ` [ 31/69] ipc: introduce ipc object locking helpers Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 33/69] ipc: move locking out of ipcctl_pre_down_nolock Greg Kroah-Hartman
` (38 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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();
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 33/69] ipc: move locking out of ipcctl_pre_down_nolock
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (31 preceding siblings ...)
2013-10-16 17:44 ` [ 32/69] ipc: close open coded spin lock calls Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 34/69] ipc,msg: shorten critical region in msgctl_down Greg Kroah-Hartman
` (37 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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);
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 34/69] ipc,msg: shorten critical region in msgctl_down
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (32 preceding siblings ...)
2013-10-16 17:44 ` [ 33/69] ipc: move locking out of ipcctl_pre_down_nolock Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 35/69] ipc,msg: introduce msgctl_nolock Greg Kroah-Hartman
` (36 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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:
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 35/69] ipc,msg: introduce msgctl_nolock
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (33 preceding siblings ...)
2013-10-16 17:44 ` [ 34/69] ipc,msg: shorten critical region in msgctl_down Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 36/69] ipc,msg: introduce lockless functions to obtain the ipc object Greg Kroah-Hartman
` (35 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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)
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 36/69] ipc,msg: introduce lockless functions to obtain the ipc object
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (34 preceding siblings ...)
2013-10-16 17:44 ` [ 35/69] ipc,msg: introduce msgctl_nolock Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 37/69] ipc,msg: make msgctl_nolock lockless Greg Kroah-Hartman
` (34 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 37/69] ipc,msg: make msgctl_nolock lockless
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (35 preceding siblings ...)
2013-10-16 17:44 ` [ 36/69] ipc,msg: introduce lockless functions to obtain the ipc object Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 38/69] ipc,msg: shorten critical region in msgsnd Greg Kroah-Hartman
` (33 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 38/69] ipc,msg: shorten critical region in msgsnd
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (36 preceding siblings ...)
2013-10-16 17:44 ` [ 37/69] ipc,msg: make msgctl_nolock lockless Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 39/69] ipc,msg: shorten critical region in msgrcv Greg Kroah-Hartman
` (32 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 39/69] ipc,msg: shorten critical region in msgrcv
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (37 preceding siblings ...)
2013-10-16 17:44 ` [ 38/69] ipc,msg: shorten critical region in msgsnd Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 40/69] ipc: remove unused functions Greg Kroah-Hartman
` (31 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Sedat Dilek, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 40/69] ipc: remove unused functions
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (38 preceding siblings ...)
2013-10-16 17:44 ` [ 39/69] ipc,msg: shorten critical region in msgrcv Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 41/69] ipc/util.c, ipc_rcu_alloc: cacheline align allocation Greg Kroah-Hartman
` (30 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Andi Kleen,
Rik van Riel, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
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;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 41/69] ipc/util.c, ipc_rcu_alloc: cacheline align allocation
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (39 preceding siblings ...)
2013-10-16 17:44 ` [ 40/69] ipc: remove unused functions Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 42/69] ipc/sem.c: cacheline align the semaphore structures Greg Kroah-Hartman
` (29 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Rik van Riel,
Davidlohr Bueso, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit 196aa0132fc7261f34b10ae1bfb44abc1bc69b3c upstream.
Enforce that ipc_rcu_alloc returns a cacheline aligned pointer on SMP.
Rationale:
The SysV sem code tries to move the main spinlock into a seperate
cacheline (____cacheline_aligned_in_smp). This works only if
ipc_rcu_alloc returns cacheline aligned pointers. vmalloc and kmalloc
return cacheline algined pointers, the implementation of ipc_rcu_alloc
breaks that.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -468,9 +468,7 @@ void ipc_free(void* ptr, int size)
struct ipc_rcu {
struct rcu_head rcu;
atomic_t refcount;
- /* "void *" makes sure alignment of following data is sane. */
- void *data[0];
-};
+} ____cacheline_aligned_in_smp;
/**
* ipc_rcu_alloc - allocate ipc and rcu space
@@ -488,12 +486,14 @@ void *ipc_rcu_alloc(int size)
if (unlikely(!out))
return NULL;
atomic_set(&out->refcount, 1);
- return out->data;
+ return out + 1;
}
int ipc_rcu_getref(void *ptr)
{
- return atomic_inc_not_zero(&container_of(ptr, struct ipc_rcu, data)->refcount);
+ struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1;
+
+ return atomic_inc_not_zero(&p->refcount);
}
/**
@@ -507,7 +507,7 @@ static void ipc_schedule_free(struct rcu
void ipc_rcu_putref(void *ptr)
{
- struct ipc_rcu *p = container_of(ptr, struct ipc_rcu, data);
+ struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1;
if (!atomic_dec_and_test(&p->refcount))
return;
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 42/69] ipc/sem.c: cacheline align the semaphore structures
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (40 preceding siblings ...)
2013-10-16 17:44 ` [ 41/69] ipc/util.c, ipc_rcu_alloc: cacheline align allocation Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 43/69] ipc/sem: separate wait-for-zero and alter tasks into seperate queues Greg Kroah-Hartman
` (28 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Rik van Riel,
Davidlohr Bueso, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit f5c936c0f267ec58641451cf8b8d39b4c207ee4d upstream.
As now each semaphore has its own spinlock and parallel operations are
possible, give each semaphore its own cacheline.
On a i3 laptop, this gives up to 28% better performance:
#semscale 10 | grep "interleave 2"
- before:
Cpus 1, interleave 2 delay 0: 36109234 in 10 secs
Cpus 2, interleave 2 delay 0: 55276317 in 10 secs
Cpus 3, interleave 2 delay 0: 62411025 in 10 secs
Cpus 4, interleave 2 delay 0: 81963928 in 10 secs
-after:
Cpus 1, interleave 2 delay 0: 35527306 in 10 secs
Cpus 2, interleave 2 delay 0: 70922909 in 10 secs <<< + 28%
Cpus 3, interleave 2 delay 0: 80518538 in 10 secs
Cpus 4, interleave 2 delay 0: 89115148 in 10 secs <<< + 8.7%
i3, with 2 cores and with hyperthreading enabled. Interleave 2 in order
use first the full cores. HT partially hides the delay from cacheline
trashing, thus the improvement is "only" 8.7% if 4 threads are running.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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/sem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -96,7 +96,7 @@ struct sem {
int sempid; /* pid of last operation */
spinlock_t lock; /* spinlock for fine-grained semtimedop */
struct list_head sem_pending; /* pending single-sop operations */
-};
+} ____cacheline_aligned_in_smp;
/* One queue for each sleeping process in the system. */
struct sem_queue {
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 43/69] ipc/sem: separate wait-for-zero and alter tasks into seperate queues
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (41 preceding siblings ...)
2013-10-16 17:44 ` [ 42/69] ipc/sem.c: cacheline align the semaphore structures Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 44/69] ipc/sem.c: always use only one queue for alter operations Greg Kroah-Hartman
` (27 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Rik van Riel,
Davidlohr Bueso, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit 1a82e9e1d0f1b45f47a97c9e2349020536ff8987 upstream.
Introduce separate queues for operations that do not modify the
semaphore values. Advantages:
- Simpler logic in check_restart().
- Faster update_queue(): Right now, all wait-for-zero operations are
always tested, even if the semaphore value is not 0.
- wait-for-zero gets again priority, as in linux <=3.0.9
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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>
---
include/linux/sem.h | 5 -
ipc/sem.c | 211 +++++++++++++++++++++++++++++++++++++---------------
2 files changed, 155 insertions(+), 61 deletions(-)
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -15,7 +15,10 @@ struct sem_array {
time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
struct sem *sem_base; /* ptr to first semaphore in array */
- struct list_head sem_pending; /* pending operations to be processed */
+ struct list_head pending_alter; /* pending operations */
+ /* that alter the array */
+ struct list_head pending_const; /* pending complex operations */
+ /* that do not alter semvals */
struct list_head list_id; /* undo requests on this array */
int sem_nsems; /* no. of semaphores in array */
int complex_count; /* pending complex operations */
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -95,7 +95,10 @@ struct sem {
int semval; /* current value */
int sempid; /* pid of last operation */
spinlock_t lock; /* spinlock for fine-grained semtimedop */
- struct list_head sem_pending; /* pending single-sop operations */
+ struct list_head pending_alter; /* pending single-sop operations */
+ /* that alter the semaphore */
+ struct list_head pending_const; /* pending single-sop operations */
+ /* that do not alter the semaphore*/
} ____cacheline_aligned_in_smp;
/* One queue for each sleeping process in the system. */
@@ -152,7 +155,7 @@ static int sysvipc_sem_proc_show(struct
/*
* linked list protection:
* sem_undo.id_next,
- * sem_array.sem_pending{,last},
+ * sem_array.pending{_alter,_cont},
* sem_array.sem_undo: sem_lock() for read/write
* sem_undo.proc_next: only "current" is allowed to read/write that field.
*
@@ -337,7 +340,7 @@ static inline void sem_rmid(struct ipc_n
* Without the check/retry algorithm a lockless wakeup is possible:
* - queue.status is initialized to -EINTR before blocking.
* - wakeup is performed by
- * * unlinking the queue entry from sma->sem_pending
+ * * unlinking the queue entry from the pending list
* * setting queue.status to IN_WAKEUP
* This is the notification for the blocked thread that a
* result value is imminent.
@@ -418,12 +421,14 @@ static int newary(struct ipc_namespace *
sma->sem_base = (struct sem *) &sma[1];
for (i = 0; i < nsems; i++) {
- INIT_LIST_HEAD(&sma->sem_base[i].sem_pending);
+ INIT_LIST_HEAD(&sma->sem_base[i].pending_alter);
+ INIT_LIST_HEAD(&sma->sem_base[i].pending_const);
spin_lock_init(&sma->sem_base[i].lock);
}
sma->complex_count = 0;
- INIT_LIST_HEAD(&sma->sem_pending);
+ INIT_LIST_HEAD(&sma->pending_alter);
+ INIT_LIST_HEAD(&sma->pending_const);
INIT_LIST_HEAD(&sma->list_id);
sma->sem_nsems = nsems;
sma->sem_ctime = get_seconds();
@@ -609,60 +614,132 @@ static void unlink_queue(struct sem_arra
* update_queue is O(N^2) when it restarts scanning the whole queue of
* waiting operations. Therefore this function checks if the restart is
* really necessary. It is called after a previously waiting operation
- * was completed.
+ * modified the array.
+ * Note that wait-for-zero operations are handled without restart.
*/
static int check_restart(struct sem_array *sma, struct sem_queue *q)
{
- struct sem *curr;
- struct sem_queue *h;
-
- /* if the operation didn't modify the array, then no restart */
- if (q->alter == 0)
- return 0;
-
- /* pending complex operations are too difficult to analyse */
- if (sma->complex_count)
+ /* pending complex alter operations are too difficult to analyse */
+ if (!list_empty(&sma->pending_alter))
return 1;
/* we were a sleeping complex operation. Too difficult */
if (q->nsops > 1)
return 1;
- curr = sma->sem_base + q->sops[0].sem_num;
+ /* It is impossible that someone waits for the new value:
+ * - complex operations always restart.
+ * - wait-for-zero are handled seperately.
+ * - q is a previously sleeping simple operation that
+ * altered the array. It must be a decrement, because
+ * simple increments never sleep.
+ * - If there are older (higher priority) decrements
+ * in the queue, then they have observed the original
+ * semval value and couldn't proceed. The operation
+ * decremented to value - thus they won't proceed either.
+ */
+ return 0;
+}
- /* No-one waits on this queue */
- if (list_empty(&curr->sem_pending))
- return 0;
+/**
+ * wake_const_ops(sma, semnum, pt) - Wake up non-alter tasks
+ * @sma: semaphore array.
+ * @semnum: semaphore that was modified.
+ * @pt: list head for the tasks that must be woken up.
+ *
+ * wake_const_ops must be called after a semaphore in a semaphore array
+ * was set to 0. If complex const operations are pending, wake_const_ops must
+ * be called with semnum = -1, as well as with the number of each modified
+ * semaphore.
+ * The tasks that must be woken up are added to @pt. The return code
+ * is stored in q->pid.
+ * The function returns 1 if at least one operation was completed successfully.
+ */
+static int wake_const_ops(struct sem_array *sma, int semnum,
+ struct list_head *pt)
+{
+ struct sem_queue *q;
+ struct list_head *walk;
+ struct list_head *pending_list;
+ int semop_completed = 0;
+
+ if (semnum == -1)
+ pending_list = &sma->pending_const;
+ else
+ pending_list = &sma->sem_base[semnum].pending_const;
+
+ walk = pending_list->next;
+ while (walk != pending_list) {
+ int error;
+
+ q = container_of(walk, struct sem_queue, list);
+ walk = walk->next;
+
+ error = try_atomic_semop(sma, q->sops, q->nsops,
+ q->undo, q->pid);
+
+ if (error <= 0) {
+ /* operation completed, remove from queue & wakeup */
+
+ unlink_queue(sma, q);
+
+ wake_up_sem_queue_prepare(pt, q, error);
+ if (error == 0)
+ semop_completed = 1;
+ }
+ }
+ return semop_completed;
+}
- /* the new semaphore value */
- if (curr->semval) {
- /* It is impossible that someone waits for the new value:
- * - q is a previously sleeping simple operation that
- * altered the array. It must be a decrement, because
- * simple increments never sleep.
- * - The value is not 0, thus wait-for-zero won't proceed.
- * - If there are older (higher priority) decrements
- * in the queue, then they have observed the original
- * semval value and couldn't proceed. The operation
- * decremented to value - thus they won't proceed either.
+/**
+ * do_smart_wakeup_zero(sma, sops, nsops, pt) - wakeup all wait for zero tasks
+ * @sma: semaphore array
+ * @sops: operations that were performed
+ * @nsops: number of operations
+ * @pt: list head of the tasks that must be woken up.
+ *
+ * do_smart_wakeup_zero() checks all required queue for wait-for-zero
+ * operations, based on the actual changes that were performed on the
+ * semaphore array.
+ * The function returns 1 if at least one operation was completed successfully.
+ */
+static int do_smart_wakeup_zero(struct sem_array *sma, struct sembuf *sops,
+ int nsops, struct list_head *pt)
+{
+ int i;
+ int semop_completed = 0;
+ int got_zero = 0;
+
+ /* first: the per-semaphore queues, if known */
+ if (sops) {
+ for (i = 0; i < nsops; i++) {
+ int num = sops[i].sem_num;
+
+ if (sma->sem_base[num].semval == 0) {
+ got_zero = 1;
+ semop_completed |= wake_const_ops(sma, num, pt);
+ }
+ }
+ } else {
+ /*
+ * No sops means modified semaphores not known.
+ * Assume all were changed.
*/
- BUG_ON(q->sops[0].sem_op >= 0);
- return 0;
+ for (i = 0; i < sma->sem_nsems; i++) {
+ if (sma->sem_base[i].semval == 0) {
+ got_zero = 1;
+ semop_completed |= wake_const_ops(sma, i, pt);
+ }
+ }
}
/*
- * semval is 0. Check if there are wait-for-zero semops.
- * They must be the first entries in the per-semaphore queue
+ * If one of the modified semaphores got 0,
+ * then check the global queue, too.
*/
- h = list_first_entry(&curr->sem_pending, struct sem_queue, list);
- BUG_ON(h->nsops != 1);
- BUG_ON(h->sops[0].sem_num != q->sops[0].sem_num);
+ if (got_zero)
+ semop_completed |= wake_const_ops(sma, -1, pt);
- /* Yes, there is a wait-for-zero semop. Restart */
- if (h->sops[0].sem_op == 0)
- return 1;
-
- /* Again - no-one is waiting for the new value. */
- return 0;
+ return semop_completed;
}
@@ -678,6 +755,8 @@ static int check_restart(struct sem_arra
* semaphore.
* The tasks that must be woken up are added to @pt. The return code
* is stored in q->pid.
+ * The function internally checks if const operations can now succeed.
+ *
* The function return 1 if at least one semop was completed successfully.
*/
static int update_queue(struct sem_array *sma, int semnum, struct list_head *pt)
@@ -688,9 +767,9 @@ static int update_queue(struct sem_array
int semop_completed = 0;
if (semnum == -1)
- pending_list = &sma->sem_pending;
+ pending_list = &sma->pending_alter;
else
- pending_list = &sma->sem_base[semnum].sem_pending;
+ pending_list = &sma->sem_base[semnum].pending_alter;
again:
walk = pending_list->next;
@@ -702,13 +781,12 @@ again:
/* If we are scanning the single sop, per-semaphore list of
* one semaphore and that semaphore is 0, then it is not
- * necessary to scan the "alter" entries: simple increments
+ * necessary to scan further: simple increments
* that affect only one entry succeed immediately and cannot
* be in the per semaphore pending queue, and decrements
* cannot be successful if the value is already 0.
*/
- if (semnum != -1 && sma->sem_base[semnum].semval == 0 &&
- q->alter)
+ if (semnum != -1 && sma->sem_base[semnum].semval == 0)
break;
error = try_atomic_semop(sma, q->sops, q->nsops,
@@ -724,6 +802,7 @@ again:
restart = 0;
} else {
semop_completed = 1;
+ do_smart_wakeup_zero(sma, q->sops, q->nsops, pt);
restart = check_restart(sma, q);
}
@@ -742,8 +821,8 @@ again:
* @otime: force setting otime
* @pt: list head of the tasks that must be woken up.
*
- * do_smart_update() does the required called to update_queue, based on the
- * actual changes that were performed on the semaphore array.
+ * do_smart_update() does the required calls to update_queue and wakeup_zero,
+ * based on the actual changes that were performed on the semaphore array.
* Note that the function does not do the actual wake-up: the caller is
* responsible for calling wake_up_sem_queue_do(@pt).
* It is safe to perform this call after dropping all locks.
@@ -754,6 +833,8 @@ static void do_smart_update(struct sem_a
int i;
int progress;
+ otime |= do_smart_wakeup_zero(sma, sops, nsops, pt);
+
progress = 1;
retry_global:
if (sma->complex_count) {
@@ -813,14 +894,14 @@ static int count_semncnt (struct sem_arr
struct sem_queue * q;
semncnt = 0;
- list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) {
+ list_for_each_entry(q, &sma->sem_base[semnum].pending_alter, list) {
struct sembuf * sops = q->sops;
BUG_ON(sops->sem_num != semnum);
if ((sops->sem_op < 0) && !(sops->sem_flg & IPC_NOWAIT))
semncnt++;
}
- list_for_each_entry(q, &sma->sem_pending, list) {
+ list_for_each_entry(q, &sma->pending_alter, list) {
struct sembuf * sops = q->sops;
int nsops = q->nsops;
int i;
@@ -839,14 +920,14 @@ static int count_semzcnt (struct sem_arr
struct sem_queue * q;
semzcnt = 0;
- list_for_each_entry(q, &sma->sem_base[semnum].sem_pending, list) {
+ list_for_each_entry(q, &sma->sem_base[semnum].pending_const, list) {
struct sembuf * sops = q->sops;
BUG_ON(sops->sem_num != semnum);
if ((sops->sem_op == 0) && !(sops->sem_flg & IPC_NOWAIT))
semzcnt++;
}
- list_for_each_entry(q, &sma->sem_pending, list) {
+ list_for_each_entry(q, &sma->pending_const, list) {
struct sembuf * sops = q->sops;
int nsops = q->nsops;
int i;
@@ -884,13 +965,22 @@ static void freeary(struct ipc_namespace
/* Wake up all pending processes and let them fail with EIDRM. */
INIT_LIST_HEAD(&tasks);
- list_for_each_entry_safe(q, tq, &sma->sem_pending, list) {
+ list_for_each_entry_safe(q, tq, &sma->pending_const, list) {
+ unlink_queue(sma, q);
+ wake_up_sem_queue_prepare(&tasks, q, -EIDRM);
+ }
+
+ list_for_each_entry_safe(q, tq, &sma->pending_alter, list) {
unlink_queue(sma, q);
wake_up_sem_queue_prepare(&tasks, q, -EIDRM);
}
for (i = 0; i < sma->sem_nsems; i++) {
struct sem *sem = sma->sem_base + i;
- list_for_each_entry_safe(q, tq, &sem->sem_pending, list) {
+ list_for_each_entry_safe(q, tq, &sem->pending_const, list) {
+ unlink_queue(sma, q);
+ wake_up_sem_queue_prepare(&tasks, q, -EIDRM);
+ }
+ list_for_each_entry_safe(q, tq, &sem->pending_alter, list) {
unlink_queue(sma, q);
wake_up_sem_queue_prepare(&tasks, q, -EIDRM);
}
@@ -1658,14 +1748,15 @@ SYSCALL_DEFINE4(semtimedop, int, semid,
curr = &sma->sem_base[sops->sem_num];
if (alter)
- list_add_tail(&queue.list, &curr->sem_pending);
+ list_add_tail(&queue.list, &curr->pending_alter);
else
- list_add(&queue.list, &curr->sem_pending);
+ list_add_tail(&queue.list, &curr->pending_const);
} else {
if (alter)
- list_add_tail(&queue.list, &sma->sem_pending);
+ list_add_tail(&queue.list, &sma->pending_alter);
else
- list_add(&queue.list, &sma->sem_pending);
+ list_add_tail(&queue.list, &sma->pending_const);
+
sma->complex_count++;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 44/69] ipc/sem.c: always use only one queue for alter operations
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (42 preceding siblings ...)
2013-10-16 17:44 ` [ 43/69] ipc/sem: separate wait-for-zero and alter tasks into seperate queues Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 45/69] ipc/sem.c: replace shared sem_otime with per-semaphore value Greg Kroah-Hartman
` (26 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Rik van Riel,
Davidlohr Bueso, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit f269f40ad5aeee229ed70044926f44318abe41ef upstream.
There are two places that can contain alter operations:
- the global queue: sma->pending_alter
- the per-semaphore queues: sma->sem_base[].pending_alter.
Since one of the queues must be processed first, this causes an odd
priorization of the wakeups: complex operations have priority over
simple ops.
The patch restores the behavior of linux <=3.0.9: The longest waiting
operation has the highest priority.
This is done by using only one queue:
- if there are complex ops, then sma->pending_alter is used.
- otherwise, the per-semaphore queues are used.
As a side effect, do_smart_update_queue() becomes much simpler: no more
goto logic.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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/sem.c | 128 ++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 88 insertions(+), 40 deletions(-)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -192,6 +192,53 @@ void __init sem_init (void)
IPC_SEM_IDS, sysvipc_sem_proc_show);
}
+/**
+ * unmerge_queues - unmerge queues, if possible.
+ * @sma: semaphore array
+ *
+ * The function unmerges the wait queues if complex_count is 0.
+ * It must be called prior to dropping the global semaphore array lock.
+ */
+static void unmerge_queues(struct sem_array *sma)
+{
+ struct sem_queue *q, *tq;
+
+ /* complex operations still around? */
+ if (sma->complex_count)
+ return;
+ /*
+ * We will switch back to simple mode.
+ * Move all pending operation back into the per-semaphore
+ * queues.
+ */
+ list_for_each_entry_safe(q, tq, &sma->pending_alter, list) {
+ struct sem *curr;
+ curr = &sma->sem_base[q->sops[0].sem_num];
+
+ list_add_tail(&q->list, &curr->pending_alter);
+ }
+ INIT_LIST_HEAD(&sma->pending_alter);
+}
+
+/**
+ * merge_queues - Merge single semop queues into global queue
+ * @sma: semaphore array
+ *
+ * This function merges all per-semaphore queues into the global queue.
+ * It is necessary to achieve FIFO ordering for the pending single-sop
+ * operations when a multi-semop operation must sleep.
+ * Only the alter operations must be moved, the const operations can stay.
+ */
+static void merge_queues(struct sem_array *sma)
+{
+ int i;
+ for (i = 0; i < sma->sem_nsems; i++) {
+ struct sem *sem = sma->sem_base + i;
+
+ list_splice_init(&sem->pending_alter, &sma->pending_alter);
+ }
+}
+
/*
* If the request contains only one semaphore operation, and there are
* no complex transactions pending, lock only the semaphore involved.
@@ -262,6 +309,7 @@ static inline int sem_lock(struct sem_ar
static inline void sem_unlock(struct sem_array *sma, int locknum)
{
if (locknum == -1) {
+ unmerge_queues(sma);
ipc_unlock_object(&sma->sem_perm);
} else {
struct sem *sem = sma->sem_base + locknum;
@@ -831,49 +879,38 @@ static void do_smart_update(struct sem_a
int otime, struct list_head *pt)
{
int i;
- int progress;
otime |= do_smart_wakeup_zero(sma, sops, nsops, pt);
- progress = 1;
-retry_global:
- if (sma->complex_count) {
- if (update_queue(sma, -1, pt)) {
- progress = 1;
- otime = 1;
- sops = NULL;
- }
- }
- if (!progress)
- goto done;
-
- if (!sops) {
- /* No semops; something special is going on. */
- for (i = 0; i < sma->sem_nsems; i++) {
- if (update_queue(sma, i, pt)) {
- otime = 1;
- progress = 1;
+ if (!list_empty(&sma->pending_alter)) {
+ /* semaphore array uses the global queue - just process it. */
+ otime |= update_queue(sma, -1, pt);
+ } else {
+ if (!sops) {
+ /*
+ * No sops, thus the modified semaphores are not
+ * known. Check all.
+ */
+ for (i = 0; i < sma->sem_nsems; i++)
+ otime |= update_queue(sma, i, pt);
+ } else {
+ /*
+ * Check the semaphores that were increased:
+ * - No complex ops, thus all sleeping ops are
+ * decrease.
+ * - if we decreased the value, then any sleeping
+ * semaphore ops wont be able to run: If the
+ * previous value was too small, then the new
+ * value will be too small, too.
+ */
+ for (i = 0; i < nsops; i++) {
+ if (sops[i].sem_op > 0) {
+ otime |= update_queue(sma,
+ sops[i].sem_num, pt);
+ }
}
}
- goto done_checkretry;
- }
-
- /* Check the semaphores that were modified. */
- for (i = 0; i < nsops; i++) {
- if (sops[i].sem_op > 0 ||
- (sops[i].sem_op < 0 &&
- sma->sem_base[sops[i].sem_num].semval == 0))
- if (update_queue(sma, sops[i].sem_num, pt)) {
- otime = 1;
- progress = 1;
- }
- }
-done_checkretry:
- if (progress) {
- progress = 0;
- goto retry_global;
}
-done:
if (otime)
sma->sem_otime = get_seconds();
}
@@ -1747,11 +1784,22 @@ SYSCALL_DEFINE4(semtimedop, int, semid,
struct sem *curr;
curr = &sma->sem_base[sops->sem_num];
- if (alter)
- list_add_tail(&queue.list, &curr->pending_alter);
- else
+ if (alter) {
+ if (sma->complex_count) {
+ list_add_tail(&queue.list,
+ &sma->pending_alter);
+ } else {
+
+ list_add_tail(&queue.list,
+ &curr->pending_alter);
+ }
+ } else {
list_add_tail(&queue.list, &curr->pending_const);
+ }
} else {
+ if (!sma->complex_count)
+ merge_queues(sma);
+
if (alter)
list_add_tail(&queue.list, &sma->pending_alter);
else
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 45/69] ipc/sem.c: replace shared sem_otime with per-semaphore value
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (43 preceding siblings ...)
2013-10-16 17:44 ` [ 44/69] ipc/sem.c: always use only one queue for alter operations Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 46/69] ipc/sem.c: rename try_atomic_semop() to perform_atomic_semop(), docu update Greg Kroah-Hartman
` (25 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Rik van Riel,
Davidlohr Bueso, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit d12e1e50e47e0900dbbf52237b7e171f4f15ea1e upstream.
sem_otime contains the time of the last semaphore operation that
completed successfully. Every operation updates this value, thus access
from multiple cpus can cause thrashing.
Therefore the patch replaces the variable with a per-semaphore variable.
The per-array sem_otime is only calculated when required.
No performance improvement on a single-socket i3 - only important for
larger systems.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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>
---
include/linux/sem.h | 1 -
ipc/sem.c | 37 +++++++++++++++++++++++++++++++------
2 files changed, 31 insertions(+), 7 deletions(-)
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -12,7 +12,6 @@ struct task_struct;
struct sem_array {
struct kern_ipc_perm ____cacheline_aligned_in_smp
sem_perm; /* permissions .. see ipc.h */
- time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
struct sem *sem_base; /* ptr to first semaphore in array */
struct list_head pending_alter; /* pending operations */
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -99,6 +99,7 @@ struct sem {
/* that alter the semaphore */
struct list_head pending_const; /* pending single-sop operations */
/* that do not alter the semaphore*/
+ time_t sem_otime; /* candidate for sem_otime */
} ____cacheline_aligned_in_smp;
/* One queue for each sleeping process in the system. */
@@ -911,8 +912,14 @@ static void do_smart_update(struct sem_a
}
}
}
- if (otime)
- sma->sem_otime = get_seconds();
+ if (otime) {
+ if (sops == NULL) {
+ sma->sem_base[0].sem_otime = get_seconds();
+ } else {
+ sma->sem_base[sops[0].sem_num].sem_otime =
+ get_seconds();
+ }
+ }
}
@@ -1058,6 +1065,21 @@ static unsigned long copy_semid_to_user(
}
}
+static time_t get_semotime(struct sem_array *sma)
+{
+ int i;
+ time_t res;
+
+ res = sma->sem_base[0].sem_otime;
+ for (i = 1; i < sma->sem_nsems; i++) {
+ time_t to = sma->sem_base[i].sem_otime;
+
+ if (to > res)
+ res = to;
+ }
+ return res;
+}
+
static int semctl_nolock(struct ipc_namespace *ns, int semid,
int cmd, int version, void __user *p)
{
@@ -1131,9 +1153,9 @@ static int semctl_nolock(struct ipc_name
goto out_unlock;
kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
- tbuf.sem_otime = sma->sem_otime;
- tbuf.sem_ctime = sma->sem_ctime;
- tbuf.sem_nsems = sma->sem_nsems;
+ tbuf.sem_otime = get_semotime(sma);
+ tbuf.sem_ctime = sma->sem_ctime;
+ tbuf.sem_nsems = sma->sem_nsems;
rcu_read_unlock();
if (copy_semid_to_user(p, &tbuf, version))
return -EFAULT;
@@ -2025,6 +2047,9 @@ static int sysvipc_sem_proc_show(struct
{
struct user_namespace *user_ns = seq_user_ns(s);
struct sem_array *sma = it;
+ time_t sem_otime;
+
+ sem_otime = get_semotime(sma);
return seq_printf(s,
"%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n",
@@ -2036,7 +2061,7 @@ static int sysvipc_sem_proc_show(struct
from_kgid_munged(user_ns, sma->sem_perm.gid),
from_kuid_munged(user_ns, sma->sem_perm.cuid),
from_kgid_munged(user_ns, sma->sem_perm.cgid),
- sma->sem_otime,
+ sem_otime,
sma->sem_ctime);
}
#endif
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 46/69] ipc/sem.c: rename try_atomic_semop() to perform_atomic_semop(), docu update
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (44 preceding siblings ...)
2013-10-16 17:44 ` [ 45/69] ipc/sem.c: replace shared sem_otime with per-semaphore value Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 47/69] ipc/msg.c: Fix lost wakeup in msgsnd() Greg Kroah-Hartman
` (24 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Rik van Riel,
Davidlohr Bueso, Andrew Morton, Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit 758a6ba39ef6df4cdc615e5edd7bd86eab81a5f7 upstream.
Cleanup: Some minor points that I noticed while writing the previous
patches
1) The name try_atomic_semop() is misleading: The function performs the
operation (if it is possible).
2) Some documentation updates.
No real code change, a rename and documentation changes.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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/sem.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -154,12 +154,15 @@ static int sysvipc_sem_proc_show(struct
#define SEMOPM_FAST 64 /* ~ 372 bytes on stack */
/*
- * linked list protection:
+ * Locking:
* sem_undo.id_next,
+ * sem_array.complex_count,
* sem_array.pending{_alter,_cont},
- * sem_array.sem_undo: sem_lock() for read/write
+ * sem_array.sem_undo: global sem_lock() for read/write
* sem_undo.proc_next: only "current" is allowed to read/write that field.
*
+ * sem_array.sem_base[i].pending_{const,alter}:
+ * global or semaphore sem_lock() for read/write
*/
#define sc_semmsl sem_ctls[0]
@@ -536,12 +539,19 @@ SYSCALL_DEFINE3(semget, key_t, key, int,
return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
}
-/*
- * Determine whether a sequence of semaphore operations would succeed
- * all at once. Return 0 if yes, 1 if need to sleep, else return error code.
+/** perform_atomic_semop - Perform (if possible) a semaphore operation
+ * @sma: semaphore array
+ * @sops: array with operations that should be checked
+ * @nsems: number of sops
+ * @un: undo array
+ * @pid: pid that did the change
+ *
+ * Returns 0 if the operation was possible.
+ * Returns 1 if the operation is impossible, the caller must sleep.
+ * Negative values are error codes.
*/
-static int try_atomic_semop (struct sem_array * sma, struct sembuf * sops,
+static int perform_atomic_semop(struct sem_array *sma, struct sembuf *sops,
int nsops, struct sem_undo *un, int pid)
{
int result, sem_op;
@@ -724,8 +734,8 @@ static int wake_const_ops(struct sem_arr
q = container_of(walk, struct sem_queue, list);
walk = walk->next;
- error = try_atomic_semop(sma, q->sops, q->nsops,
- q->undo, q->pid);
+ error = perform_atomic_semop(sma, q->sops, q->nsops,
+ q->undo, q->pid);
if (error <= 0) {
/* operation completed, remove from queue & wakeup */
@@ -838,7 +848,7 @@ again:
if (semnum != -1 && sma->sem_base[semnum].semval == 0)
break;
- error = try_atomic_semop(sma, q->sops, q->nsops,
+ error = perform_atomic_semop(sma, q->sops, q->nsops,
q->undo, q->pid);
/* Does q->sleeper still need to sleep? */
@@ -1686,7 +1696,6 @@ static int get_queue_result(struct sem_q
return error;
}
-
SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
unsigned, nsops, const struct timespec __user *, timeout)
{
@@ -1784,7 +1793,8 @@ SYSCALL_DEFINE4(semtimedop, int, semid,
if (un && un->semid == -1)
goto out_unlock_free;
- error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current));
+ error = perform_atomic_semop(sma, sops, nsops, un,
+ task_tgid_vnr(current));
if (error <= 0) {
if (alter && error == 0)
do_smart_update(sma, sops, nsops, 1, &tasks);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 47/69] ipc/msg.c: Fix lost wakeup in msgsnd().
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (45 preceding siblings ...)
2013-10-16 17:44 ` [ 46/69] ipc/sem.c: rename try_atomic_semop() to perform_atomic_semop(), docu update Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 48/69] ipc,shm: introduce lockless functions to obtain the ipc object Greg Kroah-Hartman
` (23 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Rik van Riel, Manfred Spraul,
Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit bebcb928c820d0ee83aca4b192adc195e43e66a2 upstream.
The check if the queue is full and adding current to the wait queue of
pending msgsnd() operations (ss_add()) must be atomic.
Otherwise:
- the thread that performs msgsnd() finds a full queue and decides to
sleep.
- the thread that performs msgrcv() first reads all messages from the
queue and then sleeps, because the queue is empty.
- the msgrcv() calls do not perform any wakeups, because the msgsnd()
task has not yet called ss_add().
- then the msgsnd()-thread first calls ss_add() and then sleeps.
Net result: msgsnd() and msgrcv() both sleep forever.
Observed with msgctl08 from ltp with a preemptible kernel.
Fix: Call ipc_lock_object() before performing the check.
The patch also moves security_msg_queue_msgsnd() under ipc_lock_object:
- msgctl(IPC_SET) explicitely mentions that it tries to expunge any
pending operations that are not allowed anymore with the new
permissions. If security_msg_queue_msgsnd() is called without locks,
then there might be races.
- it makes the patch much simpler.
Reported-and-tested-by: Vineet Gupta <Vineet.Gupta1@synopsys.com>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
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, 5 insertions(+), 7 deletions(-)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -680,16 +680,18 @@ long do_msgsnd(int msqid, long mtype, vo
goto out_unlock1;
}
+ ipc_lock_object(&msq->q_perm);
+
for (;;) {
struct msg_sender s;
err = -EACCES;
if (ipcperms(ns, &msq->q_perm, S_IWUGO))
- goto out_unlock1;
+ goto out_unlock0;
err = security_msg_queue_msgsnd(msq, msg, msgflg);
if (err)
- goto out_unlock1;
+ goto out_unlock0;
if (msgsz + msq->q_cbytes <= msq->q_qbytes &&
1 + msq->q_qnum <= msq->q_qbytes) {
@@ -699,10 +701,9 @@ long do_msgsnd(int msqid, long mtype, vo
/* queue full, wait: */
if (msgflg & IPC_NOWAIT) {
err = -EAGAIN;
- goto out_unlock1;
+ goto out_unlock0;
}
- ipc_lock_object(&msq->q_perm);
ss_add(msq, &s);
if (!ipc_rcu_getref(msq)) {
@@ -730,10 +731,7 @@ long do_msgsnd(int msqid, long mtype, vo
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();
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 48/69] ipc,shm: introduce lockless functions to obtain the ipc object
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (46 preceding siblings ...)
2013-10-16 17:44 ` [ 47/69] ipc/msg.c: Fix lost wakeup in msgsnd() Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 49/69] ipc,shm: shorten critical region in shmctl_down Greg Kroah-Hartman
` (22 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 8b8d52ac382b17a19906b930cd69e2edb0aca8ba upstream.
This is the third and final patchset that deals with reducing the amount
of contention we impose on the ipc lock (kern_ipc_perm.lock). These
changes mostly deal with shared memory, previous work has already been
done for semaphores and message queues:
http://lkml.org/lkml/2013/3/20/546 (sems)
http://lkml.org/lkml/2013/5/15/584 (mqueues)
With these patches applied, a custom shm microbenchmark stressing shmctl
doing IPC_STAT with 4 threads a million times, reduces the execution
time by 50%. A similar run, this time with IPC_SET, reduces the
execution time from 3 mins and 35 secs to 27 seconds.
Patches 1-8: replaces blindly taking the ipc lock for a smarter
combination of rcu and ipc_obtain_object, only acquiring the spinlock
when updating.
Patch 9: renames the ids rw_mutex to rwsem, which is what it already was.
Patch 10: is a trivial mqueue leftover cleanup
Patch 11: adds a brief lock scheme description, requested by Andrew.
This patch:
Add shm_obtain_object() and shm_obtain_object_check(), which will allow us
to get the ipc object without acquiring the lock. Just as with other
forms of ipc, these functions are basically wrappers around
ipc_obtain_object*().
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -124,6 +124,26 @@ void __init shm_init (void)
IPC_SHM_IDS, sysvipc_shm_proc_show);
}
+static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
/*
* shm_lock_(check_) routines are called in the paths where the rw_mutex
* is not necessarily held.
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 49/69] ipc,shm: shorten critical region in shmctl_down
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (47 preceding siblings ...)
2013-10-16 17:44 ` [ 48/69] ipc,shm: introduce lockless functions to obtain the ipc object Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:44 ` [ 50/69] ipc: drop ipcctl_pre_down Greg Kroah-Hartman
` (21 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 79ccf0f8c8e04e8b9eda6645ba0f63b0915a3075 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>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -780,11 +780,10 @@ static int shmctl_down(struct ipc_namesp
down_write(&shm_ids(ns).rw_mutex);
rcu_read_lock();
- ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd,
- &shmid64.shm_perm, 0);
+ ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
+ &shmid64.shm_perm, 0);
if (IS_ERR(ipcp)) {
err = PTR_ERR(ipcp);
- /* the ipc lock is not held upon failure */
goto out_unlock1;
}
@@ -792,14 +791,16 @@ static int shmctl_down(struct ipc_namesp
err = security_shm_shmctl(shp, cmd);
if (err)
- goto out_unlock0;
+ goto out_unlock1;
switch (cmd) {
case IPC_RMID:
+ ipc_lock_object(&shp->shm_perm);
/* do_shm_rmid unlocks the ipc object and rcu */
do_shm_rmid(ns, ipcp);
goto out_up;
case IPC_SET:
+ ipc_lock_object(&shp->shm_perm);
err = ipc_update_perm(&shmid64.shm_perm, ipcp);
if (err)
goto out_unlock0;
@@ -807,6 +808,7 @@ static int shmctl_down(struct ipc_namesp
break;
default:
err = -EINVAL;
+ goto out_unlock1;
}
out_unlock0:
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 50/69] ipc: drop ipcctl_pre_down
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (48 preceding siblings ...)
2013-10-16 17:44 ` [ 49/69] ipc,shm: shorten critical region in shmctl_down Greg Kroah-Hartman
@ 2013-10-16 17:44 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 51/69] ipc,shm: introduce shmctl_nolock Greg Kroah-Hartman
` (20 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:44 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 3b1c4ad37741e53804ffe0a30dd01e08b2ab6241 upstream.
Now that sem, msgque and shm, through *_down(), all use the lockless
variant of ipcctl_pre_down(), go ahead and delete it.
[akpm@linux-foundation.org: fix function name in kerneldoc, cleanups]
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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.c | 24 ++++--------------------
ipc/util.h | 3 ---
2 files changed, 4 insertions(+), 23 deletions(-)
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -733,7 +733,7 @@ int ipc_update_perm(struct ipc64_perm *i
}
/**
- * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd
+ * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd
* @ns: the ipc namespace
* @ids: the table of ids where to look for the ipc
* @id: the id of the ipc to retrieve
@@ -746,29 +746,13 @@ 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 the ipc lock held in case of success
- * or an err-code without any lock held otherwise.
+ * - returns a pointer to the ipc object or otherwise, the corresponding error.
*
* 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,
- struct ipc64_perm *perm, int extra_perm)
-{
- struct kern_ipc_perm *ipcp;
-
- ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm);
- if (IS_ERR(ipcp))
- goto out;
-
- spin_lock(&ipcp->lock);
-out:
- return ipcp;
-}
-
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm)
+ struct ipc_ids *ids, int id, int cmd,
+ struct ipc64_perm *perm, int extra_perm)
{
kuid_t euid;
int err = -EPERM;
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -131,9 +131,6 @@ int ipc_update_perm(struct ipc64_perm *i
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm);
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm);
#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
/* On IA-64, we always use the "64-bit version" of the IPC structures. */
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 51/69] ipc,shm: introduce shmctl_nolock
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (49 preceding siblings ...)
2013-10-16 17:44 ` [ 50/69] ipc: drop ipcctl_pre_down Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 52/69] ipc,shm: make shmctl_nolock lockless Greg Kroah-Hartman
` (19 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 68eccc1dc345539d589ae78ee43b835c1a06a134 upstream.
Similar to semctl and msgctl, when calling msgctl, the *_INFO and *_STAT
commands can be performed without acquiring the ipc object.
Add a shmctl_nolock() function and move the logic of *_INFO and *_STAT out
of msgctl(). Since we are just moving functionality, 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>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 57 +++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 18 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -820,29 +820,24 @@ out_up:
return err;
}
-SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
+ int cmd, int version, void __user *buf)
{
+ int err;
struct shmid_kernel *shp;
- int err, version;
- struct ipc_namespace *ns;
- if (cmd < 0 || shmid < 0) {
- err = -EINVAL;
- goto out;
+ /* preliminary security checks for *_INFO */
+ if (cmd == IPC_INFO || cmd == SHM_INFO) {
+ err = security_shm_shmctl(NULL, cmd);
+ if (err)
+ return err;
}
- version = ipc_parse_version(&cmd);
- ns = current->nsproxy->ipc_ns;
-
- switch (cmd) { /* replace with proc interface ? */
+ switch (cmd) {
case IPC_INFO:
{
struct shminfo64 shminfo;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shminfo, 0, sizeof(shminfo));
shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
shminfo.shmmax = ns->shm_ctlmax;
@@ -864,10 +859,6 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
{
struct shm_info shm_info;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shm_info, 0, sizeof(shm_info));
down_read(&shm_ids(ns).rw_mutex);
shm_info.used_ids = shm_ids(ns).in_use;
@@ -928,6 +919,36 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
err = result;
goto out;
}
+ default:
+ return -EINVAL;
+ }
+
+out_unlock:
+ shm_unlock(shp);
+out:
+ return err;
+}
+
+SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+{
+ struct shmid_kernel *shp;
+ int err, version;
+ struct ipc_namespace *ns;
+
+ if (cmd < 0 || shmid < 0) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
+
+ switch (cmd) {
+ case IPC_INFO:
+ case SHM_INFO:
+ case SHM_STAT:
+ case IPC_STAT:
+ return shmctl_nolock(ns, shmid, cmd, version, buf);
case SHM_LOCK:
case SHM_UNLOCK:
{
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 52/69] ipc,shm: make shmctl_nolock lockless
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (50 preceding siblings ...)
2013-10-16 17:45 ` [ 51/69] ipc,shm: introduce shmctl_nolock Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 53/69] ipc,shm: shorten critical region for shmctl Greg Kroah-Hartman
` (18 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit c97cb9ccab8c85428ec21eff690642ad2ce1fa8a 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.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -882,27 +882,31 @@ static int shmctl_nolock(struct ipc_name
struct shmid64_ds tbuf;
int result;
+ rcu_read_lock();
if (cmd == SHM_STAT) {
- shp = shm_lock(ns, shmid);
+ shp = shm_obtain_object(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = shp->shm_perm.id;
} else {
- shp = shm_lock_check(ns, shmid);
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = 0;
}
+
err = -EACCES;
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
goto out_unlock;
+
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;
+
memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
tbuf.shm_segsz = shp->shm_segsz;
@@ -912,8 +916,9 @@ static int shmctl_nolock(struct ipc_name
tbuf.shm_cpid = shp->shm_cprid;
tbuf.shm_lpid = shp->shm_lprid;
tbuf.shm_nattch = shp->shm_nattch;
- shm_unlock(shp);
- if(copy_shmid_to_user (buf, &tbuf, version))
+ rcu_read_unlock();
+
+ if (copy_shmid_to_user(buf, &tbuf, version))
err = -EFAULT;
else
err = result;
@@ -924,7 +929,7 @@ static int shmctl_nolock(struct ipc_name
}
out_unlock:
- shm_unlock(shp);
+ rcu_read_unlock();
out:
return err;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 53/69] ipc,shm: shorten critical region for shmctl
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (51 preceding siblings ...)
2013-10-16 17:45 ` [ 52/69] ipc,shm: make shmctl_nolock lockless Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 54/69] ipc,shm: cleanup do_shmat pasta Greg Kroah-Hartman
` (17 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 2caacaa82a51b78fc0c800e206473874094287ed upstream.
With the *_INFO, *_STAT, IPC_RMID and IPC_SET commands already optimized,
deal with the remaining SHM_LOCK and SHM_UNLOCK commands. Take the
shm_perm lock after doing the initial auditing and security checks. The
rest of the logic remains unchanged.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 49 +++++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 24 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -940,10 +940,8 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
int err, version;
struct ipc_namespace *ns;
- if (cmd < 0 || shmid < 0) {
- err = -EINVAL;
- goto out;
- }
+ if (cmd < 0 || shmid < 0)
+ return -EINVAL;
version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns;
@@ -954,36 +952,40 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
case SHM_STAT:
case IPC_STAT:
return shmctl_nolock(ns, shmid, cmd, version, buf);
+ case IPC_RMID:
+ case IPC_SET:
+ return shmctl_down(ns, shmid, cmd, buf, version);
case SHM_LOCK:
case SHM_UNLOCK:
{
struct file *shm_file;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock1;
}
audit_ipc_obj(&(shp->shm_perm));
+ err = security_shm_shmctl(shp, cmd);
+ if (err)
+ goto out_unlock1;
+ ipc_lock_object(&shp->shm_perm);
if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
kuid_t euid = current_euid();
err = -EPERM;
if (!uid_eq(euid, shp->shm_perm.uid) &&
!uid_eq(euid, shp->shm_perm.cuid))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
- goto out_unlock;
+ goto out_unlock0;
}
- err = security_shm_shmctl(shp, cmd);
- if (err)
- goto out_unlock;
-
shm_file = shp->shm_file;
if (is_file_hugepages(shm_file))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK) {
struct user_struct *user = current_user();
@@ -992,32 +994,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
shp->shm_perm.mode |= SHM_LOCKED;
shp->mlock_user = user;
}
- goto out_unlock;
+ goto out_unlock0;
}
/* SHM_UNLOCK */
if (!(shp->shm_perm.mode & SHM_LOCKED))
- goto out_unlock;
+ goto out_unlock0;
shmem_lock(shm_file, 0, shp->mlock_user);
shp->shm_perm.mode &= ~SHM_LOCKED;
shp->mlock_user = NULL;
get_file(shm_file);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
shmem_unlock_mapping(shm_file->f_mapping);
+
fput(shm_file);
- goto out;
- }
- case IPC_RMID:
- case IPC_SET:
- err = shmctl_down(ns, shmid, cmd, buf, version);
return err;
+ }
default:
return -EINVAL;
}
-out_unlock:
- shm_unlock(shp);
-out:
+out_unlock0:
+ ipc_unlock_object(&shp->shm_perm);
+out_unlock1:
+ rcu_read_unlock();
return err;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 54/69] ipc,shm: cleanup do_shmat pasta
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (52 preceding siblings ...)
2013-10-16 17:45 ` [ 53/69] ipc,shm: shorten critical region for shmctl Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 55/69] ipc,shm: shorten critical region for shmat Greg Kroah-Hartman
` (16 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit f42569b1388b1408b574a5e93a23a663647d4181 upstream.
Clean up some of the messy do_shmat() spaghetti code, getting rid of
out_free and out_put_dentry labels. This makes shortening the critical
region of this function in the next patch a little easier to do and read.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1108,16 +1108,21 @@ long do_shmat(int shmid, char __user *sh
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
- if (!sfd)
- goto out_put_dentry;
+ if (!sfd) {
+ path_put(&path);
+ goto out_nattch;
+ }
file = alloc_file(&path, f_mode,
is_file_hugepages(shp->shm_file) ?
&shm_file_operations_huge :
&shm_file_operations);
err = PTR_ERR(file);
- if (IS_ERR(file))
- goto out_free;
+ if (IS_ERR(file)) {
+ kfree(sfd);
+ path_put(&path);
+ goto out_nattch;
+ }
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
@@ -1143,7 +1148,7 @@ long do_shmat(int shmid, char __user *sh
addr > current->mm->start_stack - size - PAGE_SIZE * 5)
goto invalid;
}
-
+
addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate);
*raddr = addr;
err = 0;
@@ -1167,19 +1172,12 @@ out_nattch:
else
shm_unlock(shp);
up_write(&shm_ids(ns).rw_mutex);
-
-out:
return err;
out_unlock:
shm_unlock(shp);
- goto out;
-
-out_free:
- kfree(sfd);
-out_put_dentry:
- path_put(&path);
- goto out_nattch;
+out:
+ return err;
}
SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 55/69] ipc,shm: shorten critical region for shmat
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (53 preceding siblings ...)
2013-10-16 17:45 ` [ 54/69] ipc,shm: cleanup do_shmat pasta Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 56/69] ipc: rename ids->rw_mutex Greg Kroah-Hartman
` (15 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Sasha Levin, Andrew Morton,
Linus Torvalds, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit c2c737a0461e61a34676bd0bd1bc1a70a1b4e396 upstream.
Similar to other system calls, acquire the kern_ipc_perm lock after doing
the initial permission and security checks.
[sasha.levin@oracle.com: dont leave do_shmat with rcu lock held]
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.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/shm.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -19,6 +19,9 @@
* namespaces support
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * Better ipc lock (kern_ipc_perm.lock) handling
+ * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013.
*/
#include <linux/slab.h>
@@ -1086,10 +1089,11 @@ long do_shmat(int shmid, char __user *sh
* additional creator id...
*/
ns = current->nsproxy->ipc_ns;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
err = -EACCES;
@@ -1100,11 +1104,13 @@ long do_shmat(int shmid, char __user *sh
if (err)
goto out_unlock;
+ ipc_lock_object(&shp->shm_perm);
path = shp->shm_file->f_path;
path_get(&path);
shp->shm_nattch++;
size = i_size_read(path.dentry->d_inode);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
@@ -1175,7 +1181,7 @@ out_nattch:
return err;
out_unlock:
- shm_unlock(shp);
+ rcu_read_unlock();
out:
return err;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 56/69] ipc: rename ids->rw_mutex
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (54 preceding siblings ...)
2013-10-16 17:45 ` [ 55/69] ipc,shm: shorten critical region for shmat Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 57/69] ipc,msg: drop msg_unlock Greg Kroah-Hartman
` (14 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit d9a605e40b1376eb02b067d7690580255a0df68f upstream.
Since in some situations the lock can be shared for readers, we shouldn't
be calling it a mutex, rename it to rwsem.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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>
---
include/linux/ipc_namespace.h | 2 -
ipc/msg.c | 20 +++++++--------
ipc/namespace.c | 4 +--
ipc/sem.c | 24 +++++++++---------
ipc/shm.c | 56 +++++++++++++++++++++---------------------
ipc/util.c | 28 ++++++++++-----------
ipc/util.h | 4 +--
7 files changed, 69 insertions(+), 69 deletions(-)
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -22,7 +22,7 @@ struct ipc_ids {
int in_use;
unsigned short seq;
unsigned short seq_max;
- struct rw_semaphore rw_mutex;
+ struct rw_semaphore rwsem;
struct idr ipcs_idr;
int next_id;
};
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -172,7 +172,7 @@ static inline void msg_rmid(struct ipc_n
* @ns: namespace
* @params: ptr to the structure that contains the key and msgflg
*
- * Called with msg_ids.rw_mutex held (writer)
+ * Called with msg_ids.rwsem held (writer)
*/
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
@@ -259,8 +259,8 @@ static void expunge_all(struct msg_queue
* removes the message queue from message queue ID IDR, and cleans up all the
* messages associated with this queue.
*
- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
- * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
+ * msg_ids.rwsem (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rwsem remains locked on exit.
*/
static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -282,7 +282,7 @@ static void freeque(struct ipc_namespace
}
/*
- * Called with msg_ids.rw_mutex and ipcp locked.
+ * Called with msg_ids.rwsem and ipcp locked.
*/
static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
{
@@ -386,9 +386,9 @@ copy_msqid_from_user(struct msqid64_ds *
}
/*
- * This function handles some msgctl commands which require the rw_mutex
+ * This function handles some msgctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
struct msqid_ds __user *buf, int version)
@@ -403,7 +403,7 @@ static int msgctl_down(struct ipc_namesp
return -EFAULT;
}
- down_write(&msg_ids(ns).rw_mutex);
+ down_write(&msg_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
@@ -459,7 +459,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&msg_ids(ns).rw_mutex);
+ up_write(&msg_ids(ns).rwsem);
return err;
}
@@ -494,7 +494,7 @@ static int msgctl_nolock(struct ipc_name
msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- down_read(&msg_ids(ns).rw_mutex);
+ down_read(&msg_ids(ns).rwsem);
if (cmd == MSG_INFO) {
msginfo.msgpool = msg_ids(ns).in_use;
msginfo.msgmap = atomic_read(&ns->msg_hdrs);
@@ -505,7 +505,7 @@ static int msgctl_nolock(struct ipc_name
msginfo.msgtql = MSGTQL;
}
max_id = ipc_get_maxid(&msg_ids(ns));
- up_read(&msg_ids(ns).rw_mutex);
+ up_read(&msg_ids(ns).rwsem);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -81,7 +81,7 @@ void free_ipcs(struct ipc_namespace *ns,
int next_id;
int total, in_use;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
in_use = ids->in_use;
@@ -93,7 +93,7 @@ void free_ipcs(struct ipc_namespace *ns,
free(ns, perm);
total++;
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
}
static void free_ipc_ns(struct ipc_namespace *ns)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -322,7 +322,7 @@ static inline void sem_unlock(struct sem
}
/*
- * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * sem_lock_(check_) routines are called in the paths where the rwsem
* is not held.
*
* The caller holds the RCU read lock.
@@ -426,7 +426,7 @@ static inline void sem_rmid(struct ipc_n
* @ns: namespace
* @params: ptr to the structure that contains key, semflg and nsems
*
- * Called with sem_ids.rw_mutex held (as a writer)
+ * Called with sem_ids.rwsem held (as a writer)
*/
static int newary(struct ipc_namespace *ns, struct ipc_params *params)
@@ -492,7 +492,7 @@ static int newary(struct ipc_namespace *
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
{
@@ -503,7 +503,7 @@ static inline int sem_security(struct ke
}
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -994,8 +994,8 @@ static int count_semzcnt (struct sem_arr
return semzcnt;
}
-/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem
* remains locked on exit.
*/
static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
@@ -1116,7 +1116,7 @@ static int semctl_nolock(struct ipc_name
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- down_read(&sem_ids(ns).rw_mutex);
+ down_read(&sem_ids(ns).rwsem);
if (cmd == SEM_INFO) {
seminfo.semusz = sem_ids(ns).in_use;
seminfo.semaem = ns->used_sems;
@@ -1125,7 +1125,7 @@ static int semctl_nolock(struct ipc_name
seminfo.semaem = SEMAEM;
}
max_id = ipc_get_maxid(&sem_ids(ns));
- up_read(&sem_ids(ns).rw_mutex);
+ up_read(&sem_ids(ns).rwsem);
if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -1431,9 +1431,9 @@ copy_semid_from_user(struct semid64_ds *
}
/*
- * This function handles some semctl commands which require the rw_mutex
+ * This function handles some semctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int semctl_down(struct ipc_namespace *ns, int semid,
int cmd, int version, void __user *p)
@@ -1448,7 +1448,7 @@ static int semctl_down(struct ipc_namesp
return -EFAULT;
}
- down_write(&sem_ids(ns).rw_mutex);
+ down_write(&sem_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
@@ -1487,7 +1487,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&sem_ids(ns).rw_mutex);
+ up_write(&sem_ids(ns).rwsem);
return err;
}
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -83,8 +83,8 @@ void shm_init_ns(struct ipc_namespace *n
}
/*
- * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
- * Only shm_ids.rw_mutex remains locked on exit.
+ * Called with shm_ids.rwsem (writer) and the shp structure locked.
+ * Only shm_ids.rwsem remains locked on exit.
*/
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -148,7 +148,7 @@ static inline struct shmid_kernel *shm_o
}
/*
- * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * shm_lock_(check_) routines are called in the paths where the rwsem
* is not necessarily held.
*/
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
@@ -205,7 +205,7 @@ static void shm_open(struct vm_area_stru
* @ns: namespace
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
+ * It has to be called with shp and shm_ids.rwsem (writer) locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -253,7 +253,7 @@ static void shm_close(struct vm_area_str
struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns;
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
/* remove from the list of attaches of the shm segment */
shp = shm_lock(ns, sfd->id);
BUG_ON(IS_ERR(shp));
@@ -264,10 +264,10 @@ static void shm_close(struct vm_area_str
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_current(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -298,7 +298,7 @@ static int shm_try_destroy_current(int i
return 0;
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_orphaned(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -309,7 +309,7 @@ static int shm_try_destroy_orphaned(int
* We want to destroy segments without users and with already
* exit'ed originating process.
*
- * As shp->* are changed under rw_mutex, it's safe to skip shp locking.
+ * As shp->* are changed under rwsem, it's safe to skip shp locking.
*/
if (shp->shm_creator != NULL)
return 0;
@@ -323,10 +323,10 @@ static int shm_try_destroy_orphaned(int
void shm_destroy_orphaned(struct ipc_namespace *ns)
{
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
@@ -338,10 +338,10 @@ void exit_shm(struct task_struct *task)
return;
/* Destroy all already created segments, but not mapped yet */
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -475,7 +475,7 @@ static const struct vm_operations_struct
* @ns: namespace
* @params: ptr to the structure that contains key, size and shmflg
*
- * Called with shm_ids.rw_mutex held as a writer.
+ * Called with shm_ids.rwsem held as a writer.
*/
static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
@@ -583,7 +583,7 @@ no_file:
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
{
@@ -594,7 +594,7 @@ static inline int shm_security(struct ke
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -707,7 +707,7 @@ static inline unsigned long copy_shminfo
/*
* Calculate and add used RSS and swap pages of a shm.
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_add_rss_swap(struct shmid_kernel *shp,
unsigned long *rss_add, unsigned long *swp_add)
@@ -734,7 +734,7 @@ static void shm_add_rss_swap(struct shmi
}
/*
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
unsigned long *swp)
@@ -763,9 +763,9 @@ static void shm_get_stat(struct ipc_name
}
/*
- * This function handles some shmctl commands which require the rw_mutex
+ * This function handles some shmctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
struct shmid_ds __user *buf, int version)
@@ -780,7 +780,7 @@ static int shmctl_down(struct ipc_namesp
return -EFAULT;
}
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
@@ -819,7 +819,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
}
@@ -850,9 +850,9 @@ static int shmctl_nolock(struct ipc_name
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if(err<0)
err = 0;
@@ -863,14 +863,14 @@ static int shmctl_nolock(struct ipc_name
struct shm_info shm_info;
memset(&shm_info, 0, sizeof(shm_info));
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -1169,7 +1169,7 @@ out_fput:
fput(file);
out_nattch:
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
shp = shm_lock(ns, shmid);
BUG_ON(IS_ERR(shp));
shp->shm_nattch--;
@@ -1177,7 +1177,7 @@ out_nattch:
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
out_unlock:
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -119,7 +119,7 @@ __initcall(ipc_init);
void ipc_init_ids(struct ipc_ids *ids)
{
- init_rwsem(&ids->rw_mutex);
+ init_rwsem(&ids->rwsem);
ids->in_use = 0;
ids->seq = 0;
@@ -174,7 +174,7 @@ void __init ipc_init_proc_interface(cons
* @ids: Identifier set
* @key: The key to find
*
- * Requires ipc_ids.rw_mutex locked.
+ * Requires ipc_ids.rwsem locked.
* Returns the LOCKED pointer to the ipc structure if found or NULL
* if not.
* If key is found ipc points to the owning ipc structure
@@ -208,7 +208,7 @@ static struct kern_ipc_perm *ipc_findkey
* ipc_get_maxid - get the last assigned id
* @ids: IPC identifier set
*
- * Called with ipc_ids.rw_mutex held.
+ * Called with ipc_ids.rwsem held.
*/
int ipc_get_maxid(struct ipc_ids *ids)
@@ -246,7 +246,7 @@ 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 writer ipc_ids.rw_mutex held.
+ * Called with writer ipc_ids.rwsem held.
*/
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
{
@@ -312,9 +312,9 @@ static int ipcget_new(struct ipc_namespa
{
int err;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
err = ops->getnew(ns, params);
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -331,7 +331,7 @@ static int ipcget_new(struct ipc_namespa
*
* On success, the IPC id is returned.
*
- * It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ * It is called with ipc_ids.rwsem and ipcp->lock held.
*/
static int ipc_check_perms(struct ipc_namespace *ns,
struct kern_ipc_perm *ipcp,
@@ -376,7 +376,7 @@ static int ipcget_public(struct ipc_name
* Take the lock as a writer since we are potentially going to add
* a new entry + read locks are not "upgradable"
*/
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
ipcp = ipc_findkey(ids, params->key);
if (ipcp == NULL) {
/* key not used */
@@ -402,7 +402,7 @@ static int ipcget_public(struct ipc_name
}
ipc_unlock(ipcp);
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -413,7 +413,7 @@ static int ipcget_public(struct ipc_name
* @ids: IPC identifier set
* @ipcp: ipc perm structure containing the identifier to remove
*
- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
* before this function is called, and remain locked on the exit.
*/
@@ -621,7 +621,7 @@ struct kern_ipc_perm *ipc_obtain_object(
}
/**
- * ipc_lock - Lock an ipc structure without rw_mutex held
+ * ipc_lock - Lock an ipc structure without rwsem held
* @ids: IPC identifier set
* @id: ipc id to look for
*
@@ -748,7 +748,7 @@ int ipc_update_perm(struct ipc64_perm *i
* - performs some audit and permission check, depending on the given cmd
* - returns a pointer to the ipc object or otherwise, the corresponding error.
*
- * Call holding the both the rw_mutex and the rcu read lock.
+ * Call holding the both the rwsem and the rcu read lock.
*/
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
@@ -868,7 +868,7 @@ static void *sysvipc_proc_start(struct s
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- down_read(&ids->rw_mutex);
+ down_read(&ids->rwsem);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -895,7 +895,7 @@ static void sysvipc_proc_stop(struct seq
ids = &iter->ns->ids[iface->ids];
/* Release the lock we took in start() */
- up_read(&ids->rw_mutex);
+ up_read(&ids->rwsem);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -94,10 +94,10 @@ void __init ipc_init_proc_interface(cons
#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
-/* must be called with ids->rw_mutex acquired for writing */
+/* must be called with ids->rwsem acquired for writing */
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
-/* must be called with ids->rw_mutex acquired for reading */
+/* must be called with ids->rwsem acquired for reading */
int ipc_get_maxid(struct ipc_ids *);
/* must be called with both locks acquired. */
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 57/69] ipc,msg: drop msg_unlock
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (55 preceding siblings ...)
2013-10-16 17:45 ` [ 56/69] ipc: rename ids->rw_mutex Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 58/69] ipc: document general ipc locking scheme Greg Kroah-Hartman
` (13 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 4718787d1f626f45ddb239912bc07266b9880044 upstream.
There is only one user left, drop this function and just call
ipc_unlock_object() and rcu_read_unlock().
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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 | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -70,8 +70,6 @@ struct msg_sender {
#define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-
static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
static int newque(struct ipc_namespace *, struct ipc_params *);
#ifdef CONFIG_PROC_FS
@@ -270,7 +268,8 @@ static void freeque(struct ipc_namespace
expunge_all(msq, -EIDRM);
ss_wakeup(&msq->q_senders, 1);
msg_rmid(ns, msq);
- msg_unlock(msq);
+ ipc_unlock_object(&msq->q_perm);
+ rcu_read_unlock();
list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) {
atomic_dec(&ns->msg_hdrs);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 58/69] ipc: document general ipc locking scheme
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (56 preceding siblings ...)
2013-10-16 17:45 ` [ 57/69] ipc,msg: drop msg_unlock Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 59/69] ipc, shm: guard against non-existant vma in shmdt(2) Greg Kroah-Hartman
` (12 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 05603c44a7627793219b0bd9a7b236099dc9cd9d upstream.
As suggested by Andrew, add a generic initial locking scheme used
throughout all sysv ipc mechanisms. Documenting the ids rwsem, how rcu
can be enough to do the initial checks and when to actually acquire the
kern_ipc_perm.lock spinlock.
I found that adding it to util.c was generic enough.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -15,6 +15,14 @@
* Jun 2006 - namespaces ssupport
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * General sysv ipc locking scheme:
+ * when doing ipc id lookups, take the ids->rwsem
+ * rcu_read_lock()
+ * obtain the ipc object (kern_ipc_perm)
+ * perform security, capabilities, auditing and permission checks, etc.
+ * acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object()
+ * perform data updates (ie: SET, RMID, LOCK/UNLOCK commands)
*/
#include <linux/mm.h>
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 59/69] ipc, shm: guard against non-existant vma in shmdt(2)
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (57 preceding siblings ...)
2013-10-16 17:45 ` [ 58/69] ipc: document general ipc locking scheme Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 60/69] ipc: drop ipc_lock_by_ptr Greg Kroah-Hartman
` (11 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 530fcd16d87cd2417c472a581ba5a1e501556c86 upstream.
When !CONFIG_MMU there's a chance we can derefence a NULL pointer when the
VM area isn't found - check the return value of find_vma().
Also, remove the redundant -EINVAL return: retval is set to the proper
return code and *only* changed to 0, when we actually unmap the segments.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1288,8 +1288,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, sh
#else /* CONFIG_MMU */
/* under NOMMU conditions, the exact address to be destroyed must be
* given */
- retval = -EINVAL;
- if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
+ if (vma && vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
retval = 0;
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 60/69] ipc: drop ipc_lock_by_ptr
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (58 preceding siblings ...)
2013-10-16 17:45 ` [ 59/69] ipc, shm: guard against non-existant vma in shmdt(2) Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 61/69] ipc, shm: drop shm_lock_check Greg Kroah-Hartman
` (10 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 32a2750010981216fb788c5190fb0e646abfab30 upstream.
After previous cleanups and optimizations, this function is no longer
heavily used and we don't have a good reason to keep it. Update the few
remaining callers and get rid of it.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/namespace.c | 3 ++-
ipc/util.c | 6 ++++--
ipc/util.h | 6 ------
3 files changed, 6 insertions(+), 9 deletions(-)
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -89,7 +89,8 @@ void free_ipcs(struct ipc_namespace *ns,
perm = idr_find(&ids->ipcs_idr, next_id);
if (perm == NULL)
continue;
- ipc_lock_by_ptr(perm);
+ rcu_read_lock();
+ ipc_lock_object(perm);
free(ns, perm);
total++;
}
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -205,7 +205,8 @@ static struct kern_ipc_perm *ipc_findkey
continue;
}
- ipc_lock_by_ptr(ipc);
+ rcu_read_lock();
+ ipc_lock_object(ipc);
return ipc;
}
@@ -838,7 +839,8 @@ static struct kern_ipc_perm *sysvipc_fin
ipc = idr_find(&ids->ipcs_idr, pos);
if (ipc != NULL) {
*new_pos = pos + 1;
- ipc_lock_by_ptr(ipc);
+ rcu_read_lock();
+ ipc_lock_object(ipc);
return ipc;
}
}
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -171,12 +171,6 @@ static inline void ipc_assert_locked_obj
assert_spin_locked(&perm->lock);
}
-static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
-{
- rcu_read_lock();
- ipc_lock_object(perm);
-}
-
static inline void ipc_unlock(struct kern_ipc_perm *perm)
{
ipc_unlock_object(perm);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 61/69] ipc, shm: drop shm_lock_check
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (59 preceding siblings ...)
2013-10-16 17:45 ` [ 60/69] ipc: drop ipc_lock_by_ptr Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 62/69] ipc: drop ipc_lock_check Greg Kroah-Hartman
` (9 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 7a25dd9e042b2b94202a67e5551112f4ac87285a upstream.
This function was replaced by a the lockless shm_obtain_object_check(),
and no longer has any users.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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/shm.c | 11 -----------
1 file changed, 11 deletions(-)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -167,17 +167,6 @@ static inline void shm_lock_by_ptr(struc
ipc_lock_object(&ipcp->shm_perm);
}
-static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns,
- int id)
-{
- struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id);
-
- if (IS_ERR(ipcp))
- return (struct shmid_kernel *)ipcp;
-
- return container_of(ipcp, struct shmid_kernel, shm_perm);
-}
-
static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
{
ipc_rmid(&shm_ids(ns), &s->shm_perm);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 62/69] ipc: drop ipc_lock_check
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (60 preceding siblings ...)
2013-10-16 17:45 ` [ 61/69] ipc, shm: drop shm_lock_check Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 63/69] ipc: fix race with LSMs Greg Kroah-Hartman
` (8 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Sedat Dilek,
Rik van Riel, Manfred Spraul, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
commit 20b8875abcf2daa1dda5cf70bd6369df5e85d4c1 upstream.
No remaining users, we now use ipc_obtain_object_check().
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.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.c | 16 ----------------
ipc/util.h | 1 -
2 files changed, 17 deletions(-)
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -686,22 +686,6 @@ out:
return out;
}
-struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, int id)
-{
- struct kern_ipc_perm *out;
-
- out = ipc_lock(ids, id);
- if (IS_ERR(out))
- return out;
-
- if (ipc_checkid(out, id)) {
- ipc_unlock(out);
- return ERR_PTR(-EIDRM);
- }
-
- return out;
-}
-
/**
* ipcget - Common sys_*get() code
* @ns : namsepace
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -177,7 +177,6 @@ static inline void ipc_unlock(struct ker
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,
struct ipc_ops *ops, struct ipc_params *params);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 63/69] ipc: fix race with LSMs
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (61 preceding siblings ...)
2013-10-16 17:45 ` [ 62/69] ipc: drop ipc_lock_check Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 64/69] ipc/sem.c: fix race in sem_lock() Greg Kroah-Hartman
` (7 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Linus Torvalds, Davidlohr Bueso,
Manfred Spraul, Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr@hp.com>
commit 53dad6d3a8e5ac1af8bacc6ac2134ae1a8b085f1 upstream.
Currently, IPC mechanisms do security and auditing related checks under
RCU. However, since security modules can free the security structure,
for example, through selinux_[sem,msg_queue,shm]_free_security(), we can
race if the structure is freed before other tasks are done with it,
creating a use-after-free condition. Manfred illustrates this nicely,
for instance with shared mem and selinux:
-> do_shmat calls rcu_read_lock()
-> do_shmat calls shm_object_check().
Checks that the object is still valid - but doesn't acquire any locks.
Then it returns.
-> do_shmat calls security_shm_shmat (e.g. selinux_shm_shmat)
-> selinux_shm_shmat calls ipc_has_perm()
-> ipc_has_perm accesses ipc_perms->security
shm_close()
-> shm_close acquires rw_mutex & shm_lock
-> shm_close calls shm_destroy
-> shm_destroy calls security_shm_free (e.g. selinux_shm_free_security)
-> selinux_shm_free_security calls ipc_free_security(&shp->shm_perm)
-> ipc_free_security calls kfree(ipc_perms->security)
This patch delays the freeing of the security structures after all RCU
readers are done. Furthermore it aligns the security life cycle with
that of the rest of IPC - freeing them based on the reference counter.
For situations where we need not free security, the current behavior is
kept. Linus states:
"... the old behavior was suspect for another reason too: having the
security blob go away from under a user sounds like it could cause
various other problems anyway, so I think the old code was at least
_prone_ to bugs even if it didn't have catastrophic behavior."
I have tested this patch with IPC testcases from LTP on both my
quad-core laptop and on a 64 core NUMA server. In both cases selinux is
enabled, and tests pass for both voluntary and forced preemption models.
While the mentioned races are theoretical (at least no one as reported
them), I wanted to make sure that this new logic doesn't break anything
we weren't aware of.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
Acked-by: Manfred Spraul <manfred@colorfullife.com>
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 | 19 +++++++++++++------
ipc/sem.c | 34 ++++++++++++++++++----------------
ipc/shm.c | 17 ++++++++++++-----
ipc/util.c | 32 ++++++++++++--------------------
ipc/util.h | 10 +++++++++-
5 files changed, 64 insertions(+), 48 deletions(-)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -165,6 +165,15 @@ static inline void msg_rmid(struct ipc_n
ipc_rmid(&msg_ids(ns), &s->q_perm);
}
+static void msg_rcu_free(struct rcu_head *head)
+{
+ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu);
+ struct msg_queue *msq = ipc_rcu_to_struct(p);
+
+ security_msg_queue_free(msq);
+ ipc_rcu_free(head);
+}
+
/**
* newque - Create a new msg queue
* @ns: namespace
@@ -189,15 +198,14 @@ static int newque(struct ipc_namespace *
msq->q_perm.security = NULL;
retval = security_msg_queue_alloc(msq);
if (retval) {
- ipc_rcu_putref(msq);
+ ipc_rcu_putref(msq, ipc_rcu_free);
return retval;
}
/* 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);
- ipc_rcu_putref(msq);
+ ipc_rcu_putref(msq, msg_rcu_free);
return id;
}
@@ -276,8 +284,7 @@ static void freeque(struct ipc_namespace
free_msg(msg);
}
atomic_sub(msq->q_cbytes, &ns->msg_bytes);
- security_msg_queue_free(msq);
- ipc_rcu_putref(msq);
+ ipc_rcu_putref(msq, msg_rcu_free);
}
/*
@@ -717,7 +724,7 @@ long do_msgsnd(int msqid, long mtype, vo
rcu_read_lock();
ipc_lock_object(&msq->q_perm);
- ipc_rcu_putref(msq);
+ ipc_rcu_putref(msq, ipc_rcu_free);
if (msq->q_perm.deleted) {
err = -EIDRM;
goto out_unlock0;
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -243,6 +243,15 @@ static void merge_queues(struct sem_arra
}
}
+static void sem_rcu_free(struct rcu_head *head)
+{
+ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu);
+ struct sem_array *sma = ipc_rcu_to_struct(p);
+
+ security_sem_free(sma);
+ ipc_rcu_free(head);
+}
+
/*
* If the request contains only one semaphore operation, and there are
* no complex transactions pending, lock only the semaphore involved.
@@ -374,12 +383,7 @@ static inline struct sem_array *sem_obta
static inline void sem_lock_and_putref(struct sem_array *sma)
{
sem_lock(sma, NULL, -1);
- ipc_rcu_putref(sma);
-}
-
-static inline void sem_putref(struct sem_array *sma)
-{
- ipc_rcu_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
}
static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
@@ -458,14 +462,13 @@ static int newary(struct ipc_namespace *
sma->sem_perm.security = NULL;
retval = security_sem_alloc(sma);
if (retval) {
- ipc_rcu_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
return retval;
}
id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
if (id < 0) {
- security_sem_free(sma);
- ipc_rcu_putref(sma);
+ ipc_rcu_putref(sma, sem_rcu_free);
return id;
}
ns->used_sems += nsems;
@@ -1047,8 +1050,7 @@ static void freeary(struct ipc_namespace
wake_up_sem_queue_do(&tasks);
ns->used_sems -= sma->sem_nsems;
- security_sem_free(sma);
- ipc_rcu_putref(sma);
+ ipc_rcu_putref(sma, sem_rcu_free);
}
static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version)
@@ -1292,7 +1294,7 @@ static int semctl_main(struct ipc_namesp
rcu_read_unlock();
sem_io = ipc_alloc(sizeof(ushort)*nsems);
if(sem_io == NULL) {
- sem_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
return -ENOMEM;
}
@@ -1328,20 +1330,20 @@ static int semctl_main(struct ipc_namesp
if(nsems > SEMMSL_FAST) {
sem_io = ipc_alloc(sizeof(ushort)*nsems);
if(sem_io == NULL) {
- sem_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
return -ENOMEM;
}
}
if (copy_from_user (sem_io, p, nsems*sizeof(ushort))) {
- sem_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
err = -EFAULT;
goto out_free;
}
for (i = 0; i < nsems; i++) {
if (sem_io[i] > SEMVMX) {
- sem_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
err = -ERANGE;
goto out_free;
}
@@ -1629,7 +1631,7 @@ static struct sem_undo *find_alloc_undo(
/* step 2: allocate new undo structure */
new = kzalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL);
if (!new) {
- sem_putref(sma);
+ ipc_rcu_putref(sma, ipc_rcu_free);
return ERR_PTR(-ENOMEM);
}
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -167,6 +167,15 @@ static inline void shm_lock_by_ptr(struc
ipc_lock_object(&ipcp->shm_perm);
}
+static void shm_rcu_free(struct rcu_head *head)
+{
+ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu);
+ struct shmid_kernel *shp = ipc_rcu_to_struct(p);
+
+ security_shm_free(shp);
+ ipc_rcu_free(head);
+}
+
static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
{
ipc_rmid(&shm_ids(ns), &s->shm_perm);
@@ -208,8 +217,7 @@ static void shm_destroy(struct ipc_names
user_shm_unlock(file_inode(shp->shm_file)->i_size,
shp->mlock_user);
fput (shp->shm_file);
- security_shm_free(shp);
- ipc_rcu_putref(shp);
+ ipc_rcu_putref(shp, shm_rcu_free);
}
/*
@@ -497,7 +505,7 @@ static int newseg(struct ipc_namespace *
shp->shm_perm.security = NULL;
error = security_shm_alloc(shp);
if (error) {
- ipc_rcu_putref(shp);
+ ipc_rcu_putref(shp, ipc_rcu_free);
return error;
}
@@ -566,8 +574,7 @@ no_id:
user_shm_unlock(size, shp->mlock_user);
fput(file);
no_file:
- security_shm_free(shp);
- ipc_rcu_putref(shp);
+ ipc_rcu_putref(shp, shm_rcu_free);
return error;
}
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -474,11 +474,6 @@ void ipc_free(void* ptr, int size)
kfree(ptr);
}
-struct ipc_rcu {
- struct rcu_head rcu;
- atomic_t refcount;
-} ____cacheline_aligned_in_smp;
-
/**
* ipc_rcu_alloc - allocate ipc and rcu space
* @size: size desired
@@ -505,27 +500,24 @@ int ipc_rcu_getref(void *ptr)
return atomic_inc_not_zero(&p->refcount);
}
-/**
- * ipc_schedule_free - free ipc + rcu space
- * @head: RCU callback structure for queued work
- */
-static void ipc_schedule_free(struct rcu_head *head)
-{
- vfree(container_of(head, struct ipc_rcu, rcu));
-}
-
-void ipc_rcu_putref(void *ptr)
+void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head))
{
struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1;
if (!atomic_dec_and_test(&p->refcount))
return;
- if (is_vmalloc_addr(ptr)) {
- call_rcu(&p->rcu, ipc_schedule_free);
- } else {
- kfree_rcu(p, rcu);
- }
+ call_rcu(&p->rcu, func);
+}
+
+void ipc_rcu_free(struct rcu_head *head)
+{
+ struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu);
+
+ if (is_vmalloc_addr(p))
+ vfree(p);
+ else
+ kfree(p);
}
/**
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -47,6 +47,13 @@ static inline void msg_exit_ns(struct ip
static inline void shm_exit_ns(struct ipc_namespace *ns) { }
#endif
+struct ipc_rcu {
+ struct rcu_head rcu;
+ atomic_t refcount;
+} ____cacheline_aligned_in_smp;
+
+#define ipc_rcu_to_struct(p) ((void *)(p+1))
+
/*
* Structure that holds the parameters needed by the ipc operations
* (see after)
@@ -120,7 +127,8 @@ void ipc_free(void* ptr, int size);
*/
void* ipc_rcu_alloc(int size);
int ipc_rcu_getref(void *ptr);
-void ipc_rcu_putref(void *ptr);
+void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head));
+void ipc_rcu_free(struct rcu_head *head);
struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 64/69] ipc/sem.c: fix race in sem_lock()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (62 preceding siblings ...)
2013-10-16 17:45 ` [ 63/69] ipc: fix race with LSMs Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 65/69] ipc/sem.c: optimize sem_lock() Greg Kroah-Hartman
` (6 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Mike Galbraith,
Rik van Riel, Davidlohr Bueso, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit 5e9d527591421ccdb16acb8c23662231135d8686 upstream.
The exclusion of complex operations in sem_lock() is insufficient: after
acquiring the per-semaphore lock, a simple op must first check that
sem_perm.lock is not locked and only after that test check
complex_count. The current code does it the other way around - and that
creates a race. Details are below.
The patch is a complete rewrite of sem_lock(), based in part on the code
from Mike Galbraith. It removes all gotos and all loops and thus the
risk of livelocks.
I have tested the patch (together with the next one) on my i3 laptop and
it didn't cause any problems.
The bug is probably also present in 3.10 and 3.11, but for these kernels
it might be simpler just to move the test of sma->complex_count after
the spin_is_locked() test.
Details of the bug:
Assume:
- sma->complex_count = 0.
- Thread 1: semtimedop(complex op that must sleep)
- Thread 2: semtimedop(simple op).
Pseudo-Trace:
Thread 1: sem_lock(): acquire sem_perm.lock
Thread 1: sem_lock(): check for ongoing simple ops
Nothing ongoing, thread 2 is still before sem_lock().
Thread 1: try_atomic_semop()
<<< preempted.
Thread 2: sem_lock():
static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
int nsops)
{
int locknum;
again:
if (nsops == 1 && !sma->complex_count) {
struct sem *sem = sma->sem_base + sops->sem_num;
/* Lock just the semaphore we are interested in. */
spin_lock(&sem->lock);
/*
* If sma->complex_count was set while we were spinning,
* we may need to look at things we did not lock here.
*/
if (unlikely(sma->complex_count)) {
spin_unlock(&sem->lock);
goto lock_array;
}
<<<<<<<<<
<<< complex_count is still 0.
<<<
<<< Here it is preempted
<<<<<<<<<
Thread 1: try_atomic_semop() returns, notices that it must sleep.
Thread 1: increases sma->complex_count.
Thread 1: drops sem_perm.lock
Thread 2:
/*
* Another process is holding the global lock on the
* sem_array; we cannot enter our critical section,
* but have to wait for the global lock to be released.
*/
if (unlikely(spin_is_locked(&sma->sem_perm.lock))) {
spin_unlock(&sem->lock);
spin_unlock_wait(&sma->sem_perm.lock);
goto again;
}
<<< sem_perm.lock already dropped, thus no "goto again;"
locknum = sops->sem_num;
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Mike Galbraith <bitbucket@online.de>
Cc: Rik van Riel <riel@redhat.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.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/sem.c | 122 +++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 78 insertions(+), 44 deletions(-)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -253,70 +253,104 @@ static void sem_rcu_free(struct rcu_head
}
/*
+ * Wait until all currently ongoing simple ops have completed.
+ * Caller must own sem_perm.lock.
+ * New simple ops cannot start, because simple ops first check
+ * that sem_perm.lock is free.
+ */
+static void sem_wait_array(struct sem_array *sma)
+{
+ int i;
+ struct sem *sem;
+
+ for (i = 0; i < sma->sem_nsems; i++) {
+ sem = sma->sem_base + i;
+ spin_unlock_wait(&sem->lock);
+ }
+}
+
+/*
* If the request contains only one semaphore operation, and there are
* no complex transactions pending, lock only the semaphore involved.
* Otherwise, lock the entire semaphore array, since we either have
* multiple semaphores in our own semops, or we need to look at
* semaphores from other pending complex operations.
- *
- * Carefully guard against sma->complex_count changing between zero
- * and non-zero while we are spinning for the lock. The value of
- * sma->complex_count cannot change while we are holding the lock,
- * so sem_unlock should be fine.
- *
- * The global lock path checks that all the local locks have been released,
- * checking each local lock once. This means that the local lock paths
- * cannot start their critical sections while the global lock is held.
*/
static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
int nsops)
{
- int locknum;
- again:
- if (nsops == 1 && !sma->complex_count) {
- struct sem *sem = sma->sem_base + sops->sem_num;
+ struct sem *sem;
- /* Lock just the semaphore we are interested in. */
- spin_lock(&sem->lock);
+ if (nsops != 1) {
+ /* Complex operation - acquire a full lock */
+ ipc_lock_object(&sma->sem_perm);
- /*
- * If sma->complex_count was set while we were spinning,
- * we may need to look at things we did not lock here.
+ /* And wait until all simple ops that are processed
+ * right now have dropped their locks.
*/
- if (unlikely(sma->complex_count)) {
- spin_unlock(&sem->lock);
- goto lock_array;
- }
+ sem_wait_array(sma);
+ return -1;
+ }
+
+ /*
+ * Only one semaphore affected - try to optimize locking.
+ * The rules are:
+ * - optimized locking is possible if no complex operation
+ * is either enqueued or processed right now.
+ * - The test for enqueued complex ops is simple:
+ * sma->complex_count != 0
+ * - Testing for complex ops that are processed right now is
+ * a bit more difficult. Complex ops acquire the full lock
+ * and first wait that the running simple ops have completed.
+ * (see above)
+ * Thus: If we own a simple lock and the global lock is free
+ * and complex_count is now 0, then it will stay 0 and
+ * thus just locking sem->lock is sufficient.
+ */
+ sem = sma->sem_base + sops->sem_num;
+ if (sma->complex_count == 0) {
/*
- * Another process is holding the global lock on the
- * sem_array; we cannot enter our critical section,
- * but have to wait for the global lock to be released.
+ * It appears that no complex operation is around.
+ * Acquire the per-semaphore lock.
*/
- if (unlikely(spin_is_locked(&sma->sem_perm.lock))) {
- spin_unlock(&sem->lock);
- spin_unlock_wait(&sma->sem_perm.lock);
- goto again;
+ spin_lock(&sem->lock);
+
+ /* Then check that the global lock is free */
+ if (!spin_is_locked(&sma->sem_perm.lock)) {
+ /* spin_is_locked() is not a memory barrier */
+ smp_mb();
+
+ /* Now repeat the test of complex_count:
+ * It can't change anymore until we drop sem->lock.
+ * Thus: if is now 0, then it will stay 0.
+ */
+ if (sma->complex_count == 0) {
+ /* fast path successful! */
+ return sops->sem_num;
+ }
}
+ spin_unlock(&sem->lock);
+ }
+
+ /* slow path: acquire the full lock */
+ ipc_lock_object(&sma->sem_perm);
- locknum = sops->sem_num;
+ if (sma->complex_count == 0) {
+ /* False alarm:
+ * There is no complex operation, thus we can switch
+ * back to the fast path.
+ */
+ spin_lock(&sem->lock);
+ ipc_unlock_object(&sma->sem_perm);
+ return sops->sem_num;
} else {
- int i;
- /*
- * Lock the semaphore array, and wait for all of the
- * individual semaphore locks to go away. The code
- * above ensures no new single-lock holders will enter
- * their critical section while the array lock is held.
+ /* Not a false alarm, thus complete the sequence for a
+ * full lock.
*/
- lock_array:
- 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);
- }
- locknum = -1;
+ sem_wait_array(sma);
+ return -1;
}
- return locknum;
}
static inline void sem_unlock(struct sem_array *sma, int locknum)
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 65/69] ipc/sem.c: optimize sem_lock()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (63 preceding siblings ...)
2013-10-16 17:45 ` [ 64/69] ipc/sem.c: fix race in sem_lock() Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 66/69] ipc/sem.c: synchronize the proc interface Greg Kroah-Hartman
` (5 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Mike Galbraith,
Rik van Riel, Davidlohr Bueso, Andrew Morton, Linus Torvalds,
Mike Galbraith
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit 6d07b68ce16ae9535955ba2059dedba5309c3ca1 upstream.
Operations that need access to the whole array must guarantee that there
are no simple operations ongoing. Right now this is achieved by
spin_unlock_wait(sem->lock) on all semaphores.
If complex_count is nonzero, then this spin_unlock_wait() is not
necessary, because it was already performed in the past by the thread
that increased complex_count and even though sem_perm.lock was dropped
inbetween, no simple operation could have started, because simple
operations cannot start when complex_count is non-zero.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Mike Galbraith <bitbucket@online.de>
Cc: Rik van Riel <riel@redhat.com>
Reviewed-by: Davidlohr Bueso <davidlohr@hp.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/sem.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -257,12 +257,20 @@ static void sem_rcu_free(struct rcu_head
* Caller must own sem_perm.lock.
* New simple ops cannot start, because simple ops first check
* that sem_perm.lock is free.
+ * that a) sem_perm.lock is free and b) complex_count is 0.
*/
static void sem_wait_array(struct sem_array *sma)
{
int i;
struct sem *sem;
+ if (sma->complex_count) {
+ /* The thread that increased sma->complex_count waited on
+ * all sem->lock locks. Thus we don't need to wait again.
+ */
+ return;
+ }
+
for (i = 0; i < sma->sem_nsems; i++) {
sem = sma->sem_base + i;
spin_unlock_wait(&sem->lock);
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 66/69] ipc/sem.c: synchronize the proc interface
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (64 preceding siblings ...)
2013-10-16 17:45 ` [ 65/69] ipc/sem.c: optimize sem_lock() Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 67/69] ipc/sem.c: update sem_otime for all operations Greg Kroah-Hartman
` (4 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Davidlohr Bueso,
Mike Galbraith, Rik van Riel, Andrew Morton, Linus Torvalds
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit d8c633766ad88527f25d9f81a5c2f083d78a2b39 upstream.
The proc interface is not aware of sem_lock(), it instead calls
ipc_lock_object() directly. This means that simple semop() operations
can run in parallel with the proc interface. Right now, this is
uncritical, because the implementation doesn't do anything that requires
a proper synchronization.
But it is dangerous and therefore should be fixed.
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Mike Galbraith <efault@gmx.de>
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
ipc/sem.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -2103,6 +2103,14 @@ static int sysvipc_sem_proc_show(struct
struct sem_array *sma = it;
time_t sem_otime;
+ /*
+ * The proc interface isn't aware of sem_lock(), it calls
+ * ipc_lock_object() directly (in sysvipc_find_ipc).
+ * In order to stay compatible with sem_lock(), we must wait until
+ * all simple semop() calls have left their critical regions.
+ */
+ sem_wait_array(sma);
+
sem_otime = get_semotime(sma);
return seq_printf(s,
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 67/69] ipc/sem.c: update sem_otime for all operations
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (65 preceding siblings ...)
2013-10-16 17:45 ` [ 66/69] ipc/sem.c: synchronize the proc interface Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 68/69] ipc,msg: prevent race with rmid in msgsnd,msgrcv Greg Kroah-Hartman
` (3 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Manfred Spraul, Jia He,
Davidlohr Bueso, Mike Galbraith, Andrew Morton, Linus Torvalds
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manfred Spraul <manfred@colorfullife.com>
commit 0e8c665699e953fa58dc1b0b0d09e5dce7343cc7 upstream.
In commit 0a2b9d4c7967 ("ipc/sem.c: move wake_up_process out of the
spinlock section"), the update of semaphore's sem_otime(last semop time)
was moved to one central position (do_smart_update).
But since do_smart_update() is only called for operations that modify
the array, this means that wait-for-zero semops do not update sem_otime
anymore.
The fix is simple:
Non-alter operations must update sem_otime.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Reported-by: Jia He <jiakernel@gmail.com>
Tested-by: Jia He <jiakernel@gmail.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
ipc/sem.c | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -918,6 +918,24 @@ again:
}
/**
+ * set_semotime(sma, sops) - set sem_otime
+ * @sma: semaphore array
+ * @sops: operations that modified the array, may be NULL
+ *
+ * sem_otime is replicated to avoid cache line trashing.
+ * This function sets one instance to the current time.
+ */
+static void set_semotime(struct sem_array *sma, struct sembuf *sops)
+{
+ if (sops == NULL) {
+ sma->sem_base[0].sem_otime = get_seconds();
+ } else {
+ sma->sem_base[sops[0].sem_num].sem_otime =
+ get_seconds();
+ }
+}
+
+/**
* do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue
* @sma: semaphore array
* @sops: operations that were performed
@@ -967,17 +985,10 @@ static void do_smart_update(struct sem_a
}
}
}
- if (otime) {
- if (sops == NULL) {
- sma->sem_base[0].sem_otime = get_seconds();
- } else {
- sma->sem_base[sops[0].sem_num].sem_otime =
- get_seconds();
- }
- }
+ if (otime)
+ set_semotime(sma, sops);
}
-
/* The following counts are associated to each semaphore:
* semncnt number of tasks waiting on semval being nonzero
* semzcnt number of tasks waiting on semval being zero
@@ -1839,12 +1850,17 @@ SYSCALL_DEFINE4(semtimedop, int, semid,
error = perform_atomic_semop(sma, sops, nsops, un,
task_tgid_vnr(current));
- if (error <= 0) {
- if (alter && error == 0)
+ if (error == 0) {
+ /* If the operation was successful, then do
+ * the required updates.
+ */
+ if (alter)
do_smart_update(sma, sops, nsops, 1, &tasks);
-
- goto out_unlock_free;
+ else
+ set_semotime(sma, sops);
}
+ if (error <= 0)
+ goto out_unlock_free;
/* We need to sleep on this operation, so we put the current
* task into the pending queue and go to sleep.
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 68/69] ipc,msg: prevent race with rmid in msgsnd,msgrcv
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (66 preceding siblings ...)
2013-10-16 17:45 ` [ 67/69] ipc/sem.c: update sem_otime for all operations Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 17:45 ` [ 69/69] x86: avoid remapping data in parse_setup_data() Greg Kroah-Hartman
` (2 subsequent siblings)
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Davidlohr Bueso, Manfred Spraul,
Rik van Riel, Mike Galbraith, Andrew Morton, Linus Torvalds
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davidlohr Bueso <davidlohr@hp.com>
commit 4271b05a227dc6175b66c3d9941aeab09048aeb2 upstream.
This fixes a race in both msgrcv() and msgsnd() between finding the msg
and actually dealing with the queue, as another thread can delete shmid
underneath us if we are preempted before acquiring the
kern_ipc_perm.lock.
Manfred illustrates this nicely:
Assume a preemptible kernel that is preempted just after
msq = msq_obtain_object_check(ns, msqid)
in do_msgrcv(). The only lock that is held is rcu_read_lock().
Now the other thread processes IPC_RMID. When the first task is
resumed, then it will happily wait for messages on a deleted queue.
Fix this by checking for if the queue has been deleted after taking the
lock.
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
Reported-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
ipc/msg.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -695,6 +695,12 @@ long do_msgsnd(int msqid, long mtype, vo
if (ipcperms(ns, &msq->q_perm, S_IWUGO))
goto out_unlock0;
+ /* raced with RMID? */
+ if (msq->q_perm.deleted) {
+ err = -EIDRM;
+ goto out_unlock0;
+ }
+
err = security_msg_queue_msgsnd(msq, msg, msgflg);
if (err)
goto out_unlock0;
@@ -901,6 +907,13 @@ long do_msgrcv(int msqid, void __user *b
goto out_unlock1;
ipc_lock_object(&msq->q_perm);
+
+ /* raced with RMID? */
+ if (msq->q_perm.deleted) {
+ msg = ERR_PTR(-EIDRM);
+ goto out_unlock0;
+ }
+
msg = find_msg(msq, &msgtyp, mode);
if (!IS_ERR(msg)) {
/*
^ permalink raw reply [flat|nested] 73+ messages in thread
* [ 69/69] x86: avoid remapping data in parse_setup_data()
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (67 preceding siblings ...)
2013-10-16 17:45 ` [ 68/69] ipc,msg: prevent race with rmid in msgsnd,msgrcv Greg Kroah-Hartman
@ 2013-10-16 17:45 ` Greg Kroah-Hartman
2013-10-16 22:11 ` [ 00/69] 3.10.17-stable review Guenter Roeck
2013-10-17 16:50 ` Shuah Khan
70 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-16 17:45 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Linn Crosetto, Yinghai Lu,
Pekka Enberg, H. Peter Anvin, Paul Gortmaker
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linn Crosetto <linn@hp.com>
commit 30e46b574a1db7d14404e52dca8e1aa5f5155fd2 upstream.
Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().
To avoid this, remap the setup_data header and allow parsing functions
for individual types to handle their own data remapping.
Signed-off-by: Linn Crosetto <linn@hp.com>
Link: http://lkml.kernel.org/r/1376430401-67445-1-git-send-email-linn@hp.com
Acked-by: Yinghai Lu <yinghai@kernel.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/include/asm/e820.h | 2 +-
arch/x86/kernel/e820.c | 5 ++++-
arch/x86/kernel/setup.c | 19 ++++++++-----------
3 files changed, 13 insertions(+), 13 deletions(-)
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -29,7 +29,7 @@ extern void e820_setup_gap(void);
extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
unsigned long start_addr, unsigned long long end_addr);
struct setup_data;
-extern void parse_e820_ext(struct setup_data *data);
+extern void parse_e820_ext(u64 phys_addr, u32 data_len);
#if defined(CONFIG_X86_64) || \
(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void)
* boot_params.e820_map, others are passed via SETUP_E820_EXT node of
* linked list of struct setup_data, which is parsed here.
*/
-void __init parse_e820_ext(struct setup_data *sdata)
+void __init parse_e820_ext(u64 phys_addr, u32 data_len)
{
int entries;
struct e820entry *extmap;
+ struct setup_data *sdata;
+ sdata = early_memremap(phys_addr, data_len);
entries = sdata->len / sizeof(struct e820entry);
extmap = (struct e820entry *)(sdata->data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+ early_iounmap(sdata, data_len);
printk(KERN_INFO "e820: extended physical RAM map:\n");
e820_print_map("extended");
}
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,25 +426,23 @@ static void __init reserve_initrd(void)
static void __init parse_setup_data(void)
{
struct setup_data *data;
- u64 pa_data;
+ u64 pa_data, pa_next;
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
- u32 data_len, map_len;
+ u32 data_len, map_len, data_type;
map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
(u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data->len + sizeof(struct setup_data);
- if (data_len > map_len) {
- early_iounmap(data, map_len);
- data = early_memremap(pa_data, data_len);
- map_len = data_len;
- }
+ data_type = data->type;
+ pa_next = data->next;
+ early_iounmap(data, map_len);
- switch (data->type) {
+ switch (data_type) {
case SETUP_E820_EXT:
- parse_e820_ext(data);
+ parse_e820_ext(pa_data, data_len);
break;
case SETUP_DTB:
add_dtb(pa_data);
@@ -452,8 +450,7 @@ static void __init parse_setup_data(void
default:
break;
}
- pa_data = data->next;
- early_iounmap(data, map_len);
+ pa_data = pa_next;
}
}
^ permalink raw reply [flat|nested] 73+ messages in thread
* Re: [ 00/69] 3.10.17-stable review
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (68 preceding siblings ...)
2013-10-16 17:45 ` [ 69/69] x86: avoid remapping data in parse_setup_data() Greg Kroah-Hartman
@ 2013-10-16 22:11 ` Guenter Roeck
2013-10-17 1:07 ` Greg Kroah-Hartman
2013-10-17 16:50 ` Shuah Khan
70 siblings, 1 reply; 73+ messages in thread
From: Guenter Roeck @ 2013-10-16 22:11 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linux-kernel, torvalds, akpm, stable
On Wed, Oct 16, 2013 at 10:44:09AM -0700, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 3.10.17 release.
> There are 69 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> You might notice a bunch of ipc patches in this series. That is to
> resolve some reported ipc bugs / scalabity issues. Additional testing
> of these code paths would be greatly appreciated.
>
> Responses should be made by Fri Oct 18 17:41:53 UTC 2013.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.10.17-rc1.gz
> and the diffstat can be found below.
>
Build results:
total: 110 pass: 110 skipped: 0 fail: 0
qemu tests all pass, with the usual warning for the 'sh' target.
Details are at http://server.roeck-us.net:8010/builders.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 73+ messages in thread
* Re: [ 00/69] 3.10.17-stable review
2013-10-16 22:11 ` [ 00/69] 3.10.17-stable review Guenter Roeck
@ 2013-10-17 1:07 ` Greg Kroah-Hartman
0 siblings, 0 replies; 73+ messages in thread
From: Greg Kroah-Hartman @ 2013-10-17 1:07 UTC (permalink / raw)
To: Guenter Roeck; +Cc: linux-kernel, torvalds, akpm, stable
On Wed, Oct 16, 2013 at 03:11:46PM -0700, Guenter Roeck wrote:
> On Wed, Oct 16, 2013 at 10:44:09AM -0700, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 3.10.17 release.
> > There are 69 patches in this series, all will be posted as a response
> > to this one. If anyone has any issues with these being applied, please
> > let me know.
> >
> > You might notice a bunch of ipc patches in this series. That is to
> > resolve some reported ipc bugs / scalabity issues. Additional testing
> > of these code paths would be greatly appreciated.
> >
> > Responses should be made by Fri Oct 18 17:41:53 UTC 2013.
> > Anything received after that time might be too late.
> >
> > The whole patch series can be found in one patch at:
> > kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.10.17-rc1.gz
> > and the diffstat can be found below.
> >
>
> Build results:
> total: 110 pass: 110 skipped: 0 fail: 0
>
> qemu tests all pass, with the usual warning for the 'sh' target.
>
> Details are at http://server.roeck-us.net:8010/builders.
Great, thanks for testing and letting me know.
greg k-h
^ permalink raw reply [flat|nested] 73+ messages in thread
* Re: [ 00/69] 3.10.17-stable review
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
` (69 preceding siblings ...)
2013-10-16 22:11 ` [ 00/69] 3.10.17-stable review Guenter Roeck
@ 2013-10-17 16:50 ` Shuah Khan
70 siblings, 0 replies; 73+ messages in thread
From: Shuah Khan @ 2013-10-17 16:50 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-kernel, torvalds, akpm, stable, Shuah Khan,
shuahkhan@gmail.com
On 10/16/2013 11:44 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 3.10.17 release.
> There are 69 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> You might notice a bunch of ipc patches in this series. That is to
> resolve some reported ipc bugs / scalabity issues. Additional testing
> of these code paths would be greatly appreciated.
>
> Responses should be made by Fri Oct 18 17:41:53 UTC 2013.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.10.17-rc1.gz
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>
3.10.17
Patch applied cleanly - yes
Compile testing - passed
Boot testing - passed
dmesg regression testing - passed
dmesgs look good. No regressions compared to the previous dmesgs for
this release. dmesg emerg, crit, alert, err are clean. No regressions in
warn.
Test systems:
Samsung Series 9 900X4C Intel Corei5 (3.4 and later)
HP ProBook 6475b AMD A10-4600M APU with Radeon(tm) HD Graphics
HP Compaq dc7700 SFF desktop: x86-64 Intel Core-i2 (cross-compile testing)
alpha defconfig Passed Passed
arm defconfig Passed Passed
arm64 defconfig Passed Passed
blackfin defconfig Passed Passed
c6x defconfig Passed Passed
mips defconfig Passed Passed
mipsel defconfig Passed Passed
powerpc Passed Passed
sh defconfig Passed Passed
sparc defconfig Passed Passed
tile defconfig Passed Passed
-- Shuah
--
Shuah Khan
Senior Linux Kernel Developer - Open Source Group
Samsung Research America(Silicon Valley)
shuah.kh@samsung.com | (970) 672-0658
^ permalink raw reply [flat|nested] 73+ messages in thread
end of thread, other threads:[~2013-10-17 16:50 UTC | newest]
Thread overview: 73+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-16 17:44 [ 00/69] 3.10.17-stable review Greg Kroah-Hartman
2013-10-16 17:44 ` [ 01/69] ALSA: snd-usb-usx2y: remove bogus frame checks Greg Kroah-Hartman
2013-10-16 17:44 ` [ 02/69] ALSA: hda - hdmi: Fix channel map switch not taking effect Greg Kroah-Hartman
2013-10-16 17:44 ` [ 03/69] ALSA: hda - Add fixup for ASUS N56VZ Greg Kroah-Hartman
2013-10-16 17:44 ` [ 04/69] ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model) Greg Kroah-Hartman
2013-10-16 17:44 ` [ 05/69] random: run random_int_secret_init() run after all late_initcalls Greg Kroah-Hartman
2013-10-16 17:44 ` [ 06/69] vfs: allow O_PATH file descriptors for fstatfs() Greg Kroah-Hartman
2013-10-16 17:44 ` [ 07/69] i2c: omap: Clear ARDY bit twice Greg Kroah-Hartman
2013-10-16 17:44 ` [ 08/69] hwmon: (applesmc) Always read until end of data Greg Kroah-Hartman
2013-10-16 17:44 ` [ 09/69] Btrfs: use right root when checking for hash collision Greg Kroah-Hartman
2013-10-16 17:44 ` [ 10/69] ext4: fix memory leak in xattr Greg Kroah-Hartman
2013-10-16 17:44 ` [ 11/69] KVM: PPC: Book3S HV: Fix typo in saving DSCR Greg Kroah-Hartman
2013-10-16 17:44 ` [ 12/69] parisc: fix interruption handler to respect pagefault_disable() Greg Kroah-Hartman
2013-10-16 17:44 ` [ 13/69] ARM: Fix the world famous typo with is_gate_vma() Greg Kroah-Hartman
2013-10-16 17:44 ` [ 14/69] ARC: Setup Vector Table Base in early boot Greg Kroah-Hartman
2013-10-16 17:44 ` [ 15/69] ARC: SMP failed to boot due to missing IVT setup Greg Kroah-Hartman
2013-10-16 17:44 ` [ 16/69] ARC: Fix __udelay calculation Greg Kroah-Hartman
2013-10-16 17:44 ` [ 17/69] ARC: Handle zero-overhead-loop in unaligned access handler Greg Kroah-Hartman
2013-10-16 17:44 ` [ 18/69] ARC: Fix 32-bit wrap around in access_ok() Greg Kroah-Hartman
2013-10-16 17:44 ` [ 19/69] ARC: Workaround spinlock livelock in SMP SystemC simulation Greg Kroah-Hartman
2013-10-16 17:44 ` [ 20/69] ARC: Fix signal frame management for SA_SIGINFO Greg Kroah-Hartman
2013-10-16 17:44 ` [ 21/69] ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc" Greg Kroah-Hartman
2013-10-16 17:44 ` [ 22/69] watchdog: ts72xx_wdt: locking bug in ioctl Greg Kroah-Hartman
2013-10-16 17:44 ` [ 23/69] compiler/gcc4: Add quirk for asm goto miscompilation bug Greg Kroah-Hartman
2013-10-16 17:44 ` [ 24/69] ALSA: hda - Fix mono speakers and headset mic on Dell Vostro 5470 Greg Kroah-Hartman
2013-10-16 17:44 ` [ 25/69] cope with potentially long ->d_dname() output for shmem/hugetlb Greg Kroah-Hartman
2013-10-16 17:44 ` [ 26/69] drm/i915: Only apply DPMS to the encoder if enabled Greg Kroah-Hartman
2013-10-16 17:44 ` [ 27/69] drm/radeon: forever loop on error in radeon_do_test_moves() Greg Kroah-Hartman
2013-10-16 17:44 ` [ 28/69] drm/radeon: fix typo in CP DMA register headers Greg Kroah-Hartman
2013-10-16 17:44 ` [ 29/69] drm/radeon: fix hw contexts for SUMO2 asics Greg Kroah-Hartman
2013-10-16 17:44 ` [ 30/69] ipc: move rcu lock out of ipc_addid Greg Kroah-Hartman
2013-10-16 17:44 ` [ 31/69] ipc: introduce ipc object locking helpers Greg Kroah-Hartman
2013-10-16 17:44 ` [ 32/69] ipc: close open coded spin lock calls Greg Kroah-Hartman
2013-10-16 17:44 ` [ 33/69] ipc: move locking out of ipcctl_pre_down_nolock Greg Kroah-Hartman
2013-10-16 17:44 ` [ 34/69] ipc,msg: shorten critical region in msgctl_down Greg Kroah-Hartman
2013-10-16 17:44 ` [ 35/69] ipc,msg: introduce msgctl_nolock Greg Kroah-Hartman
2013-10-16 17:44 ` [ 36/69] ipc,msg: introduce lockless functions to obtain the ipc object Greg Kroah-Hartman
2013-10-16 17:44 ` [ 37/69] ipc,msg: make msgctl_nolock lockless Greg Kroah-Hartman
2013-10-16 17:44 ` [ 38/69] ipc,msg: shorten critical region in msgsnd Greg Kroah-Hartman
2013-10-16 17:44 ` [ 39/69] ipc,msg: shorten critical region in msgrcv Greg Kroah-Hartman
2013-10-16 17:44 ` [ 40/69] ipc: remove unused functions Greg Kroah-Hartman
2013-10-16 17:44 ` [ 41/69] ipc/util.c, ipc_rcu_alloc: cacheline align allocation Greg Kroah-Hartman
2013-10-16 17:44 ` [ 42/69] ipc/sem.c: cacheline align the semaphore structures Greg Kroah-Hartman
2013-10-16 17:44 ` [ 43/69] ipc/sem: separate wait-for-zero and alter tasks into seperate queues Greg Kroah-Hartman
2013-10-16 17:44 ` [ 44/69] ipc/sem.c: always use only one queue for alter operations Greg Kroah-Hartman
2013-10-16 17:44 ` [ 45/69] ipc/sem.c: replace shared sem_otime with per-semaphore value Greg Kroah-Hartman
2013-10-16 17:44 ` [ 46/69] ipc/sem.c: rename try_atomic_semop() to perform_atomic_semop(), docu update Greg Kroah-Hartman
2013-10-16 17:44 ` [ 47/69] ipc/msg.c: Fix lost wakeup in msgsnd() Greg Kroah-Hartman
2013-10-16 17:44 ` [ 48/69] ipc,shm: introduce lockless functions to obtain the ipc object Greg Kroah-Hartman
2013-10-16 17:44 ` [ 49/69] ipc,shm: shorten critical region in shmctl_down Greg Kroah-Hartman
2013-10-16 17:44 ` [ 50/69] ipc: drop ipcctl_pre_down Greg Kroah-Hartman
2013-10-16 17:45 ` [ 51/69] ipc,shm: introduce shmctl_nolock Greg Kroah-Hartman
2013-10-16 17:45 ` [ 52/69] ipc,shm: make shmctl_nolock lockless Greg Kroah-Hartman
2013-10-16 17:45 ` [ 53/69] ipc,shm: shorten critical region for shmctl Greg Kroah-Hartman
2013-10-16 17:45 ` [ 54/69] ipc,shm: cleanup do_shmat pasta Greg Kroah-Hartman
2013-10-16 17:45 ` [ 55/69] ipc,shm: shorten critical region for shmat Greg Kroah-Hartman
2013-10-16 17:45 ` [ 56/69] ipc: rename ids->rw_mutex Greg Kroah-Hartman
2013-10-16 17:45 ` [ 57/69] ipc,msg: drop msg_unlock Greg Kroah-Hartman
2013-10-16 17:45 ` [ 58/69] ipc: document general ipc locking scheme Greg Kroah-Hartman
2013-10-16 17:45 ` [ 59/69] ipc, shm: guard against non-existant vma in shmdt(2) Greg Kroah-Hartman
2013-10-16 17:45 ` [ 60/69] ipc: drop ipc_lock_by_ptr Greg Kroah-Hartman
2013-10-16 17:45 ` [ 61/69] ipc, shm: drop shm_lock_check Greg Kroah-Hartman
2013-10-16 17:45 ` [ 62/69] ipc: drop ipc_lock_check Greg Kroah-Hartman
2013-10-16 17:45 ` [ 63/69] ipc: fix race with LSMs Greg Kroah-Hartman
2013-10-16 17:45 ` [ 64/69] ipc/sem.c: fix race in sem_lock() Greg Kroah-Hartman
2013-10-16 17:45 ` [ 65/69] ipc/sem.c: optimize sem_lock() Greg Kroah-Hartman
2013-10-16 17:45 ` [ 66/69] ipc/sem.c: synchronize the proc interface Greg Kroah-Hartman
2013-10-16 17:45 ` [ 67/69] ipc/sem.c: update sem_otime for all operations Greg Kroah-Hartman
2013-10-16 17:45 ` [ 68/69] ipc,msg: prevent race with rmid in msgsnd,msgrcv Greg Kroah-Hartman
2013-10-16 17:45 ` [ 69/69] x86: avoid remapping data in parse_setup_data() Greg Kroah-Hartman
2013-10-16 22:11 ` [ 00/69] 3.10.17-stable review Guenter Roeck
2013-10-17 1:07 ` Greg Kroah-Hartman
2013-10-17 16:50 ` Shuah Khan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).