]> www.infradead.org Git - linux.git/commitdiff
drm/xe/oa: Move functions up so they can be reused for config ioctl
authorAshutosh Dixit <ashutosh.dixit@intel.com>
Tue, 22 Oct 2024 20:03:50 +0000 (13:03 -0700)
committerAshutosh Dixit <ashutosh.dixit@intel.com>
Wed, 23 Oct 2024 19:42:18 +0000 (12:42 -0700)
No code changes, only code movement so that functions used during stream
open can be reused for the stream reconfiguration
ioctl (DRM_XE_OBSERVATION_IOCTL_CONFIG).

Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241022200352.1192560-6-ashutosh.dixit@intel.com
drivers/gpu/drm/xe/xe_oa.c

index 25558535076a6e46b963615e8775dca3d47b7585..8684ffca929fd03a45d9d84902000b5054b72102 100644 (file)
@@ -1141,6 +1141,235 @@ static int xe_oa_enable_metric_set(struct xe_oa_stream *stream)
        return xe_oa_emit_oa_config(stream, stream->oa_config);
 }
 
+static int decode_oa_format(struct xe_oa *oa, u64 fmt, enum xe_oa_format_name *name)
+{
+       u32 counter_size = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE, fmt);
+       u32 counter_sel = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SEL, fmt);
+       u32 bc_report = FIELD_GET(DRM_XE_OA_FORMAT_MASK_BC_REPORT, fmt);
+       u32 type = FIELD_GET(DRM_XE_OA_FORMAT_MASK_FMT_TYPE, fmt);
+       int idx;
+
+       for_each_set_bit(idx, oa->format_mask, __XE_OA_FORMAT_MAX) {
+               const struct xe_oa_format *f = &oa->oa_formats[idx];
+
+               if (counter_size == f->counter_size && bc_report == f->bc_report &&
+                   type == f->type && counter_sel == f->counter_select) {
+                       *name = idx;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int xe_oa_set_prop_oa_unit_id(struct xe_oa *oa, u64 value,
+                                    struct xe_oa_open_param *param)
+{
+       if (value >= oa->oa_unit_ids) {
+               drm_dbg(&oa->xe->drm, "OA unit ID out of range %lld\n", value);
+               return -EINVAL;
+       }
+       param->oa_unit_id = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_sample_oa(struct xe_oa *oa, u64 value,
+                                   struct xe_oa_open_param *param)
+{
+       param->sample = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_metric_set(struct xe_oa *oa, u64 value,
+                                    struct xe_oa_open_param *param)
+{
+       param->metric_set = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_oa_format(struct xe_oa *oa, u64 value,
+                                   struct xe_oa_open_param *param)
+{
+       int ret = decode_oa_format(oa, value, &param->oa_format);
+
+       if (ret) {
+               drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n", value);
+               return ret;
+       }
+       return 0;
+}
+
+static int xe_oa_set_prop_oa_exponent(struct xe_oa *oa, u64 value,
+                                     struct xe_oa_open_param *param)
+{
+#define OA_EXPONENT_MAX 31
+
+       if (value > OA_EXPONENT_MAX) {
+               drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n", OA_EXPONENT_MAX);
+               return -EINVAL;
+       }
+       param->period_exponent = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_disabled(struct xe_oa *oa, u64 value,
+                                  struct xe_oa_open_param *param)
+{
+       param->disabled = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_exec_queue_id(struct xe_oa *oa, u64 value,
+                                       struct xe_oa_open_param *param)
+{
+       param->exec_queue_id = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value,
+                                         struct xe_oa_open_param *param)
+{
+       param->engine_instance = value;
+       return 0;
+}
+
+static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
+                               struct xe_oa_open_param *param)
+{
+       param->no_preempt = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_num_syncs(struct xe_oa *oa, u64 value,
+                                   struct xe_oa_open_param *param)
+{
+       param->num_syncs = value;
+       return 0;
+}
+
+static int xe_oa_set_prop_syncs_user(struct xe_oa *oa, u64 value,
+                                    struct xe_oa_open_param *param)
+{
+       param->syncs_user = u64_to_user_ptr(value);
+       return 0;
+}
+
+typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
+                                    struct xe_oa_open_param *param);
+static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
+       [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_oa_unit_id,
+       [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_sample_oa,
+       [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set,
+       [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_oa_format,
+       [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_oa_exponent,
+       [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled,
+       [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
+       [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
+       [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
+       [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
+       [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
+};
+
+static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension,
+                                      struct xe_oa_open_param *param)
+{
+       u64 __user *address = u64_to_user_ptr(extension);
+       struct drm_xe_ext_set_property ext;
+       int err;
+       u32 idx;
+
+       err = __copy_from_user(&ext, address, sizeof(ext));
+       if (XE_IOCTL_DBG(oa->xe, err))
+               return -EFAULT;
+
+       if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs)) ||
+           XE_IOCTL_DBG(oa->xe, ext.pad))
+               return -EINVAL;
+
+       idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs));
+       return xe_oa_set_property_funcs[idx](oa, ext.value, param);
+}
+
+typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, u64 extension,
+                                      struct xe_oa_open_param *param);
+static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = {
+       [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property,
+};
+
+#define MAX_USER_EXTENSIONS    16
+static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number,
+                                struct xe_oa_open_param *param)
+{
+       u64 __user *address = u64_to_user_ptr(extension);
+       struct drm_xe_user_extension ext;
+       int err;
+       u32 idx;
+
+       if (XE_IOCTL_DBG(oa->xe, ext_number >= MAX_USER_EXTENSIONS))
+               return -E2BIG;
+
+       err = __copy_from_user(&ext, address, sizeof(ext));
+       if (XE_IOCTL_DBG(oa->xe, err))
+               return -EFAULT;
+
+       if (XE_IOCTL_DBG(oa->xe, ext.pad) ||
+           XE_IOCTL_DBG(oa->xe, ext.name >= ARRAY_SIZE(xe_oa_user_extension_funcs)))
+               return -EINVAL;
+
+       idx = array_index_nospec(ext.name, ARRAY_SIZE(xe_oa_user_extension_funcs));
+       err = xe_oa_user_extension_funcs[idx](oa, extension, param);
+       if (XE_IOCTL_DBG(oa->xe, err))
+               return err;
+
+       if (ext.next_extension)
+               return xe_oa_user_extensions(oa, ext.next_extension, ++ext_number, param);
+
+       return 0;
+}
+
+static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param)
+{
+       int ret, num_syncs, num_ufence = 0;
+
+       if (param->num_syncs && !param->syncs_user) {
+               drm_dbg(&oa->xe->drm, "num_syncs specified without sync array\n");
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       if (param->num_syncs) {
+               param->syncs = kcalloc(param->num_syncs, sizeof(*param->syncs), GFP_KERNEL);
+               if (!param->syncs) {
+                       ret = -ENOMEM;
+                       goto exit;
+               }
+       }
+
+       for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
+               ret = xe_sync_entry_parse(oa->xe, param->xef, &param->syncs[num_syncs],
+                                         &param->syncs_user[num_syncs], 0);
+               if (ret)
+                       goto err_syncs;
+
+               if (xe_sync_is_ufence(&param->syncs[num_syncs]))
+                       num_ufence++;
+       }
+
+       if (XE_IOCTL_DBG(oa->xe, num_ufence > 1)) {
+               ret = -EINVAL;
+               goto err_syncs;
+       }
+
+       return 0;
+
+err_syncs:
+       while (num_syncs--)
+               xe_sync_entry_cleanup(&param->syncs[num_syncs]);
+       kfree(param->syncs);
+exit:
+       return ret;
+}
+
 static void xe_oa_stream_enable(struct xe_oa_stream *stream)
 {
        stream->pollin = false;
@@ -1717,27 +1946,6 @@ static bool engine_supports_oa_format(const struct xe_hw_engine *hwe, int type)
        }
 }
 
-static int decode_oa_format(struct xe_oa *oa, u64 fmt, enum xe_oa_format_name *name)
-{
-       u32 counter_size = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE, fmt);
-       u32 counter_sel = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SEL, fmt);
-       u32 bc_report = FIELD_GET(DRM_XE_OA_FORMAT_MASK_BC_REPORT, fmt);
-       u32 type = FIELD_GET(DRM_XE_OA_FORMAT_MASK_FMT_TYPE, fmt);
-       int idx;
-
-       for_each_set_bit(idx, oa->format_mask, __XE_OA_FORMAT_MAX) {
-               const struct xe_oa_format *f = &oa->oa_formats[idx];
-
-               if (counter_size == f->counter_size && bc_report == f->bc_report &&
-                   type == f->type && counter_sel == f->counter_select) {
-                       *name = idx;
-                       return 0;
-               }
-       }
-
-       return -EINVAL;
-}
-
 /**
  * xe_oa_unit_id - Return OA unit ID for a hardware engine
  * @hwe: @xe_hw_engine
@@ -1784,214 +1992,6 @@ out:
        return ret;
 }
 
-static int xe_oa_set_prop_oa_unit_id(struct xe_oa *oa, u64 value,
-                                    struct xe_oa_open_param *param)
-{
-       if (value >= oa->oa_unit_ids) {
-               drm_dbg(&oa->xe->drm, "OA unit ID out of range %lld\n", value);
-               return -EINVAL;
-       }
-       param->oa_unit_id = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_sample_oa(struct xe_oa *oa, u64 value,
-                                   struct xe_oa_open_param *param)
-{
-       param->sample = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_metric_set(struct xe_oa *oa, u64 value,
-                                    struct xe_oa_open_param *param)
-{
-       param->metric_set = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_oa_format(struct xe_oa *oa, u64 value,
-                                   struct xe_oa_open_param *param)
-{
-       int ret = decode_oa_format(oa, value, &param->oa_format);
-
-       if (ret) {
-               drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n", value);
-               return ret;
-       }
-       return 0;
-}
-
-static int xe_oa_set_prop_oa_exponent(struct xe_oa *oa, u64 value,
-                                     struct xe_oa_open_param *param)
-{
-#define OA_EXPONENT_MAX 31
-
-       if (value > OA_EXPONENT_MAX) {
-               drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n", OA_EXPONENT_MAX);
-               return -EINVAL;
-       }
-       param->period_exponent = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_disabled(struct xe_oa *oa, u64 value,
-                                  struct xe_oa_open_param *param)
-{
-       param->disabled = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_exec_queue_id(struct xe_oa *oa, u64 value,
-                                       struct xe_oa_open_param *param)
-{
-       param->exec_queue_id = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value,
-                                         struct xe_oa_open_param *param)
-{
-       param->engine_instance = value;
-       return 0;
-}
-
-static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
-                               struct xe_oa_open_param *param)
-{
-       param->no_preempt = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_num_syncs(struct xe_oa *oa, u64 value,
-                                   struct xe_oa_open_param *param)
-{
-       param->num_syncs = value;
-       return 0;
-}
-
-static int xe_oa_set_prop_syncs_user(struct xe_oa *oa, u64 value,
-                                    struct xe_oa_open_param *param)
-{
-       param->syncs_user = u64_to_user_ptr(value);
-       return 0;
-}
-
-typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
-                                    struct xe_oa_open_param *param);
-static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
-       [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_oa_unit_id,
-       [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_sample_oa,
-       [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set,
-       [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_oa_format,
-       [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_oa_exponent,
-       [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled,
-       [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
-       [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
-       [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
-       [DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
-       [DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
-};
-
-static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension,
-                                      struct xe_oa_open_param *param)
-{
-       u64 __user *address = u64_to_user_ptr(extension);
-       struct drm_xe_ext_set_property ext;
-       int err;
-       u32 idx;
-
-       err = __copy_from_user(&ext, address, sizeof(ext));
-       if (XE_IOCTL_DBG(oa->xe, err))
-               return -EFAULT;
-
-       if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs)) ||
-           XE_IOCTL_DBG(oa->xe, ext.pad))
-               return -EINVAL;
-
-       idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs));
-       return xe_oa_set_property_funcs[idx](oa, ext.value, param);
-}
-
-typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, u64 extension,
-                                      struct xe_oa_open_param *param);
-static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = {
-       [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property,
-};
-
-#define MAX_USER_EXTENSIONS    16
-static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number,
-                                struct xe_oa_open_param *param)
-{
-       u64 __user *address = u64_to_user_ptr(extension);
-       struct drm_xe_user_extension ext;
-       int err;
-       u32 idx;
-
-       if (XE_IOCTL_DBG(oa->xe, ext_number >= MAX_USER_EXTENSIONS))
-               return -E2BIG;
-
-       err = __copy_from_user(&ext, address, sizeof(ext));
-       if (XE_IOCTL_DBG(oa->xe, err))
-               return -EFAULT;
-
-       if (XE_IOCTL_DBG(oa->xe, ext.pad) ||
-           XE_IOCTL_DBG(oa->xe, ext.name >= ARRAY_SIZE(xe_oa_user_extension_funcs)))
-               return -EINVAL;
-
-       idx = array_index_nospec(ext.name, ARRAY_SIZE(xe_oa_user_extension_funcs));
-       err = xe_oa_user_extension_funcs[idx](oa, extension, param);
-       if (XE_IOCTL_DBG(oa->xe, err))
-               return err;
-
-       if (ext.next_extension)
-               return xe_oa_user_extensions(oa, ext.next_extension, ++ext_number, param);
-
-       return 0;
-}
-
-static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param)
-{
-       int ret, num_syncs, num_ufence = 0;
-
-       if (param->num_syncs && !param->syncs_user) {
-               drm_dbg(&oa->xe->drm, "num_syncs specified without sync array\n");
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       if (param->num_syncs) {
-               param->syncs = kcalloc(param->num_syncs, sizeof(*param->syncs), GFP_KERNEL);
-               if (!param->syncs) {
-                       ret = -ENOMEM;
-                       goto exit;
-               }
-       }
-
-       for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
-               ret = xe_sync_entry_parse(oa->xe, param->xef, &param->syncs[num_syncs],
-                                         &param->syncs_user[num_syncs], 0);
-               if (ret)
-                       goto err_syncs;
-
-               if (xe_sync_is_ufence(&param->syncs[num_syncs]))
-                       num_ufence++;
-       }
-
-       if (XE_IOCTL_DBG(oa->xe, num_ufence > 1)) {
-               ret = -EINVAL;
-               goto err_syncs;
-       }
-
-       return 0;
-
-err_syncs:
-       while (num_syncs--)
-               xe_sync_entry_cleanup(&param->syncs[num_syncs]);
-       kfree(param->syncs);
-exit:
-       return ret;
-}
-
 /**
  * xe_oa_stream_open_ioctl - Opens an OA stream
  * @dev: @drm_device