[Intel-gfx] [PATCH 4/4] drm/i915: expose engine availability through sysfs
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Thu Nov 16 16:00:04 UTC 2017
This enables userspace to discover the engines available on the GPU.
Here is the layout :
/sys/devices/pci0000:00/0000:00:02.0/drm/card0/engines
├── bcs0
│ ├── class
│ └── instance
├── rcs0
│ ├── class
│ └── instance
├── vcs0
│ ├── class
│ ├── hevc
│ └── instance
├── vcs1
│ ├── class
│ └── instance
└── vecs0
├── class
└── instance
Further capabilities can be added later as attributes of each engine.
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/i915_sysfs.c | 92 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +
3 files changed, 95 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 44b807421af8..c4f6e8ecf212 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2749,6 +2749,7 @@ struct drm_i915_private {
struct {
struct intel_topology_kobject kobj;
+ struct kobject engines_kobj;
struct sysfs_slice {
struct intel_slice_kobject kobj;
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 1d835f164d80..992aeaa91565 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -712,6 +712,92 @@ static void i915_teardown_topology_sysfs(struct drm_i915_private *dev_priv)
kobject_del(&topology_kobj->kobj);
}
+static struct attribute engine_instance_attr = {
+ .name = "instance",
+ .mode = 0444,
+};
+
+static struct attribute engine_class_attr = {
+ .name = "class",
+ .mode = 0444,
+};
+
+static struct attribute engine_hevc_attr = {
+ .name = "hevc",
+ .mode = 0444,
+};
+
+static ssize_t
+show_engine_attr(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ struct intel_engine_cs *engine =
+ container_of(kobj, struct intel_engine_cs, kobj);
+
+ if (attr == &engine_instance_attr)
+ return sprintf(buf, "%hhu\n", engine->uabi_id);
+ if (attr == &engine_class_attr)
+ return sprintf(buf, "%hhu\n", engine->uabi_class);
+ if (attr == &engine_hevc_attr)
+ return sprintf(buf, "%i\n", INTEL_GEN(engine->i915) >= 8);
+ return sprintf(buf, "\n");
+}
+
+static const struct sysfs_ops engine_ops = {
+ .show = show_engine_attr,
+};
+
+static struct kobj_type engine_type = {
+ .sysfs_ops = &engine_ops,
+};
+
+static int i915_setup_engines_sysfs(struct drm_i915_private *dev_priv)
+{
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ kobject_init_and_add(&dev_priv->topology.engines_kobj,
+ dev_priv->drm.primary->kdev->kobj.ktype,
+ &dev_priv->drm.primary->kdev->kobj,
+ "engines");
+
+ for_each_engine(engine, dev_priv, id) {
+ int ret;
+
+ kobject_init_and_add(&engine->kobj, &engine_type,
+ &dev_priv->topology.engines_kobj,
+ engine->name);
+
+ ret = sysfs_create_file(&engine->kobj, &engine_instance_attr);
+ if (ret)
+ return ret;
+ ret = sysfs_create_file(&engine->kobj, &engine_class_attr);
+ if (ret)
+ return ret;
+ if (engine->id == VCS) {
+ ret = sysfs_create_file(&engine->kobj, &engine_hevc_attr);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void i915_teardown_engines_sysfs(struct drm_i915_private *dev_priv)
+{
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ for_each_engine(engine, dev_priv, id) {
+ sysfs_remove_file(&engine->kobj, &engine_instance_attr);
+ sysfs_remove_file(&engine->kobj, &engine_class_attr);
+ sysfs_remove_file(&engine->kobj, &engine_hevc_attr);
+ }
+
+ kobject_get(&dev_priv->topology.engines_kobj);
+ kobject_del(&dev_priv->topology.engines_kobj);
+}
+
void i915_setup_sysfs(struct drm_i915_private *dev_priv)
{
struct device *kdev = dev_priv->drm.primary->kdev;
@@ -762,6 +848,10 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv)
if (ret)
DRM_ERROR("Topology sysfs setup failed\n");
+ ret = i915_setup_engines_sysfs(dev_priv);
+ if (ret)
+ DRM_ERROR("Engines sysfs setup failed\n");
+
i915_setup_error_capture(kdev);
}
@@ -771,6 +861,8 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
i915_teardown_error_capture(kdev);
+ i915_teardown_engines_sysfs(dev_priv);
+
i915_teardown_topology_sysfs(dev_priv);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 5f96533e5341..0243a9e620da 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -290,6 +290,8 @@ struct intel_engine_cs {
struct drm_i915_private *i915;
char name[INTEL_ENGINE_CS_MAX_NAME];
+ struct kobject kobj;
+
enum intel_engine_id id;
unsigned int hw_id;
unsigned int guc_id;
--
2.15.0
More information about the Intel-gfx
mailing list