From 442b8c06fc7230772a663a00feeb5ebc61652d6d Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Mon, 7 Nov 2016 19:49:53 +0000 Subject: drm/i915: advertise available metrics via sysfs Each metric set is given a sysfs entry like: /sys/class/drm/card0/metrics//id This allows userspace to enumerate the specific sets that are available for the current system. The 'id' file contains an unsigned integer that can be used to open the associated metric set via DRM_IOCTL_I915_PERF_OPEN. The is a globally unique ID for a specific OA unit register configuration that can be reliably used by userspace as a key to lookup corresponding counter meta data and normalization equations. The guid registry is currently maintained as part of gputop along with the XML metric set descriptions and code generation scripts, ref: https://github.com/rib/gputop > gputop-data/guids.xml > scripts/update-guids.py > gputop-data/oa-*.xml > scripts/i915-perf-kernelgen.py $ make -C gputop-data -f Makefile.xml SYSFS=1 WHITELIST=RenderBasic Signed-off-by: Robert Bragg Reviewed-by: Matthew Auld Reviewed-by: Sourab Gupta Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20161107194957.3385-8-robert@sixbynine.org --- drivers/gpu/drm/i915/i915_perf.c | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'drivers/gpu/drm/i915/i915_perf.c') diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 54653bcf0d79..c427cd8cbe1b 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -812,6 +812,15 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream, int format_size; int ret; + /* If the sysfs metrics/ directory wasn't registered for some + * reason then don't let userspace try their luck with config + * IDs + */ + if (!dev_priv->perf.metrics_kobj) { + DRM_ERROR("OA metrics weren't advertised via sysfs\n"); + return -EINVAL; + } + if (!(props->sample_flags & SAMPLE_OA_REPORT)) { DRM_ERROR("Only OA report sampling supported\n"); return -EINVAL; @@ -1408,6 +1417,49 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data, return ret; } +void i915_perf_register(struct drm_i915_private *dev_priv) +{ + if (!IS_HASWELL(dev_priv)) + return; + + if (!dev_priv->perf.initialized) + return; + + /* To be sure we're synchronized with an attempted + * i915_perf_open_ioctl(); considering that we register after + * being exposed to userspace. + */ + mutex_lock(&dev_priv->perf.lock); + + dev_priv->perf.metrics_kobj = + kobject_create_and_add("metrics", + &dev_priv->drm.primary->kdev->kobj); + if (!dev_priv->perf.metrics_kobj) + goto exit; + + if (i915_perf_register_sysfs_hsw(dev_priv)) { + kobject_put(dev_priv->perf.metrics_kobj); + dev_priv->perf.metrics_kobj = NULL; + } + +exit: + mutex_unlock(&dev_priv->perf.lock); +} + +void i915_perf_unregister(struct drm_i915_private *dev_priv) +{ + if (!IS_HASWELL(dev_priv)) + return; + + if (!dev_priv->perf.metrics_kobj) + return; + + i915_perf_unregister_sysfs_hsw(dev_priv); + + kobject_put(dev_priv->perf.metrics_kobj); + dev_priv->perf.metrics_kobj = NULL; +} + void i915_perf_init(struct drm_i915_private *dev_priv) { if (!IS_HASWELL(dev_priv)) -- cgit v1.2.3