drm/xe: Add sysfs entries for engines under its GT
authorTejas Upadhyay <tejas.upadhyay@intel.com>
Fri, 4 Aug 2023 11:47:56 +0000 (17:17 +0530)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:39:21 +0000 (11:39 -0500)
Add engines sysfs directory under its GT and
create sub directory for all engine class
(note its not per instance) present on GT.

For example,
DUT# cat /sys/class/drm/cardX/device/tileN/gtN/engines/
bcs/ ccs/

V9 :
   - Add missing drmm_add_action_or_reset
V8 :
   - Rebase
V7 :
   - Remove xe_gt.h from .h and include in .c - Matt
V6 :
   - Add kernel doc and arrange file in make file by alphabet - Matt
V5 :
   - replace xe_engine with xe_hw_engine - Matt
V4 :
   - Rebase to resolve conflicts - CI
V3 :
   - Move code in its own file
   - Rename API name
V2 :
   - Correct class mask logic - Himal
   - Remove extra parenthesis

Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/Makefile
drivers/gpu/drm/xe/xe_gt.c
drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c [new file with mode: 0644]
drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h [new file with mode: 0644]

index f8d63c9b97d5b53a3bbc35be0f478c4c3538cc8d..2373832f932ec23dc9e248018d44ebc08c2fc2b0 100644 (file)
@@ -78,6 +78,7 @@ xe-y += xe_bb.o \
        xe_guc_pc.o \
        xe_guc_submit.o \
        xe_hw_engine.o \
+       xe_hw_engine_class_sysfs.o \
        xe_hw_fence.o \
        xe_huc.o \
        xe_huc_debugfs.o \
index 3077faa1e7923f5a163edc5a2592e0d5aa96c8c6..13320af4ddd3e81d33c919de465fbeaacda52e9c 100644 (file)
@@ -28,6 +28,7 @@
 #include "xe_gt_topology.h"
 #include "xe_guc_exec_queue_types.h"
 #include "xe_hw_fence.h"
+#include "xe_hw_engine_class_sysfs.h"
 #include "xe_irq.h"
 #include "xe_lrc.h"
 #include "xe_map.h"
@@ -323,6 +324,12 @@ static int gt_fw_domain_init(struct xe_gt *gt)
        if (err)
                goto err_force_wake;
 
