Hi, all
Thanks a lot for all of your patience.
Our internal team has located this issue.
This issue is caused by the lock taken from the IRQ context in host1x_intr_handle_interrupt() racing with host1x_pollfd_poll() from the process context.
To fix this issue, please build the custom kernel with the below patch.
diff --git a/drivers/gpu/host1x-fence/dev.c b/drivers/gpu/host1x-fence/dev.c
index 2229978..7396c32 100644
--- a/drivers/gpu/host1x-fence/dev.c
+++ b/drivers/gpu/host1x-fence/dev.c
@@ -204,6 +204,7 @@
{
struct host1x_pollfd *pollfd = file->private_data;
struct host1x_pollfd_fence *pfd_fence, *pfd_fence_temp;
+ unsigned long irqflags;
mutex_lock(&pollfd->lock);
@@ -214,8 +215,8 @@
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);
+ spin_lock_irqsave(pfd_fence->fence->lock, irqflags);
+ spin_unlock_irqrestore(pfd_fence->fence->lock, irqflags);
dma_fence_put(pfd_fence->fence);
kfree(pfd_fence);
@@ -233,6 +234,7 @@
struct host1x_pollfd *pollfd = file->private_data;
struct host1x_pollfd_fence *pfd_fence, *pfd_fence_temp;
unsigned int mask = 0;
+ unsigned long irqflags;
poll_wait(file, &pollfd->wq, wait);
@@ -249,8 +251,8 @@
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);
+ spin_lock_irqsave(pfd_fence->fence->lock, irqflags);
+ spin_unlock_irqrestore(pfd_fence->fence->lock, irqflags);
dma_fence_put(pfd_fence->fence);
list_del(&pfd_fence->list);
An example to build custom kernel can be found in this comment.
Thanks.