accel/habanalabs: capture interrupt timestamp in handler
authorOfir Bitton <obitton@habana.ai>
Wed, 1 Feb 2023 17:35:54 +0000 (19:35 +0200)
committerOded Gabbay <ogabbay@kernel.org>
Wed, 15 Mar 2023 11:29:13 +0000 (13:29 +0200)
In order for interrupt timestamp to be more accurate we should
capture it during the interrupt handling rather than in threaded
irq context.

Signed-off-by: Ofir Bitton <obitton@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
drivers/accel/habanalabs/common/habanalabs.h
drivers/accel/habanalabs/common/irq.c

index 5624ea19ec0bb674d5d860f3c84a3a532bdeb541..24ad152720406c933f1e110814279f100ee19802 100644 (file)
@@ -1107,6 +1107,7 @@ enum hl_user_interrupt_type {
  * @type: user interrupt type
  * @wait_list_head: head to the list of user threads pending on this interrupt
  * @wait_list_lock: protects wait_list_head
+ * @timestamp: last timestamp taken upon interrupt
  * @interrupt_id: msix interrupt id
  */
 struct hl_user_interrupt {
@@ -1114,6 +1115,7 @@ struct hl_user_interrupt {
        enum hl_user_interrupt_type     type;
        struct list_head                wait_list_head;
        spinlock_t                      wait_list_lock;
+       ktime_t                         timestamp;
        u32                             interrupt_id;
 };
 
index c61c9a294ab83ea34c17b49a1717b31c71b1c279..716228291b4644330b41facf7a1fc2c2de9f6601 100644 (file)
@@ -280,7 +280,6 @@ static void handle_user_interrupt(struct hl_device *hdev, struct hl_user_interru
        struct list_head *ts_reg_free_list_head = NULL;
        struct timestamp_reg_work_obj *job;
        bool reg_node_handle_fail = false;
-       ktime_t now = ktime_get();
        int rc;
 
        /* For registration nodes:
@@ -303,13 +302,13 @@ static void handle_user_interrupt(struct hl_device *hdev, struct hl_user_interru
                        if (pend->ts_reg_info.buf) {
                                if (!reg_node_handle_fail) {
                                        rc = handle_registration_node(hdev, pend,
-                                                               &ts_reg_free_list_head, now);
+                                                       &ts_reg_free_list_head, intr->timestamp);
                                        if (rc)
                                                reg_node_handle_fail = true;
                                }
                        } else {
                                /* Handle wait target value node */
-                               pend->fence.timestamp = now;
+                               pend->fence.timestamp = intr->timestamp;
                                complete_all(&pend->fence.completion);
                        }
                }
@@ -335,6 +334,10 @@ static void handle_user_interrupt(struct hl_device *hdev, struct hl_user_interru
  */
 irqreturn_t hl_irq_handler_user_interrupt(int irq, void *arg)
 {
+       struct hl_user_interrupt *user_int = arg;
+
+       user_int->timestamp = ktime_get();
+
        return IRQ_WAKE_THREAD;
 }