+       err = xe_hw_engine_class_sysfs_init(gt);
+       if (err)
+               drm_warn(&gt_to_xe(gt)->drm,
+                        "failed to register engines sysfs directory, err: %d\n",
+                        err);
+
        err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
        XE_WARN_ON(err);
        xe_device_mem_access_put(gt_to_xe(gt));
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
new file mode 100644 (file)
index 0000000..470a8c3
--- /dev/null
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <drm/drm_managed.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+#include "xe_gt.h"
+#include "xe_hw_engine_class_sysfs.h"
+
+#define MAX_ENGINE_CLASS_NAME_LEN    16
+static void kobj_xe_hw_engine_release(struct kobject *kobj)
+{
+       kfree(kobj);
+}
+
+static const struct kobj_type kobj_xe_hw_engine_type = {
+       .release = kobj_xe_hw_engine_release,
+       .sysfs_ops = &kobj_sysfs_ops
+};
+
+static void kobj_xe_hw_engine_fini(struct drm_device *drm, void *arg)
+{
+       struct kobject *kobj = arg;
+
+       kobject_put(kobj);
+}
+
+       static struct kobject *
+kobj_xe_hw_engine(struct xe_device *xe, struct kobject *parent, char *name)
+{
+       struct kobject *kobj;
+       int err = 0;
+
+       kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
+       if (!kobj)
+               return NULL;
+
+       kobject_init(kobj, &kobj_xe_hw_engine_type);
+       if (kobject_add(kobj, parent, "%s", name)) {
+               kobject_put(kobj);
+               return NULL;
+       }
+
+       err = drmm_add_action_or_reset(&xe->drm, kobj_xe_hw_engine_fini,
+                                      kobj);
+       if (err)
+               drm_warn(&xe->drm,
+                        "%s: drmm_add_action_or_reset failed, err: %d\n",
+                        __func__, err);
+
+       return kobj;
+}
+
+static void xe_hw_engine_sysfs_kobj_release(struct kobject *kobj)
+{
+       kfree(kobj);
+}
+
+static const struct kobj_type xe_hw_engine_sysfs_kobj_type = {
+       .release = xe_hw_engine_sysfs_kobj_release,
+       .sysfs_ops = &kobj_sysfs_ops,
+};
+
+static void hw_engine_class_sysfs_fini(struct drm_device *drm, void *arg)
+{
+       struct kobject *kobj = arg;
+
+       kobject_put(kobj);
+}
+
+/**
+ * xe_hw_engine_class_sysfs_init - Init HW engine classes on GT.
+ * @gt: Xe GT.
+ *
+ * This routine creates sysfs for HW engine classes and adds methods
+ * to get/set different scheduling properties for HW engines class.
+ *
+ * Returns: Returns error value for failure and 0 for success.
+ */
+int xe_hw_engine_class_sysfs_init(struct xe_gt *gt)
+{
+       struct xe_device *xe = gt_to_xe(gt);
+       struct xe_hw_engine *hwe;
+       enum xe_hw_engine_id id;
+       struct kobject *kobj;
+       u16 class_mask = 0;
+       int err = 0;
+
+       kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
+       if (!kobj)
+               return -ENOMEM;
+
+       kobject_init(kobj, &xe_hw_engine_sysfs_kobj_type);
+
+       err = kobject_add(kobj, gt->sysfs, "engines");
+       if (err) {
+               kobject_put(kobj);
+               return err;
+       }
+
+       for_each_hw_engine(hwe, gt, id) {
+               char name[MAX_ENGINE_CLASS_NAME_LEN];
+               struct kobject *khwe;
+
+               if (hwe->class == XE_ENGINE_CLASS_OTHER ||
+                   hwe->class == XE_ENGINE_CLASS_MAX)
+                       continue;
+
+               if ((class_mask >> hwe->class) & 1)
+                       continue;
+
+               class_mask |= 1 << hwe->class;
+
+               switch (hwe->class) {
+               case XE_ENGINE_CLASS_RENDER:
+                       strcpy(name, "rcs");
+                       break;
+               case XE_ENGINE_CLASS_VIDEO_DECODE:
+                       strcpy(name, "vcs");
+                       break;
+               case XE_ENGINE_CLASS_VIDEO_ENHANCE:
+                       strcpy(name, "vecs");
+                       break;
+               case XE_ENGINE_CLASS_COPY:
+                       strcpy(name, "bcs");
+                       break;
+               case XE_ENGINE_CLASS_COMPUTE:
+                       strcpy(name, "ccs");
+                       break;
+               default:
+                       kobject_put(kobj);
+                       return -EINVAL;
+               }
+
+               khwe = kobj_xe_hw_engine(xe, kobj, name);
+               if (!khwe) {
+                       kobject_put(kobj);
+                       return -EINVAL;
+               }
+       }
+
+       err = drmm_add_action_or_reset(&xe->drm, hw_engine_class_sysfs_fini,
+                                      kobj);
+       if (err)
+               drm_warn(&xe->drm,
+                        "%s: drmm_add_action_or_reset failed, err: %d\n",
+                        __func__, err);
+
+       return err;
+}
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h
new file mode 100644 (file)
index 0000000..b3916c3
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _XE_ENGINE_CLASS_SYSFS_H_
+#define _XE_ENGINE_CLASS_SYSFS_H__
+
+struct xe_gt;
+
+int xe_hw_engine_class_sysfs_init(struct xe_gt *gt);
+
+#endif