Skip to content

Commit a61acbb

Browse files
committed
drm/msm: Track "seqno" fences by idr
Previously the (non-fd) fence returned from submit ioctl was a raw seqno, which is scoped to the ring. But from UABI standpoint, the ioctls related to seqno fences all specify a submitqueue. We can take advantage of that to replace the seqno fences with a cyclic idr handle. This is in preperation for moving to drm scheduler, at which point the submit ioctl will return after queuing the submit job to the scheduler, but before the submit is written into the ring (and therefore before a ring seqno has been assigned). Which means we need to replace the dma_fence that userspace may need to wait on with a scheduler fence. Signed-off-by: Rob Clark <[email protected]> Acked-by: Christian König <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rob Clark <[email protected]>
1 parent be40596 commit a61acbb

File tree

7 files changed

+61
-48
lines changed

7 files changed

+61
-48
lines changed

drivers/gpu/drm/msm/msm_drv.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
911911
ktime_t timeout = to_ktime(args->timeout);
912912
struct msm_gpu_submitqueue *queue;
913913
struct msm_gpu *gpu = priv->gpu;
914+
struct dma_fence *fence;
914915
int ret;
915916

916917
if (args->pad) {
@@ -925,10 +926,35 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
925926
if (!queue)
926927
return -ENOENT;
927928

928-
ret = msm_wait_fence(gpu->rb[queue->prio]->fctx, args->fence, &timeout,
929-
true);
929+
/*
930+
* Map submitqueue scoped "seqno" (which is actually an idr key)
931+
* back to underlying dma-fence
932+
*
933+
* The fence is removed from the fence_idr when the submit is
934+
* retired, so if the fence is not found it means there is nothing
935+
* to wait for
936+
*/
937+
ret = mutex_lock_interruptible(&queue->lock);
938+
if (ret)
939+
return ret;
940+
fence = idr_find(&queue->fence_idr, args->fence);
941+
if (fence)
942+
fence = dma_fence_get_rcu(fence);
943+
mutex_unlock(&queue->lock);
944+
945+
if (!fence)
946+
return 0;
930947

948+
ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout));
949+
if (ret == 0) {
950+
ret = -ETIMEDOUT;
951+
} else if (ret != -ERESTARTSYS) {
952+
ret = 0;
953+
}
954+
955+
dma_fence_put(fence);
931956
msm_submitqueue_put(queue);
957+
932958
return ret;
933959
}
934960

drivers/gpu/drm/msm/msm_fence.c

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr,
2424
strncpy(fctx->name, name, sizeof(fctx->name));
2525
fctx->context = dma_fence_context_alloc(1);
2626
fctx->fenceptr = fenceptr;
27-
init_waitqueue_head(&fctx->event);
2827
spin_lock_init(&fctx->spinlock);
2928

3029
return fctx;
@@ -45,53 +44,12 @@ static inline bool fence_completed(struct msm_fence_context *fctx, uint32_t fenc
4544
(int32_t)(*fctx->fenceptr - fence) >= 0;
4645
}
4746

48-
/* legacy path for WAIT_FENCE ioctl: */
49-
int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence,
50-
ktime_t *timeout, bool interruptible)
51-
{
52-
int ret;
53-
54-
if (fence > fctx->last_fence) {
55-
DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n",
56-
fctx->name, fence, fctx->last_fence);
57-
return -EINVAL;
58-
}
59-
60-
if (!timeout) {
61-
/* no-wait: */
62-
ret = fence_completed(fctx, fence) ? 0 : -EBUSY;
63-
} else {
64-
unsigned long remaining_jiffies = timeout_to_jiffies(timeout);
65-
66-
if (interruptible)
67-
ret = wait_event_interruptible_timeout(fctx->event,
68-
fence_completed(fctx, fence),
69-
remaining_jiffies);
70-
else
71-
ret = wait_event_timeout(fctx->event,
72-
fence_completed(fctx, fence),
73-
remaining_jiffies);
74-
75-
if (ret == 0) {
76-
DBG("timeout waiting for fence: %u (completed: %u)",
77-
fence, fctx->completed_fence);
78-
ret = -ETIMEDOUT;
79-
} else if (ret != -ERESTARTSYS) {
80-
ret = 0;
81-
}
82-
}
83-
84-
return ret;
85-
}
86-
8747
/* called from workqueue */
8848
void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence)
8949
{
9050
spin_lock(&fctx->spinlock);
9151
fctx->completed_fence = max(fence, fctx->completed_fence);
9252
spin_unlock(&fctx->spinlock);
93-
94-
wake_up_all(&fctx->event);
9553
}
9654

