[PATCH 1/3] drm/i915: Show engine flags in sysfs

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Tue Jun 2 15:42:45 UTC 2020


From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>

Show engine flags together with other per-engine data in sysfs.

We need this in order to be able to support heterogenous feature sets
between the engines which are currently not visible from the scheduler
caps interface.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/gt/sysfs_engines.c | 86 +++++++++++++++++++++----
 1 file changed, 75 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c
index 535cc1169e54..36e0c2fcebef 100644
--- a/drivers/gpu/drm/i915/gt/sysfs_engines.c
+++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c
@@ -48,6 +48,79 @@ inst_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 static struct kobj_attribute inst_attr =
 __ATTR(instance, 0444, inst_show, NULL);
 
+static ssize_t repr_trim(char *buf, ssize_t len)
+{
+	/* Trim off the trailing space and replace with a newline */
+	if (len > PAGE_SIZE)
+		len = PAGE_SIZE;
+	if (len > 0)
+		buf[len - 1] = '\n';
+
+	return len;
+}
+
+static const char * const engine_flags[] = {
+	[ilog2(I915_ENGINE_USING_CMD_PARSER)] = "cmdparser",
+	[ilog2(I915_ENGINE_SUPPORTS_STATS)] = "busy_stats",
+	[ilog2(I915_ENGINE_HAS_PREEMPTION)] = "preemption",
+	[ilog2(I915_ENGINE_HAS_SEMAPHORES)] = "semaphores",
+	[ilog2(I915_ENGINE_HAS_TIMESLICES)] = "timeslicing",
+	[ilog2(I915_ENGINE_NEEDS_BREADCRUMB_TASKLET)] = "", /* non-abi */
+	[ilog2(I915_ENGINE_IS_VIRTUAL)] = "", /* non-abi */
+	[ilog2(I915_ENGINE_HAS_RELATIVE_MMIO)] = "relative_mmio",
+	[ilog2(I915_ENGINE_REQUIRES_CMD_PARSER)] = "requires_cmdparser",
+};
+
+static ssize_t
+__flags_show(struct intel_engine_cs *engine, unsigned int flags, char *buf,
+	     bool show_unknown)
+{
+	const unsigned int count = ARRAY_SIZE(engine_flags);
+	unsigned int n;
+	ssize_t len;
+
+	BUILD_BUG_ON(!typecheck(typeof(flags), engine->flags));
+	BUILD_BUG_ON(count > BITS_PER_TYPE(typeof(flags)));
+
+	len = 0;
+	for_each_set_bit(n,
+			 (unsigned long *)&flags,
+			 show_unknown ? BITS_PER_TYPE(typeof(flags)) : count) {
+		if (n >= count || !engine_flags[n]) {
+			if (GEM_WARN_ON(show_unknown))
+				len += snprintf(buf + len, PAGE_SIZE - len,
+						"[%x] ", n);
+		} else {
+			if (strlen(engine_flags[n]))
+				len += snprintf(buf + len, PAGE_SIZE - len,
+						"%s ", engine_flags[n]);
+		}
+		if (GEM_WARN_ON(len >= PAGE_SIZE))
+			break;
+	}
+	return repr_trim(buf, len);
+}
+
+static ssize_t
+flags_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	struct intel_engine_cs *engine = kobj_to_engine(kobj);
+
+	return __flags_show(engine, engine->flags, buf, true);
+}
+
+static struct kobj_attribute flags_attr =
+__ATTR(flags, 0444, flags_show, NULL);
+
+static ssize_t
+all_flags_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	return __flags_show(kobj_to_engine(kobj), -1, buf, false);
+}
+
+static struct kobj_attribute all_flags_attr =
+__ATTR(known_flags, 0444, all_flags_show, NULL);
+
 static ssize_t
 mmio_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 {
@@ -66,17 +139,6 @@ static const char * const vecs_caps[] = {
 	[ilog2(I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC)] = "sfc",
 };
 
-static ssize_t repr_trim(char *buf, ssize_t len)
-{
-	/* Trim off the trailing space and replace with a newline */
-	if (len > PAGE_SIZE)
-		len = PAGE_SIZE;
-	if (len > 0)
-		buf[len - 1] = '\n';
-
-	return len;
-}
-
 static ssize_t
 __caps_show(struct intel_engine_cs *engine,
 	    u32 caps, char *buf, bool show_unknown)
@@ -488,6 +550,8 @@ void intel_engines_add_sysfs(struct drm_i915_private *i915)
 		&name_attr.attr,
 		&class_attr.attr,
 		&inst_attr.attr,
+		&flags_attr.attr,
+		&all_flags_attr.attr,
 		&mmio_attr.attr,
 		&caps_attr.attr,
 		&all_caps_attr.attr,
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list