1
linux/drivers/video
Herton Ronaldo Krzesinski 9e769ff3f5 fb: avoid possible deadlock caused by fb_set_suspend
A lock ordering issue can cause deadlocks: in framebuffer/console code,
all needed struct fb_info locks are taken before acquire_console_sem(),
in places which need to take console semaphore.

But fb_set_suspend is always called with console semaphore held, and
inside it we call lock_fb_info which gets the fb_info lock, inverse
locking order of what the rest of the code does. This causes a real
deadlock issue, when we write to state fb sysfs attribute (which calls
fb_set_suspend) while a framebuffer is being unregistered by
remove_conflicting_framebuffers, as can be shown by following show
blocked state trace on a test program which loads i915 and runs another
forked processes writing to state attribute:

Test process with semaphore held and trying to get fb_info lock:
..
fb-test2      D 0000000000000000     0   237    228 0x00000000
 ffff8800774f3d68 0000000000000082 00000000000135c0 00000000000135c0
 ffff880000000000 ffff8800774f3fd8 ffff8800774f3fd8 ffff880076ee4530
 00000000000135c0 ffff8800774f3fd8 ffff8800774f2000 00000000000135c0
Call Trace:
 [<ffffffff8141287a>] __mutex_lock_slowpath+0x11a/0x1e0
 [<ffffffff814142f2>] ? _raw_spin_lock_irq+0x22/0x40
 [<ffffffff814123d3>] mutex_lock+0x23/0x50
 [<ffffffff8125dfc5>] lock_fb_info+0x25/0x60
 [<ffffffff8125e3f0>] fb_set_suspend+0x20/0x80
 [<ffffffff81263e2f>] store_fbstate+0x4f/0x70
 [<ffffffff812e7f70>] dev_attr_store+0x20/0x30
 [<ffffffff811c46b4>] sysfs_write_file+0xd4/0x160
 [<ffffffff81155a26>] vfs_write+0xc6/0x190
 [<ffffffff81155d51>] sys_write+0x51/0x90
 [<ffffffff8100c012>] system_call_fastpath+0x16/0x1b
..
modprobe process stalled because has the fb_info lock (got inside
unregister_framebuffer) but waiting for the semaphore held by the
test process which is waiting to get the fb_info lock:
..
modprobe      D 0000000000000000     0   230    218 0x00000000
 ffff880077a4d618 0000000000000082 0000000000000001 0000000000000001
 ffff880000000000 ffff880077a4dfd8 ffff880077a4dfd8 ffff8800775a2e20
 00000000000135c0 ffff880077a4dfd8 ffff880077a4c000 00000000000135c0
