From: Rob Clark <robdcl...@chromium.org>

In this case, we need to iterate the VMAs looking for ones with
MSM_VMA_DUMP flag.

Signed-off-by: Rob Clark <robdcl...@chromium.org>
---
 drivers/gpu/drm/msm/msm_gpu.c | 96 ++++++++++++++++++++++++++---------
 1 file changed, 72 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 2eaca2a22de9..b70355fc8570 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -241,9 +241,7 @@ static void msm_gpu_crashstate_get_bo(struct msm_gpu_state 
*state,
                if (!state_bo->data)
                        goto out;
 
-               msm_gem_lock(obj);
                ptr = msm_gem_get_vaddr_active(obj);
-               msm_gem_unlock(obj);
                if (IS_ERR(ptr)) {
                        kvfree(state_bo->data);
                        state_bo->data = NULL;
@@ -251,12 +249,75 @@ static void msm_gpu_crashstate_get_bo(struct 
msm_gpu_state *state,
                }
 
                memcpy(state_bo->data, ptr + offset, size);
-               msm_gem_put_vaddr(obj);
+               msm_gem_put_vaddr_locked(obj);
        }
 out:
        state->nr_bos++;
 }
 
+static void crashstate_get_bos(struct msm_gpu_state *state, struct 
msm_gem_submit *submit)
+{
+       extern bool rd_full;
+
+       if (!submit)
+               return;
+
+       if (msm_context_is_vmbind(submit->queue->ctx)) {
+               struct drm_exec exec;
+               struct drm_gpuva *vma;
+               unsigned cnt = 0;
+
+               drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
+               drm_exec_until_all_locked(&exec) {
+                       cnt = 0;
+
+                       drm_exec_lock_obj(&exec, 
drm_gpuvm_resv_obj(submit->vm));
+                       drm_exec_retry_on_contention(&exec);
+
+                       drm_gpuvm_for_each_va (vma, submit->vm) {
+                               if (!vma->gem.obj)
+                                       continue;
+
+                               cnt++;
+                               drm_exec_lock_obj(&exec, vma->gem.obj);
+                               drm_exec_retry_on_contention(&exec);
+                       }
+
+               }
+
+               drm_gpuvm_for_each_va (vma, submit->vm)
+                       cnt++;
+
+               state->bos = kcalloc(cnt, sizeof(struct msm_gpu_state_bo), 
GFP_KERNEL);
+
+               drm_gpuvm_for_each_va (vma, submit->vm) {
+                       bool dump = rd_full || (vma->flags & MSM_VMA_DUMP);
+
+                       /* Skip MAP_NULL/PRR VMAs: */
+                       if (!vma->gem.obj)
+                               continue;
+
+                       msm_gpu_crashstate_get_bo(state, vma->gem.obj, 
vma->va.addr,
+                                                 dump, vma->gem.offset, 
vma->va.range);
+               }
+
+               drm_exec_fini(&exec);
+       } else {
+               state->bos = kcalloc(submit->nr_bos,
+                       sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
+
+               for (int i = 0; state->bos && i < submit->nr_bos; i++) {
+                       struct drm_gem_object *obj = submit->bos[i].obj;
+                       bool dump = rd_full || (submit->bos[i].flags & 
MSM_SUBMIT_BO_DUMP);
+
+                       msm_gem_lock(obj);
+                       msm_gpu_crashstate_get_bo(state, obj, 
submit->bos[i].iova,
+                                                 dump, 0, obj->size);
+                       msm_gem_unlock(obj);
+               }
+       }
+}
+
 static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
                struct msm_gem_submit *submit, char *comm, char *cmd)
 {
@@ -279,30 +340,17 @@ static void msm_gpu_crashstate_capture(struct msm_gpu 
*gpu,
        state->cmd = kstrdup(cmd, GFP_KERNEL);
        state->fault_info = gpu->fault_info;
 
-       if (submit) {
-               extern bool rd_full;
-               int i;
-
-               if (state->fault_info.ttbr0) {
-                       struct msm_gpu_fault_info *info = &state->fault_info;
-                       struct msm_mmu *mmu = to_msm_vm(submit->vm)->mmu;
+       if (submit && state->fault_info.ttbr0) {
+               struct msm_gpu_fault_info *info = &state->fault_info;
+               struct msm_mmu *mmu = to_msm_vm(submit->vm)->mmu;
 
-                       msm_iommu_pagetable_params(mmu, &info->pgtbl_ttbr0,
-                                                  &info->asid);
-                       msm_iommu_pagetable_walk(mmu, info->iova, info->ptes);
-               }
-
-               state->bos = kcalloc(submit->nr_bos,
-                       sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
-
-               for (i = 0; state->bos && i < submit->nr_bos; i++) {
-                       struct drm_gem_object *obj = submit->bos[i].obj;
-                       bool dump = rd_full || (submit->bos[i].flags & 
MSM_SUBMIT_BO_DUMP);
-                       msm_gpu_crashstate_get_bo(state, obj, 
submit->bos[i].iova,
-                                                 dump, 0, obj->size);
-               }
+               msm_iommu_pagetable_params(mmu, &info->pgtbl_ttbr0,
+                                          &info->asid);
+               msm_iommu_pagetable_walk(mmu, info->iova, info->ptes);
        }
 
+       crashstate_get_bos(state, submit);
+
        /* Set the active crash state to be dumped on failure */
        gpu->crashstate = state;
 
-- 
2.49.0

Reply via email to