From ae8e0690e84791df03b8030fabd5610f10c40573 Mon Sep 17 00:00:00 2001 From: Jason Mei Date: Sat, 3 Aug 2024 21:10:33 +0800 Subject: [PATCH] host1x-fence: Remove callback and cancel fence Issue: [k6.8/l4t/] ap_compute_level1_test is failing in GVS [ 2720.076010] Call trace: [ 2720.078520] kmalloc_trace+0xa8/0x270 [ 2720.082275] 0xffffcb8bdce9f9ac [ 2720.085497] __arm64_sys_ioctl+0xa8/0x100 [ 2720.089618] invoke_syscall+0x44/0x128 [ 2720.093466] el0_svc_common.constprop.0+0x3c/0xec [ 2720.098290] do_el0_svc+0x1c/0x2c [ 2720.101690] el0_svc+0x30/0xbc [ 2720.104831] el0t_64_sync_handler+0x13c/0x158 [ 2720.109304] el0t_64_sync+0x16c/0x170 [ 2720.113060] Code: aa1403e1 f9405e64 8b000282 dac00c42 (f8606a95) [ 2720.119320] ---[ end trace 0000000000000000 ]--- [ 2720.212951] Kernel panic - not syncing: Oops: Fatal exception Fix: Remove callback and cancel fence in poll Bug 4779016 Change-Id: I49f2a67cdcb7e8882664fa203fcc90adf8c9341a Signed-off-by: Jason Mei Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3187581 GVS: buildbot_gerritrpt Reviewed-by: Mikko Perttunen Reviewed-by: svcacv --- drivers/gpu/host1x-fence/dev.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/host1x-fence/dev.c b/drivers/gpu/host1x-fence/dev.c index a6988b0f..fa95e28e 100644 --- a/drivers/gpu/host1x-fence/dev.c +++ b/drivers/gpu/host1x-fence/dev.c @@ -209,7 +209,12 @@ static int host1x_pollfd_release(struct inode *inode, struct file *file) if (pfd_fence->callback_set) { if (dma_fence_remove_callback(pfd_fence->fence, &pfd_fence->callback)) host1x_fence_cancel(pfd_fence->fence); + pfd_fence->callback_set = false; } + /*The lock/unlock just ensures that the callback execution has finished*/ + spin_lock(pfd_fence->fence->lock); + spin_unlock(pfd_fence->fence->lock); + dma_fence_put(pfd_fence->fence); kfree(pfd_fence); } @@ -234,6 +239,17 @@ static unsigned int host1x_pollfd_poll(struct file *file, poll_table *wait) list_for_each_entry_safe(pfd_fence, pfd_fence_temp, &pollfd->fences, list) { if (dma_fence_is_signaled(pfd_fence->fence)) { mask = POLLPRI | POLLIN; + + if (pfd_fence->callback_set) { + if (dma_fence_remove_callback(pfd_fence->fence, + &pfd_fence->callback)) + host1x_fence_cancel(pfd_fence->fence); + pfd_fence->callback_set = false; + } + /*The lock/unlock just ensures that the callback execution has finished*/ + spin_lock(pfd_fence->fence->lock); + spin_unlock(pfd_fence->fence->lock); + dma_fence_put(pfd_fence->fence); list_del(&pfd_fence->list); kfree(pfd_fence);