mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
drm/xe/oa/uapi: Define and parse OA sync properties
Now that we have laid the groundwork, introduce OA sync properties in the
uapi and parse the input xe_sync array as is done elsewhere in the
driver. Also add DRM_XE_OA_CAPS_SYNCS bit in OA capabilities for userspace.
v2: Fix and document DRM_XE_SYNC_TYPE_USER_FENCE for OA (Matt B)
Add DRM_XE_OA_CAPS_SYNCS bit to OA capabilities (Jose)
Acked-by: José Roberto de Souza <jose.souza@intel.com>
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-3-ashutosh.dixit@intel.com
This commit is contained in:
parent
dddcb19ad4
commit
c8507a25ce
|
|
@ -36,6 +36,7 @@
|
||||||
#include "xe_pm.h"
|
#include "xe_pm.h"
|
||||||
#include "xe_sched_job.h"
|
#include "xe_sched_job.h"
|
||||||
#include "xe_sriov.h"
|
#include "xe_sriov.h"
|
||||||
|
#include "xe_sync.h"
|
||||||
|
|
||||||
#define DEFAULT_POLL_FREQUENCY_HZ 200
|
#define DEFAULT_POLL_FREQUENCY_HZ 200
|
||||||
#define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
|
#define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
|
||||||
|
|
@ -70,6 +71,7 @@ struct flex {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xe_oa_open_param {
|
struct xe_oa_open_param {
|
||||||
|
struct xe_file *xef;
|
||||||
u32 oa_unit_id;
|
u32 oa_unit_id;
|
||||||
bool sample;
|
bool sample;
|
||||||
u32 metric_set;
|
u32 metric_set;
|
||||||
|
|
@ -81,6 +83,9 @@ struct xe_oa_open_param {
|
||||||
struct xe_exec_queue *exec_q;
|
struct xe_exec_queue *exec_q;
|
||||||
struct xe_hw_engine *hwe;
|
struct xe_hw_engine *hwe;
|
||||||
bool no_preempt;
|
bool no_preempt;
|
||||||
|
struct drm_xe_sync __user *syncs_user;
|
||||||
|
int num_syncs;
|
||||||
|
struct xe_sync_entry *syncs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xe_oa_config_bo {
|
struct xe_oa_config_bo {
|
||||||
|
|
@ -1398,6 +1403,9 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
|
||||||
stream->period_exponent = param->period_exponent;
|
stream->period_exponent = param->period_exponent;
|
||||||
stream->no_preempt = param->no_preempt;
|
stream->no_preempt = param->no_preempt;
|
||||||
|
|
||||||
|
stream->num_syncs = param->num_syncs;
|
||||||
|
stream->syncs = param->syncs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For Xe2+, when overrun mode is enabled, there are no partial reports at the end
|
* For Xe2+, when overrun mode is enabled, there are no partial reports at the end
|
||||||
* of buffer, making the OA buffer effectively a non-power-of-2 size circular
|
* of buffer, making the OA buffer effectively a non-power-of-2 size circular
|
||||||
|
|
@ -1752,6 +1760,20 @@ static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
|
||||||
return 0;
|
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,
|
typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
|
||||||
struct xe_oa_open_param *param);
|
struct xe_oa_open_param *param);
|
||||||
static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
|
static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
|
||||||
|
|
@ -1764,6 +1786,8 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
|
||||||
[DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
|
[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_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
|
||||||
[DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
|
[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,
|
static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension,
|
||||||
|
|
@ -1823,6 +1847,49 @@ static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number
|
||||||
return 0;
|
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, ¶m->syncs[num_syncs],
|
||||||
|
¶m->syncs_user[num_syncs], 0);
|
||||||
|
if (ret)
|
||||||
|
goto err_syncs;
|
||||||
|
|
||||||
|
if (xe_sync_is_ufence(¶m->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(¶m->syncs[num_syncs]);
|
||||||
|
kfree(param->syncs);
|
||||||
|
exit:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xe_oa_stream_open_ioctl - Opens an OA stream
|
* xe_oa_stream_open_ioctl - Opens an OA stream
|
||||||
* @dev: @drm_device
|
* @dev: @drm_device
|
||||||
|
|
@ -1848,6 +1915,7 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
param.xef = xef;
|
||||||
ret = xe_oa_user_extensions(oa, data, 0, ¶m);
|
ret = xe_oa_user_extensions(oa, data, 0, ¶m);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -1916,11 +1984,24 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
|
||||||
drm_dbg(&oa->xe->drm, "Using periodic sampling freq %lld Hz\n", oa_freq_hz);
|
drm_dbg(&oa->xe->drm, "Using periodic sampling freq %lld Hz\n", oa_freq_hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = xe_oa_parse_syncs(oa, ¶m);
|
||||||
|
if (ret)
|
||||||
|
goto err_exec_q;
|
||||||
|
|
||||||
mutex_lock(¶m.hwe->gt->oa.gt_lock);
|
mutex_lock(¶m.hwe->gt->oa.gt_lock);
|
||||||
ret = xe_oa_stream_open_ioctl_locked(oa, ¶m);
|
ret = xe_oa_stream_open_ioctl_locked(oa, ¶m);
|
||||||
mutex_unlock(¶m.hwe->gt->oa.gt_lock);
|
mutex_unlock(¶m.hwe->gt->oa.gt_lock);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err_sync_cleanup;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
err_sync_cleanup:
|
||||||
|
while (param.num_syncs--)
|
||||||
|
xe_sync_entry_cleanup(¶m.syncs[param.num_syncs]);
|
||||||
|
kfree(param.syncs);
|
||||||
err_exec_q:
|
err_exec_q:
|
||||||
if (ret < 0 && param.exec_q)
|
if (param.exec_q)
|
||||||
xe_exec_queue_put(param.exec_q);
|
xe_exec_queue_put(param.exec_q);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,5 +238,11 @@ struct xe_oa_stream {
|
||||||
|
|
||||||
/** @no_preempt: Whether preemption and timeslicing is disabled for stream exec_q */
|
/** @no_preempt: Whether preemption and timeslicing is disabled for stream exec_q */
|
||||||
u32 no_preempt;
|
u32 no_preempt;
|
||||||
|
|
||||||
|
/** @num_syncs: size of @syncs array */
|
||||||
|
u32 num_syncs;
|
||||||
|
|
||||||
|
/** @syncs: syncs to wait on and to signal */
|
||||||
|
struct xe_sync_entry *syncs;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -670,7 +670,7 @@ static int query_oa_units(struct xe_device *xe,
|
||||||
du->oa_unit_id = u->oa_unit_id;
|
du->oa_unit_id = u->oa_unit_id;
|
||||||
du->oa_unit_type = u->type;
|
du->oa_unit_type = u->type;
|
||||||
du->oa_timestamp_freq = xe_oa_timestamp_frequency(gt);
|
du->oa_timestamp_freq = xe_oa_timestamp_frequency(gt);
|
||||||
du->capabilities = DRM_XE_OA_CAPS_BASE;
|
du->capabilities = DRM_XE_OA_CAPS_BASE | DRM_XE_OA_CAPS_SYNCS;
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for_each_hw_engine(hwe, gt, hwe_id) {
|
for_each_hw_engine(hwe, gt, hwe_id) {
|
||||||
|
|
|
||||||
|
|
@ -1485,6 +1485,7 @@ struct drm_xe_oa_unit {
|
||||||
/** @capabilities: OA capabilities bit-mask */
|
/** @capabilities: OA capabilities bit-mask */
|
||||||
__u64 capabilities;
|
__u64 capabilities;
|
||||||
#define DRM_XE_OA_CAPS_BASE (1 << 0)
|
#define DRM_XE_OA_CAPS_BASE (1 << 0)
|
||||||
|
#define DRM_XE_OA_CAPS_SYNCS (1 << 1)
|
||||||
|
|
||||||
/** @oa_timestamp_freq: OA timestamp freq */
|
/** @oa_timestamp_freq: OA timestamp freq */
|
||||||
__u64 oa_timestamp_freq;
|
__u64 oa_timestamp_freq;
|
||||||
|
|
@ -1634,6 +1635,22 @@ enum drm_xe_oa_property_id {
|
||||||
* to be disabled for the stream exec queue.
|
* to be disabled for the stream exec queue.
|
||||||
*/
|
*/
|
||||||
DRM_XE_OA_PROPERTY_NO_PREEMPT,
|
DRM_XE_OA_PROPERTY_NO_PREEMPT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @DRM_XE_OA_PROPERTY_NUM_SYNCS: Number of syncs in the sync array
|
||||||
|
* specified in @DRM_XE_OA_PROPERTY_SYNCS
|
||||||
|
*/
|
||||||
|
DRM_XE_OA_PROPERTY_NUM_SYNCS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @DRM_XE_OA_PROPERTY_SYNCS: Pointer to struct @drm_xe_sync array
|
||||||
|
* with array size specified via @DRM_XE_OA_PROPERTY_NUM_SYNCS. OA
|
||||||
|
* configuration will wait till input fences signal. Output fences
|
||||||
|
* will signal after the new OA configuration takes effect. For
|
||||||
|
* @DRM_XE_SYNC_TYPE_USER_FENCE, @addr is a user pointer, similar
|
||||||
|
* to the VM bind case.
|
||||||
|
*/
|
||||||
|
DRM_XE_OA_PROPERTY_SYNCS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user