kernel_optimize_test/drivers/char
Mike Isely 9df5808cca drm: Fix race that can lockup the kernel
The i915_vblank_swap() function schedules an automatic buffer swap
upon receipt of the vertical sync interrupt.  Such an operation is
lengthy so it can't be allowed to happen in normal interrupt context,
thus the DRM implements this by scheduling the work in a kernel
softirq-scheduled tasklet.  In order for the buffer swap to work
safely, the DRM's central lock must be taken, via a call to
drm_lock_take() located in drivers/char/drm/drm_irq.c within the
function drm_locked_tasklet_func().  The lock-taking logic uses a
non-interrupt-blocking spinlock to implement the manipulations needed
to take the lock.  This semantic would be safe if all attempts to use
the spinlock only happen from process context.  However this buffer
swap happens from softirq context which is really a form of interrupt
context.  Thus we have an unsafe situation, in that
drm_locked_tasklet_func() can block on a spinlock already taken by a
thread in process context which will never get scheduled again because
of the blocked softirq tasklet.  This wedges the kernel hard.

To trigger this bug, run a dual-head cloned mode configuration which
uses the i915 drm, then execute an opengl application which
synchronizes buffer swaps against the vertical sync interrupt.  In my
testing, a lockup always results after running anywhere from 5 minutes
to an hour and a half.  I believe dual-head is needed to really
trigger the problem because then the vertical sync interrupt handling
is no longer predictable (due to being interrupt-sourced from two
different heads running at different speeds).  This raises the
probability of the tasklet trying to run while the userspace DRI is
doing things to the GPU (and manipulating the DRM lock).

The fix is to change the relevant spinlock semantics to be the
interrupt-blocking form.  After this change I am no longer able to
trigger the lockup; the longest test run so far was 20 hours (test
stopped after that point).

