summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhenhao Wan <whi4ed0g@gmail.com>2026-08-11 16:46:30 +0800
committerDanilo Krummrich <dakr@kernel.org>2026-09-01 10:18:00 +0200
commit38a62306c4266bcb3cd89e33c7111ee33096ebb3 (patch)
tree3035d3096bdc84118dbfc254b45881e4fd69c2bd
parentccf930812f23b8259ef64fd3394d53b093e4651a (diff)
downloadlinux-38a62306c4266bcb3cd89e33c7111ee33096ebb3.tar.gz
linux-38a62306c4266bcb3cd89e33c7111ee33096ebb3.zip
drm/nouveau/uvmm: clear the dirty flag when unwinding an OP_UNMAP_SPARSE
A successful OP_UNMAP_SPARSE marks its region dirty with nouveau_uvma_region_dirty() and defers the teardown to nouveau_uvmm_bind_job_cleanup(); it does not remove the region from uvmm->region_mt. If a later op in the job fails, the unwind path never clears reg->dirty (set in one place, cleared nowhere) and sets op->reg = NULL, so cleanup skips the teardown. The region is left in the tree with dirty set and its completion never signalled. Later binds over that range then fail permanently -- -ENOENT or -EINVAL from the dirty checks, or an unkillable wait_for_completion() in bind_validate_region() -- for the lifetime of the uvmm. Clear reg->dirty when the unwind reverts the sparse unmap, restoring the region to the state it was found in. Fixes: b88baab82871 ("drm/nouveau: implement new VM_BIND uAPI") Reported-by: Yuhao Jiang <danisjiang@gmail.com> Assisted-by: Claude:claude-opus-5 Cc: stable@vger.kernel.org Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://patch.msgid.link/20260811-nouveau-uvmm-vmbind-fixes-v2-3-aaee4b395d04@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_uvmm.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
index d30ec3709e79..fc125fd44a9b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -1475,6 +1475,7 @@ unwind:
op->va.range);
break;
case OP_UNMAP_SPARSE:
+ op->reg->dirty = false;
__nouveau_uvma_region_insert(uvmm, op->reg);
nouveau_uvmm_sm_unmap_prepare_unwind(uvmm, &op->new,
op->ops);