[PATCH v3 01/11] drm/i915: Add i915 perf infrastructure

Chris Wilson chris at chris-wilson.co.uk
Mon Aug 15 14:57:57 UTC 2016


On Mon, Aug 15, 2016 at 03:41:18PM +0100, Robert Bragg wrote:
> Adds base i915 perf infrastructure for Gen performance metrics.
> 
> This adds a DRM_IOCTL_I915_PERF_OPEN ioctl that takes an array of uint64
> properties to configure a stream of metrics and returns a new fd usable
> with standard VFS system calls including read() to read typed and sized
> records; ioctl() to enable or disable capture and poll() to wait for
> data.
> 
> A stream is opened something like:
> 
>   uint64_t properties[] = {
>       /* Single context sampling */
>       DRM_I915_PERF_PROP_CTX_HANDLE,        ctx_handle,
> 
>       /* Include OA reports in samples */
>       DRM_I915_PERF_PROP_SAMPLE_OA,         true,
> 
>       /* OA unit configuration */
>       DRM_I915_PERF_PROP_OA_METRICS_SET,    metrics_set_id,
>       DRM_I915_PERF_PROP_OA_FORMAT,         report_format,
>       DRM_I915_PERF_PROP_OA_EXPONENT,       period_exponent,
>    };
>    struct drm_i915_perf_open_param parm = {
>       .flags = I915_PERF_FLAG_FD_CLOEXEC |
>                I915_PERF_FLAG_FD_NONBLOCK |
>                I915_PERF_FLAG_DISABLED,
>       .properties_ptr = (uint64_t)properties,
>       .num_properties = sizeof(properties) / 16,
>    };
>    int fd = drmIoctl(drm_fd, DRM_IOCTL_I915_PERF_OPEN, &param);
> 
> Records read all start with a common { type, size } header with
> DRM_I915_PERF_RECORD_SAMPLE being of most interest. Sample records
> contain an extensible number of fields and it's the
> DRM_I915_PERF_PROP_SAMPLE_xyz properties given when opening that
> determine what's included in every sample.
> 
> No specific streams are supported yet so any attempt to open a stream
> will return an error.
> 
> Signed-off-by: Robert Bragg <robert at sixbynine.org>
> ---
>  drivers/gpu/drm/i915/Makefile    |   3 +
>  drivers/gpu/drm/i915/i915_drv.c  |   6 +
>  drivers/gpu/drm/i915/i915_drv.h  |  92 +++++++++
>  drivers/gpu/drm/i915/i915_perf.c | 430 +++++++++++++++++++++++++++++++++++++++
>  include/uapi/drm/i915_drm.h      |  67 ++++++
>  5 files changed, 598 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/i915_perf.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 6092f0e..9a2f1f9 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -106,6 +106,9 @@ i915-y += dvo_ch7017.o \
>  # virtual gpu code
>  i915-y += i915_vgpu.o
>  
> +# perf code
> +i915-y += i915_perf.o
> +
>  ifeq ($(CONFIG_DRM_I915_GVT),y)
>  i915-y += intel_gvt.o
>  include $(src)/gvt/Makefile
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 83afdd0..f5209ff 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1169,6 +1169,9 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
>  	 * cannot run before the connectors are registered.
>  	 */
>  	intel_fbdev_initial_config_async(dev);
> +
> +	/* Depends on sysfs having been initialized */
> +	i915_perf_init(dev_priv);

Then please call it i915_perf_register() and i915_perf_unregister()
respectively.

> +	struct {
> +		bool initialized;

This is bogus. We simply cannot allow userspace to access internals
before we set them up. As it stands you have no serialisation here, so
the protect is moot.

i915_perf_init() needs to be split up into the early initialisation
function to setup internals, and the i915_perf_register() function to
enable userspace (with however many steps you need in between).

> +		struct list_head streams;
> +	} perf;
> +
>  	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
>  	struct {
>  		int (*execbuf_submit)(struct i915_execbuffer_params *params,
> @@ -3421,6 +3506,9 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
>  int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
>  				       struct drm_file *file);
>  
> +int i915_perf_open_ioctl(struct drm_device *dev, void *data,
> +			 struct drm_file *file);
> +
>  /* i915_gem_evict.c */
>  int __must_check i915_gem_evict_something(struct drm_device *dev,
>  					  struct i915_address_space *vm,
> @@ -3540,6 +3628,10 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
>  			    u32 batch_len,
>  			    bool is_master);
>  
> +/* i915_perf.c */
> +extern void i915_perf_init(struct drm_i915_private *dev_priv);
> +extern void i915_perf_fini(struct drm_i915_private *dev_priv);
> +
>  /* i915_suspend.c */
>  extern int i915_save_state(struct drm_device *dev);
>  extern int i915_restore_state(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
> new file mode 100644
> index 0000000..d0ed645
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_perf.c
> @@ -0,0 +1,430 @@
> +/*
> + * Copyright © 2015-2016 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + *   Robert Bragg <robert at sixbynine.org>
> + */
> +
> +#include <linux/anon_inodes.h>
> +#include <linux/sizes.h>
> +
> +#include "i915_drv.h"
> +
> +struct perf_open_properties {
> +	u32 sample_flags;
> +
> +	u64 single_context:1;
> +	u64 ctx_handle;
> +};
> +
> +static ssize_t i915_perf_read_locked(struct i915_perf_stream *stream,
> +				     struct file *file,
> +				     char __user *buf,
> +				     size_t count,
> +				     loff_t *ppos)
> +{
> +	struct i915_perf_read_state state = { count, 0, buf };
> +	int ret = stream->ops->read(stream, &state);
> +
> +	/* If we've successfully copied any data then reporting that
> +	 * takes precedence over any internal error status, so the
> +	 * data isn't lost
> +	 */
> +	return state.read ? state.read : (ret ? ret : -EAGAIN);

return state.read ?: ret ?: -EAGAIN;

Alternatively you could follow the standard pattern for read. Dare I ask
what is going to go into state that needs the obfuscation?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the dri-devel mailing list