drm: Return EBUSY if the framebuffer is unbound when flipping.
It looks like there is a race condition between unbinding a framebuffer
on a hotplug event and user space trying to flip:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
IP: [<ffffffffa008c7d3>] intel_crtc_page_flip+0xc9/0x39c [i915]
PGD 114724067 PUD 1145bd067 PMD 0
Oops: 0000 [#1] SMP
Pid: 10954, comm: X Not tainted 2.6.35-rc5_stable_20100714+ #1
P5Q-EM/P5Q-EM
RIP: 0010:[<ffffffffa008c7d3>] [<ffffffffa008c7d3>]
intel_crtc_page_flip+0xc9/0x39c [i915]
RSP: 0018:ffff880114927cc8 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffff88012df48320 RCX: ffff88010c945600
RDX: ffff880001a109c8 RSI: ffff88010c945840 RDI: ffff88012df48320
RBP: ffff880114927d18 R08: ffff88012df48280 R09: ffff88012df48320
R10: 0000000003c2e0b0 R11: 0000000000003246 R12: ffff88010c945840
R13: ffff88012df48000 R14: 0000000000000060 R15: ffff88012dbb8000
FS: 00007f9e6078e830(0000) GS:ffff880001a00000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000058 CR3: 00000001177a8000 CR4: 00000000000406f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process X (pid: 10954, threadinfo ffff880114926000, task
ffff88012a4a1690)
Stack:
ffff88010c945600 ffff880115b176c0 ffff88012db10000 0000000000000246
<0> fffffff40006101c ffff88010c945600 00000000ffffffea ffff88010c945600
<0> ffff88012df48320 ffff88011b4b6780 ffff880114927d78 ffffffffa003bd0e
Call Trace:
[<ffffffffa003bd0e>] drm_mode_page_flip_ioctl+0x1bc/0x214 [drm]
[<ffffffffa00311fc>] drm_ioctl+0x25e/0x35e [drm]
[<ffffffffa003bb52>] ? drm_mode_page_flip_ioctl+0x0/0x214 [drm]
[<ffffffff810f1c3c>] vfs_ioctl+0x2a/0x9e
[<ffffffff810f227e>] do_vfs_ioctl+0x531/0x565
[<ffffffff810f2307>] sys_ioctl+0x55/0x77
[<ffffffff810e56d6>] ? sys_read+0x47/0x6f
[<ffffffff81002a2b>] system_call_fastpath+0x16/0x1b
Code: 45 d4 f4 ff ff ff 0f 84 e0 02 00 00 48 8b 4d b0 49 8d 9d 20 03 00 00 48
89 df 49 89 4c 24 38 49 8b 07 49 89 44 24 20 49 8b 47 20 <48> 8b 40 58 49 c7 04
24 00 00 00 00 49 c7 44 24 18 a9 a5 08 a0
RIP [<ffffffffa008c7d3>] intel_crtc_page_flip+0xc9/0x39c [i915]
RSP <ffff880114927cc8>
CR2: 0000000000000058
References:
Bug 28811 - [page-flipping] GPU hang when modeset after unplugging
another monitor (under compiz)
https://bugs.freedesktop.org/show_bug.cgi?id=28811
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d8d65f4..4c68f76 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2617,6 +2617,15 @@
goto out;
crtc = obj_to_crtc(obj);
+ if (crtc->fb == NULL) {
+ /* The framebuffer is currently unbound, presumably
+ * due to a hotplug event, that userspace has not
+ * yet discovered.
+ */
+ ret = -EBUSY;
+ goto out;
+ }
+
if (crtc->funcs->page_flip == NULL)
goto out;