On Mon, Nov 20, 2017 at 03:57:49PM +0000, Tvrtko Ursulin wrote:
> 
> On 20/11/2017 12:23, Lionel Landwerlin wrote:
> > This enables userspace to discover the engines available on the GPU.
> > Here is the layout on a Skylake GT4:
> > 
> > /sys/devices/pci0000:00/0000:00:02.0/drm/card0/gt
> > ├── bcs
> 
> It niggles me a bit that engine class names are directly under gt. If we end
> up having to add something else under gt then it will be a little bit of an
> enumeration trouble for userspace.
> 
> So I wanted to suggest gt/engines/rcs if that makes sense to people?
> 
> Regards,
> 
> Tvrtko
> 
Good suggestion.  After adding anything else to gt/ will be more clearly.

--
Cheers,
Ewelina
> > │   └── 0
> > │       ├── capabilities
> > │       ├── class
> > │       └── id
> > ├── rcs
> > │   └── 0
> > │       ├── capabilities
> > │       ├── class
> > │       └── id
> > ├── vcs
> > │   ├── 0
> > │   │   ├── capabilities
> > │   │   │   └── hevc
> > │   │   ├── class
> > │   │   └── id
> > │   └── 1
> > │       ├── capabilities
> > │       ├── class
> > │       └── id
> > └── vecs
> >      └── 0
> >          ├── capabilities
> >          ├── class
> >          └── id
> > 
> > Further capabilities can be added later as attributes of each engine.
> > 
> > v2: Add capabilities sub directory (Tvrtko)
> >      Move engines directory to drm/card/gt (Chris)
> > 
> > Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com>
> > ---
> >   drivers/gpu/drm/i915/i915_drv.h         |   5 +
> >   drivers/gpu/drm/i915/i915_reg.h         |   1 +
> >   drivers/gpu/drm/i915/i915_sysfs.c       | 160 
> > ++++++++++++++++++++++++++++++++
> >   drivers/gpu/drm/i915/intel_engine_cs.c  |  12 +++
> >   drivers/gpu/drm/i915/intel_ringbuffer.h |   4 +
> >   5 files changed, 182 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 78c49db4280a..db550322207c 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2729,6 +2729,11 @@ struct drm_i915_private {
> >             } oa;
> >     } perf;
> > +   struct {
> > +           struct kobject kobj;
> > +           struct kobject classes_kobjs[MAX_ENGINE_CLASS];
> > +   } gt_topology;
> > +
> >     /* Abstract the submission mechanism (legacy ringbuffer or execlists) 
> > away */
> >     struct {
> >             void (*resume)(struct drm_i915_private *);
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h 
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 96c80fa0fcac..17aecd4fc6aa 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -186,6 +186,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
> >   #define VIDEO_ENHANCEMENT_CLASS   2
> >   #define COPY_ENGINE_CLASS 3
> >   #define OTHER_CLASS               4
> > +#define MAX_ENGINE_CLASS   5
> >   /* PCI config space */
> > diff --git a/drivers/gpu/drm/i915/i915_sysfs.c 
> > b/drivers/gpu/drm/i915/i915_sysfs.c
> > index 791759f632e1..fd04d0b93eaf 100644
> > --- a/drivers/gpu/drm/i915/i915_sysfs.c
> > +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> > @@ -559,6 +559,160 @@ static void i915_setup_error_capture(struct device 
> > *kdev) {}
> >   static void i915_teardown_error_capture(struct device *kdev) {}
> >   #endif
> > +static struct attribute engine_id_attr = {
> > +   .name = "id",
> > +   .mode = 0444,
> > +};
> > +
> > +static struct attribute engine_class_attr = {
> > +   .name = "class",
> > +   .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, instance_kobj);
> > +
> > +   if (attr == &engine_id_attr)
> > +           return sprintf(buf, "%hhu\n", engine->uabi_id);
> > +   if (attr == &engine_class_attr)
> > +           return sprintf(buf, "%hhu\n", engine->uabi_class);
> > +   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 struct attribute engine_capability_hevc_attr = {
> > +   .name = "hevc",
> > +   .mode = 0444,
> > +};
> > +
> > +static ssize_t
> > +show_engine_capabilities_attr(struct kobject *kobj, struct attribute 
> > *attr, char *buf)
> > +{
> > +   struct intel_engine_cs *engine =
> > +           container_of(kobj, struct intel_engine_cs, capabilities_kobj);
> > +
> > +   if (attr == &engine_capability_hevc_attr)
> > +           return sprintf(buf, "%i\n", INTEL_GEN(engine->i915) >= 8);
> > +   return sprintf(buf, "\n");
> > +}
> > +
> > +static const struct sysfs_ops engine_capabilities_ops = {
> > +   .show = show_engine_capabilities_attr,
> > +};
> > +
> > +static struct kobj_type engine_capabilities_type = {
> > +   .sysfs_ops = &engine_capabilities_ops,
> > +};
> > +
> > +static int i915_setup_engines_sysfs(struct drm_i915_private *dev_priv,
> > +                               struct kobject *gt_kobj)
> > +{
> > +   struct intel_engine_cs *engine_for_class, *engine;
> > +   enum intel_engine_id id_for_class, id;
> > +   bool registred[MAX_ENGINE_CLASS] = { false, };
> > +   int ret;
> > +
> > +   for_each_engine(engine_for_class, dev_priv, id_for_class) {
> > +           struct kobject *engine_class_kobj =
> > +                   
> > &dev_priv->gt_topology.classes_kobjs[engine_for_class->class];
> > +
> > +           if (registred[engine_for_class->class])
> > +                   continue;
> > +
> > +           registred[engine_for_class->class] = true;
> > +
> > +           ret = kobject_init_and_add(engine_class_kobj,
> > +                                      gt_kobj->ktype,
> > +                                      gt_kobj,
> > +                                      
> > intel_engine_get_class_name(engine_for_class));
> > +           if (ret)
> > +                   return ret;
> > +
> > +           for_each_engine(engine, dev_priv, id) {
> > +                   if (engine->class != engine_for_class->class)
> > +                           continue;
> > +
> > +                   ret = kobject_init_and_add(&engine->instance_kobj,
> > +                                              &engine_type,
> > +                                              engine_class_kobj,
> > +                                              "%d", engine->instance);
> > +                   if (ret)
> > +                           return ret;
> > +
> > +                   ret = sysfs_create_file(&engine->instance_kobj,
> > +                                           &engine_id_attr);
> > +                   if (ret)
> > +                           return ret;
> > +                   ret = sysfs_create_file(&engine->instance_kobj,
> > +                                           &engine_class_attr);
> > +                   if (ret)
> > +                           return ret;
> > +
> > +                   ret = kobject_init_and_add(&engine->capabilities_kobj,
> > +                                              &engine_capabilities_type,
> > +                                              &engine->instance_kobj,
> > +                                              "capabilities");
> > +                   if (ret)
> > +                           return ret;
> > +
> > +                   if (engine->id == VCS) {
> > +                           ret = 
> > sysfs_create_file(&engine->capabilities_kobj,
> > +                                                   
> > &engine_capability_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->instance_kobj, &engine_id_attr);
> > +           sysfs_remove_file(&engine->instance_kobj, &engine_class_attr);
> > +           sysfs_remove_file(&engine->capabilities_kobj,
> > +                             &engine_capability_hevc_attr);
> > +   }
> > +}
> > +
> > +static int i915_setup_gt_sysfs(struct drm_i915_private *dev_priv,
> > +                          struct device *kdev)
> > +{
> > +   int ret;
> > +
> > +   ret = kobject_init_and_add(&dev_priv->gt_topology.kobj,
> > +                              kdev->kobj.ktype,
> > +                              &kdev->kobj,
> > +                              "gt");
> > +   if (ret)
> > +           return ret;
> > +
> > +   return i915_setup_engines_sysfs(dev_priv, &dev_priv->gt_topology.kobj);
> > +}
> > +
> > +static void i915_teardown_gt_sysfs(struct drm_i915_private *dev_priv)
> > +{
> > +   i915_teardown_engines_sysfs(dev_priv);
> > +
> > +   kobject_get(&dev_priv->gt_topology.kobj);
> > +   kobject_del(&dev_priv->gt_topology.kobj);
> > +}
> > +
> >   void i915_setup_sysfs(struct drm_i915_private *dev_priv)
> >   {
> >     struct device *kdev = dev_priv->drm.primary->kdev;
> > @@ -605,6 +759,10 @@ void i915_setup_sysfs(struct drm_i915_private 
> > *dev_priv)
> >     if (ret)
> >             DRM_ERROR("RPS sysfs setup failed\n");
> > +   ret = i915_setup_gt_sysfs(dev_priv, kdev);
> > +   if (ret)
> > +           DRM_ERROR("GT sysfs setup failed\n");
> > +
> >     i915_setup_error_capture(kdev);
> >   }
> > @@ -614,6 +772,8 @@ void i915_teardown_sysfs(struct drm_i915_private 
> > *dev_priv)
> >     i915_teardown_error_capture(kdev);
> > +   i915_teardown_gt_sysfs(dev_priv);
> > +
> >     if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> >             sysfs_remove_files(&kdev->kobj, vlv_attrs);
> >     else
> > diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
> > b/drivers/gpu/drm/i915/intel_engine_cs.c
> > index 9897c7f78c51..9d82dfbb45db 100644
> > --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> > +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> > @@ -133,6 +133,18 @@ static const struct engine_info intel_engines[] = {
> >     },
> >   };
> > +/**
> > + * intel_engine_get_class_name() - return the name of the class for an 
> > engine
> > + * @engine: engine
> > + *
> > + * Return: a string naming the class of the engine
> > + */
> > +const char *
> > +intel_engine_get_class_name(struct intel_engine_cs *engine)
> > +{
> > +   return intel_engine_classes[engine->class].name;
> > +}
> > +
> >   /**
> >    * ___intel_engine_context_size() - return the size of the context for an 
> > engine
> >    * @dev_priv: i915 device private
> > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
> > b/drivers/gpu/drm/i915/intel_ringbuffer.h
> > index 5f96533e5341..eca6c87a1e06 100644
> > --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> > +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> > @@ -290,6 +290,9 @@ struct intel_engine_cs {
> >     struct drm_i915_private *i915;
> >     char name[INTEL_ENGINE_CS_MAX_NAME];
> > +   struct kobject instance_kobj;
> > +   struct kobject capabilities_kobj;
> > +
> >     enum intel_engine_id id;
> >     unsigned int hw_id;
> >     unsigned int guc_id;
> > @@ -924,6 +927,7 @@ gen8_emit_ggtt_write(u32 *cs, u32 value, u32 gtt_offset)
> >     return cs;
> >   }
> > +const char *intel_engine_get_class_name(struct intel_engine_cs *engine);
> >   bool intel_engine_is_idle(struct intel_engine_cs *engine);
> >   bool intel_engines_are_idle(struct drm_i915_private *dev_priv);
> > 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to