Call Trace:
 [<ffffffff81411fe5>] schedule_timeout+0x215/0x310
 [<ffffffff81058051>] ? get_parent_ip+0x11/0x50
 [<ffffffff814130dd>] __down+0x6d/0xb0
 [<ffffffff81089f71>] down+0x41/0x50
 [<ffffffff810629ac>] acquire_console_sem+0x2c/0x50
 [<ffffffff812ca53d>] unbind_con_driver+0xad/0x2d0
 [<ffffffff8126f5f7>] fbcon_event_notify+0x457/0x890
 [<ffffffff814144ff>] ? _raw_spin_unlock_irqrestore+0x1f/0x50
 [<ffffffff81058051>] ? get_parent_ip+0x11/0x50
 [<ffffffff8141836d>] notifier_call_chain+0x4d/0x70
 [<ffffffff8108a3b8>] __blocking_notifier_call_chain+0x58/0x80
 [<ffffffff8108a3f6>] blocking_notifier_call_chain+0x16/0x20
 [<ffffffff8125dabb>] fb_notifier_call_chain+0x1b/0x20
 [<ffffffff8125e6ac>] unregister_framebuffer+0x7c/0x130
 [<ffffffff8125e8b3>] remove_conflicting_framebuffers+0x153/0x180
 [<ffffffff8125eef3>] register_framebuffer+0x93/0x2c0
 [<ffffffffa0331112>] drm_fb_helper_single_fb_probe+0x252/0x2f0 [drm_kms_helper]
 [<ffffffffa03314a3>] drm_fb_helper_initial_config+0x2f3/0x6d0 [drm_kms_helper]
 [<ffffffffa03318dd>] ? drm_fb_helper_single_add_all_connectors+0x5d/0x1c0 [drm_kms_helper]
 [<ffffffffa037b588>] intel_fbdev_init+0xa8/0x160 [i915]
 [<ffffffffa0343d74>] i915_driver_load+0x854/0x12b0 [i915]
 [<ffffffffa02f0e7e>] drm_get_pci_dev+0x19e/0x360 [drm]
 [<ffffffff8141821d>] ? sub_preempt_count+0x9d/0xd0
 [<ffffffffa0386f91>] i915_pci_probe+0x15/0x17 [i915]
 [<ffffffff8124481f>] local_pci_probe+0x5f/0xd0
 [<ffffffff81244f89>] pci_device_probe+0x119/0x120
 [<ffffffff812eccaa>] ? driver_sysfs_add+0x7a/0xb0
 [<ffffffff812ed003>] driver_probe_device+0xa3/0x290
 [<ffffffff812ed1f0>] ? __driver_attach+0x0/0xb0
 [<ffffffff812ed29b>] __driver_attach+0xab/0xb0
 [<ffffffff812ed1f0>] ? __driver_attach+0x0/0xb0
 [<ffffffff812ebd3e>] bus_for_each_dev+0x5e/0x90
 [<ffffffff812ecc2e>] driver_attach+0x1e/0x20
 [<ffffffff812ec6f2>] bus_add_driver+0xe2/0x320
 [<ffffffffa03aa000>] ? i915_init+0x0/0x96 [i915]
 [<ffffffff812ed536>] driver_register+0x76/0x140
 [<ffffffffa03aa000>] ? i915_init+0x0/0x96 [i915]
 [<ffffffff81245216>] __pci_register_driver+0x56/0xd0
 [<ffffffffa02f1264>] drm_pci_init+0xe4/0xf0 [drm]
 [<ffffffffa03aa000>] ? i915_init+0x0/0x96 [i915]
 [<ffffffffa02e84a8>] drm_init+0x58/0x70 [drm]
 [<ffffffffa03aa094>] i915_init+0x94/0x96 [i915]
 [<ffffffff81002194>] do_one_initcall+0x44/0x190
 [<ffffffff810a066b>] sys_init_module+0xcb/0x210
 [<ffffffff8100c012>] system_call_fastpath+0x16/0x1b
..

fb-test2 which reproduces above is available on kernel.org bug #26232.
To solve this issue, avoid calling lock_fb_info inside fb_set_suspend,
and move it out to where needed (callers of fb_set_suspend must call
lock_fb_info before if needed). So far, the only place which needs to
call lock_fb_info is store_fbstate, all other places which calls
fb_set_suspend are suspend/resume hooks that should not need the lock as
they should be run only when processes are already frozen in
suspend/resume.

