diff options
author | Lauri Peltonen <lpeltonen@nvidia.com> | 2015-02-16 16:19:29 +0900 |
---|---|---|
committer | Alexandre Courbot <acourbot@nvidia.com> | 2015-11-11 18:52:58 +0900 |
commit | 118f90550020bd198670dd3b7d64b0bb8a4e13e9 (patch) | |
tree | 21b961960f40e8bb6f113e092917a3187a03a234 /drm | |
parent | 96a5d3691af866a8d8cdb1f28280d82062a0d6c4 (diff) | |
download | nouveau-118f90550020bd198670dd3b7d64b0bb8a4e13e9.tar.gz |
drm/nouveau: Split nouveau_fence_sync
Split nouveau_fence_sync to two functions:
* nouveau_fence_sync, which only adds a fence wait to the channel
command stream, and
* nouveau_bo_sync, which gets the fences from the reservation object
and passes them to nouveau_fence_sync.
This factorizes the code in the new nouveau_fence_sync() which was
present twice otherwise.
Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com>
[acourbot@nvidia.com: factorize code some more, fix style]
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'drm')
-rw-r--r-- | drm/nouveau/nouveau_bo.c | 36 | ||||
-rw-r--r-- | drm/nouveau/nouveau_bo.h | 2 | ||||
-rw-r--r-- | drm/nouveau/nouveau_display.c | 4 | ||||
-rw-r--r-- | drm/nouveau/nouveau_fence.c | 67 | ||||
-rw-r--r-- | drm/nouveau/nouveau_fence.h | 2 | ||||
-rw-r--r-- | drm/nouveau/nouveau_gem.c | 2 |
6 files changed, 54 insertions, 59 deletions
diff --git a/drm/nouveau/nouveau_bo.c b/drm/nouveau/nouveau_bo.c index 711e40195..b7671622c 100644 --- a/drm/nouveau/nouveau_bo.c +++ b/drm/nouveau/nouveau_bo.c @@ -518,6 +518,40 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) } int +nouveau_bo_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, + bool exclusive, bool intr) +{ + struct fence *fence; + struct reservation_object *resv = nvbo->bo.resv; + struct reservation_object_list *fobj; + int ret = 0, i; + + if (!exclusive) { + ret = reservation_object_reserve_shared(resv); + + if (ret) + return ret; + } + + fobj = reservation_object_get_list(resv); + fence = reservation_object_get_excl(resv); + + if (fence && (!exclusive || !fobj || !fobj->shared_count)) + return nouveau_fence_sync(fence, chan, intr); + + if (!exclusive || !fobj) + return ret; + + for (i = 0; i < fobj->shared_count && !ret; ++i) { + fence = rcu_dereference_protected(fobj->shared[i], + reservation_object_held(resv)); + ret |= nouveau_fence_sync(fence, chan, intr); + } + + return ret; +} + +int nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible, bool no_wait_gpu) { @@ -1100,7 +1134,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, } mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); - ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, intr); + ret = nouveau_bo_sync(nouveau_bo(bo), chan, true, intr); if (ret == 0) { ret = drm->ttm.move(chan, bo, &bo->mem, new_mem); if (ret == 0) { diff --git a/drm/nouveau/nouveau_bo.h b/drm/nouveau/nouveau_bo.h index 87d07e353..7f4177faf 100644 --- a/drm/nouveau/nouveau_bo.h +++ b/drm/nouveau/nouveau_bo.h @@ -88,6 +88,8 @@ int nouveau_bo_validate(struct nouveau_bo *, bool interruptible, bool no_wait_gpu); void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo); void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo); +int nouveau_bo_sync(struct nouveau_bo *, struct nouveau_channel *, + bool exclusive, bool intr); struct nvkm_vma * nouveau_bo_vma_find(struct nouveau_bo *, struct nvkm_vm *); diff --git a/drm/nouveau/nouveau_display.c b/drm/nouveau/nouveau_display.c index db6bc6760..1abe5e8dc 100644 --- a/drm/nouveau/nouveau_display.c +++ b/drm/nouveau/nouveau_display.c @@ -679,7 +679,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, spin_unlock_irqrestore(&dev->event_lock, flags); /* Synchronize with the old framebuffer */ - ret = nouveau_fence_sync(old_bo, chan, false, false); + ret = nouveau_bo_sync(old_bo, chan, false, false); if (ret) goto fail; @@ -743,7 +743,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, goto fail_unpin; /* synchronise rendering channel with the kernel's channel */ - ret = nouveau_fence_sync(new_bo, chan, false, true); + ret = nouveau_bo_sync(new_bo, chan, false, true); if (ret) { ttm_bo_unreserve(&new_bo->bo); goto fail_unpin; diff --git a/drm/nouveau/nouveau_fence.c b/drm/nouveau/nouveau_fence.c index 574c36b49..0d98863fe 100644 --- a/drm/nouveau/nouveau_fence.c +++ b/drm/nouveau/nouveau_fence.c @@ -387,66 +387,25 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr) } int -nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool exclusive, bool intr) +nouveau_fence_sync(struct fence *fence, struct nouveau_channel *chan, bool intr) { struct nouveau_fence_chan *fctx = chan->fence; - struct fence *fence; - struct reservation_object *resv = nvbo->bo.resv; - struct reservation_object_list *fobj; + struct nouveau_channel *prev = NULL; struct nouveau_fence *f; - int ret = 0, i; - - if (!exclusive) { - ret = reservation_object_reserve_shared(resv); + bool must_wait = true; + int ret = 0; - if (ret) - return ret; + f = nouveau_local_fence(fence, chan->drm); + if (f) { + rcu_read_lock(); + prev = rcu_dereference(f->channel); + if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) + must_wait = false; + rcu_read_unlock(); } - fobj = reservation_object_get_list(resv); - fence = reservation_object_get_excl(resv); - - if (fence && (!exclusive || !fobj || !fobj->shared_count)) { - struct nouveau_channel *prev = NULL; - bool must_wait = true; - - f = nouveau_local_fence(fence, chan->drm); - if (f) { - rcu_read_lock(); - prev = rcu_dereference(f->channel); - if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) - must_wait = false; - rcu_read_unlock(); - } - - if (must_wait) - ret = fence_wait(fence, intr); - - return ret; - } - - if (!exclusive || !fobj) - return ret; - - for (i = 0; i < fobj->shared_count && !ret; ++i) { - struct nouveau_channel *prev = NULL; - bool must_wait = true; - - fence = rcu_dereference_protected(fobj->shared[i], - reservation_object_held(resv)); - - f = nouveau_local_fence(fence, chan->drm); - if (f) { - rcu_read_lock(); - prev = rcu_dereference(f->channel); - if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) - must_wait = false; - rcu_read_unlock(); - } - - if (must_wait) - ret = fence_wait(fence, intr); - } + if (must_wait) + ret = fence_wait(fence, intr); return ret; } diff --git a/drm/nouveau/nouveau_fence.h b/drm/nouveau/nouveau_fence.h index 2e3a62d38..201304b73 100644 --- a/drm/nouveau/nouveau_fence.h +++ b/drm/nouveau/nouveau_fence.h @@ -26,7 +26,7 @@ int nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *); bool nouveau_fence_done(struct nouveau_fence *); void nouveau_fence_work(struct fence *, void (*)(void *), void *); int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr); -int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool exclusive, bool intr); +int nouveau_fence_sync(struct fence *, struct nouveau_channel *, bool intr); struct nouveau_fence_chan { spinlock_t lock; diff --git a/drm/nouveau/nouveau_gem.c b/drm/nouveau/nouveau_gem.c index 789f7aaef..6920a05be 100644 --- a/drm/nouveau/nouveau_gem.c +++ b/drm/nouveau/nouveau_gem.c @@ -544,7 +544,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, return ret; } - ret = nouveau_fence_sync(nvbo, chan, !!b->write_domains, true); + ret = nouveau_bo_sync(nvbo, chan, !!b->write_domains, true); if (unlikely(ret)) { if (ret != -ERESTARTSYS) NV_PRINTK(err, cli, "fail post-validate sync\n"); |