summaryrefslogtreecommitdiff
path: root/drivers/accel
diff options
context:
space:
mode:
authorfarah kassabri <fkassabri@habana.ai>2023-08-24 15:45:21 +0300
committerOded Gabbay <ogabbay@kernel.org>2023-10-09 12:37:22 +0300
commit0165994c215f321e2d055368f89b424756e340eb (patch)
tree920bff6b1bf4a41a98244d73211c5335ed302186 /drivers/accel
parentd89d329a2bb39e0e0ad37d7a40302d0fa7e8851a (diff)
accel/habanalabs: fix bug in timestamp interrupt handling
There is a potential race between user thread seeking to re-use a timestamp record with new interrupt id, while this record is still in the middle of interrupt handling and it is about to be freed. Imagine the driver set the record in_use to 0 and only then fill the free_node information. This might lead to unpleasant scenario where the new registration thread detects the record as free to use, and change the cq buff address. That will cause the free_node to get the wrong buffer address to put refcount to. Signed-off-by: farah kassabri <fkassabri@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Diffstat (limited to 'drivers/accel')
-rw-r--r--drivers/accel/habanalabs/common/irq.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/accel/habanalabs/common/irq.c b/drivers/accel/habanalabs/common/irq.c
index f6b6c54bc868..058f27040805 100644
--- a/drivers/accel/habanalabs/common/irq.c
+++ b/drivers/accel/habanalabs/common/irq.c
@@ -259,8 +259,6 @@ static int handle_registration_node(struct hl_device *hdev, struct hl_user_pendi
dev_dbg(hdev->dev, "Irq handle: Timestamp record (%p) ts cb address (%p), interrupt_id: %u\n",
pend, pend->ts_reg_info.timestamp_kernel_addr, interrupt_id);
- /* Mark kernel CB node as free */
- pend->ts_reg_info.in_use = false;
list_del(&pend->wait_list_node);
/* Putting the refcount for ts_buff and cq_cb objects will be handled
@@ -270,6 +268,9 @@ static int handle_registration_node(struct hl_device *hdev, struct hl_user_pendi
free_node->cq_cb = pend->ts_reg_info.cq_cb;
list_add(&free_node->free_objects_node, *free_list);
+ /* Mark TS record as free */
+ pend->ts_reg_info.in_use = false;
+
return 0;
}