Skip to content

Commit bf6811f

Browse files
committed
drm/msm: handle read vs write fences
The userspace API already had everything needed to handle read vs write synchronization. This patch actually bothers to hook it up properly, so that we don't need to (for example) stall on userspace read access to a buffer that gpu is also still reading. Signed-off-by: Rob Clark <[email protected]>
1 parent 86a7e12 commit bf6811f

File tree

4 files changed

+27
-11
lines changed

4 files changed

+27
-11
lines changed

drivers/gpu/drm/msm/msm_drv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void *msm_gem_vaddr(struct drm_gem_object *obj);
153153
int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
154154
struct work_struct *work);
155155
void msm_gem_move_to_active(struct drm_gem_object *obj,
156-
struct msm_gpu *gpu, uint32_t fence);
156+
struct msm_gpu *gpu, bool write, uint32_t fence);
157157
void msm_gem_move_to_inactive(struct drm_gem_object *obj);
158158
int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
159159
struct timespec *timeout);

drivers/gpu/drm/msm/msm_gem.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,14 @@ int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
393393
}
394394

395395
void msm_gem_move_to_active(struct drm_gem_object *obj,
396-
struct msm_gpu *gpu, uint32_t fence)
396+
struct msm_gpu *gpu, bool write, uint32_t fence)
397397
{
398398
struct msm_gem_object *msm_obj = to_msm_bo(obj);
399399
msm_obj->gpu = gpu;
400-
msm_obj->fence = fence;
400+
if (write)
401+
msm_obj->write_fence = fence;
402+
else
403+
msm_obj->read_fence = fence;
401404
list_del_init(&msm_obj->mm_list);
402405
list_add_tail(&msm_obj->mm_list, &gpu->active_list);
403406
}
@@ -411,7 +414,8 @@ void msm_gem_move_to_inactive(struct drm_gem_object *obj)
411414
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
412415

413416
msm_obj->gpu = NULL;
414-
msm_obj->fence = 0;
417+
msm_obj->read_fence = 0;
418+
msm_obj->write_fence = 0;
415419
list_del_init(&msm_obj->mm_list);
416420
list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
417421

@@ -433,8 +437,14 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
433437
struct msm_gem_object *msm_obj = to_msm_bo(obj);
434438
int ret = 0;
435439

436-
if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC))
437-
ret = msm_wait_fence_interruptable(dev, msm_obj->fence, timeout);
440+
if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC)) {
441+
uint32_t fence = 0;
442+
if (op & MSM_PREP_READ)
443+
fence = msm_obj->write_fence;
444+
if (op & MSM_PREP_WRITE)
445+
fence = max(fence, msm_obj->read_fence);
446+
ret = msm_wait_fence_interruptable(dev, fence, timeout);
447+
}
438448

439449
/* TODO cache maintenance */
440450

@@ -455,9 +465,10 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
455465
uint64_t off = drm_vma_node_start(&obj->vma_node);
456466

457467
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
458-
seq_printf(m, "%08x: %c(%d) %2d (%2d) %08llx %p %d\n",
468+
seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %d\n",
459469
msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
460-
msm_obj->fence, obj->name, obj->refcount.refcount.counter,
470+
msm_obj->read_fence, msm_obj->write_fence,
471+
obj->name, obj->refcount.refcount.counter,
461472
off, msm_obj->vaddr, obj->size);
462473
}
463474

drivers/gpu/drm/msm/msm_gem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct msm_gem_object {
3636
*/
3737
struct list_head mm_list;
3838
struct msm_gpu *gpu; /* non-null if active */
39-
uint32_t fence;
39+
uint32_t read_fence, write_fence;
4040

4141
/* Transiently in the process of submit ioctl, objects associated
4242
* with the submit are on submit->bo_list.. this only lasts for

drivers/gpu/drm/msm/msm_gpu.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ static void retire_worker(struct work_struct *work)
265265
obj = list_first_entry(&gpu->active_list,
266266
struct msm_gem_object, mm_list);
267267

268-
if (obj->fence <= fence) {
268+
if ((obj->read_fence <= fence) &&
269+
(obj->write_fence <= fence)) {
269270
/* move to inactive: */
270271
msm_gem_move_to_inactive(&obj->base);
271272
msm_gem_put_iova(&obj->base, gpu->id);
@@ -321,7 +322,11 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
321322
submit->gpu->id, &iova);
322323
}
323324

324-
msm_gem_move_to_active(&msm_obj->base, gpu, submit->fence);
325+
if (submit->bos[i].flags & MSM_SUBMIT_BO_READ)
326+
msm_gem_move_to_active(&msm_obj->base, gpu, false, submit->fence);
327+
328+
if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE)
329+
msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence);
325330
}
326331
hangcheck_timer_reset(gpu);
327332
mutex_unlock(&dev->struct_mutex);

0 commit comments

Comments
 (0)