diff options
author | Dave Airlie <airlied@redhat.com> | 2022-01-07 14:13:40 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2022-01-07 14:13:40 +1000 |
commit | 3fcb2531073d29aad26a2fdb323a3c8c1c4307af (patch) | |
tree | ff61ba66171c7cfbfa5d0146ec23d4e74748ff76 /drivers/gpu/drm/nouveau/nouveau_fence.c | |
parent | 51a1809d7fcd03d74ad0f1294af559f2729aae42 (diff) | |
parent | cb6846fbb83b574c85c2a80211b402a6347b60b1 (diff) |
Merge branch 'drm-next' of git://anongit.freedesktop.org/git/drm/drmdrm-next-5.17-merged
Trial merge with correct nouveau_fence.c fix
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_fence.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 75 |
1 files changed, 29 insertions, 46 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 0ae416aa76dc..b8ce61808026 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -339,70 +339,53 @@ 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 nouveau_bo *nvbo, struct nouveau_channel *chan, + bool exclusive, bool intr) { struct nouveau_fence_chan *fctx = chan->fence; - struct dma_fence *fence; struct dma_resv *resv = nvbo->bo.base.resv; - struct dma_resv_list *fobj; + struct dma_resv_iter cursor; + struct dma_fence *fence; struct nouveau_fence *f; - int ret = 0, i; + int i, ret; if (!exclusive) { ret = dma_resv_reserve_shared(resv, 1); - if (ret) return ret; - fobj = NULL; - } else { - fobj = dma_resv_shared_list(resv); } /* Waiting for the exclusive fence first causes performance regressions * under some circumstances. So manually wait for the shared ones first. */ - for (i = 0; i < (fobj ? fobj->shared_count : 0) && !ret; ++i) { - struct nouveau_channel *prev = NULL; - bool must_wait = true; - - fence = rcu_dereference_protected(fobj->shared[i], - dma_resv_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(); + for (i = 0; i < 2; ++i) { + dma_resv_for_each_fence(&cursor, resv, exclusive, fence) { + struct nouveau_channel *prev = NULL; + bool must_wait = true; + + if (i == 0 && dma_resv_iter_is_exclusive(&cursor)) + continue; + + 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 = dma_fence_wait(fence, intr); + if (ret) + return ret; + } } - - if (must_wait) - ret = dma_fence_wait(fence, intr); } - fence = dma_resv_excl_fence(resv); - if (fence) { - 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 = dma_fence_wait(fence, intr); - - return ret; - } - - return ret; + return 0; } void |