Consistent with the kernel.perf_event_paranoid sysctl option that can allow non-root users to access system wide cpu metrics, this can optionally allow non-root users to access system wide OA counter metrics from Gen graphics hardware.
Signed-off-by: Robert Bragg <rob...@sixbynine.org> --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_perf.c | 46 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1406b93..2ac32b2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2081,6 +2081,7 @@ struct drm_i915_private { bool initialized; struct kobject *metrics_kobj; + struct ctl_table_header *sysctl_header; struct mutex lock; struct list_head streams; diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index f2db3de..c2ba16a 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -59,6 +59,8 @@ #define POLL_FREQUENCY 200 #define POLL_PERIOD (NSEC_PER_SEC / POLL_FREQUENCY) +static u32 i915_perf_stream_paranoid = true; + /* The maximum exponent the hardware accepts is 63 (essentially it selects one * of the 64bit timestamp bits to trigger reports from) but there's currently * no known use case for sampling as infrequently as once per 47 thousand years. @@ -1105,7 +1107,13 @@ int i915_perf_open_ioctl_locked(struct drm_device *dev, } } - if (!specific_ctx && !capable(CAP_SYS_ADMIN)) { + /* Similar to perf's kernel.perf_paranoid_cpu sysctl option + * we check a dev.i915.perf_stream_paranoid sysctl option + * to determine if it's ok to access system wide OA counters + * without CAP_SYS_ADMIN privileges. + */ + if (!specific_ctx && + i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) { DRM_ERROR("Insufficient privileges to open system-wide i915 perf stream\n"); ret = -EACCES; goto err_ctx; @@ -1309,6 +1317,38 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data, return ret; } + +static struct ctl_table oa_table[] = { + { + .procname = "perf_stream_paranoid", + .data = &i915_perf_stream_paranoid, + .maxlen = sizeof(i915_perf_stream_paranoid), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + {} +}; + +static struct ctl_table i915_root[] = { + { + .procname = "i915", + .maxlen = 0, + .mode = 0555, + .child = oa_table, + }, + {} +}; + +static struct ctl_table dev_root[] = { + { + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .child = i915_root, + }, + {} +}; + void i915_perf_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -1354,6 +1394,8 @@ void i915_perf_init(struct drm_device *dev) return; } + dev_priv->perf.sysctl_header = register_sysctl_table(dev_root); + dev_priv->perf.initialized = true; return; @@ -1366,6 +1408,8 @@ void i915_perf_fini(struct drm_device *dev) if (!dev_priv->perf.initialized) return; + unregister_sysctl_table(dev_priv->perf.sysctl_header); + i915_perf_deinit_sysfs_hsw(dev_priv); kobject_put(dev_priv->perf.metrics_kobj); -- 2.7.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx