[Intel-xe] [PATCH 21/21] drm/xe/uapi: Convert OA property key/value pairs to a struct
Ashutosh Dixit
ashutosh.dixit at intel.com
Tue Sep 19 16:10:49 UTC 2023
Change OA uapi to take a param struct rather than property key value
pairs. A param struct is simpler and param structs can be extenended in the
future using xe_user_extension so there seems to be no reason to use
property key value pairs.
Suggested-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa at intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit at intel.com>
---
drivers/gpu/drm/xe/xe_oa.c | 244 ++++++++++++-------------------
drivers/gpu/drm/xe/xe_oa_types.h | 4 +-
include/uapi/drm/xe_drm.h | 127 ++++++++--------
3 files changed, 151 insertions(+), 224 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
index ded52d5aabea6..dfadc336c1876 100644
--- a/drivers/gpu/drm/xe/xe_oa.c
+++ b/drivers/gpu/drm/xe/xe_oa.c
@@ -59,23 +59,10 @@ static const struct xe_oa_format oa_formats[] = {
[XE_OAM_FORMAT_MPEC8u32_B8_C8] = { 2, 128, XE_OA_FMT_TYPE_OAM_MPEC, HDR_64_BIT },
};
-struct xe_oa_open_properties {
- u16 oa_unit_id;
- bool sample;
-
- bool single_exec_q;
- u64 exec_q_id;
+struct xe_oa_derived_params {
struct xe_exec_queue *exec_q;
- u16 instance;
-
- int metrics_set;
enum xe_oa_format_name oa_format;
- bool oa_periodic;
- int oa_period_exponent;
-
struct xe_hw_engine *hwe;
-
- u64 poll_oa_period;
};
struct xe_oa_config_bo {
@@ -272,7 +259,7 @@ static enum hrtimer_restart xe_oa_poll_check_timer_cb(struct hrtimer *hrtimer)
wake_up(&stream->poll_wq);
}
- hrtimer_forward_now(hrtimer, ns_to_ktime(stream->poll_oa_period));
+ hrtimer_forward_now(hrtimer, ns_to_ktime(stream->poll_period_ns));
return HRTIMER_RESTART;
}
@@ -1077,7 +1064,7 @@ static void xe_oa_stream_enable(struct xe_oa_stream *stream)
if (stream->sample)
hrtimer_start(&stream->poll_check_timer,
- ns_to_ktime(stream->poll_oa_period),
+ ns_to_ktime(stream->poll_period_ns),
HRTIMER_MODE_REL_PINNED);
}
@@ -1284,24 +1271,26 @@ static int xe_oa_set_ctx_ctrl_offset(struct xe_oa_stream *stream)
}
static int xe_oa_stream_init(struct xe_oa_stream *stream,
- struct xe_oa_open_properties *props)
+ struct drm_xe_oa_open_param *param,
+ struct xe_oa_derived_params *dp)
{
- struct xe_oa_group *g = props->hwe->oa_group;
- struct xe_gt *gt = props->hwe->gt;
+ struct xe_oa_group *g = dp->hwe->oa_group;
+ struct xe_gt *gt = dp->hwe->gt;
struct xe_oa *oa = stream->oa;
int ret;
- stream->exec_q = props->exec_q;
- stream->poll_oa_period = props->poll_oa_period;
- stream->hwe = props->hwe;
+ stream->exec_q = dp->exec_q;
+ stream->poll_period_ns = param->poll_period_us ?
+ param->poll_period_us * NSEC_PER_USEC : DEFAULT_POLL_PERIOD_NS;
+ stream->hwe = dp->hwe;
stream->gt = stream->hwe->gt;
stream->sample_size = sizeof(struct drm_xe_oa_record_header);
- stream->oa_buffer.format = &oa->oa_formats[props->oa_format];
+ stream->oa_buffer.format = &oa->oa_formats[dp->oa_format];
- stream->sample = props->sample;
+ stream->sample = param->sample_oa;
stream->sample_size += stream->oa_buffer.format->size;
- stream->periodic = props->oa_periodic;
- stream->period_exponent = props->oa_period_exponent;
+ stream->periodic = param->period_exponent > 0;
+ stream->period_exponent = param->period_exponent;
if (stream->exec_q && engine_supports_mi_query(stream->hwe)) {
/* If we don't find the context offset, just return error */
@@ -1314,9 +1303,9 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
}
}
- stream->oa_config = xe_oa_get_oa_config(oa, props->metrics_set);
+ stream->oa_config = xe_oa_get_oa_config(oa, param->metric_set);
if (!stream->oa_config) {
- drm_dbg(&oa->xe->drm, "Invalid OA config id=%i\n", props->metrics_set);
+ drm_dbg(&oa->xe->drm, "Invalid OA config id=%i\n", param->metric_set);
ret = -EINVAL;
goto exit;
}
@@ -1382,7 +1371,7 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
static int
xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
struct drm_xe_oa_open_param *param,
- struct xe_oa_open_properties *props)
+ struct xe_oa_derived_params *dp)
{
struct xe_oa_stream *stream;
unsigned long f_flags = 0;
@@ -1390,7 +1379,7 @@ xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
int ret;
/* We currently only allow exclusive access */
- if (props->hwe->oa_group->exclusive_stream) {
+ if (dp->hwe->oa_group->exclusive_stream) {
drm_dbg(&oa->xe->drm, "OA unit already in use\n");
ret = -EBUSY;
goto exit;
@@ -1403,13 +1392,13 @@ xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
}
stream->oa = oa;
- ret = xe_oa_stream_init(stream, props);
+ ret = xe_oa_stream_init(stream, param, dp);
if (ret)
goto err_free;
- if (param->flags & XE_OA_FLAG_FD_CLOEXEC)
+ if (param->open_flags & XE_OA_FLAG_FD_CLOEXEC)
f_flags |= O_CLOEXEC;
- if (param->flags & XE_OA_FLAG_FD_NONBLOCK)
+ if (param->open_flags & XE_OA_FLAG_FD_NONBLOCK)
f_flags |= O_NONBLOCK;
stream_fd = anon_inode_getfd("[xe_oa]", &xe_oa_fops, stream, f_flags);
@@ -1418,7 +1407,7 @@ xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
goto err_destroy;
}
- if (!(param->flags & XE_OA_FLAG_DISABLED))
+ if (!(param->open_flags & XE_OA_FLAG_DISABLED))
xe_oa_enable_locked(stream);
/* Hold a reference on the drm device till stream_fd is released */
@@ -1483,10 +1472,10 @@ static bool engine_supports_oa_format(const struct xe_hw_engine *hwe, int type)
}
}
-static int decode_oa_format(struct xe_oa *oa, u64 prop, enum xe_oa_format_name *name)
+static int decode_oa_format(struct xe_oa *oa, u64 fmt, enum xe_oa_format_name *name)
{
- u32 counter_sel = FIELD_GET(XE_OA_MASK_COUNTER_SEL, prop);
- u32 type = FIELD_GET(XE_OA_MASK_FMT_TYPE, prop);
+ u32 counter_sel = FIELD_GET(XE_OA_MASK_COUNTER_SEL, fmt);
+ u32 type = FIELD_GET(XE_OA_MASK_FMT_TYPE, fmt);
int idx;
for_each_set_bit(idx, oa->format_mask, XE_OA_FORMAT_MAX) {
@@ -1507,20 +1496,21 @@ u16 xe_oa_unit_id(struct xe_hw_engine *hwe)
hwe->oa_group->oa_unit_id : U16_MAX;
}
-static int xe_oa_assign_hwe(struct xe_oa *oa, struct xe_oa_open_properties *props)
+static int xe_oa_assign_hwe(struct xe_oa *oa, struct drm_xe_oa_open_param *param,
+ struct xe_oa_derived_params *dp)
{
struct xe_gt *gt;
int i, ret = 0;
- if (props->exec_q) {
+ if (dp->exec_q) {
/* When we have an exec_q, get hwe from the exec_q */
for_each_gt(gt, oa->xe, i) {
- props->hwe = xe_gt_hw_engine(gt, props->exec_q->class,
- props->instance, false);
- if (props->hwe)
+ dp->hwe = xe_gt_hw_engine(gt, dp->exec_q->class,
+ param->engine_instance, false);
+ if (dp->hwe)
break;
}
- if (props->hwe && (xe_oa_unit_id(props->hwe) != props->oa_unit_id)) {
+ if (dp->hwe && (xe_oa_unit_id(dp->hwe) != param->oa_unit_id)) {
drm_dbg(&oa->xe->drm, "OA unit ID mismatch for exec_q\n");
ret = -EINVAL;
}
@@ -1531,35 +1521,35 @@ static int xe_oa_assign_hwe(struct xe_oa *oa, struct xe_oa_open_properties *prop
/* Else just get the first hwe attached to the oa unit */
for_each_gt(gt, oa->xe, i) {
for_each_hw_engine(hwe, gt, id) {
- if (xe_oa_unit_id(hwe) == props->oa_unit_id) {
- props->hwe = hwe;
+ if (xe_oa_unit_id(hwe) == param->oa_unit_id) {
+ dp->hwe = hwe;
goto out;
}
}
}
}
out:
- if (!props->hwe) {
+ if (!dp->hwe) {
drm_dbg(&oa->xe->drm, "Unable to find hwe for OA unit ID %d\n",
- props->oa_unit_id);
+ param->oa_unit_id);
ret = -EINVAL;
}
return ret;
}
-static int xe_oa_validate_properties(struct xe_oa *oa,
- struct xe_oa_open_properties *props,
- struct drm_file *file)
+static int __xe_oa_open_check_params(struct xe_oa *oa, struct drm_file *file,
+ struct drm_xe_oa_open_param *param,
+ struct xe_oa_derived_params *dp)
{
struct xe_file *xef = to_xe_file(file);
const struct xe_oa_format *f;
bool privileged_op = true;
int ret;
- if (props->single_exec_q) {
- props->exec_q = xe_exec_queue_lookup(xef, props->exec_q_id);
- if (XE_IOCTL_DBG(oa->xe, !props->exec_q)) {
+ if (param->exec_queue_id > 0) {
+ dp->exec_q = xe_exec_queue_lookup(xef, param->exec_queue_id);
+ if (XE_IOCTL_DBG(oa->xe, !dp->exec_q)) {
ret = -ENOENT;
goto err_exec_q;
}
@@ -1570,7 +1560,7 @@ static int xe_oa_validate_properties(struct xe_oa *oa,
* requirements if the user doesn't request global stream access,
* i.e. query based sampling using MI_REPORT_PERF_COUNT
*/
- if (props->exec_q && !props->sample)
+ if (dp->exec_q && !param->sample_oa)
privileged_op = false;
if (privileged_op && xe_oa_stream_paranoid && !perfmon_capable()) {
@@ -1579,29 +1569,29 @@ static int xe_oa_validate_properties(struct xe_oa *oa,
goto err_exec_q;
}
- if (!props->exec_q && !props->sample) {
+ if (!dp->exec_q && !param->sample_oa) {
drm_dbg(&oa->xe->drm, "Only OA report sampling supported\n");
ret = -EINVAL;
goto err_exec_q;
}
- ret = xe_oa_assign_hwe(oa, props);
+ ret = xe_oa_assign_hwe(oa, param, dp);
if (ret)
goto err_exec_q;
- f = &oa->oa_formats[props->oa_format];
- if (!props->oa_format || !f->size ||
- !engine_supports_oa_format(props->hwe, f->type)) {
+ f = &oa->oa_formats[dp->oa_format];
+ if (!dp->oa_format || !f->size ||
+ !engine_supports_oa_format(dp->hwe, f->type)) {
drm_dbg(&oa->xe->drm, "Invalid OA format %d type %d size %d for class %d\n",
- props->oa_format, f->type, f->size, props->hwe->class);
+ dp->oa_format, f->type, f->size, dp->hwe->class);
ret = -EINVAL;
goto err_exec_q;
}
- if (props->oa_periodic) {
+ if (param->period_exponent > 0) {
u64 oa_period, oa_freq_hz;
- oa_period = oa_exponent_to_ns(props->hwe->gt, props->oa_period_exponent);
+ oa_period = oa_exponent_to_ns(dp->hwe->gt, param->period_exponent);
oa_freq_hz = div64_u64(NSEC_PER_SEC, oa_period);
if (oa_freq_hz > xe_oa_max_sample_rate && !perfmon_capable()) {
drm_dbg(&oa->xe->drm,
@@ -1615,98 +1605,54 @@ static int xe_oa_validate_properties(struct xe_oa *oa,
return 0;
err_exec_q:
- if (props->exec_q)
- xe_exec_queue_put(props->exec_q);
+ if (dp->exec_q)
+ xe_exec_queue_put(dp->exec_q);
return ret;
}
+static int xe_oa_open_check_params(struct xe_oa *oa, struct drm_file *file,
+ struct drm_xe_oa_open_param *param,
+ struct xe_oa_derived_params *dp)
+{
#define OA_EXPONENT_MAX 31
-static int xe_oa_read_properties_unlocked(struct xe_oa *oa, u64 __user *uprops,
- u32 n_props, struct drm_file *file,
- struct xe_oa_open_properties *props)
-{
- u64 __user *uprop = uprops;
+ u32 known_open_flags;
int ret;
- u32 i;
- if (!n_props || n_props >= DRM_XE_OA_PROP_MAX) {
- drm_dbg(&oa->xe->drm, "Invalid number of xe perf properties given\n");
+ if (param->oa_unit_id >= oa->oa_unit_ids) {
+ drm_dbg(&oa->xe->drm, "OA unit ID out of range %d\n", param->oa_unit_id);
return -EINVAL;
}
- props->poll_oa_period = DEFAULT_POLL_PERIOD_NS;
-
- for (i = 0; i < n_props; i++) {
- u64 id, value;
+ ret = decode_oa_format(oa, param->oa_format, &dp->oa_format);
+ if (ret) {
+ drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n", param->oa_format);
+ return ret;
+ }
- ret = get_user(id, uprop);
- if (ret)
- return ret;
+ /* FIXME: not needed, check and remove */
+ if (!param->metric_set) {
+ drm_dbg(&oa->xe->drm, "Unknown OA metric set ID %d\n", param->metric_set);
+ return -EINVAL;
+ }
- ret = get_user(value, uprop + 1);
- if (ret)
- return ret;
+ if (param->period_exponent > OA_EXPONENT_MAX) {
+ drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n", OA_EXPONENT_MAX);
+ return -EINVAL;
+ }
- switch ((enum drm_xe_oa_property_id)id) {
- case DRM_XE_OA_PROP_OA_UNIT_ID:
- if (value >= oa->oa_unit_ids) {
- drm_dbg(&oa->xe->drm, "OA unit ID out of range %lld\n", value);
- return -EINVAL;
- }
- props->oa_unit_id = value;
- break;
- case DRM_XE_OA_PROP_SAMPLE_OA:
- props->sample = value;
- break;
- case DRM_XE_OA_PROP_OA_METRICS_SET:
- if (!value) {
- drm_dbg(&oa->xe->drm, "Unknown OA metric set ID\n");
- return -EINVAL;
- }
- props->metrics_set = value;
- break;
- case DRM_XE_OA_PROP_OA_FORMAT:
- ret = decode_oa_format(oa, value, &props->oa_format);
- if (ret) {
- drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n",
- value);
- return ret;
- }
- break;
- case DRM_XE_OA_PROP_OA_EXPONENT:
- if (value > OA_EXPONENT_MAX) {
- drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n",
- OA_EXPONENT_MAX);
- return -EINVAL;
- }
- props->oa_periodic = true;
- props->oa_period_exponent = value;
- break;
- case DRM_XE_OA_PROP_POLL_OA_PERIOD:
- if (value < 100000 /* 100us */) {
- drm_dbg(&oa->xe->drm, "OA timer too small (%lluns < 100us)\n",
- value);
- return -EINVAL;
- }
- props->poll_oa_period = value;
- break;
- case DRM_XE_OA_PROP_EXEC_QUEUE_ID:
- props->single_exec_q = true;
- props->exec_q_id = value;
- break;
- case DRM_XE_OA_PROP_OA_ENGINE_INSTANCE:
- props->instance = value;
- break;
- default:
- drm_dbg(&oa->xe->drm, "Unknown xe oa property ID %lld\n", id);
- return -EINVAL;
- }
+ if (param->poll_period_us && param->poll_period_us < 100) {
+ drm_dbg(&oa->xe->drm, "OA timer too small (%dus < 100us)\n", param->poll_period_us);
+ return -EINVAL;
+ }
- uprop += 2;
+ known_open_flags = XE_OA_FLAG_FD_CLOEXEC | XE_OA_FLAG_FD_NONBLOCK | XE_OA_FLAG_DISABLED;
+ if (param->open_flags & ~known_open_flags) {
+ drm_dbg(&oa->xe->drm, "Unknown open_flag %#x\n", param->open_flags);
+ return -EINVAL;
}
- ret = xe_oa_validate_properties(oa, props, file);
+ ret = __xe_oa_open_check_params(oa, file, param, dp);
if (ret)
return ret;
@@ -1716,9 +1662,8 @@ static int xe_oa_read_properties_unlocked(struct xe_oa *oa, u64 __user *uprops,
int xe_oa_stream_open_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
struct xe_oa *oa = &to_xe_device(dev)->oa;
- struct xe_oa_open_properties props = {};
+ struct xe_oa_derived_params dp = {};
struct drm_xe_oa_open_param param;
- u32 known_open_flags;
struct xe_gt *gt;
int ret;
@@ -1731,26 +1676,19 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, void *data, struct drm_file
if (XE_IOCTL_DBG(oa->xe, ret))
return -EFAULT;
- known_open_flags = XE_OA_FLAG_FD_CLOEXEC | XE_OA_FLAG_FD_NONBLOCK | XE_OA_FLAG_DISABLED;
- if (param.flags & ~known_open_flags) {
- drm_dbg(&oa->xe->drm, "Unknown drm_xe_oa_open_param flag\n");
- return -EINVAL;
- }
-
- ret = xe_oa_read_properties_unlocked(oa, u64_to_user_ptr(param.properties_ptr),
- param.num_properties, file, &props);
+ ret = xe_oa_open_check_params(oa, file, ¶m, &dp);
if (ret)
return ret;
- gt = props.hwe->gt;
+ gt = dp.hwe->gt;
mutex_lock(>->oa.lock);
- ret = xe_oa_stream_open_ioctl_locked(oa, ¶m, &props);
+ ret = xe_oa_stream_open_ioctl_locked(oa, ¶m, &dp);
mutex_unlock(>->oa.lock);
- /* Drop exec_q reference taken in read_properties/validate_properties on error */
- if (ret < 0 && props.exec_q)
- xe_exec_queue_put(props.exec_q);
+ /* On error, drop reference taken in validate_params/xe_exec_queue_lookup */
+ if (ret < 0 && dp.exec_q)
+ xe_exec_queue_put(dp.exec_q);
return ret;
}
diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h
index 7566fef55b0ab..f37f3ef6d80eb 100644
--- a/drivers/gpu/drm/xe/xe_oa_types.h
+++ b/drivers/gpu/drm/xe/xe_oa_types.h
@@ -293,10 +293,10 @@ struct xe_oa_stream {
} oa_buffer;
/**
- * @poll_oa_period: The period in nanoseconds at which the OA
+ * @poll_period_ns: The period in nanoseconds at which the OA
* buffer should be checked for available data.
*/
- u64 poll_oa_period;
+ u64 poll_period_ns;
/**
* @override_gucrc: GuC RC has been overridden for the perf stream,
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index c0018abee4052..8ba11c4eb36b5 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1175,30 +1175,26 @@ struct drm_xe_query_oa_info {
} oau[];
};
-enum drm_xe_oa_property_id {
- /**
- * ID of the OA unit on which to open the OA stream, see
- * @oa_unit_id in 'struct drm_xe_engine_class_instance'. Defaults
- * to 0 if not provided.
- */
- DRM_XE_OA_PROP_OA_UNIT_ID = 1,
+struct drm_xe_oa_open_param {
+ /** @extensions: Pointer to the first extension struct, if any */
+ __u64 extensions;
/**
- * A value of 1 requests the inclusion of raw OA unit reports as
- * part of stream samples.
+ * @oa_unit_id: ID of the OA unit on which to open the OA stream,
+ * see @oa_unit_id in struct @drm_xe_engine_class_instance
*/
- DRM_XE_OA_PROP_SAMPLE_OA,
+ __u32 oa_unit_id;
/**
- * The value specifies which set of OA unit metrics should be
- * configured, defining the contents of any OA unit reports.
+ * @sample_oa: A value of 1 requests the inclusion of raw OA unit
+ * reports as part of stream samples
*/
- DRM_XE_OA_PROP_OA_METRICS_SET,
+ __u32 sample_oa;
/**
- * The value specifies the size and layout of OA unit reports.
+ * @oa_format: The value specifies the size and layout of OA unit reports
*/
- DRM_XE_OA_PROP_OA_FORMAT,
+ __u64 oa_format;
/**
* OA_FORMAT's are specified the same way as in Bspec, in terms of
* the following quantities: a. enum @drm_xe_oa_format_type
@@ -1210,86 +1206,79 @@ enum drm_xe_oa_property_id {
#define XE_OA_MASK_BC_REPORT (0xff << 24)
/**
- * Specifying this property implicitly requests periodic OA unit
- * sampling and (at least on Haswell) the sampling frequency is derived
- * from this exponent as follows:
- *
- * 80ns * 2^(period_exponent + 1)
+ * @metric_set: specifies which set of OA unit metrics should be
+ * configured, defining the contents of any OA unit reports. Metric
+ * set ID is returned by the XE_PERF_ADD_CONFIG op of the PREF ioctl
*/
- DRM_XE_OA_PROP_OA_EXPONENT,
+ __u32 metric_set;
/**
- * Specifying this property is only valid when specify a context to
- * filter with DRM_XE_OA_PROP_ENGINE_ID. Specifying this property
- * will hold preemption of the particular engine we want to gather
- * performance data about.
+ * @period_exponent: Specifying this property implicitly requests
+ * periodic OA unit sampling. The sampling period is:
+ *
+ * 2^(period_exponent + 1) / @oa_timestamp_freq
+ *
+ * Set period_exponent *negative* to disable periodic sampling
*/
- DRM_XE_OA_PROP_HOLD_PREEMPTION,
+ __s32 period_exponent;
/**
- * Specify a global OA buffer size to be allocated in bytes. The
- * size specified must be supported by HW (powers of 2 ranging from
- * 128 KB to 128Mb depending on the platform)
+ * @oa_buffer_size: Specify a global OA buffer size to be allocated
+ * in bytes. The size specified must be supported by HW (powers of
+ * 2 ranging from 128 KB to 128Mb depending on the platform). A
+ * value of 0 will choose a default size of 16 MB.
*/
- DRM_XE_OA_PROP_OA_BUFFER_SIZE,
+ __u32 oa_buffer_size;
/**
- * This optional parameter specifies the timer interval in nanoseconds
- * at which the xe driver will check the OA buffer for available data.
- * Minimum allowed value is 100 microseconds. A default value is used by
- * the driver if this parameter is not specified. Note that larger timer
- * values will reduce cpu consumption during OA perf captures. However,
- * excessively large values would potentially result in OA buffer
- * overwrites as captures reach end of the OA buffer.
+ * @poll_period: Specify timer interval in micro-seconds at which
+ * the xe driver will check the OA buffer for available
+ * data. Minimum allowed value is 100 microseconds. A value of 0
+ * selects a default value is used by the driver. Note that larger
+ * timer values will reduce cpu consumption during OA perf
+ * captures. However, excessively large values would potentially
+ * result in OA buffer overwrites as captures reach end of the OA
+ * buffer.
*/
- DRM_XE_OA_PROP_POLL_OA_PERIOD,
+ __u32 poll_period_us;
+
+ /** @open_flags: Flags */
+ __u32 open_flags;
+#define XE_OA_FLAG_FD_CLOEXEC (1 << 0)
+#define XE_OA_FLAG_FD_NONBLOCK (1 << 1)
+#define XE_OA_FLAG_DISABLED (1 << 2)
/**
- * Open the stream for a specific exec queue id (as used with
- * drm_xe_exec). A stream opened for a specific exec queue id this
- * way won't typically require root privileges.
+ * @exec_queue_id: Open the stream for a specific exec queue id (as
+ * used with drm_xe_exec). A stream opened for a specific exec
+ * queue id this way won't typically require root
+ * privileges. Pass a value <= 0 to not specify an exec queue id.
*/
- DRM_XE_OA_PROP_EXEC_QUEUE_ID,
+ __s32 exec_queue_id;
/**
- * This parameter specifies the engine instance and can be passed along
- * with DRM_XE_OA_PROP_EXEC_QUEUE_ID or will default to 0.
+ * @engine_instance: engine instance to use with @exec_queue_id.
*/
- DRM_XE_OA_PROP_OA_ENGINE_INSTANCE,
+ __u32 engine_instance;
- DRM_XE_OA_PROP_MAX /* non-ABI */
-};
-
-struct drm_xe_oa_open_param {
- /** @extensions: Pointer to the first extension struct, if any */
- __u64 extensions;
+ /**
+ * @hold_preemption: If true, this will disable preemption for the
+ * exec queue selected with @exec_queue_id
+ */
+ __u32 hold_preemption;
/**
- * @config_syncobj: (Output) handle to configuration syncobj
+ * @config_syncobj: (output) handle to configuration syncobj
*
* Handle to a syncobj which the kernel will signal after stream
* configuration or re-configuration is complete (after return from
* the ioctl). This handle can be provided as a dependency to the
- * next XE exec ioctl.
+ * next xe exec ioctl to synchronize xe exec with oa config changes
*/
__u32 config_syncobj;
- __u32 reserved;
-
- /** @flags: Flags */
- __u32 flags;
-#define XE_OA_FLAG_FD_CLOEXEC (1 << 0)
-#define XE_OA_FLAG_FD_NONBLOCK (1 << 1)
-#define XE_OA_FLAG_DISABLED (1 << 2)
-
- /** The number of u64 (id, value) pairs */
- __u32 num_properties;
-
- /**
- * Pointer to array of u64 (id, value) pairs configuring the stream
- * to open.
- */
- __u64 properties_ptr;
+ /** @reserved: reserved (MBZ) */
+ __u64 reserved[4];
};
struct drm_xe_oa_record_header {
--
2.41.0
More information about the Intel-xe
mailing list