From: Daniel Vetter Date: Fri, 14 Jan 2022 14:15:56 +0000 (+0100) Subject: Merge tag 'drm-misc-fixes-2022-01-14' of git://anongit.freedesktop.org/drm/drm-misc... X-Git-Tag: v5.17-rc1~77^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71e4a7029045e3904e0e9242b4a7cd84d47b8fe5;p=thirdparty%2Fkernel%2Flinux.git Merge tag 'drm-misc-fixes-2022-01-14' of git://anongit.freedesktop.org/drm/drm-misc into drm-next Two DT bindings fixes for meson, a device refcounting fix for sun4i, a probe fix for vga16fb, a locking fix for the CMA dma-buf heap and a compilation fix for ttm. Signed-off-by: Daniel Vetter [danvet: I made sure I have exactly the same conflict resolution as Linus in 8d0749b4f83b ("Merge tag 'drm-next-2022-01-07' of git://anongit.freedesktop.org/drm/drm") to avoid further conflict fun. From: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20220114125454.zs46ny52lrxk3ljz@houat --- 71e4a7029045e3904e0e9242b4a7cd84d47b8fe5 diff --cc drivers/gpu/drm/nouveau/nouveau_fence.c index 26f9299df881a,0ae416aa76dcb..a3a04e0d76ec4 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@@ -339,44 -339,70 +339,54 @@@ nouveau_fence_wait(struct nouveau_fenc } 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_iter cursor; - struct dma_fence *fence; - struct dma_resv_list *fobj; -- struct nouveau_fence *f; - int ret; - 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); } - dma_resv_for_each_fence(&cursor, resv, exclusive, 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(); - } + /* 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) { ++ struct dma_resv_iter cursor; ++ struct dma_fence *fence; ++ ++ dma_resv_for_each_fence(&cursor, resv, exclusive, fence) { ++ struct nouveau_fence *f; ++ ++ if (i == 0 && dma_resv_iter_is_exclusive(&cursor)) ++ continue; ++ ++ f = nouveau_local_fence(fence, chan->drm); ++ if (f) { ++ struct nouveau_channel *prev; ++ bool must_wait = true; ++ ++ 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) ++ continue; ++ } - if (must_wait) { - 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 (ret) + return ret; } - - if (must_wait) - ret = dma_fence_wait(fence, intr); - - return ret; } + - return ret; + return 0; } void