+7
-7
drivers/gpu/drm/xe/xe_device.c
+7
-7
drivers/gpu/drm/xe/xe_device.c
···
988
988
989
989
drm_dbg(&xe->drm, "Shutting down device\n");
990
990
991
-
if (xe_driver_flr_disabled(xe)) {
992
-
xe_display_pm_shutdown(xe);
991
+
xe_display_pm_shutdown(xe);
993
992
994
-
xe_irq_suspend(xe);
993
+
xe_irq_suspend(xe);
995
994
996
-
for_each_gt(gt, xe, id)
997
-
xe_gt_shutdown(gt);
995
+
for_each_gt(gt, xe, id)
996
+
xe_gt_shutdown(gt);
998
997
999
-
xe_display_pm_shutdown_late(xe);
1000
-
} else {
998
+
xe_display_pm_shutdown_late(xe);
999
+
1000
+
if (!xe_driver_flr_disabled(xe)) {
1001
1001
/* BOOM! */
1002
1002
__xe_driver_flr(xe);
1003
1003
}
+2
-1
drivers/gpu/drm/xe/xe_exec.c
+2
-1
drivers/gpu/drm/xe/xe_exec.c
···
165
165
166
166
for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
167
167
err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
168
-
&syncs_user[num_syncs], SYNC_PARSE_FLAG_EXEC |
168
+
&syncs_user[num_syncs], NULL, 0,
169
+
SYNC_PARSE_FLAG_EXEC |
169
170
(xe_vm_in_lr_mode(vm) ?
170
171
SYNC_PARSE_FLAG_LR_MODE : 0));
171
172
if (err)
+14
drivers/gpu/drm/xe/xe_exec_queue.c
+14
drivers/gpu/drm/xe/xe_exec_queue.c
···
10
10
#include <drm/drm_device.h>
11
11
#include <drm/drm_drv.h>
12
12
#include <drm/drm_file.h>
13
+
#include <drm/drm_syncobj.h>
13
14
#include <uapi/drm/xe_drm.h>
14
15
15
16
#include "xe_dep_scheduler.h"
···
325
324
}
326
325
xe_vm_put(migrate_vm);
327
326
327
+
if (!IS_ERR(q)) {
328
+
int err = drm_syncobj_create(&q->ufence_syncobj,
329
+
DRM_SYNCOBJ_CREATE_SIGNALED,
330
+
NULL);
331
+
if (err) {
332
+
xe_exec_queue_put(q);
333
+
return ERR_PTR(err);
334
+
}
335
+
}
336
+
328
337
return q;
329
338
}
330
339
ALLOW_ERROR_INJECTION(xe_exec_queue_create_bind, ERRNO);
···
343
332
{
344
333
struct xe_exec_queue *q = container_of(ref, struct xe_exec_queue, refcount);
345
334
struct xe_exec_queue *eq, *next;
335
+
336
+
if (q->ufence_syncobj)
337
+
drm_syncobj_put(q->ufence_syncobj);
346
338
347
339
if (xe_exec_queue_uses_pxp(q))
348
340
xe_pxp_exec_queue_remove(gt_to_xe(q->gt)->pxp, q);
+7
drivers/gpu/drm/xe/xe_exec_queue_types.h
+7
drivers/gpu/drm/xe/xe_exec_queue_types.h
···
15
15
#include "xe_hw_fence_types.h"
16
16
#include "xe_lrc_types.h"
17
17
18
+
struct drm_syncobj;
18
19
struct xe_execlist_exec_queue;
19
20
struct xe_gt;
20
21
struct xe_guc_exec_queue;
···
155
154
/** @pxp.link: link into the list of PXP exec queues */
156
155
struct list_head link;
157
156
} pxp;
157
+
158
+
/** @ufence_syncobj: User fence syncobj */
159
+
struct drm_syncobj *ufence_syncobj;
160
+
161
+
/** @ufence_timeline_value: User fence timeline value */
162
+
u64 ufence_timeline_value;
158
163
159
164
/** @ops: submission backend exec queue operations */
160
165
const struct xe_exec_queue_ops *ops;
+3
drivers/gpu/drm/xe/xe_guc_ct.c
+3
drivers/gpu/drm/xe/xe_guc_ct.c
+30
-15
drivers/gpu/drm/xe/xe_oa.c
+30
-15
drivers/gpu/drm/xe/xe_oa.c
···
10
10
11
11
#include <drm/drm_drv.h>
12
12
#include <drm/drm_managed.h>
13
+
#include <drm/drm_syncobj.h>
13
14
#include <uapi/drm/xe_drm.h>
14
15
15
16
#include <generated/xe_wa_oob.h>
···
1390
1389
return 0;
1391
1390
}
1392
1391
1393
-
static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param)
1392
+
static int xe_oa_parse_syncs(struct xe_oa *oa,
1393
+
struct xe_oa_stream *stream,
1394
+
struct xe_oa_open_param *param)
1394
1395
{
1395
1396
int ret, num_syncs, num_ufence = 0;
1396
1397
···
1412
1409
1413
1410
for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
1414
1411
ret = xe_sync_entry_parse(oa->xe, param->xef, ¶m->syncs[num_syncs],
1415
-
¶m->syncs_user[num_syncs], 0);
1412
+
¶m->syncs_user[num_syncs],
1413
+
stream->ufence_syncobj,
1414
+
++stream->ufence_timeline_value, 0);
1416
1415
if (ret)
1417
1416
goto err_syncs;
1418
1417
···
1544
1539
return -ENODEV;
1545
1540
1546
1541
param.xef = stream->xef;
1547
-
err = xe_oa_parse_syncs(stream->oa, ¶m);
1542
+
err = xe_oa_parse_syncs(stream->oa, stream, ¶m);
1548
1543
if (err)
1549
1544
goto err_config_put;
1550
1545
···
1640
1635
if (stream->exec_q)
1641
1636
xe_exec_queue_put(stream->exec_q);
1642
1637
1638
+
drm_syncobj_put(stream->ufence_syncobj);
1643
1639
kfree(stream);
1644
1640
}
1645
1641
···
1832
1826
struct xe_oa_open_param *param)
1833
1827
{
1834
1828
struct xe_oa_stream *stream;
1829
+
struct drm_syncobj *ufence_syncobj;
1835
1830
int stream_fd;
1836
1831
int ret;
1837
1832
···
1843
1836
goto exit;
1844
1837
}
1845
1838
1839
+
ret = drm_syncobj_create(&ufence_syncobj, DRM_SYNCOBJ_CREATE_SIGNALED,
1840
+
NULL);
1841
+
if (ret)
1842
+
goto exit;
1843
+
1846
1844
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
1847
1845
if (!stream) {
1848
1846
ret = -ENOMEM;
1849
-
goto exit;
1847
+
goto err_syncobj;
1850
1848
}
1851
-
1849
+
stream->ufence_syncobj = ufence_syncobj;
1852
1850
stream->oa = oa;
1853
-
ret = xe_oa_stream_init(stream, param);
1851
+
1852
+
ret = xe_oa_parse_syncs(oa, stream, param);
1854
1853
if (ret)
1855
1854
goto err_free;
1855
+
1856
+
ret = xe_oa_stream_init(stream, param);
1857
+
if (ret) {
1858
+
while (param->num_syncs--)
1859
+
xe_sync_entry_cleanup(¶m->syncs[param->num_syncs]);
1860
+
kfree(param->syncs);
1861
+
goto err_free;
1862
+
}
1856
1863
1857
1864
if (!param->disabled) {
1858
1865
ret = xe_oa_enable_locked(stream);
···
1891
1870
xe_oa_stream_destroy(stream);
1892
1871
err_free:
1893
1872
kfree(stream);
1873
+
err_syncobj:
1874
+
drm_syncobj_put(ufence_syncobj);
1894
1875
exit:
1895
1876
return ret;
1896
1877
}
···
2106
2083
goto err_exec_q;
2107
2084
}
2108
2085
2109
-
ret = xe_oa_parse_syncs(oa, ¶m);
2110
-
if (ret)
2111
-
goto err_exec_q;
2112
-
2113
2086
mutex_lock(¶m.hwe->gt->oa.gt_lock);
2114
2087
ret = xe_oa_stream_open_ioctl_locked(oa, ¶m);
2115
2088
mutex_unlock(¶m.hwe->gt->oa.gt_lock);
2116
2089
if (ret < 0)
2117
-
goto err_sync_cleanup;
2090
+
goto err_exec_q;
2118
2091
2119
2092
return ret;
2120
2093
2121
-
err_sync_cleanup:
2122
-
while (param.num_syncs--)
2123
-
xe_sync_entry_cleanup(¶m.syncs[param.num_syncs]);
2124
-
kfree(param.syncs);
2125
2094
err_exec_q:
2126
2095
if (param.exec_q)
2127
2096
xe_exec_queue_put(param.exec_q);
+8
drivers/gpu/drm/xe/xe_oa_types.h
+8
drivers/gpu/drm/xe/xe_oa_types.h
···
15
15
#include "regs/xe_reg_defs.h"
16
16
#include "xe_hw_engine_types.h"
17
17
18
+
struct drm_syncobj;
19
+
18
20
#define DEFAULT_XE_OA_BUFFER_SIZE SZ_16M
19
21
20
22
enum xe_oa_report_header {
···
249
247
250
248
/** @xef: xe_file with which the stream was opened */
251
249
struct xe_file *xef;
250
+
251
+
/** @ufence_syncobj: User fence syncobj */
252
+
struct drm_syncobj *ufence_syncobj;
253
+
254
+
/** @ufence_timeline_value: User fence timeline value */
255
+
u64 ufence_timeline_value;
252
256
253
257
/** @last_fence: fence to use in stream destroy when needed */
254
258
struct dma_fence *last_fence;
+15
-2
drivers/gpu/drm/xe/xe_sync.c
+15
-2
drivers/gpu/drm/xe/xe_sync.c
···
113
113
int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
114
114
struct xe_sync_entry *sync,
115
115
struct drm_xe_sync __user *sync_user,
116
+
struct drm_syncobj *ufence_syncobj,
117
+
u64 ufence_timeline_value,
116
118
unsigned int flags)
117
119
{
118
120
struct drm_xe_sync sync_in;
···
194
192
if (exec) {
195
193
sync->addr = sync_in.addr;
196
194
} else {
195
+
sync->ufence_timeline_value = ufence_timeline_value;
197
196
sync->ufence = user_fence_create(xe, sync_in.addr,
198
197
sync_in.timeline_value);
199
198
if (XE_IOCTL_DBG(xe, IS_ERR(sync->ufence)))
200
199
return PTR_ERR(sync->ufence);
200
+
sync->ufence_chain_fence = dma_fence_chain_alloc();
201
+
if (!sync->ufence_chain_fence)
202
+
return -ENOMEM;
203
+
sync->ufence_syncobj = ufence_syncobj;
201
204
}
202
205
203
206
break;
···
246
239
} else if (sync->ufence) {
247
240
int err;
248
241
249
-
dma_fence_get(fence);
242
+
drm_syncobj_add_point(sync->ufence_syncobj,
243
+
sync->ufence_chain_fence,
244
+
fence, sync->ufence_timeline_value);
245
+
sync->ufence_chain_fence = NULL;
246
+
247
+
fence = drm_syncobj_fence_get(sync->ufence_syncobj);
250
248
user_fence_get(sync->ufence);
251
249
err = dma_fence_add_callback(fence, &sync->ufence->cb,
252
250
user_fence_cb);
···
271
259
drm_syncobj_put(sync->syncobj);
272
260
dma_fence_put(sync->fence);
273
261
dma_fence_chain_free(sync->chain_fence);
274
-
if (sync->ufence)
262
+
dma_fence_chain_free(sync->ufence_chain_fence);
263
+
if (!IS_ERR_OR_NULL(sync->ufence))
275
264
user_fence_put(sync->ufence);
276
265
}
277
266
+3
drivers/gpu/drm/xe/xe_sync.h
+3
drivers/gpu/drm/xe/xe_sync.h
···
8
8
9
9
#include "xe_sync_types.h"
10
10
11
+
struct drm_syncobj;
11
12
struct xe_device;
12
13
struct xe_exec_queue;
13
14
struct xe_file;
···
22
21
int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
23
22
struct xe_sync_entry *sync,
24
23
struct drm_xe_sync __user *sync_user,
24
+
struct drm_syncobj *ufence_syncobj,
25
+
u64 ufence_timeline_value,
25
26
unsigned int flags);
26
27
int xe_sync_entry_add_deps(struct xe_sync_entry *sync,
27
28
struct xe_sched_job *job);
+3
drivers/gpu/drm/xe/xe_sync_types.h
+3
drivers/gpu/drm/xe/xe_sync_types.h
···
18
18
struct drm_syncobj *syncobj;
19
19
struct dma_fence *fence;
20
20
struct dma_fence_chain *chain_fence;
21
+
struct dma_fence_chain *ufence_chain_fence;
22
+
struct drm_syncobj *ufence_syncobj;
21
23
struct xe_user_fence *ufence;
22
24
u64 addr;
23
25
u64 timeline_value;
26
+
u64 ufence_timeline_value;
24
27
u32 type;
25
28
u32 flags;
26
29
};
+4
drivers/gpu/drm/xe/xe_vm.c
+4
drivers/gpu/drm/xe/xe_vm.c
···
3606
3606
3607
3607
syncs_user = u64_to_user_ptr(args->syncs);
3608
3608
for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
3609
+
struct xe_exec_queue *__q = q ?: vm->q[0];
3610
+
3609
3611
err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
3610
3612
&syncs_user[num_syncs],
3613
+
__q->ufence_syncobj,
3614
+
++__q->ufence_timeline_value,
3611
3615
(xe_vm_in_lr_mode(vm) ?
3612
3616
SYNC_PARSE_FLAG_LR_MODE : 0) |
3613
3617
(!args->num_binds ?