habanalabs: expose sync manager resources allocation in INFO IOCTL
authorOfir Bitton <obitton@habana.ai>
Sun, 19 Jul 2020 08:08:09 +0000 (11:08 +0300)
committerOded Gabbay <oded.gabbay@gmail.com>
Tue, 22 Sep 2020 15:49:49 +0000 (18:49 +0300)
Although the driver defines the first user-available sync manager object
and monitor in habanalabs.h, we would like to also expose this information
via the INFO IOCTL so the runtime can get this information dynamically.
This is because in future ASICs we won't need to define it statically.

Signed-off-by: Ofir Bitton <obitton@habana.ai>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/misc/habanalabs/common/habanalabs.h
drivers/misc/habanalabs/common/habanalabs_ioctl.c
drivers/misc/habanalabs/gaudi/gaudi.c
include/uapi/misc/habanalabs.h

index 2c9fcb5132156d9fa53f1184c384fef01b8e4832..caced12f278facf510c28d6e7fcb796ae6f432fc 100644 (file)
@@ -65,6 +65,8 @@
 
 #define HL_PCI_NUM_BARS                        6
 
+#define HL_MAX_DCORES                  4
+
 /**
  * struct pgt_info - MMU hop page info.
  * @node: hash linked-list node for the pgts shadow hash of pgts.
@@ -291,6 +293,8 @@ struct hl_mmu_properties {
  * @max_queues: maximum amount of queues in the system
  * @sync_stream_first_sob: first sync object available for sync stream use
  * @sync_stream_first_mon: first monitor available for sync stream use
+ * @first_available_user_sob: first sob available for the user
+ * @first_available_user_mon: first monitor available for the user
  * @tpc_enabled_mask: which TPCs are enabled.
  * @completion_queues_count: number of completion queues.
  */
@@ -337,6 +341,8 @@ struct asic_fixed_properties {
        u32                             max_queues;
        u16                             sync_stream_first_sob;
        u16                             sync_stream_first_mon;
+       u16                             first_available_user_sob[HL_MAX_DCORES];
+       u16                             first_available_user_mon[HL_MAX_DCORES];
        u8                              tpc_enabled_mask;
        u8                              completion_queues_count;
 };
index 4d838b1a3bbee5a20cbcbaed4b5af2b9a60174e5..fe6c5534d378bbe56491f7ba622c69a6b888a463 100644 (file)
@@ -8,6 +8,7 @@
 #include <uapi/misc/habanalabs.h>
 #include "habanalabs.h"
 
+#include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
@@ -314,7 +315,7 @@ static int clk_throttle_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
 static int cs_counters_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
 {
        struct hl_device *hdev = hpriv->hdev;
-       struct hl_info_cs_counters cs_counters = {0};
+       struct hl_info_cs_counters cs_counters = { {0} };
        u32 max_size = args->return_size;
        void __user *out = (void __user *) (uintptr_t) args->return_pointer;
 
@@ -332,6 +333,30 @@ static int cs_counters_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
                min((size_t) max_size, sizeof(cs_counters))) ? -EFAULT : 0;
 }
 
