The information which is currently provided as a response to the "HL_INFO_HW_IDLE" IOCTL is merely a general boolean value. This patch extends it and provides also a bitmask that indicates which of the device engines are busy.
Unified · Split
| @@ -506,7 +506,7 @@ static int engines_show(struct seq_file *s, void *data) · 505 unmodified lines | |||
| 506 | struct hl_dbg_device_entry *dev_entry = entry->dev_entry; | 506 | struct hl_dbg_device_entry *dev_entry = entry->dev_entry; |
| 507 | struct hl_device *hdev = dev_entry->hdev; | 507 | struct hl_device *hdev = dev_entry->hdev; |
| 508 | 508 | ||
| 509 | hdev->asic_funcs->is_device_idle(hdev, s); | 509 | hdev->asic_funcs->is_device_idle(hdev, NULL, s); |
| 510 | 510 | ||
| 511 | return 0; | 511 | return 0; |
| 512 | } | 512 | } |
| @@ -2828,7 +2828,7 @@ static int goya_send_job_on_qman0(struct hl_device *hdev, struct hl_cs_job *job) · 2827 unmodified lines | |||
| 2828 | else | 2828 | else |
| 2829 | timeout = HL_DEVICE_TIMEOUT_USEC; | 2829 | timeout = HL_DEVICE_TIMEOUT_USEC; |
| 2830 | 2830 | ||
| 2831 | if (!hdev->asic_funcs->is_device_idle(hdev, NULL)) { | 2831 | if (!hdev->asic_funcs->is_device_idle(hdev, NULL, NULL)) { |
| 2832 | dev_err_ratelimited(hdev->dev, | 2832 | dev_err_ratelimited(hdev->dev, |
| 2833 | "Can't send KMD job on QMAN0 because the device is not idle\n"); | 2833 | "Can't send KMD job on QMAN0 because the device is not idle\n"); |
| 2834 | return -EBUSY; | 2834 | return -EBUSY; |
| @@ -4914,7 +4914,8 @@ int goya_armcp_info_get(struct hl_device *hdev) · 2079 unmodified lines | |||
| 4914 | return 0; | 4914 | return 0; |
| 4915 | } | 4915 | } |
| 4916 | 4916 | ||
| 4917 | static bool goya_is_device_idle(struct hl_device *hdev, struct seq_file *s) | 4917 | static bool goya_is_device_idle(struct hl_device *hdev, u32 *mask, |
| 4918 | struct seq_file *s) | ||
| 4918 | { | 4919 | { |
| 4919 | const char *fmt = "%-5d%-9s%#-14x%#-16x%#x\n"; | 4920 | const char *fmt = "%-5d%-9s%#-14x%#-16x%#x\n"; |
| 4920 | const char *dma_fmt = "%-5d%-9s%#-14x%#x\n"; | 4921 | const char *dma_fmt = "%-5d%-9s%#-14x%#x\n"; |
| @@ -4937,6 +4938,8 @@ static bool goya_is_device_idle(struct hl_device *hdev, struct seq_file *s) · 16 unmodified lines | |||
| 4937 | IS_DMA_IDLE(dma_core_sts0); | 4938 | IS_DMA_IDLE(dma_core_sts0); |
| 4938 | is_idle &= is_eng_idle; | 4939 | is_idle &= is_eng_idle; |
| 4939 | 4940 | ||
| 4941 | if (mask) | ||
| 4942 | *mask |= !is_eng_idle << (GOYA_ENGINE_ID_DMA_0 + i); | ||
| 4940 | if (s) | 4943 | if (s) |
| 4941 | seq_printf(s, dma_fmt, i, is_eng_idle ? "Y" : "N", | 4944 | seq_printf(s, dma_fmt, i, is_eng_idle ? "Y" : "N", |
| 4942 | qm_glbl_sts0, dma_core_sts0); | 4945 | qm_glbl_sts0, dma_core_sts0); |
| @@ -4958,6 +4961,8 @@ static bool goya_is_device_idle(struct hl_device *hdev, struct seq_file *s) · 15 unmodified lines | |||
| 4958 | IS_TPC_IDLE(tpc_cfg_sts); | 4961 | IS_TPC_IDLE(tpc_cfg_sts); |
| 4959 | is_idle &= is_eng_idle; | 4962 | is_idle &= is_eng_idle; |
| 4960 | 4963 | ||
| 4964 | if (mask) | ||
| 4965 | *mask |= !is_eng_idle << (GOYA_ENGINE_ID_TPC_0 + i); | ||
| 4961 | if (s) | 4966 | if (s) |
| 4962 | seq_printf(s, fmt, i, is_eng_idle ? "Y" : "N", | 4967 | seq_printf(s, fmt, i, is_eng_idle ? "Y" : "N", |
| 4963 | qm_glbl_sts0, cmdq_glbl_sts0, tpc_cfg_sts); | 4968 | qm_glbl_sts0, cmdq_glbl_sts0, tpc_cfg_sts); |
| @@ -4976,6 +4981,8 @@ static bool goya_is_device_idle(struct hl_device *hdev, struct seq_file *s) · 12 unmodified lines | |||
| 4976 | IS_MME_IDLE(mme_arch_sts); | 4981 | IS_MME_IDLE(mme_arch_sts); |
| 4977 | is_idle &= is_eng_idle; | 4982 | is_idle &= is_eng_idle; |
| 4978 | 4983 | ||
| 4984 | if (mask) | ||
| 4985 | *mask |= !is_eng_idle << GOYA_ENGINE_ID_MME_0; | ||
| 4979 | if (s) { | 4986 | if (s) { |
| 4980 | seq_printf(s, fmt, 0, is_eng_idle ? "Y" : "N", qm_glbl_sts0, | 4987 | seq_printf(s, fmt, 0, is_eng_idle ? "Y" : "N", qm_glbl_sts0, |
| 4981 | cmdq_glbl_sts0, mme_arch_sts); | 4988 | cmdq_glbl_sts0, mme_arch_sts); |
| @@ -557,7 +557,8 @@ struct hl_asic_funcs { · 556 unmodified lines | |||
| 557 | u32 asid, u64 va, u64 size); | 557 | u32 asid, u64 va, u64 size); |
| 558 | int (*send_heartbeat)(struct hl_device *hdev); | 558 | int (*send_heartbeat)(struct hl_device *hdev); |
| 559 | int (*debug_coresight)(struct hl_device *hdev, void *data); | 559 | int (*debug_coresight)(struct hl_device *hdev, void *data); |
| 560 | bool (*is_device_idle)(struct hl_device *hdev, struct seq_file *s); | 560 | bool (*is_device_idle)(struct hl_device *hdev, u32 *mask, |
| 561 | struct seq_file *s); | ||
| 561 | int (*soft_reset_late_init)(struct hl_device *hdev); | 562 | int (*soft_reset_late_init)(struct hl_device *hdev); |
| 562 | void (*hw_queues_lock)(struct hl_device *hdev); | 563 | void (*hw_queues_lock)(struct hl_device *hdev); |
| 563 | void (*hw_queues_unlock)(struct hl_device *hdev); | 564 | void (*hw_queues_unlock)(struct hl_device *hdev); |
| @@ -119,7 +119,8 @@ static int hw_idle(struct hl_device *hdev, struct hl_info_args *args) · 118 unmodified lines | |||
| 119 | if ((!max_size) || (!out)) | 119 | if ((!max_size) || (!out)) |
| 120 | return -EINVAL; | 120 | return -EINVAL; |
| 121 | 121 | ||
| 122 | hw_idle.is_idle = hdev->asic_funcs->is_device_idle(hdev, NULL); | 122 | hw_idle.is_idle = hdev->asic_funcs->is_device_idle(hdev, |
| 123 | &hw_idle.busy_engines_mask, NULL); | ||
| 123 | 124 | ||
| 124 | return copy_to_user(out, &hw_idle, | 125 | return copy_to_user(out, &hw_idle, |
| 125 | min((size_t) max_size, sizeof(hw_idle))) ? -EFAULT : 0; | 126 | min((size_t) max_size, sizeof(hw_idle))) ? -EFAULT : 0; |
| @@ -45,6 +45,30 @@ enum goya_queue_id { · 44 unmodified lines | |||
| 45 | GOYA_QUEUE_ID_SIZE | 45 | GOYA_QUEUE_ID_SIZE |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | /* | ||
| 49 | * Engine Numbering | ||
| 50 | * | ||
| 51 | * Used in the "busy_engines_mask" field in `struct hl_info_hw_idle' | ||
| 52 | */ | ||
| 53 | |||
| 54 | enum goya_engine_id { | ||
| 55 | GOYA_ENGINE_ID_DMA_0 = 0, | ||
| 56 | GOYA_ENGINE_ID_DMA_1, | ||
| 57 | GOYA_ENGINE_ID_DMA_2, | ||
| 58 | GOYA_ENGINE_ID_DMA_3, | ||
| 59 | GOYA_ENGINE_ID_DMA_4, | ||
| 60 | GOYA_ENGINE_ID_MME_0, | ||
| 61 | GOYA_ENGINE_ID_TPC_0, | ||
| 62 | GOYA_ENGINE_ID_TPC_1, | ||
| 63 | GOYA_ENGINE_ID_TPC_2, | ||
| 64 | GOYA_ENGINE_ID_TPC_3, | ||
| 65 | GOYA_ENGINE_ID_TPC_4, | ||
| 66 | GOYA_ENGINE_ID_TPC_5, | ||
| 67 | GOYA_ENGINE_ID_TPC_6, | ||
| 68 | GOYA_ENGINE_ID_TPC_7, | ||
| 69 | GOYA_ENGINE_ID_SIZE | ||
| 70 | }; | ||
| 71 | |||
| 48 | enum hl_device_status { | 72 | enum hl_device_status { |
| 49 | HL_DEVICE_STATUS_OPERATIONAL, | 73 | HL_DEVICE_STATUS_OPERATIONAL, |
| 50 | HL_DEVICE_STATUS_IN_RESET, | 74 | HL_DEVICE_STATUS_IN_RESET, |
| @@ -86,7 +110,11 @@ struct hl_info_dram_usage { · 35 unmodified lines | |||
| 86 | 110 | ||
| 87 | struct hl_info_hw_idle { | 111 | struct hl_info_hw_idle { |
| 88 | __u32 is_idle; | 112 | __u32 is_idle; |
| 89 | __u32 pad; | 113 | /* |
| 114 | * Bitmask of busy engines. | ||
| 115 | * Bits definition is according to `enum <chip>_enging_id'. | ||
| 116 | */ | ||
| 117 | __u32 busy_engines_mask; | ||
| 90 | }; | 118 | }; |
| 91 | 119 | ||
| 92 | struct hl_info_device_status { | 120 | struct hl_info_device_status { |