9755
struct msm_fence {

drivers/gpu/drm/msm/msm_fence.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,13 @@ struct msm_fence_context {
4949
*/
5050
volatile uint32_t *fenceptr;
5151

52-
wait_queue_head_t event;
5352
spinlock_t spinlock;
5453
};
5554

5655
struct msm_fence_context * msm_fence_context_alloc(struct drm_device *dev,
5756
volatile uint32_t *fenceptr, const char *name);
5857
void msm_fence_context_free(struct msm_fence_context *fctx);
5958

60-
int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence,
61-
ktime_t *timeout, bool interruptible);
6259
void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence);
6360

6461
struct dma_fence * msm_fence_alloc(struct msm_fence_context *fctx);

drivers/gpu/drm/msm/msm_gem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ struct msm_gem_submit {
320320
struct ww_acquire_ctx ticket;
321321
uint32_t seqno; /* Sequence number of the submit on the ring */
322322
struct dma_fence *fence;
323+
int fence_id; /* key into queue->fence_idr */
323324
struct msm_gpu_submitqueue *queue;
324325
struct pid *pid; /* submitting process */
325326
bool fault_dumped; /* Limit devcoredump dumping to one per submit */

drivers/gpu/drm/msm/msm_gem_submit.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,14 @@ void __msm_gem_submit_destroy(struct kref *kref)
6868
container_of(kref, struct msm_gem_submit, ref);
6969
unsigned i;
7070

71+
if (submit->fence_id) {
72+
mutex_lock(&submit->queue->lock);
73+
idr_remove(&submit->queue->fence_idr, submit->fence_id);
74+
mutex_unlock(&submit->queue->lock);
75+
}
76+
7177
dma_fence_put(submit->fence);
78+
7279
put_pid(submit->pid);
7380
msm_submitqueue_put(submit->queue);
7481

@@ -872,6 +879,20 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
872879
goto out;
873880
}
874881

882+
/*
883+
* Allocate an id which can be used by WAIT_FENCE ioctl to map back
884+
* to the underlying fence.
885+
*/
886+
mutex_lock(&queue->lock);
887+
submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
888+
submit->fence, 0, INT_MAX, GFP_KERNEL);
889+
mutex_unlock(&queue->lock);
890+
if (submit->fence_id < 0) {
891+
ret = submit->fence_id = 0;
892+
submit->fence_id = 0;
893+
goto out;
894+
}
895+
875896
if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
876897
struct sync_file *sync_file = sync_file_create(submit->fence);
877898
if (!sync_file) {
@@ -886,7 +907,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
886907

887908
msm_gpu_submit(gpu, submit);
888909

889-
args->fence = submit->fence->seqno;
910+
args->fence = submit->fence_id;
890911

891912
msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
892913
msm_process_post_deps(post_deps, args->nr_out_syncobjs,

drivers/gpu/drm/msm/msm_gpu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ struct msm_gpu_perfcntr {
263263
* which set of pgtables do submits jobs associated with the
264264
* submitqueue use)
265265
* @node: node in the context's list of submitqueues
266+
* @fence_idr: maps fence-id to dma_fence for userspace visible fence
267+
* seqno, protected by submitqueue lock
268+
* @lock: submitqueue lock
266269
* @ref: reference count
267270
*/
268271
struct msm_gpu_submitqueue {
@@ -272,6 +275,8 @@ struct msm_gpu_submitqueue {
272275
int faults;
273276
struct msm_file_private *ctx;
274277
struct list_head node;
278+
struct idr fence_idr;
279+
struct mutex lock;
275280
struct kref ref;
276281
};
277282

drivers/gpu/drm/msm/msm_submitqueue.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ void msm_submitqueue_destroy(struct kref *kref)
1212
struct msm_gpu_submitqueue *queue = container_of(kref,
1313
struct msm_gpu_submitqueue, ref);
1414

15+
idr_destroy(&queue->fence_idr);
16+
1517
msm_file_private_put(queue->ctx);
1618

1719
kfree(queue);
@@ -89,6 +91,9 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
8991
if (id)
9092
*id = queue->id;
9193

94+
idr_init(&queue->fence_idr);
95+
mutex_init(&queue->lock);
96+
9297
list_add_tail(&queue->node, &ctx->submitqueues);
9398

9499
write_unlock(&ctx->queuelock);

0 commit comments

Comments
 (0)