Commit 84190b92 authored by farah kassabri's avatar farah kassabri Committed by Oded Gabbay

accel/habanalabs: fix bug in decoder wait for cs completion

The decoder interrupts are handled in the interrupt context
same as all user interrupts.
In such case, the wait list should be protected by
spin_lock_irqsave in order to avoid deadlock that might happen
with the user submission flow.
Signed-off-by: default avatarfarah kassabri <fkassabri@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 2ba0236f
......@@ -3526,7 +3526,7 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_
u64 *timestamp)
{
struct hl_user_pending_interrupt *pend;
unsigned long timeout;
unsigned long timeout, flags;
u64 completion_value;
long completion_rc;
int rc = 0;
......@@ -3546,9 +3546,9 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_
/* Add pending user interrupt to relevant list for the interrupt
* handler to monitor
*/
spin_lock(&interrupt->wait_list_lock);
spin_lock_irqsave(&interrupt->wait_list_lock, flags);
list_add_tail(&pend->list_node, &interrupt->wait_list_head);
spin_unlock(&interrupt->wait_list_lock);
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
/* We check for completion value as interrupt could have been received
* before we added the node to the wait list
......@@ -3579,14 +3579,14 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_
* If comparison fails, keep waiting until timeout expires
*/
if (completion_rc > 0) {
spin_lock(&interrupt->wait_list_lock);
spin_lock_irqsave(&interrupt->wait_list_lock, flags);
/* reinit_completion must be called before we check for user
* completion value, otherwise, if interrupt is received after
* the comparison and before the next wait_for_completion,
* we will reach timeout and fail
*/
reinit_completion(&pend->fence.completion);
spin_unlock(&interrupt->wait_list_lock);
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
if (copy_from_user(&completion_value, u64_to_user_ptr(user_address), 8)) {
dev_err(hdev->dev, "Failed to copy completion value from user\n");
......@@ -3623,9 +3623,9 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_
}
remove_pending_user_interrupt:
spin_lock(&interrupt->wait_list_lock);
spin_lock_irqsave(&interrupt->wait_list_lock, flags);
list_del(&pend->list_node);
spin_unlock(&interrupt->wait_list_lock);
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
*timestamp = ktime_to_ns(pend->fence.timestamp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment