On Tue, Aug 5, 2025 at 12:44 PM Rob Clark <robin.cl...@oss.qualcomm.com> wrote: > > Detect and handle the special case of a MAP op simply updating the vma > flags of an existing vma, and skip the pgtable updates. This allows > turnip to set the MSM_VMA_DUMP flag on an existing mapping without > requiring additional synchronization against commands running on the > GPU. > > Signed-off-by: Rob Clark <robin.cl...@oss.qualcomm.com>
Tested that this fixes the occasional page faults with the zink a618 jobs on Mesa CI with my Mesa MR. Tested-by: Connor Abbott <cwabbo...@gmail.com> > --- > drivers/gpu/drm/msm/msm_gem_vma.c | 41 ++++++++++++++++++++++++++++--- > 1 file changed, 37 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c > b/drivers/gpu/drm/msm/msm_gem_vma.c > index d1f5bb2e0a16..00d0f3b7ba32 100644 > --- a/drivers/gpu/drm/msm/msm_gem_vma.c > +++ b/drivers/gpu/drm/msm/msm_gem_vma.c > @@ -451,6 +451,8 @@ msm_gem_vm_bo_validate(struct drm_gpuvm_bo *vm_bo, struct > drm_exec *exec) > struct op_arg { > unsigned flags; > struct msm_vm_bind_job *job; > + const struct msm_vm_bind_op *op; > + bool kept; > }; > > static void > @@ -472,14 +474,18 @@ vma_from_op(struct op_arg *arg, struct drm_gpuva_op_map > *op) > } > > static int > -msm_gem_vm_sm_step_map(struct drm_gpuva_op *op, void *arg) > +msm_gem_vm_sm_step_map(struct drm_gpuva_op *op, void *_arg) > { > - struct msm_vm_bind_job *job = ((struct op_arg *)arg)->job; > + struct op_arg *arg = _arg; > + struct msm_vm_bind_job *job = arg->job; > struct drm_gem_object *obj = op->map.gem.obj; > struct drm_gpuva *vma; > struct sg_table *sgt; > unsigned prot; > > + if (arg->kept) > + return 0; > + > vma = vma_from_op(arg, &op->map); > if (WARN_ON(IS_ERR(vma))) > return PTR_ERR(vma); > @@ -599,15 +605,41 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void > *arg) > } > > static int > -msm_gem_vm_sm_step_unmap(struct drm_gpuva_op *op, void *arg) > +msm_gem_vm_sm_step_unmap(struct drm_gpuva_op *op, void *_arg) > { > - struct msm_vm_bind_job *job = ((struct op_arg *)arg)->job; > + struct op_arg *arg = _arg; > + struct msm_vm_bind_job *job = arg->job; > struct drm_gpuva *vma = op->unmap.va; > struct msm_gem_vma *msm_vma = to_msm_vma(vma); > > vm_dbg("%p:%p:%p: %016llx %016llx", vma->vm, vma, vma->gem.obj, > vma->va.addr, vma->va.range); > > + /* > + * Detect in-place remap. Turnip does this to change the vma flags, > + * in particular MSM_VMA_DUMP. In this case we want to avoid actually > + * touching the page tables, as that would require synchronization > + * against SUBMIT jobs running on the GPU. > + */ > + if (op->unmap.keep && > + (arg->op->op == MSM_VM_BIND_OP_MAP) && > + (vma->gem.obj == arg->op->obj) && > + (vma->gem.offset == arg->op->obj_offset) && > + (vma->va.addr == arg->op->iova) && > + (vma->va.range == arg->op->range)) { > + /* We are only expecting a single in-place unmap+map cb pair: > */ > + WARN_ON(arg->kept); > + > + /* Leave the existing VMA in place, but signal that to the > map cb: */ > + arg->kept = true; > + > + /* Only flags are changing, so update that in-place: */ > + unsigned orig_flags = vma->flags & (DRM_GPUVA_USERBITS - 1); > + vma->flags = orig_flags | arg->flags; > + > + return 0; > + } > + > if (!msm_vma->mapped) > goto out_close; > > @@ -1268,6 +1300,7 @@ vm_bind_job_prepare(struct msm_vm_bind_job *job) > const struct msm_vm_bind_op *op = &job->ops[i]; > struct op_arg arg = { > .job = job, > + .op = op, > }; > > switch (op->op) { > -- > 2.50.1 >