Message ID | 20191010071434.31195-3-chris@chris-wilson.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/10] drm/i915: Note the addition of timeslicing to the pretend scheduler | expand |
On 10/10/2019 08:14, Chris Wilson wrote: > Preliminary stub to add engines underneath /sys/class/drm/cardN/, so > that we can expose properties on each engine to the sysadmin. > > To start with we have basic analogues of the i915_query ioctl so that we > can pretty print engine discovery from the shell, and flesh out the > directory structure. Later we will add writeable sysadmin properties such > as per-engine timeout controls. > > An example tree of the engine properties on Braswell: > /sys/class/drm/card0 > └── engine > ├── bcs0 > │ ├── class > │ ├── heartbeat_interval_ms Not present in this patch. > │ ├── instance > │ ├── mmio_base I vote for putting mmio_base in a followup patch. And how about we add capabilities in the first patch? So we get another way of engine discovery. Ideally with mapping of bits to user friendly strings. Regards, Tvrtko > │ └── name > ├── rcs0 > │ ├── class > │ ├── heartbeat_interval_ms > │ ├── instance > │ ├── mmio_base > │ └── name > ├── vcs0 > │ ├── class > │ ├── heartbeat_interval_ms > │ ├── instance > │ ├── mmio_base > │ └── name > └── vecs0 > ├── class > ├── heartbeat_interval_ms > ├── instance > ├── mmio_base > └── name > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> > Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> > Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> > Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> > --- > drivers/gpu/drm/i915/Makefile | 3 +- > drivers/gpu/drm/i915/gt/intel_engine_sysfs.c | 119 +++++++++++++++++++ > drivers/gpu/drm/i915/gt/intel_engine_sysfs.h | 14 +++ > drivers/gpu/drm/i915/i915_sysfs.c | 3 + > 4 files changed, 138 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_sysfs.c > create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_sysfs.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index e791d9323b51..cd9a10ba2516 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -78,8 +78,9 @@ gt-y += \ > gt/intel_breadcrumbs.o \ > gt/intel_context.o \ > gt/intel_engine_cs.o \ > - gt/intel_engine_pool.o \ > gt/intel_engine_pm.o \ > + gt/intel_engine_pool.o \ > + gt/intel_engine_sysfs.o \ > gt/intel_engine_user.o \ > gt/intel_gt.o \ > gt/intel_gt_irq.o \ > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_sysfs.c b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.c > new file mode 100644 > index 000000000000..cbe9ec59beeb > --- /dev/null > +++ b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.c > @@ -0,0 +1,119 @@ > +/* > + * SPDX-License-Identifier: MIT > + * > + * Copyright © 2019 Intel Corporation > + */ > + > +#include <linux/kobject.h> > +#include <linux/sysfs.h> > + > +#include "i915_drv.h" > +#include "intel_engine.h" > +#include "intel_engine_sysfs.h" > + > +struct kobj_engine { > + struct kobject base; > + struct intel_engine_cs *engine; > +}; > + > +static struct intel_engine_cs *kobj_to_engine(struct kobject *kobj) > +{ > + return container_of(kobj, struct kobj_engine, base)->engine; > +} > + > +static ssize_t > +name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) > +{ > + return sprintf(buf, "%s\n", kobj_to_engine(kobj)->name); > +} > + > +static ssize_t > +class_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) > +{ > + return sprintf(buf, "%d\n", kobj_to_engine(kobj)->uabi_class); > +} > + > +static ssize_t > +inst_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) > +{ > + return sprintf(buf, "%d\n", kobj_to_engine(kobj)->uabi_instance); > +} > + > +static ssize_t > +mmio_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) > +{ > + return sprintf(buf, "0x%x\n", kobj_to_engine(kobj)->mmio_base); > +} > + > +static struct kobj_attribute name_attr = __ATTR(name, 0444, name_show, NULL); > +static struct kobj_attribute class_attr = __ATTR(class, 0444, class_show, NULL); > +static struct kobj_attribute inst_attr = __ATTR(instance, 0444, inst_show, NULL); > +static struct kobj_attribute mmio_attr = __ATTR(mmio_base, 0444, mmio_show, NULL); > + > +static void kobj_engine_release(struct kobject *kobj) > +{ > + kfree(kobj); > +} > + > +static struct kobj_type kobj_engine_type = { > + .release = kobj_engine_release, > + .sysfs_ops = &kobj_sysfs_ops > +}; > + > +static struct kobject * > +kobj_engine(struct kobject *dir, struct intel_engine_cs *engine) > +{ > + struct kobj_engine *ke; > + > + ke = kzalloc(sizeof(*ke), GFP_KERNEL); > + if (!ke) > + return NULL; > + > + kobject_init(&ke->base, &kobj_engine_type); > + ke->engine = engine; > + > + if (kobject_add(&ke->base, dir, "%s", engine->name)) { > + kobject_put(&ke->base); > + return NULL; > + } > + > + /* xfer ownership to sysfs tree */ > + return &ke->base; > +} > + > +void intel_engines_add_sysfs(struct drm_i915_private *i915) > +{ > + static const struct attribute *files[] = { > + &name_attr.attr, > + &class_attr.attr, > + &inst_attr.attr, > + &mmio_attr.attr, > + NULL > + }; > + > + struct device *kdev = i915->drm.primary->kdev; > + struct intel_engine_cs *engine; > + struct kobject *dir; > + > + dir = kobject_create_and_add("engine", &kdev->kobj); > + if (!dir) > + return; > + > + for_each_uabi_engine(engine, i915) { > + struct kobject *kobj; > + > + kobj = kobj_engine(dir, engine); > + if (!kobj) > + goto err_engine; > + > + if (sysfs_create_files(kobj, files)) > + goto err_engine; > + > + if (0) { > +err_engine: > + dev_err(kdev, "Failed to add sysfs engine '%s'\n", > + engine->name); > + break; > + } > + } > +} > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_sysfs.h b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.h > new file mode 100644 > index 000000000000..ef44a745b70a > --- /dev/null > +++ b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.h > @@ -0,0 +1,14 @@ > +/* > + * SPDX-License-Identifier: MIT > + * > + * Copyright © 2019 Intel Corporation > + */ > + > +#ifndef INTEL_ENGINE_SYSFS_H > +#define INTEL_ENGINE_SYSFS_H > + > +struct drm_i915_private; > + > +void intel_engines_add_sysfs(struct drm_i915_private *i915); > + > +#endif /* INTEL_ENGINE_SYSFS_H */ > diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c > index bf039b8ba593..7b665f69f301 100644 > --- a/drivers/gpu/drm/i915/i915_sysfs.c > +++ b/drivers/gpu/drm/i915/i915_sysfs.c > @@ -30,6 +30,7 @@ > #include <linux/stat.h> > #include <linux/sysfs.h> > > +#include "gt/intel_engine_sysfs.h" > #include "gt/intel_rc6.h" > > #include "i915_drv.h" > @@ -616,6 +617,8 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv) > DRM_ERROR("RPS sysfs setup failed\n"); > > i915_setup_error_capture(kdev); > + > + intel_engines_add_sysfs(dev_priv); > } > > void i915_teardown_sysfs(struct drm_i915_private *dev_priv) >
Quoting Tvrtko Ursulin (2019-10-11 09:44:16) > > On 10/10/2019 08:14, Chris Wilson wrote: > > Preliminary stub to add engines underneath /sys/class/drm/cardN/, so > > that we can expose properties on each engine to the sysadmin. > > > > To start with we have basic analogues of the i915_query ioctl so that we > > can pretty print engine discovery from the shell, and flesh out the > > directory structure. Later we will add writeable sysadmin properties such > > as per-engine timeout controls. > > > > An example tree of the engine properties on Braswell: > > /sys/class/drm/card0 > > └── engine > > ├── bcs0 > > │ ├── class > > │ ├── heartbeat_interval_ms > > Not present in this patch. I did say an example tree, not this tree :) > > │ ├── instance > > │ ├── mmio_base > > I vote for putting mmio_base in a followup patch. Darn your eagle eyes ;) > > And how about we add capabilities in the first patch? So we get another > way of engine discovery. Ideally with mapping of bits to user friendly > strings. Right, I was about to ask if we should do a /proc/cpuinfo style capabilities. Do we need both? Or just stick to the more human readable output for sysfs? -Chris
On 11/10/2019 09:49, Chris Wilson wrote: > Quoting Tvrtko Ursulin (2019-10-11 09:44:16) >> >> On 10/10/2019 08:14, Chris Wilson wrote: >>> Preliminary stub to add engines underneath /sys/class/drm/cardN/, so >>> that we can expose properties on each engine to the sysadmin. >>> >>> To start with we have basic analogues of the i915_query ioctl so that we >>> can pretty print engine discovery from the shell, and flesh out the >>> directory structure. Later we will add writeable sysadmin properties such >>> as per-engine timeout controls. >>> >>> An example tree of the engine properties on Braswell: >>> /sys/class/drm/card0 >>> └── engine >>> ├── bcs0 >>> │ ├── class >>> │ ├── heartbeat_interval_ms >> >> Not present in this patch. > > I did say an example tree, not this tree :) > >>> │ ├── instance >>> │ ├── mmio_base >> >> I vote for putting mmio_base in a followup patch. > > Darn your eagle eyes ;) > >> >> And how about we add capabilities in the first patch? So we get another >> way of engine discovery. Ideally with mapping of bits to user friendly >> strings. > > Right, I was about to ask if we should do a /proc/cpuinfo style > capabilities. Do we need both? Or just stick to the more human readable > output for sysfs? Interesting question and I am not sure. I'd definitely have human readable and that even being an aggregation of engine->flags and engine->uabi_capabilities. Whether or not to also put hex in there.. For uabi_capabilities it's possible, but for the rest not so much. So that probably means only human readable? Regards, Tvrtko
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index e791d9323b51..cd9a10ba2516 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -78,8 +78,9 @@ gt-y += \ gt/intel_breadcrumbs.o \ gt/intel_context.o \ gt/intel_engine_cs.o \ - gt/intel_engine_pool.o \ gt/intel_engine_pm.o \ + gt/intel_engine_pool.o \ + gt/intel_engine_sysfs.o \ gt/intel_engine_user.o \ gt/intel_gt.o \ gt/intel_gt_irq.o \ diff --git a/drivers/gpu/drm/i915/gt/intel_engine_sysfs.c b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.c new file mode 100644 index 000000000000..cbe9ec59beeb --- /dev/null +++ b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.c @@ -0,0 +1,119 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2019 Intel Corporation + */ + +#include <linux/kobject.h> +#include <linux/sysfs.h> + +#include "i915_drv.h" +#include "intel_engine.h" +#include "intel_engine_sysfs.h" + +struct kobj_engine { + struct kobject base; + struct intel_engine_cs *engine; +}; + +static struct intel_engine_cs *kobj_to_engine(struct kobject *kobj) +{ + return container_of(kobj, struct kobj_engine, base)->engine; +} + +static ssize_t +name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", kobj_to_engine(kobj)->name); +} + +static ssize_t +class_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", kobj_to_engine(kobj)->uabi_class); +} + +static ssize_t +inst_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", kobj_to_engine(kobj)->uabi_instance); +} + +static ssize_t +mmio_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "0x%x\n", kobj_to_engine(kobj)->mmio_base); +} + +static struct kobj_attribute name_attr = __ATTR(name, 0444, name_show, NULL); +static struct kobj_attribute class_attr = __ATTR(class, 0444, class_show, NULL); +static struct kobj_attribute inst_attr = __ATTR(instance, 0444, inst_show, NULL); +static struct kobj_attribute mmio_attr = __ATTR(mmio_base, 0444, mmio_show, NULL); + +static void kobj_engine_release(struct kobject *kobj) +{ + kfree(kobj); +} + +static struct kobj_type kobj_engine_type = { + .release = kobj_engine_release, + .sysfs_ops = &kobj_sysfs_ops +}; + +static struct kobject * +kobj_engine(struct kobject *dir, struct intel_engine_cs *engine) +{ + struct kobj_engine *ke; + + ke = kzalloc(sizeof(*ke), GFP_KERNEL); + if (!ke) + return NULL; + + kobject_init(&ke->base, &kobj_engine_type); + ke->engine = engine; + + if (kobject_add(&ke->base, dir, "%s", engine->name)) { + kobject_put(&ke->base); + return NULL; + } + + /* xfer ownership to sysfs tree */ + return &ke->base; +} + +void intel_engines_add_sysfs(struct drm_i915_private *i915) +{ + static const struct attribute *files[] = { + &name_attr.attr, + &class_attr.attr, + &inst_attr.attr, + &mmio_attr.attr, + NULL + }; + + struct device *kdev = i915->drm.primary->kdev; + struct intel_engine_cs *engine; + struct kobject *dir; + + dir = kobject_create_and_add("engine", &kdev->kobj); + if (!dir) + return; + + for_each_uabi_engine(engine, i915) { + struct kobject *kobj; + + kobj = kobj_engine(dir, engine); + if (!kobj) + goto err_engine; + + if (sysfs_create_files(kobj, files)) + goto err_engine; + + if (0) { +err_engine: + dev_err(kdev, "Failed to add sysfs engine '%s'\n", + engine->name); + break; + } + } +} diff --git a/drivers/gpu/drm/i915/gt/intel_engine_sysfs.h b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.h new file mode 100644 index 000000000000..ef44a745b70a --- /dev/null +++ b/drivers/gpu/drm/i915/gt/intel_engine_sysfs.h @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2019 Intel Corporation + */ + +#ifndef INTEL_ENGINE_SYSFS_H +#define INTEL_ENGINE_SYSFS_H + +struct drm_i915_private; + +void intel_engines_add_sysfs(struct drm_i915_private *i915); + +#endif /* INTEL_ENGINE_SYSFS_H */ diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index bf039b8ba593..7b665f69f301 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -30,6 +30,7 @@ #include <linux/stat.h> #include <linux/sysfs.h> +#include "gt/intel_engine_sysfs.h" #include "gt/intel_rc6.h" #include "i915_drv.h" @@ -616,6 +617,8 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv) DRM_ERROR("RPS sysfs setup failed\n"); i915_setup_error_capture(kdev); + + intel_engines_add_sysfs(dev_priv); } void i915_teardown_sysfs(struct drm_i915_private *dev_priv)