From b5b4c264df4d270819676b290cef9a11d04c35f0 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 17 May 2016 15:43:35 -0400 Subject: drm/msm: use mutex_lock_interruptible for submit ioctl Be kinder to things that do lots of signal handling (ie. Xorg) Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem_submit.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c') diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index eb4bb8b2f3a5..ea5f709e2e27 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -372,11 +372,15 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (args->nr_cmds > MAX_CMDS) return -EINVAL; - submit = submit_create(dev, gpu, args->nr_bos); - if (!submit) - return -ENOMEM; + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; - mutex_lock(&dev->struct_mutex); + submit = submit_create(dev, gpu, args->nr_bos); + if (!submit) { + ret = -ENOMEM; + goto out_unlock; + } ret = submit_lookup_objects(submit, args, file); if (ret) @@ -462,6 +466,7 @@ out: submit_cleanup(submit); if (ret) msm_gem_submit_free(submit); +out_unlock: mutex_unlock(&dev->struct_mutex); return ret; } -- cgit v1.2.3 From 18f23049f640e2590930c34009418c66e6ebf7b6 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 26 May 2016 16:24:35 -0400 Subject: drm/msm: change gem->vmap() to get/put Before we can add vmap shrinking, we really need to know which vmap'ings are currently being used. So switch to get/put interface. Stubbed put fxns for now. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 6 +++++- drivers/gpu/drm/msm/dsi/dsi_host.c | 5 ++++- drivers/gpu/drm/msm/msm_drv.h | 6 ++++-- drivers/gpu/drm/msm/msm_fbdev.c | 3 ++- drivers/gpu/drm/msm/msm_gem.c | 17 ++++++++++++++--- drivers/gpu/drm/msm/msm_gem_prime.c | 4 ++-- drivers/gpu/drm/msm/msm_gem_submit.c | 4 +++- drivers/gpu/drm/msm/msm_rd.c | 4 +++- drivers/gpu/drm/msm/msm_ringbuffer.c | 6 ++++-- 9 files changed, 41 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 2aec27dbb5bb..7dfe22ea2920 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -407,7 +407,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, return ret; } - adreno_gpu->memptrs = msm_gem_vaddr(adreno_gpu->memptrs_bo); + adreno_gpu->memptrs = msm_gem_get_vaddr(adreno_gpu->memptrs_bo); if (IS_ERR(adreno_gpu->memptrs)) { dev_err(drm->dev, "could not vmap memptrs\n"); return -ENOMEM; @@ -426,8 +426,12 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, void adreno_gpu_cleanup(struct adreno_gpu *gpu) { if (gpu->memptrs_bo) { + if (gpu->memptrs) + msm_gem_put_vaddr(gpu->memptrs_bo); + if (gpu->memptrs_iova) msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); + drm_gem_object_unreference_unlocked(gpu->memptrs_bo); } release_firmware(gpu->pm4); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 80d8594c68ba..ddc4c7d678ed 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1066,7 +1066,7 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host, } if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) { - data = msm_gem_vaddr(msm_host->tx_gem_obj); + data = msm_gem_get_vaddr(msm_host->tx_gem_obj); if (IS_ERR(data)) { ret = PTR_ERR(data); pr_err("%s: get vaddr failed, %d\n", __func__, ret); @@ -1094,6 +1094,9 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host, if (packet.size < len) memset(data + packet.size, 0xff, len - packet.size); + if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) + msm_gem_put_vaddr(msm_host->tx_gem_obj); + return len; } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 4755894d9229..ecf0b3b03e0e 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -200,8 +200,10 @@ struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); int msm_gem_prime_pin(struct drm_gem_object *obj); void msm_gem_prime_unpin(struct drm_gem_object *obj); -void *msm_gem_vaddr_locked(struct drm_gem_object *obj); -void *msm_gem_vaddr(struct drm_gem_object *obj); +void *msm_gem_get_vaddr_locked(struct drm_gem_object *obj); +void *msm_gem_get_vaddr(struct drm_gem_object *obj); +void msm_gem_put_vaddr_locked(struct drm_gem_object *obj); +void msm_gem_put_vaddr(struct drm_gem_object *obj); int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv); void msm_gem_purge(struct drm_gem_object *obj); int msm_gem_sync_object(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index a9223bea871b..ffd4a338ca12 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -158,7 +158,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, dev->mode_config.fb_base = paddr; - fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo); + fbi->screen_base = msm_gem_get_vaddr_locked(fbdev->bo); if (IS_ERR(fbi->screen_base)) { ret = PTR_ERR(fbi->screen_base); goto fail_unlock; @@ -251,6 +251,7 @@ void msm_fbdev_free(struct drm_device *dev) /* this will free the backing object */ if (fbdev->fb) { + msm_gem_put_vaddr(fbdev->bo); drm_framebuffer_unregister_private(fbdev->fb); drm_framebuffer_remove(fbdev->fb); } diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 444d0b5680f5..c05fc1d0dce7 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -408,7 +408,7 @@ fail: return ret; } -void *msm_gem_vaddr_locked(struct drm_gem_object *obj) +void *msm_gem_get_vaddr_locked(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); @@ -424,15 +424,26 @@ void *msm_gem_vaddr_locked(struct drm_gem_object *obj) return msm_obj->vaddr; } -void *msm_gem_vaddr(struct drm_gem_object *obj) +void *msm_gem_get_vaddr(struct drm_gem_object *obj) { void *ret; mutex_lock(&obj->dev->struct_mutex); - ret = msm_gem_vaddr_locked(obj); + ret = msm_gem_get_vaddr_locked(obj); mutex_unlock(&obj->dev->struct_mutex); return ret; } +void msm_gem_put_vaddr_locked(struct drm_gem_object *obj) +{ + WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); + /* no-op for now */ +} + +void msm_gem_put_vaddr(struct drm_gem_object *obj) +{ + /* no-op for now */ +} + /* Update madvise status, returns true if not purged, else * false or -errno. */ diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c index 6b90890faffe..60bb290700ce 100644 --- a/drivers/gpu/drm/msm/msm_gem_prime.c +++ b/drivers/gpu/drm/msm/msm_gem_prime.c @@ -33,12 +33,12 @@ struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) void *msm_gem_prime_vmap(struct drm_gem_object *obj) { - return msm_gem_vaddr(obj); + return msm_gem_get_vaddr(obj); } void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) { - /* TODO msm_gem_vunmap() */ + msm_gem_put_vaddr(obj); } int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index ea5f709e2e27..736f15881b6a 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -279,7 +279,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob /* For now, just map the entire thing. Eventually we probably * to do it page-by-page, w/ kmap() if not vmap()d.. */ - ptr = msm_gem_vaddr_locked(&obj->base); + ptr = msm_gem_get_vaddr_locked(&obj->base); if (IS_ERR(ptr)) { ret = PTR_ERR(ptr); @@ -332,6 +332,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob last_offset = off; } + msm_gem_put_vaddr_locked(&obj->base); + return 0; } diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 0857710c2ff2..3eeb8af0c855 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -310,7 +310,7 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) uint32_t iova = submit->cmd[i].iova; uint32_t szd = submit->cmd[i].size; /* in dwords */ struct msm_gem_object *obj = submit->bos[idx].obj; - const char *buf = msm_gem_vaddr_locked(&obj->base); + const char *buf = msm_gem_get_vaddr_locked(&obj->base); if (IS_ERR(buf)) continue; @@ -335,6 +335,8 @@ void msm_rd_dump_submit(struct msm_gem_submit *submit) (uint32_t[2]){ iova, szd }, 8); break; } + + msm_gem_put_vaddr_locked(&obj->base); } } #endif diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 42f5359cf988..f326cf6a32e6 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -39,7 +39,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) goto fail; } - ring->start = msm_gem_vaddr_locked(ring->bo); + ring->start = msm_gem_get_vaddr_locked(ring->bo); if (IS_ERR(ring->start)) { ret = PTR_ERR(ring->start); goto fail; @@ -59,7 +59,9 @@ fail: void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) { - if (ring->bo) + if (ring->bo) { + msm_gem_put_vaddr(ring->bo); drm_gem_object_unreference_unlocked(ring->bo); + } kfree(ring); } -- cgit v1.2.3 From 6b597ce2f7c7a0f8116d753902db9aba6bc05cb0 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 1 Jun 2016 14:17:40 -0400 Subject: drm/msm: deal with arbitrary # of cmd buffers For some optimizations coming on the userspace side, splitting larger draw or gmem cmds into multiple cmdstream buffers, we need to support much more than the previous small/arbitrary limit. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 11 ++--------- drivers/gpu/drm/msm/msm_gem.h | 4 +--- drivers/gpu/drm/msm/msm_gem_submit.c | 11 +++++------ 3 files changed, 8 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 7dfe22ea2920..f386f463278d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -139,7 +139,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct msm_drm_private *priv = gpu->dev->dev_private; struct msm_ringbuffer *ring = gpu->rb; - unsigned i, ibs = 0; + unsigned i; for (i = 0; i < submit->nr_cmds; i++) { switch (submit->cmd[i].type) { @@ -155,18 +155,11 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2); OUT_RING(ring, submit->cmd[i].iova); OUT_RING(ring, submit->cmd[i].size); - ibs++; + OUT_PKT2(ring); break; } } - /* on a320, at least, we seem to need to pad things out to an - * even number of qwords to avoid issue w/ CP hanging on wrap- - * around: - */ - if (ibs % 2) - OUT_PKT2(ring); - OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1); OUT_RING(ring, submit->fence->seqno); diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 7a4da819731a..b2f13cfe945e 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -93,8 +93,6 @@ static inline bool is_vunmapable(struct msm_gem_object *msm_obj) return (msm_obj->vmap_count == 0) && msm_obj->vaddr; } -#define MAX_CMDS 4 - /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, * associated with the cmdstream submission for synchronization (and * make it easier to unwind when things go wrong, etc). This only @@ -116,7 +114,7 @@ struct msm_gem_submit { uint32_t size; /* in dwords */ uint32_t iova; uint32_t idx; /* cmdstream buffer idx in bos[] */ - } cmd[MAX_CMDS]; + } *cmd; /* array of size nr_cmds */ struct { uint32_t flags; struct msm_gem_object *obj; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 736f15881b6a..9766f9ae4b7d 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -29,10 +29,11 @@ #define BO_PINNED 0x2000 static struct msm_gem_submit *submit_create(struct drm_device *dev, - struct msm_gpu *gpu, int nr) + struct msm_gpu *gpu, int nr_bos, int nr_cmds) { struct msm_gem_submit *submit; - int sz = sizeof(*submit) + (nr * sizeof(submit->bos[0])); + int sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) + + (nr_cmds * sizeof(*submit->cmd)); submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY); if (!submit) @@ -42,6 +43,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->gpu = gpu; submit->fence = NULL; submit->pid = get_pid(task_pid(current)); + submit->cmd = (void *)&submit->bos[nr_bos]; /* initially, until copy_from_user() and bo lookup succeeds: */ submit->nr_bos = 0; @@ -371,14 +373,11 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (args->pipe != MSM_PIPE_3D0) return -EINVAL; - if (args->nr_cmds > MAX_CMDS) - return -EINVAL; - ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - submit = submit_create(dev, gpu, args->nr_bos); + submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds); if (!submit) { ret = -ENOMEM; goto out_unlock; -- cgit v1.2.3