]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
habanalabs: fix host memory polling in BE architecture
authorBen Segal <bpsegal20@gmail.com>
Thu, 18 Jul 2019 12:27:00 +0000 (12:27 +0000)
committerOded Gabbay <oded.gabbay@gmail.com>
Mon, 29 Jul 2019 08:40:25 +0000 (11:40 +0300)
This patch fix a bug in the host memory polling macro. The bug is that the
memory being polled can be written by the device, which always writes it
in LE. However, if the host is running Linux in BE mode, we need to
convert the value that was written by the device before matching it to the
required value that the caller has given to the macro.

Signed-off-by: Ben Segal <bpsegal20@gmail.com>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/misc/habanalabs/command_submission.c
drivers/misc/habanalabs/firmware_if.c
drivers/misc/habanalabs/goya/goya.c
drivers/misc/habanalabs/habanalabs.h

index 6ad83d5ef4b006759351962d54795b724e0dc590..f00d1c32f6d6f83a3e523abc0d8301057d6cadc5 100644 (file)
@@ -683,7 +683,7 @@ int hl_cs_ioctl(struct hl_fpriv *hpriv, void *data)
 
                rc = hl_poll_timeout_memory(hdev,
                        &ctx->thread_ctx_switch_wait_token, tmp, (tmp == 1),
-                       100, jiffies_to_usecs(hdev->timeout_jiffies));
+                       100, jiffies_to_usecs(hdev->timeout_jiffies), false);
 
                if (rc == -ETIMEDOUT) {
                        dev_err(hdev->dev,
index 61112eda4dd226e12371ef24d5b38e84ebcbc8ca..ea2ca67fbfbfaf9fc01f8160b539a57149bd8e0f 100644 (file)
@@ -97,7 +97,8 @@ int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg,
        }
 
        rc = hl_poll_timeout_memory(hdev, &pkt->fence, tmp,
-                               (tmp == ARMCP_PACKET_FENCE_VAL), 1000, timeout);
+                               (tmp == ARMCP_PACKET_FENCE_VAL), 1000,
+                               timeout, true);
 
        hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
 
index 1a2c062a57d4de9d09e41a36914921251e47b072..a0e181714891f46f8f19f6e5539aad3a670df9ab 100644 (file)
@@ -2864,7 +2864,8 @@ static int goya_send_job_on_qman0(struct hl_device *hdev, struct hl_cs_job *job)
        }
 
        rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp,
-                               (tmp == GOYA_QMAN0_FENCE_VAL), 1000, timeout);
+                               (tmp == GOYA_QMAN0_FENCE_VAL), 1000,
+                               timeout, true);
 
        hl_hw_queue_inc_ci_kernel(hdev, GOYA_QUEUE_ID_DMA_0);
 
@@ -2945,7 +2946,7 @@ int goya_test_queue(struct hl_device *hdev, u32 hw_queue_id)
        }
 
        rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp, (tmp == fence_val),
-                                       1000, GOYA_TEST_QUEUE_WAIT_USEC);
+                                       1000, GOYA_TEST_QUEUE_WAIT_USEC, true);
 
        hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
 
index 10da9940ee0dd1ac2cbad4291dee1d297897877a..6a4c64b97f3863bc8f968c0fcdf0f5e38ce3ea16 100644 (file)
@@ -1062,9 +1062,17 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
 /*
  * address in this macro points always to a memory location in the
  * host's (server's) memory. That location is updated asynchronously
- * either by the direct access of the device or by another core
+ * either by the direct access of the device or by another core.
+ *
+ * To work both in LE and BE architectures, we need to distinguish between the
+ * two states (device or another core updates the memory location). Therefore,
+ * if mem_written_by_device is true, the host memory being polled will be
+ * updated directly by the device. If false, the host memory being polled will
+ * be updated by host CPU. Required so host knows whether or not the memory
+ * might need to be byte-swapped before returning value to caller.
  */
-#define hl_poll_timeout_memory(hdev, addr, val, cond, sleep_us, timeout_us) \
+#define hl_poll_timeout_memory(hdev, addr, val, cond, sleep_us, timeout_us, \
+                               mem_written_by_device) \
 ({ \
        ktime_t __timeout; \
        /* timeout should be longer when working with simulator */ \
@@ -1077,10 +1085,14 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
                /* Verify we read updates done by other cores or by device */ \
                mb(); \
                (val) = *((u32 *) (uintptr_t) (addr)); \
+               if (mem_written_by_device) \
+                       (val) = le32_to_cpu(val); \
                if (cond) \
                        break; \
                if (timeout_us && ktime_compare(ktime_get(), __timeout) > 0) { \
                        (val) = *((u32 *) (uintptr_t) (addr)); \
+                       if (mem_written_by_device) \
+                               (val) = le32_to_cpu(val); \
                        break; \
                } \
                if (sleep_us) \