Skip to content

Commit 84190b9

Browse files
Farah-kassabriogabbay
authored andcommitted
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: farah kassabri <[email protected]> Reviewed-by: Oded Gabbay <[email protected]> Signed-off-by: Oded Gabbay <[email protected]>
1 parent 2ba0236 commit 84190b9

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

drivers/accel/habanalabs/common/command_submission.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,7 +3526,7 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_
35263526
u64 *timestamp)
35273527
{
35283528
struct hl_user_pending_interrupt *pend;
3529-
unsigned long timeout;
3529+
unsigned long timeout, flags;
35303530
u64 completion_value;
35313531
long completion_rc;
35323532
int rc = 0;
@@ -3546,9 +3546,9 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_
35463546
/* Add pending user interrupt to relevant list for the interrupt
35473547
* handler to monitor
35483548
*/
3549-
spin_lock(&interrupt->wait_list_lock);
3549+
spin_lock_irqsave(&interrupt->wait_list_lock, flags);
35503550
list_add_tail(&pend->list_node, &interrupt->wait_list_head);
3551-
spin_unlock(&interrupt->wait_list_lock);
3551+
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
35523552

35533553
/* We check for completion value as interrupt could have been received
35543554
* 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_
35793579
* If comparison fails, keep waiting until timeout expires
35803580
*/
35813581
if (completion_rc > 0) {
3582-
spin_lock(&interrupt->wait_list_lock);
3582+
spin_lock_irqsave(&interrupt->wait_list_lock, flags);
35833583
/* reinit_completion must be called before we check for user
35843584
* completion value, otherwise, if interrupt is received after
35853585
* the comparison and before the next wait_for_completion,
35863586
* we will reach timeout and fail
35873587
*/
35883588
reinit_completion(&pend->fence.completion);
3589-
spin_unlock(&interrupt->wait_list_lock);
3589+
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
35903590

35913591
if (copy_from_user(&completion_value, u64_to_user_ptr(user_address), 8)) {
35923592
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_
36233623
}
36243624

36253625
remove_pending_user_interrupt:
3626-
spin_lock(&interrupt->wait_list_lock);
3626+
spin_lock_irqsave(&interrupt->wait_list_lock, flags);
36273627
list_del(&pend->list_node);
3628-
spin_unlock(&interrupt->wait_list_lock);
3628+
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
36293629

36303630
*timestamp = ktime_to_ns(pend->fence.timestamp);
36313631

0 commit comments

Comments
 (0)