Skip to content

Commit c8507a2

Browse files
committed
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 <[email protected]> Reviewed-by: Jonathan Cavitt <[email protected]> Signed-off-by: Ashutosh Dixit <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent dddcb19 commit c8507a2

File tree

4 files changed

+106
-2
lines changed

4 files changed

+106
-2
lines changed

drivers/gpu/drm/xe/xe_oa.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "xe_pm.h"
3737
#include "xe_sched_job.h"
3838
#include "xe_sriov.h"
39+
#include "xe_sync.h"
3940

4041
#define DEFAULT_POLL_FREQUENCY_HZ 200
4142
#define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
@@ -70,6 +71,7 @@ struct flex {
7071
};
7172

7273
struct xe_oa_open_param {
74+
struct xe_file *xef;
7375
u32 oa_unit_id;
7476
bool sample;
7577
u32 metric_set;
@@ -81,6 +83,9 @@ struct xe_oa_open_param {
8183
struct xe_exec_queue *exec_q;
8284
struct xe_hw_engine *hwe;
8385
bool no_preempt;
86+
struct drm_xe_sync __user *syncs_user;
87+
int num_syncs;
88+
struct xe_sync_entry *syncs;
8489
};
8590

8691
struct xe_oa_config_bo {
@@ -1398,6 +1403,9 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
13981403
stream->period_exponent = param->period_exponent;
13991404
stream->no_preempt = param->no_preempt;
14001405

1406+
stream->num_syncs = param->num_syncs;
1407+
stream->syncs = param->syncs;
1408+
14011409
/*
14021410
* For Xe2+, when overrun mode is enabled, there are no partial reports at the end
14031411
* 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,
17521760
return 0;
17531761
}
17541762

1763+
static int xe_oa_set_prop_num_syncs(struct xe_oa *oa, u64 value,
1764+
struct xe_oa_open_param *param)
1765+
{
1766+
param->num_syncs = value;
1767+
return 0;
1768+
}
1769+
1770+
static int xe_oa_set_prop_syncs_user(struct xe_oa *oa, u64 value,
1771+
struct xe_oa_open_param *param)
1772+
{
1773+
param->syncs_user = u64_to_user_ptr(value);
1774+
return 0;
1775+
}
1776+
17551777
typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value,
17561778
struct xe_oa_open_param *param);
17571779
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[] = {
17641786
[DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id,
17651787
[DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance,
17661788
[DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt,
1789+
[DRM_XE_OA_PROPERTY_NUM_SYNCS] = xe_oa_set_prop_num_syncs,
1790+
[DRM_XE_OA_PROPERTY_SYNCS] = xe_oa_set_prop_syncs_user,
17671791
};
17681792

17691793
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
18231847
return 0;
18241848
}
18251849

1850+
static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param)
1851+
{
1852+
int ret, num_syncs, num_ufence = 0;
1853+
1854+
if (param->num_syncs && !param->syncs_user) {
1855+
drm_dbg(&oa->xe->drm, "num_syncs specified without sync array\n");
1856+
ret = -EINVAL;
1857+
goto exit;
1858+
}
1859+
1860+
if (param->num_syncs) {
1861+
param->syncs = kcalloc(param->num_syncs, sizeof(*param->syncs), GFP_KERNEL);
1862+
if (!param->syncs) {
1863+
ret = -ENOMEM;
1864+
goto exit;
1865+
}
1866+
}
1867+
1868+
for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
1869+
ret = xe_sync_entry_parse(oa->xe, param->xef, &param->syncs[num_syncs],
1870+
&param->syncs_user[num_syncs], 0);
1871+
if (ret)
1872+
goto err_syncs;
1873+
1874+
if (xe_sync_is_ufence(&param->syncs[num_syncs]))
1875+
num_ufence++;
1876+
}
1877+
1878+
if (XE_IOCTL_DBG(oa->xe, num_ufence > 1)) {
1879+
ret = -EINVAL;
1880+
goto err_syncs;
1881+
}
1882+
1883+
return 0;
1884+
1885+
err_syncs:
1886+
while (num_syncs--)
1887+
xe_sync_entry_cleanup(&param->syncs[num_syncs]);
1888+
kfree(param->syncs);
1889+
exit:
1890+
return ret;
1891+
}
1892+
18261893
/**
18271894
* xe_oa_stream_open_ioctl - Opens an OA stream
18281895
* @dev: @drm_device
@@ -1848,6 +1915,7 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
18481915
return -ENODEV;
18491916
}
18501917

1918+
param.xef = xef;
18511919
ret = xe_oa_user_extensions(oa, data, 0, &param);
18521920
if (ret)
18531921
return ret;
@@ -1916,11 +1984,24 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
19161984
drm_dbg(&oa->xe->drm, "Using periodic sampling freq %lld Hz\n", oa_freq_hz);
19171985
}
19181986

1987+
ret = xe_oa_parse_syncs(oa, &param);
1988+
if (ret)
1989+
goto err_exec_q;
1990+
19191991
mutex_lock(&param.hwe->gt->oa.gt_lock);
19201992
ret = xe_oa_stream_open_ioctl_locked(oa, &param);
19211993
mutex_unlock(&param.hwe->gt->oa.gt_lock);
1994+
if (ret < 0)
1995+
goto err_sync_cleanup;
1996+
1997+
return ret;
1998+
1999+
err_sync_cleanup:
2000+
while (param.num_syncs--)
2001+
xe_sync_entry_cleanup(&param.syncs[param.num_syncs]);
2002+
kfree(param.syncs);
19222003
err_exec_q:
1923-
if (ret < 0 && param.exec_q)
2004+
if (param.exec_q)
19242005
xe_exec_queue_put(param.exec_q);
19252006
return ret;
19262007
}

drivers/gpu/drm/xe/xe_oa_types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,5 +238,11 @@ struct xe_oa_stream {
238238

239239
/** @no_preempt: Whether preemption and timeslicing is disabled for stream exec_q */
240240
u32 no_preempt;
241+
242+
/** @num_syncs: size of @syncs array */
243+
u32 num_syncs;
244+
245+
/** @syncs: syncs to wait on and to signal */
246+
struct xe_sync_entry *syncs;
241247
};
242248
#endif

drivers/gpu/drm/xe/xe_query.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ static int query_oa_units(struct xe_device *xe,
670670
du->oa_unit_id = u->oa_unit_id;
671671
du->oa_unit_type = u->type;
672672
du->oa_timestamp_freq = xe_oa_timestamp_frequency(gt);
673-
du->capabilities = DRM_XE_OA_CAPS_BASE;
673+
du->capabilities = DRM_XE_OA_CAPS_BASE | DRM_XE_OA_CAPS_SYNCS;
674674

675675
j = 0;
676676
for_each_hw_engine(hwe, gt, hwe_id) {

include/uapi/drm/xe_drm.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,7 @@ struct drm_xe_oa_unit {
14851485
/** @capabilities: OA capabilities bit-mask */
14861486
__u64 capabilities;
14871487
#define DRM_XE_OA_CAPS_BASE (1 << 0)
1488+
#define DRM_XE_OA_CAPS_SYNCS (1 << 1)
14881489

14891490
/** @oa_timestamp_freq: OA timestamp freq */
14901491
__u64 oa_timestamp_freq;
@@ -1634,6 +1635,22 @@ enum drm_xe_oa_property_id {
16341635
* to be disabled for the stream exec queue.
16351636
*/
16361637
DRM_XE_OA_PROPERTY_NO_PREEMPT,
1638+
1639+
/**
1640+
* @DRM_XE_OA_PROPERTY_NUM_SYNCS: Number of syncs in the sync array
1641+
* specified in @DRM_XE_OA_PROPERTY_SYNCS
1642+
*/
1643+
DRM_XE_OA_PROPERTY_NUM_SYNCS,
1644+
1645+
/**
1646+
* @DRM_XE_OA_PROPERTY_SYNCS: Pointer to struct @drm_xe_sync array
1647+
* with array size specified via @DRM_XE_OA_PROPERTY_NUM_SYNCS. OA
1648+
* configuration will wait till input fences signal. Output fences
1649+
* will signal after the new OA configuration takes effect. For
1650+
* @DRM_XE_SYNC_TYPE_USER_FENCE, @addr is a user pointer, similar
1651+
* to the VM bind case.
1652+
*/
1653+
DRM_XE_OA_PROPERTY_SYNCS,
16371654
};
16381655

16391656
/**

0 commit comments

Comments
 (0)