Skip to content

Commit 17154ad

Browse files
committed
drm/msm: Add MSM_SUBMIT_FENCE_SN_IN
Add a way for userspace to specify the sequence number fence used to track completion of the submit. As the seqno fence is simply an incrementing counter which is local to the submitqueue, it is easy for userspace to know the next value. This is useful for native userspace drivers in a vm guest, as the guest to host roundtrip can have high latency. Assigning the fence seqno in the guest userspace allows the guest to continue without waiting for response from the host. Signed-off-by: Rob Clark <robdclark@chromium.org> Link: https://lore.kernel.org/r/20220224222321.60653-1-robdclark@gmail.com
1 parent 5f9ffe8 commit 17154ad

3 files changed

Lines changed: 41 additions & 8 deletions

File tree

drivers/gpu/drm/msm/msm_drv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@
4141
* - 1.6.0 - Syncobj support
4242
* - 1.7.0 - Add MSM_PARAM_SUSPENDS to access suspend count
4343
* - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx)
44+
* - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN
4445
*/
4546
#define MSM_VERSION_MAJOR 1
46-
#define MSM_VERSION_MINOR 8
47+
#define MSM_VERSION_MINOR 9
4748
#define MSM_VERSION_PATCHLEVEL 0
4849

4950
static const struct drm_mode_config_funcs mode_config_funcs = {

drivers/gpu/drm/msm/msm_gem_submit.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -872,16 +872,46 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
872872

873873
submit->nr_cmds = i;
874874

875+
/*
876+
* If using userspace provided seqno fence, validate that the id
877+
* is available before arming sched job. Since access to fence_idr
878+
* is serialized on the queue lock, the slot should be still avail
879+
* after the job is armed
880+
*/
881+
if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) &&
882+
idr_find(&queue->fence_idr, args->fence)) {
883+
ret = -EINVAL;
884+
goto out;
885+
}
886+
875887
drm_sched_job_arm(&submit->base);
876888

877889
submit->user_fence = dma_fence_get(&submit->base.s_fence->finished);
878890

879-
/*
880-
* Allocate an id which can be used by WAIT_FENCE ioctl to map back
881-
* to the underlying fence.
882-
*/
883-
submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
884-
submit->user_fence, 1, INT_MAX, GFP_KERNEL);
891+
if (args->flags & MSM_SUBMIT_FENCE_SN_IN) {
892+
/*
893+
* Userspace has assigned the seqno fence that it wants
894+
* us to use. It is an error to pick a fence sequence
895+
* number that is not available.
896+
*/
897+
submit->fence_id = args->fence;
898+
ret = idr_alloc_u32(&queue->fence_idr, submit->user_fence,
899+
&submit->fence_id, submit->fence_id,
900+
GFP_KERNEL);
901+
/*
902+
* We've already validated that the fence_id slot is valid,
903+
* so if idr_alloc_u32 failed, it is a kernel bug
904+
*/
905+
WARN_ON(ret);
906+
} else {
907+
/*
908+
* Allocate an id which can be used by WAIT_FENCE ioctl to map
909+
* back to the underlying fence.
910+
*/
911+
submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
912+
submit->user_fence, 1,
913+
INT_MAX, GFP_KERNEL);
914+
}
885915
if (submit->fence_id < 0) {
886916
ret = submit->fence_id = 0;
887917
submit->fence_id = 0;

include/uapi/drm/msm_drm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,15 @@ struct drm_msm_gem_submit_bo {
232232
#define MSM_SUBMIT_SUDO 0x10000000 /* run submitted cmds from RB */
233233
#define MSM_SUBMIT_SYNCOBJ_IN 0x08000000 /* enable input syncobj */
234234
#define MSM_SUBMIT_SYNCOBJ_OUT 0x04000000 /* enable output syncobj */
235+
#define MSM_SUBMIT_FENCE_SN_IN 0x02000000 /* userspace passes in seqno fence */
235236
#define MSM_SUBMIT_FLAGS ( \
236237
MSM_SUBMIT_NO_IMPLICIT | \
237238
MSM_SUBMIT_FENCE_FD_IN | \
238239
MSM_SUBMIT_FENCE_FD_OUT | \
239240
MSM_SUBMIT_SUDO | \
240241
MSM_SUBMIT_SYNCOBJ_IN | \
241242
MSM_SUBMIT_SYNCOBJ_OUT | \
243+
MSM_SUBMIT_FENCE_SN_IN | \
242244
0)
243245

244246
#define MSM_SUBMIT_SYNCOBJ_RESET 0x00000001 /* Reset syncobj after wait. */
@@ -258,7 +260,7 @@ struct drm_msm_gem_submit_syncobj {
258260
*/
259261
struct drm_msm_gem_submit {
260262
__u32 flags; /* MSM_PIPE_x | MSM_SUBMIT_x */
261-
__u32 fence; /* out */
263+
__u32 fence; /* out (or in with MSM_SUBMIT_FENCE_SN_IN flag) */
262264
__u32 nr_bos; /* in, number of submit_bo's */
263265
__u32 nr_cmds; /* in, number of submit_cmd's */
264266
__u64 bos; /* in, ptr to array of submit_bo's */

0 commit comments

Comments
 (0)