Note: I have examined the places where this spinlock is being
employed; all are reasonably short bounded sequences and should be
suitable for interrupts being blocked without impacting overall kernel
interrupt response latency.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2008-03-17 09:54:58 +10:00
..
agp agp: fix missing casts that produced a warning. 2008-02-20 10:37:08 +10:00
drm drm: Fix race that can lockup the kernel 2008-03-17 09:54:58 +10:00
hw_random via-rng: enable secondary noise source on CPUs where it is present 2008-02-06 10:41:05 -08:00
ip2 Char: char/serial, remove SERIAL_TYPE_NORMAL redefines 2008-02-07 08:42:33 -08:00
ipmi drivers/char/ipmi/ipmi_msghandler.c: use LIST_HEAD instead of LIST_HEAD_INIT 2008-02-06 10:41:07 -08:00
mwave
pcmcia ipwireless: fix potential tty == NULL dereference 2008-03-04 16:35:13 -08:00
rio
tpm tpm: infineon section mismatch 2008-02-06 10:41:10 -08:00
xilinx_hwicap [POWERPC] Xilinx: hwicap cleanup 2008-02-28 10:38:33 -06:00
.gitignore
amiserial.c
apm-emulation.c
applicom.c Char: applicom, use pci_match_id 2008-02-08 09:22:41 -08:00
applicom.h
briq_panel.c
cd1865.h
ChangeLog
consolemap.c
cp437.uni
cs5535_gpio.c
cyclades.c
defkeymap.c_shipped Fix default compose table initialization 2008-03-03 14:53:16 -08:00
defkeymap.map
digi1.h
digiFep1.h
digiPCI.h
ds1286.c
ds1302.c
ds1620.c
dsp56k.c
dtlk.c
efirtc.c drivers/char/: Spelling fixes 2008-02-03 17:11:42 +02:00
epca.c drivers/char/: Spelling fixes 2008-02-03 17:11:42 +02:00
epca.h Char: char/serial, remove SERIAL_TYPE_NORMAL redefines 2008-02-07 08:42:33 -08:00
epcaconfig.h
esp.c drivers/char/esp.c: fix bootup lockup 2008-03-07 10:05:13 -08:00
generic_nvram.c
generic_serial.c
genrtc.c
hangcheck-timer.c drivers/char/: Spelling fixes 2008-02-03 17:11:42 +02:00
hpet.c
hvc_beat.c
hvc_console.c drivers/char: use LIST_HEAD instead of LIST_HEAD_INIT 2008-02-06 10:41:07 -08:00
hvc_console.h
hvc_iseries.c
hvc_rtas.c [POWERPC] hvc_rtas_init() must be __init 2008-02-14 22:11:02 +11:00
hvc_vio.c
hvc_xen.c
hvcs.c drivers/char: use LIST_HEAD instead of LIST_HEAD_INIT 2008-02-06 10:41:07 -08:00
hvsi.c
i8k.c i8k: Inspiron E1705 fix 2008-02-07 08:42:33 -08:00
ip27-rtc.c ip27-rtc: convert ioctl to unlocked_ioctl 2008-02-06 10:41:14 -08:00
isicom.c drivers/char/isicom.c: correct use of ! and & 2008-03-04 16:35:15 -08:00
istallion.c Char: istallion, remove hangup bottomhalf 2008-02-07 08:42:34 -08:00
Kconfig sonypi - Move sonypi.txt to Documentation/laptops 2008-02-09 04:15:53 -05:00
keyboard.c
lcd.c
lcd.h
lp.c Parallel port: convert port_mutex to the mutex API 2008-02-06 10:41:01 -08:00
Makefile Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc 2008-02-07 09:02:26 -08:00
mbcs.c MBCS: convert dmareadlock to mutex 2008-02-07 08:42:25 -08:00
mbcs.h MBCS: convert dmareadlock to mutex 2008-02-07 08:42:25 -08:00
mem.c
misc.c Misc: Add possibility to remove misc devices during suspend/resume 2008-02-05 09:44:23 -08:00
mmtimer.c
moxa.c moxa: first pass at termios reporting 2008-02-08 09:22:24 -08:00
mspec.c vm audit: add VM_DONTEXPAND to mmap for drivers that need it 2008-02-04 07:55:38 -08:00
mxser.c Char: mxser, add support for CP-114UL 2008-02-07 08:42:35 -08:00
mxser.h Char: mxser, remove it 2008-02-07 08:42:34 -08:00
n_hdlc.c
n_r3964.c
n_tty.c n_tty: clean up old code to follow coding style and (mostly) checkpatch 2008-02-08 09:22:25 -08:00
nozomi.c nozomi: fix initialization and early flow control access 2008-03-10 16:33:32 -07:00
nsc_gpio.c
nvram.c
nwbutton.c
nwbutton.h
nwflash.c
pc8736x_gpio.c
ppdev.c
ps3flash.c
pty.c
random.c drivers/char/random.c:write_pool() cond_resched() needed 2008-02-06 10:41:06 -08:00
raw.c
riscom8_reg.h
riscom8.c char: riscom, fix rc_board indexing 2008-03-13 13:11:43 -07:00
riscom8.h Char: riscom8, remove wakeup and hangup bottomhalves 2008-02-07 08:42:34 -08:00
rocket_int.h Char: rocket, remove useless macros 2008-02-07 08:42:33 -08:00
rocket.c rocket: don't let random users reset the controller 2008-02-08 09:22:25 -08:00
rocket.h
rtc.c Fix hpet_(un)register_irq_handler() for emulation 2008-02-29 08:06:37 -08:00
scc.h
scx200_gpio.c
selection.c
ser_a2232.c Amiga serial driver: port_write_mutex fixup 2008-02-06 10:41:08 -08:00
ser_a2232.h
ser_a2232fw.ax
ser_a2232fw.h
serial167.c Char: serial167, remove bottomhalf 2008-02-07 08:42:34 -08:00
snsc_event.c
snsc.c
snsc.h
sonypi.c
specialix_io8.h Char: specialix, remove bottomhalves 2008-02-07 08:42:34 -08:00
specialix.c specialix.c: fix possible double-unlock 2008-03-04 16:35:10 -08:00
stallion.c Char: stallion, remove bottomhalf 2008-02-07 08:42:34 -08:00
sx.c
sx.h Char: char/serial, remove SERIAL_TYPE_NORMAL redefines 2008-02-07 08:42:33 -08:00
sxboards.h
sxwindow.h
synclink_gt.c synclink_gt fix missed serial input signal changes 2008-02-06 10:41:06 -08:00
synclink.c synclink: standardize format of linux header file include's with "<>" 2008-02-06 10:41:06 -08:00
synclinkmp.c synclink: standardize format of linux header file include's with "<>" 2008-02-06 10:41:06 -08:00
sysrq.c
tb0219.c
tlclk.c
toshiba.c drivers/char/: Spelling fixes 2008-02-03 17:11:42 +02:00
tty_audit.c tty_audit: fix checkpatch complaint 2008-02-08 09:22:25 -08:00
tty_io.c tty_io: drag screaming into coding style compliance 2008-02-08 09:22:25 -08:00
tty_ioctl.c tty_ioctl: drag screaming into compliance with the coding style 2008-02-08 09:22:25 -08:00
vc_screen.c
viocons.c
viotape.c
virtio_console.c virtio: simplify config mechanism. 2008-02-04 23:49:57 +11:00
vme_scc.c
vr41xx_giu.c
vt_ioctl.c
vt.c VT notifier fix for VT switch 2008-03-04 16:35:11 -08:00