Skip to content

Commit 7f2a0b5

Browse files
committed
drm/nouveau: fence: separate fence alloc and emit
The new (VM_BIND) UAPI exports DMA fences through DRM syncobjs. Hence, in order to emit fences within DMA fence signalling critical sections (e.g. as typically done in the DRM GPU schedulers run_job() callback) we need to separate fence allocation and fence emitting. Reviewed-by: Dave Airlie <[email protected]> Signed-off-by: Danilo Krummrich <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent fbc0ced commit 7f2a0b5

File tree

7 files changed

+59
-41
lines changed

7 files changed

+59
-41
lines changed

drivers/gpu/drm/nouveau/dispnv04/crtc.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,11 +1122,18 @@ nv04_page_flip_emit(struct nouveau_channel *chan,
11221122
PUSH_NVSQ(push, NV_SW, NV_SW_PAGE_FLIP, 0x00000000);
11231123
PUSH_KICK(push);
11241124

1125-
ret = nouveau_fence_new(chan, false, pfence);
1125+
ret = nouveau_fence_new(pfence);
11261126
if (ret)
11271127
goto fail;
11281128

1129+
ret = nouveau_fence_emit(*pfence, chan);
1130+
if (ret)
1131+
goto fail_fence_unref;
1132+
11291133
return 0;
1134+
1135+
fail_fence_unref:
1136+
nouveau_fence_unref(pfence);
11301137
fail:
11311138
spin_lock_irqsave(&dev->event_lock, flags);
11321139
list_del(&s->head);

drivers/gpu/drm/nouveau/nouveau_bo.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -823,29 +823,39 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict,
823823
mutex_lock(&cli->mutex);
824824
else
825825
mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING);
826+
826827
ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, ctx->interruptible);
827-
if (ret == 0) {
828-
ret = drm->ttm.move(chan, bo, bo->resource, new_reg);
829-
if (ret == 0) {
830-
ret = nouveau_fence_new(chan, false, &fence);
831-
if (ret == 0) {
832-
/* TODO: figure out a better solution here
833-
*
834-
* wait on the fence here explicitly as going through
835-
* ttm_bo_move_accel_cleanup somehow doesn't seem to do it.
836-
*
837-
* Without this the operation can timeout and we'll fallback to a
838-
* software copy, which might take several minutes to finish.
839-
*/
840-
nouveau_fence_wait(fence, false, false);
841-
ret = ttm_bo_move_accel_cleanup(bo,
842-
&fence->base,
843-
evict, false,
844-
new_reg);
845-
nouveau_fence_unref(&fence);
846-
}
847-
}
828+
if (ret)
829+
goto out_unlock;
830+
831+
ret = drm->ttm.move(chan, bo, bo->resource, new_reg);
832+
if (ret)
833+
goto out_unlock;
834+
835+
ret = nouveau_fence_new(&fence);
836+
if (ret)
837+
goto out_unlock;
838+
839+
ret = nouveau_fence_emit(fence, chan);
840+
if (ret) {
841+
nouveau_fence_unref(&fence);
842+
goto out_unlock;
848843
}
844+
845+
/* TODO: figure out a better solution here
846+
*
847+
* wait on the fence here explicitly as going through
848+
* ttm_bo_move_accel_cleanup somehow doesn't seem to do it.
849+
*
850+
* Without this the operation can timeout and we'll fallback to a
851+
* software copy, which might take several minutes to finish.
852+
*/
853+
nouveau_fence_wait(fence, false, false);
854+
ret = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, false,
855+
new_reg);
856+
nouveau_fence_unref(&fence);
857+
858+
out_unlock:
849859
mutex_unlock(&cli->mutex);
850860
return ret;
851861
}

drivers/gpu/drm/nouveau/nouveau_chan.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ nouveau_channel_idle(struct nouveau_channel *chan)
6262
struct nouveau_fence *fence = NULL;
6363
int ret;
6464

65-
ret = nouveau_fence_new(chan, false, &fence);
65+
ret = nouveau_fence_new(&fence);
6666
if (!ret) {
67-
ret = nouveau_fence_wait(fence, false, false);
67+
ret = nouveau_fence_emit(fence, chan);
68+
if (!ret)
69+
ret = nouveau_fence_wait(fence, false, false);
6870
nouveau_fence_unref(&fence);
6971
}
7072

