diff mbox series

[v7,4/4] drm/i915/perf: enable filtering on multiple contexts

Message ID 20200428100816.951014-5-lionel.g.landwerlin@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/perf: Add support for multi context perf queries | expand

Commit Message

Lionel Landwerlin April 28, 2020, 10:08 a.m. UTC
Add 2 new properties to the i915-perf open ioctl to specify an array
of GEM context handles as well as the length of the array.

This can be used by drivers using multiple GEM contexts to implement a
single GL context.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 drivers/gpu/drm/i915/i915_perf.c | 58 ++++++++++++++++++++++++++++++--
 include/uapi/drm/i915_drm.h      | 21 ++++++++++++
 2 files changed, 76 insertions(+), 3 deletions(-)

Comments

Joonas Lahtinen April 30, 2020, 1:04 p.m. UTC | #1
Quoting Lionel Landwerlin (2020-04-28 13:08:16)
> Add 2 new properties to the i915-perf open ioctl to specify an array
> of GEM context handles as well as the length of the array.
> 
> This can be used by drivers using multiple GEM contexts to implement a
> single GL context.
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

Do add link to the userspace changes in the actual patch so that it
is preserved at merge time, not only the cover letter.

Regards, Joonas

> ---
>  drivers/gpu/drm/i915/i915_perf.c | 58 ++++++++++++++++++++++++++++++--
>  include/uapi/drm/i915_drm.h      | 21 ++++++++++++
>  2 files changed, 76 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
> index 79f68efd7d5b..e236d2a8720b 100644
> --- a/drivers/gpu/drm/i915/i915_perf.c
> +++ b/drivers/gpu/drm/i915/i915_perf.c
> @@ -3686,7 +3686,8 @@ static int read_properties_unlocked(struct i915_perf *perf,
>                                     struct perf_open_properties *props)
>  {
>         u64 __user *uprop = uprops;
> -       u32 i;
> +       u32 __user *uctx_handles = NULL;
> +       u32 i, n_uctx_handles = 0;
>         int err;
>  
>         memset(props, 0, sizeof(struct perf_open_properties));
> @@ -3737,7 +3738,7 @@ static int read_properties_unlocked(struct i915_perf *perf,
>  
>                 switch ((enum drm_i915_perf_property_id)id) {
>                 case DRM_I915_PERF_PROP_CTX_HANDLE:
> -                       if (props->n_ctx_handles > 0) {
> +                       if (props->n_ctx_handles > 0 || n_uctx_handles > 0) {
>                                 DRM_DEBUG("Context handle specified multiple times\n");
>                                 err = -EINVAL;
>                                 goto error;
> @@ -3851,6 +3852,38 @@ static int read_properties_unlocked(struct i915_perf *perf,
>                         }
>                         props->poll_oa_period = value;
>                         break;
> +               case DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY:
> +                       /* HSW can only filter in HW and only on a single
> +                        * context.
> +                        */
> +                       if (IS_HASWELL(perf->i915)) {
> +                               DRM_DEBUG("Multi context filter not supported on HSW\n");
> +                               err = -ENODEV;
> +                               goto error;
> +                       }
> +                       uctx_handles = u64_to_user_ptr(value);
> +                       break;
> +               case DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY_LENGTH:
> +                       if (IS_HASWELL(perf->i915)) {
> +                               DRM_DEBUG("Multi context filter not supported on HSW\n");
> +                               err = -ENODEV;
> +                               goto error;
> +                       }
> +                       if (props->n_ctx_handles > 0 || n_uctx_handles > 0) {
> +                               DRM_DEBUG("Context handle specified multiple times\n");
> +                               err = -EINVAL;
> +                               goto error;
> +                       }
> +                       props->ctx_handles =
> +                               kmalloc_array(value,
> +                                             sizeof(*props->ctx_handles),
> +                                             GFP_KERNEL);
> +                       if (!props->ctx_handles) {
> +                               err = -ENOMEM;
> +                               goto error;
> +                       }
> +                       n_uctx_handles = value;
> +                       break;
>                 case DRM_I915_PERF_PROP_MAX:
>                         MISSING_CASE(id);
>                         err = -EINVAL;
> @@ -3860,6 +3893,21 @@ static int read_properties_unlocked(struct i915_perf *perf,
>                 uprop += 2;
>         }
>  
> +       if (n_uctx_handles > 0 && props->n_ctx_handles > 0) {
> +               DRM_DEBUG("Context handle specified multiple times\n");
> +               err = -EINVAL;
> +               goto error;
> +       }
> +
> +       for (i = 0; i < n_uctx_handles; i++) {
> +               err = get_user(props->ctx_handles[i], uctx_handles);
> +               if (err)
> +                       goto error;
> +
> +               uctx_handles++;
> +               props->n_ctx_handles++;
> +       }
> +
>         return 0;
>  
>  error:
> @@ -4643,8 +4691,12 @@ int i915_perf_ioctl_version(void)
>          *
>          * 5: Add DRM_I915_PERF_PROP_POLL_OA_PERIOD parameter that controls the
>          *    interval for the hrtimer used to check for OA data.
> +        *
> +        * 6: Add DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY &
> +        *    DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY_LENGTH to allow an
> +        *    application monitor/pin multiple contexts.
>          */
> -       return 5;
> +       return 6;
>  }
>  
>  #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 14b67cd6b54b..f80e7932d728 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1993,6 +1993,27 @@ enum drm_i915_perf_property_id {
>          */
>         DRM_I915_PERF_PROP_POLL_OA_PERIOD,
>  
> +       /**
> +        * Specifies an array of u32 GEM context handles to filter reports
> +        * with.
> +        *
> +        * Using this parameter is incompatible with using
> +        * DRM_I915_PERF_PROP_CTX_HANDLE.
> +        *
> +        * This property is available in perf revision 6.
> +        */
> +       DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY,
> +
> +       /**
> +        * Specifies the length of the array specified with
> +        * DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY.
> +        *
> +        * The length must be in the range [1, 4].
> +        *
> +        * This property is available in perf revision 6.
> +        */
> +       DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY_LENGTH,
> +
>         DRM_I915_PERF_PROP_MAX /* non-ABI */
>  };
>  
> -- 
> 2.26.2
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 79f68efd7d5b..e236d2a8720b 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -3686,7 +3686,8 @@  static int read_properties_unlocked(struct i915_perf *perf,
 				    struct perf_open_properties *props)
 {
 	u64 __user *uprop = uprops;
-	u32 i;
+	u32 __user *uctx_handles = NULL;
+	u32 i, n_uctx_handles = 0;
 	int err;
 
 	memset(props, 0, sizeof(struct perf_open_properties));
@@ -3737,7 +3738,7 @@  static int read_properties_unlocked(struct i915_perf *perf,
 
 		switch ((enum drm_i915_perf_property_id)id) {
 		case DRM_I915_PERF_PROP_CTX_HANDLE:
-			if (props->n_ctx_handles > 0) {
+			if (props->n_ctx_handles > 0 || n_uctx_handles > 0) {
 				DRM_DEBUG("Context handle specified multiple times\n");
 				err = -EINVAL;
 				goto error;
@@ -3851,6 +3852,38 @@  static int read_properties_unlocked(struct i915_perf *perf,
 			}
 			props->poll_oa_period = value;
 			break;
+		case DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY:
+			/* HSW can only filter in HW and only on a single
+			 * context.
+			 */
+			if (IS_HASWELL(perf->i915)) {
+				DRM_DEBUG("Multi context filter not supported on HSW\n");
+				err = -ENODEV;
+				goto error;
+			}
+			uctx_handles = u64_to_user_ptr(value);
+			break;
+		case DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY_LENGTH:
+			if (IS_HASWELL(perf->i915)) {
+				DRM_DEBUG("Multi context filter not supported on HSW\n");
+				err = -ENODEV;
+				goto error;
+			}
+			if (props->n_ctx_handles > 0 || n_uctx_handles > 0) {
+				DRM_DEBUG("Context handle specified multiple times\n");
+				err = -EINVAL;
+				goto error;
+			}
+			props->ctx_handles =
+				kmalloc_array(value,
+					      sizeof(*props->ctx_handles),
+					      GFP_KERNEL);
+			if (!props->ctx_handles) {
+				err = -ENOMEM;
+				goto error;
+			}
+			n_uctx_handles = value;
+			break;
 		case DRM_I915_PERF_PROP_MAX:
 			MISSING_CASE(id);
 			err = -EINVAL;
@@ -3860,6 +3893,21 @@  static int read_properties_unlocked(struct i915_perf *perf,
 		uprop += 2;
 	}
 
+	if (n_uctx_handles > 0 && props->n_ctx_handles > 0) {
+		DRM_DEBUG("Context handle specified multiple times\n");
+		err = -EINVAL;
+		goto error;
+	}
+
+	for (i = 0; i < n_uctx_handles; i++) {
+		err = get_user(props->ctx_handles[i], uctx_handles);
+		if (err)
+			goto error;
+
+		uctx_handles++;
+		props->n_ctx_handles++;
+	}
+
 	return 0;
 
 error:
@@ -4643,8 +4691,12 @@  int i915_perf_ioctl_version(void)
 	 *
 	 * 5: Add DRM_I915_PERF_PROP_POLL_OA_PERIOD parameter that controls the
 	 *    interval for the hrtimer used to check for OA data.
+	 *
+	 * 6: Add DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY &
+	 *    DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY_LENGTH to allow an
+	 *    application monitor/pin multiple contexts.
 	 */
-	return 5;
+	return 6;
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 14b67cd6b54b..f80e7932d728 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1993,6 +1993,27 @@  enum drm_i915_perf_property_id {
 	 */
 	DRM_I915_PERF_PROP_POLL_OA_PERIOD,
 
+	/**
+	 * Specifies an array of u32 GEM context handles to filter reports
+	 * with.
+	 *
+	 * Using this parameter is incompatible with using
+	 * DRM_I915_PERF_PROP_CTX_HANDLE.
+	 *
+	 * This property is available in perf revision 6.
+	 */
+	DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY,
+
+	/**
+	 * Specifies the length of the array specified with
+	 * DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY.
+	 *
+	 * The length must be in the range [1, 4].
+	 *
+	 * This property is available in perf revision 6.
+	 */
+	DRM_I915_PERF_PROP_CTX_HANDLE_ARRAY_LENGTH,
+
 	DRM_I915_PERF_PROP_MAX /* non-ABI */
 };