+static int sync_manager_info(struct hl_fpriv *hpriv, struct hl_info_args *args)
+{
+       struct hl_device *hdev = hpriv->hdev;
+       struct asic_fixed_properties *prop = &hdev->asic_prop;
+       struct hl_info_sync_manager sm_info = {0};
+       u32 max_size = args->return_size;
+       void __user *out = (void __user *) (uintptr_t) args->return_pointer;
+
+       if ((!max_size) || (!out))
+               return -EINVAL;
+
+       if (args->dcore_id >= HL_MAX_DCORES)
+               return -EINVAL;
+
+       sm_info.first_available_sync_object =
+                       prop->first_available_user_sob[args->dcore_id];
+       sm_info.first_available_monitor =
+                       prop->first_available_user_mon[args->dcore_id];
+
+
+       return copy_to_user(out, &sm_info, min_t(size_t, (size_t) max_size,
+                       sizeof(sm_info))) ? -EFAULT : 0;
+}
+
 static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
                                struct device *dev)
 {
@@ -401,6 +426,9 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data,
        case HL_INFO_CLK_THROTTLE_REASON:
                return clk_throttle_info(hpriv, args);
 
+       case HL_INFO_SYNC_MANAGER:
+               return sync_manager_info(hpriv, args);
+
        default:
                dev_err(dev, "Invalid request %d\n", args->op);
                rc = -ENOTTY;
index adb5c5594ac1a47230e1980050c7e8cb1234af1d..45ba3a5f5b141da0f0eb223b4fea1e0155ecd5e4 100644 (file)
@@ -367,6 +367,7 @@ static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid);
 static int gaudi_get_fixed_properties(struct hl_device *hdev)
 {
        struct asic_fixed_properties *prop = &hdev->asic_prop;
+       u32 num_sync_stream_queues = 0;
        int i;
 
        prop->max_queues = GAUDI_QUEUE_ID_SIZE;
@@ -383,6 +384,7 @@ static int gaudi_get_fixed_properties(struct hl_device *hdev)
                        prop->hw_queues_props[i].driver_only = 0;
                        prop->hw_queues_props[i].requires_kernel_cb = 1;
                        prop->hw_queues_props[i].supports_sync_stream = 1;
+                       num_sync_stream_queues++;
                } else if (gaudi_queue_type[i] == QUEUE_TYPE_CPU) {
                        prop->hw_queues_props[i].type = QUEUE_TYPE_CPU;
                        prop->hw_queues_props[i].driver_only = 1;
@@ -469,6 +471,11 @@ static int gaudi_get_fixed_properties(struct hl_device *hdev)
 
        prop->max_pending_cs = GAUDI_MAX_PENDING_CS;
 
+       prop->first_available_user_sob[HL_GAUDI_WS_DCORE] =
+                       num_sync_stream_queues * HL_RSVD_SOBS;
+       prop->first_available_user_mon[HL_GAUDI_WS_DCORE] =
+                       num_sync_stream_queues * HL_RSVD_MONS;
+
        return 0;
 }
 
index ee13b919db35a8c238847d3864fc97358eb353a9..ca6dc1fc250ecd2e34081d446575c5df4acbfc1f 100644 (file)
@@ -266,6 +266,7 @@ enum hl_device_status {
  * HL_INFO_CS_COUNTERS   - Retrieve command submission counters
  * HL_INFO_PCI_COUNTERS  - Retrieve PCI counters
  * HL_INFO_CLK_THROTTLE_REASON - Retrieve clock throttling reason
+ * HL_INFO_SYNC_MANAGER  - Retrieve sync manager info per dcore
  */
 #define HL_INFO_HW_IP_INFO             0
 #define HL_INFO_HW_EVENTS              1
@@ -280,6 +281,7 @@ enum hl_device_status {
 #define HL_INFO_CS_COUNTERS            11
 #define HL_INFO_PCI_COUNTERS           12
 #define HL_INFO_CLK_THROTTLE_REASON    13
+#define HL_INFO_SYNC_MANAGER           14
 
 #define HL_INFO_VERSION_MAX_LEN        128
 #define HL_INFO_CARD_NAME_MAX_LEN      16
@@ -367,6 +369,16 @@ struct hl_info_clk_throttle {
        __u32 clk_throttling_reason;
 };
 
+/**
+ * struct hl_info_sync_manager - sync manager information
+ * @first_available_sync_object: first available sob
+ * @first_available_monitor: first available monitor
+ */
+struct hl_info_sync_manager {
+       __u32 first_available_sync_object;
+       __u32 first_available_monitor;
+};
+
 /**
  * struct hl_info_cs_counters - command submission counters
  * @out_of_mem_drop_cnt: dropped due to memory allocation issue
@@ -386,6 +398,13 @@ struct hl_info_cs_counters {
        struct hl_cs_counters ctx_cs_counters;
 };
 
+enum gaudi_dcores {
+       HL_GAUDI_WS_DCORE,
+       HL_GAUDI_WN_DCORE,
+       HL_GAUDI_EN_DCORE,
+       HL_GAUDI_ES_DCORE
+};
+
 struct hl_info_args {
        /* Location of relevant struct in userspace */
        __u64 return_pointer;
@@ -402,6 +421,10 @@ struct hl_info_args {
        __u32 op;
 
        union {
+               /* Dcore id for which the information is relevant.
+                * For Gaudi refer to 'enum gaudi_dcores'
+                */
+               __u32 dcore_id;
                /* Context ID - Currently not in use */
                __u32 ctx_id;
                /* Period value for utilization rate (100ms - 1000ms, in 100ms