drivers/gpu/drm/nouveau/nouveau_dmem.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
209209
goto done;
210210
}
211211

212-
nouveau_fence_new(dmem->migrate.chan, false, &fence);
212+
if (!nouveau_fence_new(&fence))
213+
nouveau_fence_emit(fence, dmem->migrate.chan);
213214
migrate_vma_pages(&args);
214215
nouveau_dmem_fence_done(&fence);
215216
dma_unmap_page(drm->dev->dev, dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
@@ -402,7 +403,8 @@ nouveau_dmem_evict_chunk(struct nouveau_dmem_chunk *chunk)
402403
}
403404
}
404405

405-
nouveau_fence_new(chunk->drm->dmem->migrate.chan, false, &fence);
406+
if (!nouveau_fence_new(&fence))
407+
nouveau_fence_emit(fence, chunk->drm->dmem->migrate.chan);
406408
migrate_device_pages(src_pfns, dst_pfns, npages);
407409
nouveau_dmem_fence_done(&fence);
408410
migrate_device_finalize(src_pfns, dst_pfns, npages);
@@ -675,7 +677,8 @@ static void nouveau_dmem_migrate_chunk(struct nouveau_drm *drm,
675677
addr += PAGE_SIZE;
676678
}
677679

678-
nouveau_fence_new(drm->dmem->migrate.chan, false, &fence);
680+
if (!nouveau_fence_new(&fence))
681+
nouveau_fence_emit(fence, chunk->drm->dmem->migrate.chan);
679682
migrate_vma_pages(args);
680683
nouveau_dmem_fence_done(&fence);
681684
nouveau_pfns_map(svmm, args->vma->vm_mm, args->start, pfns, i);

drivers/gpu/drm/nouveau/nouveau_fence.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan)
210210
struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
211211
int ret;
212212

213+
if (unlikely(!chan->fence))
214+
return -ENODEV;
215+
213216
fence->channel = chan;
214217
fence->timeout = jiffies + (15 * HZ);
215218

@@ -396,25 +399,16 @@ nouveau_fence_unref(struct nouveau_fence **pfence)
396399
}
397400

398401
int
399-
nouveau_fence_new(struct nouveau_channel *chan, bool sysmem,
400-
struct nouveau_fence **pfence)
402+
nouveau_fence_new(struct nouveau_fence **pfence)
401403
{
402404
struct nouveau_fence *fence;
403-
int ret = 0;
404-
405-
if (unlikely(!chan->fence))
406-
return -ENODEV;
407405

408406
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
409407
if (!fence)
410408
return -ENOMEM;
411409

412-
ret = nouveau_fence_emit(fence, chan);
413-
if (ret)
414-
nouveau_fence_unref(&fence);
415-
416410
*pfence = fence;
417-
return ret;
411+
return 0;
418412
}
419413

420414
static const char *nouveau_fence_get_get_driver_name(struct dma_fence *fence)

drivers/gpu/drm/nouveau/nouveau_fence.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ struct nouveau_fence {
1717
unsigned long timeout;
1818
};
1919

20-
int nouveau_fence_new(struct nouveau_channel *, bool sysmem,
21-
struct nouveau_fence **);
20+
int nouveau_fence_new(struct nouveau_fence **);
2221
void nouveau_fence_unref(struct nouveau_fence **);
2322

2423
int nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *);

drivers/gpu/drm/nouveau/nouveau_gem.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,8 +873,11 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
873873
}
874874
}
875875

876-
ret = nouveau_fence_new(chan, false, &fence);
876+
ret = nouveau_fence_new(&fence);
877+
if (!ret)
878+
ret = nouveau_fence_emit(fence, chan);
877879
if (ret) {
880+
nouveau_fence_unref(&fence);
878881
NV_PRINTK(err, cli, "error fencing pushbuf: %d\n", ret);
879882
WIND_RING(chan);
880883
goto out;

0 commit comments

Comments
 (0)