Commit af9aa6f3 authored by Rob Clark's avatar Rob Clark
Browse files

drm/msm: Crashdump support for sparse



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

Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Signed-off-by: default avatarRob Clark <robin.clark@oss.qualcomm.com>
Tested-by: default avatarAntonino Maniscalco <antomani103@gmail.com>
Reviewed-by: default avatarAntonino Maniscalco <antomani103@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/661504/
parent 4570dbb8
Loading
Loading
Loading
Loading
+72 −24
Original line number Diff line number Diff line
@@ -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, struct msm_gpu_fault_info *fault_info,
		char *comm, char *cmd)
@@ -281,11 +342,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
	if (fault_info)
		state->fault_info = *fault_info;

	if (submit) {
		extern bool rd_full;
		int i;

		if (state->fault_info.ttbr0) {
	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;

@@ -294,16 +351,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
		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);
		}
	}
	crashstate_get_bos(state, submit);

	/* Set the active crash state to be dumped on failure */
	gpu->crashstate = state;