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

drm/msm: Add opt-in for VM_BIND



Add a SET_PARAM for userspace to request to manage to the VM itself,
instead of getting a kernel managed VM.

In order to transition to a userspace managed VM, this param must be set
before any mappings are created.

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/661494/
parent 6bf32afd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2276,7 +2276,7 @@ a6xx_create_vm(struct msm_gpu *gpu, struct platform_device *pdev)
}

static struct drm_gpuvm *
a6xx_create_private_vm(struct msm_gpu *gpu)
a6xx_create_private_vm(struct msm_gpu *gpu, bool kernel_managed)
{
	struct msm_mmu *mmu;

@@ -2286,7 +2286,7 @@ a6xx_create_private_vm(struct msm_gpu *gpu)
		return ERR_CAST(mmu);

	return msm_gem_vm_create(gpu->dev, mmu, "gpu", ADRENO_VM_START,
				 adreno_private_vm_size(gpu), true);
				 adreno_private_vm_size(gpu), kernel_managed);
}

static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+15 −0
Original line number Diff line number Diff line
@@ -504,6 +504,21 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_context *ctx,
		if (!capable(CAP_SYS_ADMIN))
			return UERR(EPERM, drm, "invalid permissions");
		return msm_context_set_sysprof(ctx, gpu, value);
	case MSM_PARAM_EN_VM_BIND:
		/* We can only support VM_BIND with per-process pgtables: */
		if (ctx->vm == gpu->vm)
			return UERR(EINVAL, drm, "requires per-process pgtables");

		/*
		 * We can only swtich to VM_BIND mode if the VM has not yet
		 * been created:
		 */
		if (ctx->vm)
			return UERR(EBUSY, drm, "VM already created");

		ctx->userspace_managed_vm = value;

		return 0;
	default:
		return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, param);
	}
+20 −2
Original line number Diff line number Diff line
@@ -232,9 +232,21 @@ static void load_gpu(struct drm_device *dev)
 */
struct drm_gpuvm *msm_context_vm(struct drm_device *dev, struct msm_context *ctx)
{
	static DEFINE_MUTEX(init_lock);
	struct msm_drm_private *priv = dev->dev_private;
	if (!ctx->vm)
		ctx->vm = msm_gpu_create_private_vm(priv->gpu, current);

	/* Once ctx->vm is created it is valid for the lifetime of the context: */
	if (ctx->vm)
		return ctx->vm;

	mutex_lock(&init_lock);
	if (!ctx->vm) {
		ctx->vm = msm_gpu_create_private_vm(
			priv->gpu, current, !ctx->userspace_managed_vm);

	}
	mutex_unlock(&init_lock);

	return ctx->vm;
}

@@ -424,6 +436,9 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
	if (!priv->gpu)
		return -EINVAL;

	if (msm_context_is_vmbind(ctx))
		return UERR(EINVAL, dev, "VM_BIND is enabled");

	if (should_fail(&fail_gem_iova, obj->size))
		return -ENOMEM;

@@ -445,6 +460,9 @@ static int msm_ioctl_gem_info_set_iova(struct drm_device *dev,
	if (!priv->gpu)
		return -EINVAL;

	if (msm_context_is_vmbind(ctx))
		return UERR(EINVAL, dev, "VM_BIND is enabled");

	/* Only supported if per-process address space is supported: */
	if (priv->gpu->vm == vm)
		return UERR(EOPNOTSUPP, dev, "requires per-process pgtables");
+8 −0
Original line number Diff line number Diff line
@@ -81,6 +81,14 @@ static void msm_gem_close(struct drm_gem_object *obj, struct drm_file *file)
	if (!ctx->vm)
		return;

	/*
	 * VM_BIND does not depend on implicit teardown of VMAs on handle
	 * close, but instead on implicit teardown of the VM when the device
	 * is closed (see msm_gem_vm_close())
	 */
	if (msm_context_is_vmbind(ctx))
		return;

	/*
	 * TODO we might need to kick this to a queue to avoid blocking
	 * in CLOSE ioctl
+3 −2
Original line number Diff line number Diff line
@@ -829,7 +829,8 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)

/* Return a new address space for a msm_drm_private instance */
struct drm_gpuvm *
msm_gpu_create_private_vm(struct msm_gpu *gpu, struct task_struct *task)
msm_gpu_create_private_vm(struct msm_gpu *gpu, struct task_struct *task,
			  bool kernel_managed)
{
	struct drm_gpuvm *vm = NULL;

@@ -841,7 +842,7 @@ msm_gpu_create_private_vm(struct msm_gpu *gpu, struct task_struct *task)
	 * the global one
	 */
	if (gpu->funcs->create_private_vm) {
		vm = gpu->funcs->create_private_vm(gpu);
		vm = gpu->funcs->create_private_vm(gpu, kernel_managed);
		if (!IS_ERR(vm))
			to_msm_vm(vm)->pid = get_pid(task_pid(task));
	}
Loading