The 'keep' hint on the unmap is only half useful, without being able to link it to a map cb. Instead combine the two ops into a remap op to give the driver a chance to figure things out.
Signed-off-by: Rob Clark <robin.cl...@oss.qualcomm.com> --- drivers/gpu/drm/drm_gpuvm.c | 21 +++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_uvmm.c | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index bbc7fecb6f4a..e21782a97fbe 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -2125,6 +2125,27 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, offset == req_offset; if (end == req_end) { + if (merge) { + /* + * This is an exact remap of the existing + * VA (potentially flags change)? Pass + * this to the driver as a remap so it can + * do an in-place update: + */ + struct drm_gpuva_op_map n = { + .va.addr = va->va.addr, + .va.range = va->va.range, + .gem.obj = va->gem.obj, + .gem.offset = va->gem.offset, + }; + struct drm_gpuva_op_unmap u = { + .va = va, + .keep = true, + }; + + return op_remap_cb(ops, priv, NULL, &n, &u); + } + ret = op_unmap_cb(ops, priv, va, merge); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c index 48f105239f42..c3e3a15eb3c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c @@ -820,7 +820,8 @@ op_remap(struct drm_gpuva_op_remap *r, if (r->next) end = r->next->va.addr; - op_unmap_range(u, addr, end - addr); + if (!u->keep) + op_unmap_range(u, addr, end - addr); } static int -- 2.50.1