dma-buf: Use fence_get_rcu_safe() for retrieving the exclusive fence
The current code is subject to a race where we may try to acquire a
reference on a stale fence:
[13703.335118] WARNING: CPU: 1 PID: 14975 at ./include/linux/kref.h:46 i915_gem_object_wait+0x1a3/0x1c0
[13703.335184] Modules linked in:
[13703.335202] CPU: 1 PID: 14975 Comm: gem_concurrent_ Not tainted 4.9.0-rc4+ #26
[13703.335216] Hardware name: / , BIOS PYBSWCEL.86A.0027.2015.0507.1758 05/07/2015
[13703.335233]
ffffc90002f5bcc8 ffffffff812807de 0000000000000000 0000000000000000
[13703.335257]
ffffc90002f5bd08 ffffffff81073811 0000002e80000000 ffff88026bf7c780
[13703.335279]
7fffffffffffffff 0000000000000001 ffff88027045a550 ffff88026bf7c780
[13703.335301] Call Trace:
[13703.335316] [<
ffffffff812807de>] dump_stack+0x4d/0x6f
[13703.335331] [<
ffffffff81073811>] __warn+0xc1/0xe0
[13703.335343] [<
ffffffff810738e8>] warn_slowpath_null+0x18/0x20
[13703.335355] [<
ffffffff813ac443>] i915_gem_object_wait+0x1a3/0x1c0
[13703.335367] [<
ffffffff813ae8ec>] i915_gem_set_domain_ioctl+0xcc/0x330
[13703.335386] [<
ffffffff813534ab>] drm_ioctl+0x1cb/0x410
[13703.335400] [<
ffffffff813ae820>] ? i915_gem_obj_prepare_shmem_write+0x1d0/0x1d0
[13703.335416] [<
ffffffff8135359b>] ? drm_ioctl+0x2bb/0x410
[13703.335429] [<
ffffffff8117d32f>] do_vfs_ioctl+0x8f/0x5c0
[13703.335442] [<
ffffffff8117d89c>] SyS_ioctl+0x3c/0x70
[13703.335456] [<
ffffffff815a07a4>] entry_SYSCALL_64_fastpath+0x17/0x98
[13703.335558] ---[ end trace
fd24176416ba6981 ]---
[13703.382778] general protection fault: 0000 [#1] SMP
[13703.382802] Modules linked in:
[13703.382816] CPU: 1 PID: 14967 Comm: gem_concurrent_ Tainted: G W 4.9.0-rc4+ #26
[13703.382828] Hardware name: / , BIOS PYBSWCEL.86A.0027.2015.0507.1758 05/07/2015
[13703.382841] task:
ffff880275458000 task.stack:
ffffc90002f18000
[13703.382849] RIP: 0010:[<
ffffffff813b3534>] [<
ffffffff813b3534>] i915_gem_request_retire+0x2b4/0x320
[13703.382870] RSP: 0018:
ffffc90002f1bbc8 EFLAGS:
00010293
[13703.382878] RAX:
dead000000000200 RBX:
ffff88026bf7dce8 RCX:
dead000000000100
[13703.382887] RDX:
dead000000000100 RSI:
ffff88026bf7c930 RDI:
ffff88026bf7dd00
[13703.382897] RBP:
ffffc90002f1bbf8 R08:
00000000ffffffff R09:
ffff88026b89a000
[13703.382905] R10:
0000000000000001 R11:
ffff88026bbe8fe0 R12:
ffff88026bf7c000
[13703.382913] R13:
ffff880275af8000 R14:
ffff88026bf7c180 R15:
dead000000000200
[13703.382922] FS:
00007f89e787d740(0000) GS:
ffff88027fd00000(0000) knlGS:
0000000000000000
[13703.382934] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[13703.382942] CR2:
00007f9053d2e000 CR3:
000000026d414000 CR4:
00000000001006e0
[13703.382951] Stack:
[13703.382958]
ffff880275413000 ffffc90002f1bde8 ffff880275af8000 ffff880274e8a600
[13703.382976]
ffff880276a06000 ffffc90002f1bde8 ffffc90002f1bc38 ffffffff813b48c5
[13703.382995]
ffffc90002f1bc00 ffffc90002f1bde8 ffff88026972a440 0000000000000000
[13703.383021] Call Trace:
[13703.383032] [<
ffffffff813b48c5>] i915_gem_request_alloc+0xa5/0x350
[13703.383043] [<
ffffffff813a17c3>] i915_gem_do_execbuffer.isra.41+0x7b3/0x18b0
[13703.383055] [<
ffffffff813b144c>] ? i915_gem_object_get_sg+0x25c/0x2b0
[13703.383065] [<
ffffffff813b1d4d>] ? i915_gem_object_get_page+0x1d/0x50
[13703.383076] [<
ffffffff813b28cc>] ? i915_gem_pwrite_ioctl+0x66c/0x6d0
[13703.383086] [<
ffffffff813a2c25>] i915_gem_execbuffer2+0x95/0x1e0
[13703.383096] [<
ffffffff813534ab>] drm_ioctl+0x1cb/0x410
[13703.383105] [<
ffffffff813a2b90>] ? i915_gem_execbuffer+0x2d0/0x2d0
[13703.383117] [<
ffffffff810c3df0>] ? hrtimer_start_range_ns+0x1a0/0x310
[13703.383128] [<
ffffffff8117d32f>] do_vfs_ioctl+0x8f/0x5c0
[13703.383140] [<
ffffffff810c60e8>] ? SyS_timer_settime+0x118/0x1a0
[13703.383150] [<
ffffffff8117d89c>] SyS_ioctl+0x3c/0x70
[13703.383162] [<
ffffffff815a07a4>] entry_SYSCALL_64_fastpath+0x17/0x98
[13703.383172] Code: 49 39 c6 48 8d 70 e8 48 8d 5f e8 75 16 eb 47 48 8d 43 18 48 8b 53 18 48 89 de 49 39 c6 48 8d 5a e8 74 33 48 8b 56 08 48 8b 46 10 <48> 89 42 08 48 89 10 f6 46 38 01 48 89 4e 08 4c 89 7e 10 74 cf
[13703.383557] RIP [<
ffffffff813b3534>] i915_gem_request_retire+0x2b4/0x320
[13703.383570] RSP <
ffffc90002f1bbc8>
[13703.383586] ---[ end trace
fd24176416ba6982 ]---
This is fixed by using the kref_get_unless_zero() as a full memory
barrier to validate the fence is still the current exclusive fence before
returning it back to the caller. (Note the fix only requires using
dma_fence_get_rcu() and correct handling, but we may as well use the
helper rather than inline equivalent code.)
Note: Issue can only be hit with the i915 driver.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal@linaro.org
Fixes: d07f0e59b2c7 ("drm/i915: Move GEM activity tracking into a common struct reservation_object")
Reviewed-by: Christian König <christian.koenig@amd.com>.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161114115540.31155-1-chris@chris-wilson.co.uk