References: https://bugzilla.kernel.org/show_bug.cgi?id=26232
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: stable@kernel.org
2011-09-02 17:58:29 +00:00
..
aty radeonfb: use display information in info not in var for panning 2011-08-19 10:30:16 +02:00
backlight Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
console Merge branch 'master' into for-next 2011-04-26 10:22:59 +02:00
display Fix common misspellings 2011-03-31 11:26:23 -03:00
geode gx1fb: Fix section mismatch warnings 2011-06-24 17:00:31 +09:00
i810 treewide: fix potentially dangerous trailing ';' in #defined values/expressions 2011-07-21 14:10:00 +02:00
intelfb intelfb: use display information in info not in var for panning 2011-08-19 10:32:31 +02:00
kyro Fix common misspellings 2011-03-31 11:26:23 -03:00
logo
matrox Fix common misspellings 2011-03-31 11:26:23 -03:00
mb862xx video: mb862xx-i2c: fix for reliable decoder register access 2011-09-02 17:57:38 +00:00
mbx
msm Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
nvidia backlight: add backlight type 2011-03-22 17:43:59 -07:00
omap Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6 2011-05-26 12:11:54 -07:00
omap2 OMAP: DSS2: HDMI: fix hdmi clock name 2011-08-01 14:56:53 +03:00
pnx4008
riva backlight: add backlight type 2011-03-22 17:43:59 -07:00
savage savagefb: use display information in info not in var for panning 2011-08-19 10:34:44 +02:00
sis sisfb: use display information in info not in var for panning 2011-08-19 10:34:52 +02:00
vermilion atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
via Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
68328fb.c 68328fb: use display information in info not in var for panning 2011-08-19 10:28:58 +02:00
acornfb.c acornfb: use display information in info not in var for panning 2011-08-19 10:29:34 +02:00
acornfb.h
amba-clcd.c fbdev: amba: Link fb device to its parent 2011-06-24 17:11:50 +09:00
amifb.c fbdev/amifb: Remove superfluous alignment of frame buffer memory 2011-05-24 16:26:31 +09:00
arcfb.c video: Convert vmalloc/memset to vzalloc 2011-06-02 17:25:35 +09:00
arkfb.c arkfb: use display information in info not in var for panning 2011-08-19 10:29:44 +02:00
asiliantfb.c
atafb_iplan2p2.c
atafb_iplan2p4.c
atafb_iplan2p8.c
atafb_mfb.c
atafb_utils.h
atafb.c m68k/atari: Do not use "/" in interrupt names 2011-05-19 18:19:10 +02:00
atafb.h
atmel_lcdfb.c atmel_lcdfb: use display information in info not in var for panning 2011-08-19 10:30:02 +02:00
au1100fb.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
au1100fb.h
au1200fb.c fbdev: au1200fb: silence debug output 2011-09-02 17:57:47 +00:00
au1200fb.h
bf54x-lq043fb.c backlight: add backlight type 2011-03-22 17:43:59 -07:00
bf537-lq035.c fbdev: bf537-lq035: add missing blacklight properties type 2011-06-02 17:07:35 +09:00
bfin_adv7393fb.c
bfin_adv7393fb.h Fix common misspellings 2011-03-31 11:26:23 -03:00
bfin-lq035q1-fb.c drivers/video/bfin-lq035q1-fb.c: introduce missing kfree 2011-04-06 09:44:57 -07:00
bfin-t350mcqb-fb.c backlight: add backlight type 2011-03-22 17:43:59 -07:00
broadsheetfb.c video: Convert vmalloc/memset to vzalloc 2011-06-02 17:25:35 +09:00
bt431.h
bt455.h
bw2.c dt/video: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:45 -07:00
c2p_core.h
c2p_iplan2.c
c2p_planar.c
c2p.h
carminefb_regs.h
carminefb.c carminefb: Fix module parameters permissions 2011-07-13 16:53:23 +09:00
carminefb.h
cfbcopyarea.c
cfbfillrect.c
cfbimgblt.c
cg3.c dt/video: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:45 -07:00
cg6.c video: add missing framebuffer_release in error path 2011-03-22 16:35:44 +09:00
cg14.c video: add missing framebuffer_release in error path 2011-03-22 16:35:44 +09:00
chipsfb.c console: rename acquire/release_console_sem() to console_lock/unlock() 2011-01-26 10:50:06 +10:00
cirrusfb.c
clps711xfb.c
cobalt_lcdfb.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
controlfb.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
controlfb.h
cyber2000fb.c VIDEO: cyberpro: remove unused cyber2000fb_get_fb_var() 2011-02-11 10:16:07 +00:00
cyber2000fb.h VIDEO: cyberpro: remove unused cyber2000fb_get_fb_var() 2011-02-11 10:16:07 +00:00
da8xx-fb.c fbdev: da8xx: use display information in info not in var for panning 2011-08-19 10:30:47 +02:00
dnfb.c
edid.h video: Fix EDID macros H_SYNC_WIDTH and H_SYNC_OFFSET 2011-03-22 16:45:03 +09:00
efifb.c efifb: Fix call to wrong unregister function 2011-06-14 16:37:46 +09:00
ep93xx-fb.c Change Ryan Mallon's email address across the kernel 2011-06-16 11:22:05 +02:00
epson1355fb.c
fb_ddc.c
fb_defio.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
fb_draw.h
fb_notify.c
fb_sys_fops.c
fb-puv3.c fbdev: unicore32: use display information in info not in var for panning 2011-08-19 10:31:01 +02:00
fbcmap.c
fbcvt.c
fbmem.c fb: avoid possible deadlock caused by fb_set_suspend 2011-09-02 17:58:29 +00:00
fbmon.c fbdev: fix parsing of standard timings 2011-09-01 00:31:05 +00:00
fbsysfs.c fb: avoid possible deadlock caused by fb_set_suspend 2011-09-02 17:58:29 +00:00
ffb.c video: ffb: fix ffb_probe error path 2011-03-22 16:18:51 +09:00
fm2fb.c Fix common misspellings 2011-03-31 11:26:23 -03:00
fsl-diu-fb.c drivers/video: use strings to specify the Freescale DIU monitor port 2011-07-13 17:01:39 +09:00
g364fb.c g364fb: use display information in info not in var for panning 2011-08-19 10:31:09 +02:00
gbefb.c Fix common misspellings 2011-03-31 11:26:23 -03:00
grvga.c video: Add Aeroflex Gaisler GRVGA framebuffer device driver 2011-07-13 16:58:52 +09:00
gxt4500.c gxt4500: use display information in info not in var for panning 2011-08-19 10:31:17 +02:00
hecubafb.c hecubafb: add module_put on error path in hecubafb_probe() 2011-06-24 17:00:39 +09:00
hgafb.c hgafb: use display information in info not in var for panning 2011-08-19 10:31:28 +02:00
hitfb.c
hpfb.c video: hpfb: use resource_size() 2011-03-22 16:07:32 +09:00
igafb.c
imsttfb.c imsttfb: use display information in info not in var for panning 2011-08-19 10:31:39 +02:00
imxfb.c drivers/video/imxfb.c: add missing clk_put 2011-06-02 17:07:41 +09:00
jz4740_fb.c console: rename acquire/release_console_sem() to console_lock/unlock() 2011-01-26 10:50:06 +10:00
Kconfig Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
leo.c dt/video: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:45 -07:00
macfb.c
macmodes.c
macmodes.h
Makefile video: Add Aeroflex Gaisler GRVGA framebuffer device driver 2011-07-13 16:58:52 +09:00
maxinefb.c
metronomefb.c video: Convert vmalloc/memset to vzalloc 2011-06-02 17:25:35 +09:00
modedb.c savagefb: Use panel CVT mode as default 2011-06-02 17:05:18 +09:00
mx3fb.c mx3fb: use display information in info not in var for panning 2011-08-19 10:32:52 +02:00
mxsfb.c video: mxsfb: add missing include of linux/module.h 2011-09-01 00:28:24 +00:00
n411.c
neofb.c neofb: use display information in info not in var for panning 2011-08-19 10:33:02 +02:00
nuc900fb.c video: nuc900fb: remove include of mach/clkdev.h 2011-09-01 00:28:24 +00:00
nuc900fb.h Fix common misspellings 2011-03-31 11:26:23 -03:00
offb.c
output.c
p9100.c dt/video: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:45 -07:00
platinumfb.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
platinumfb.h
pm2fb.c pm2fb: use display information in info not in var for panning 2011-08-19 10:33:16 +02:00
pm3fb.c pm3fb: use display information in info not in var for panning 2011-08-19 10:34:01 +02:00
pmag-aa-fb.c
pmag-ba-fb.c
pmagb-b-fb.c
ps3fb.c console: rename acquire/release_console_sem() to console_lock/unlock() 2011-01-26 10:50:06 +10:00
pvr2fb.c
pxa3xx-gcu.c Remove unneeded version.h includes from drivers/video/ 2011-06-24 17:16:51 +09:00
pxa3xx-gcu.h
pxa168fb.c treewide: Convert uses of struct resource to resource_size(ptr) 2011-06-10 14:55:36 +02:00
pxa168fb.h
pxafb.c ARM: pxafb: Fix access to nonexistent member of pxafb_info 2011-04-12 23:07:42 +08:00
pxafb.h ARM: pxafb: rework pxafb overlay memory management 2011-03-16 17:37:03 +08:00
q40fb.c
s1d13xxxfb.c
s3c2410fb.c video: s3c2410: remove unused variable 2011-07-13 16:53:17 +09:00
s3c2410fb.h
s3c-fb.c video: s3c-fb: Add support EXYNOS4 FIMD 2011-08-24 10:14:23 +00:00
s3fb.c s3fb: use display information in info not in var for panning 2011-08-19 10:34:34 +02:00
sa1100fb.c
sa1100fb.h
sbuslib.c
sbuslib.h
sgivwfb.c
sh7760fb.c drivers/video: Convert release_resource to release_mem_region 2011-05-24 16:08:54 +09:00
sh_mipi_dsi.c
sh_mobile_hdmi.c fbdev: sh_mobile_hdmi: fix regression: statically enable RTPM 2011-06-15 14:51:46 +09:00
sh_mobile_lcdcfb.c fbdev: sh_mobile_meram: Remove unneeded sh_mobile_meram.h 2011-08-19 08:22:45 +02:00
sh_mobile_lcdcfb.h fbdev: sh_mobile_lcdc: Restart LCDC in runtime PM resume handler 2011-08-19 08:22:41 +02:00
sh_mobile_meram.c fbdev: sh_mobile_meram: Remove unneeded sh_mobile_meram.h 2011-08-19 08:22:45 +02:00
skeletonfb.c video: Fix speficied typo 2011-06-24 17:14:39 +09:00
sm501fb.c sm501fb: use display information in info not in var for panning 2011-08-19 10:35:10 +02:00
sstfb.c Fix common misspellings 2011-03-31 11:26:23 -03:00
sticore.h Fix common misspellings 2011-03-31 11:26:23 -03:00
stifb.c
sunxvr500.c
sunxvr1000.c dt/video: Eliminate users of of_platform_{,un}register_driver 2011-02-28 13:22:45 -07:00
sunxvr2500.c
svgalib.c svga: Make svga_set_timings() take an iomem regbase pointer. 2011-03-22 15:47:22 +09:00
syscopyarea.c
sysfillrect.c
sysimgblt.c
tcx.c video: add missing framebuffer_release in error path 2011-03-22 16:35:44 +09:00
tdfxfb.c Fix common misspellings 2011-03-31 11:26:23 -03:00
tgafb.c
tmiofb.c fb: Use platform_data to retrieve tmiofb platform bits 2011-05-26 19:45:03 +02:00
tridentfb.c tridentfb: use display information in info not in var for panning 2011-08-19 10:35:18 +02:00
udlfb.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x into fbdev-next 2011-08-29 09:14:30 +00:00
uvesafb.c uvesafb,vesafb: create WC or WB PAT-entries 2011-03-22 16:20:44 +09:00
valkyriefb.c video: Fix speficied typo 2011-06-24 17:14:39 +09:00
valkyriefb.h
vesafb.c vesafb: fix memory leak 2011-07-04 16:02:48 +09:00
vfb.c vfb: use display information in info not in var for panning 2011-08-19 10:35:27 +02:00
vga16fb.c vga16fb: use display information in info not in var for panning 2011-08-19 10:35:34 +02:00
vgastate.c
vt8500lcdfb.c vt8500lcdfb: use display information in info not in var for panning 2011-08-19 10:36:12 +02:00
vt8500lcdfb.h
vt8623fb.c vt8623fb: use display information in info not in var for panning 2011-08-19 10:36:20 +02:00
w100fb.c Fix common misspellings 2011-03-31 11:26:23 -03:00
w100fb.h
wm8505fb_regs.h
wm8505fb.c
wmt_ge_rops.c
wmt_ge_rops.h
xen-fbfront.c video: Convert vmalloc/memset to vzalloc 2011-06-02 17:25:35 +09:00
xilinxfb.c Remove unneeded version.h includes from drivers/video/ 2011-06-24 17:16:51 +09:00