Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7de1545 authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark
Browse files

drm/msm: Add per-instance submit queues



Currently the behavior of a command stream is provided by the user
application during submission and the application is expected to internally
maintain the settings for each 'context' or 'rendering queue' and specify
the correct ones.

This works okay for simple cases but as applications become more
complex we will want to set context specific flags and do various
permission checks to allow certain contexts to enable additional
privileges.

Add kernel-side submit queues to be analogous to 'contexts' or
'rendering queues' on the application side. Each file descriptor
instance will maintain its own list of queues. Queues cannot be
shared between file descriptors.

For backwards compatibility context id '0' is defined as a default
context specifying no priority and no special flags. This is
intended to be the usual configuration for 99% of applications so
that a garden variety application can function correctly without
creating a queue. Only those applications requiring the specific
benefit of different queues need create one.

Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 0033e1b5
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ msm-y := \
	msm_iommu.o \
	msm_perf.o \
	msm_rd.o \
	msm_ringbuffer.o
	msm_ringbuffer.o \
	msm_submitqueue.o

msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o
+48 −8
Original line number Diff line number Diff line
@@ -29,9 +29,12 @@
 * - 1.0.0 - initial interface
 * - 1.1.0 - adds madvise, and support for submits with > 4 cmd buffers
 * - 1.2.0 - adds explicit fence support for submit ioctl
 * - 1.3.0 - adds GMEM_BASE + NR_RINGS params, SUBMITQUEUE_NEW +
 *           SUBMITQUEUE_CLOSE ioctls, and MSM_INFO_IOVA flag for
 *           MSM_GEM_INFO ioctl.
 */
#define MSM_VERSION_MAJOR	1
#define MSM_VERSION_MINOR	2
#define MSM_VERSION_MINOR	3
#define MSM_VERSION_PATCHLEVEL	0

static void msm_fb_output_poll_changed(struct drm_device *dev)
@@ -504,24 +507,37 @@ static void load_gpu(struct drm_device *dev)
	mutex_unlock(&init_lock);
}

static int msm_open(struct drm_device *dev, struct drm_file *file)
static int context_init(struct drm_file *file)
{
	struct msm_file_private *ctx;

	/* For now, load gpu on open.. to avoid the requirement of having
	 * firmware in the initrd.
	 */
	load_gpu(dev);

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	msm_submitqueue_init(ctx);

	file->driver_priv = ctx;

	return 0;
}

static int msm_open(struct drm_device *dev, struct drm_file *file)
{
	/* For now, load gpu on open.. to avoid the requirement of having
	 * firmware in the initrd.
	 */
	load_gpu(dev);

	return context_init(file);
}

static void context_close(struct msm_file_private *ctx)
{
	msm_submitqueue_close(ctx);
	kfree(ctx);
}

static void msm_postclose(struct drm_device *dev, struct drm_file *file)
{
	struct msm_drm_private *priv = dev->dev_private;
@@ -532,7 +548,7 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
		priv->lastctx = NULL;
	mutex_unlock(&dev->struct_mutex);

	kfree(ctx);
	context_close(ctx);
}

static void msm_lastclose(struct drm_device *dev)
@@ -777,6 +793,28 @@ static int msm_ioctl_gem_madvise(struct drm_device *dev, void *data,
	return ret;
}


static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data,
		struct drm_file *file)
{
	struct drm_msm_submitqueue *args = data;

	if (args->flags & ~MSM_SUBMITQUEUE_FLAGS)
		return -EINVAL;

	return msm_submitqueue_create(file->driver_priv, args->prio,
		args->flags, &args->id);
}


static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data,
		struct drm_file *file)
{
	u32 id = *(u32 *) data;

	return msm_submitqueue_remove(file->driver_priv, id);
}

static const struct drm_ioctl_desc msm_ioctls[] = {
	DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,    msm_ioctl_get_param,    DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,      msm_ioctl_gem_new,      DRM_AUTH|DRM_RENDER_ALLOW),
@@ -786,6 +824,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
	DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT,   msm_ioctl_gem_submit,   DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE,   msm_ioctl_wait_fence,   DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE,  msm_ioctl_gem_madvise,  DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_AUTH|DRM_RENDER_ALLOW),
};

static const struct vm_operations_struct vm_ops = {
+15 −5
Original line number Diff line number Diff line
@@ -56,11 +56,9 @@ struct msm_gem_address_space;
struct msm_gem_vma;

struct msm_file_private {
	/* currently we don't do anything useful with this.. but when
	 * per-context address spaces are supported we'd keep track of
	 * the context's page-tables here.
	 */
	int dummy;
	rwlock_t queuelock;
	struct list_head submitqueues;
	int queueid;
};

enum msm_mdp_plane_property {
@@ -319,6 +317,18 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
void msm_writel(u32 data, void __iomem *addr);
u32 msm_readl(const void __iomem *addr);

struct msm_gpu_submitqueue;
int msm_submitqueue_init(struct msm_file_private *ctx);
struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
		u32 id);
int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio,
		u32 flags, u32 *id);
int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
void msm_submitqueue_close(struct msm_file_private *ctx);

void msm_submitqueue_destroy(struct kref *kref);


#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)

+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ struct msm_gem_submit {
	struct list_head bo_list;
	struct ww_acquire_ctx ticket;
	struct dma_fence *fence;
	struct msm_gpu_submitqueue *queue;
	struct pid *pid;    /* submitting process */
	bool valid;         /* true if no cmdstream patching needed */
	unsigned int nr_cmds;
+12 −2
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@
#define BO_PINNED   0x2000

static struct msm_gem_submit *submit_create(struct drm_device *dev,
		struct msm_gpu *gpu, uint32_t nr_bos, uint32_t nr_cmds)
		struct msm_gpu *gpu, struct msm_gpu_submitqueue *queue,
		uint32_t nr_bos, uint32_t nr_cmds)
{
	struct msm_gem_submit *submit;
	uint64_t sz = sizeof(*submit) + ((u64)nr_bos * sizeof(submit->bos[0])) +
@@ -49,6 +50,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
	submit->fence = NULL;
	submit->pid = get_pid(task_pid(current));
	submit->cmd = (void *)&submit->bos[nr_bos];
	submit->queue = queue;

	/* initially, until copy_from_user() and bo lookup succeeds: */
	submit->nr_bos = 0;
@@ -66,6 +68,8 @@ void msm_gem_submit_free(struct msm_gem_submit *submit)
	dma_fence_put(submit->fence);
	list_del(&submit->node);
	put_pid(submit->pid);
	msm_submitqueue_put(submit->queue);

	kfree(submit);
}

@@ -405,6 +409,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
	struct msm_gpu *gpu = priv->gpu;
	struct dma_fence *in_fence = NULL;
	struct sync_file *sync_file = NULL;
	struct msm_gpu_submitqueue *queue;
	int out_fence_fd = -1;
	unsigned i;
	int ret;
@@ -421,6 +426,10 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
	if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS)
		return -EINVAL;

	queue = msm_submitqueue_get(ctx, args->queueid);
	if (!queue)
		return -ENOENT;

	if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
		in_fence = sync_file_get_fence(args->fence_fd);

@@ -451,7 +460,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
	}
	priv->struct_mutex_task = current;

	submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds);
	submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds);
	if (!submit) {
		ret = -ENOMEM;
		goto out_unlock;
@@ -535,6 +544,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
	submit->nr_cmds = i;

	submit->fence = msm_fence_alloc(gpu->fctx);

	if (IS_ERR(submit->fence)) {
		ret = PTR_ERR(submit->fence);
		submit->fence = NULL;
Loading