Skip to contentSkip to conversation

drm/msm: separate iova allocation and mapping

PATCH New Jordan Crouse 2 participants 10 messages Nov 7, 2018 1 message not in the archive

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v2 cover drm/msm: separate iova allocation and mapping

Currently in the msm driver iova addresses are mapped in the IOMMU at allocation time and stay there for the life of the buffer. This may not be desirable for long lived user space buffers that could be temporarily swapped or moved.

This first set of patches breaks up the allocation and mapping into distinct steps and adds reference counting for pinning and unpinning the memory. Future code can use this information to manipulate the memory when it isn't in use.

Revision 2 adds an additional 2 patches to add a description to each buffer object so the output from the debugfs file gives a clue as to what the buffer is used for. This is useful for debugging leaks and will also be helpful when we start to figure out how to shrink or move memory around.

The last patch fixes an annoyance where the ringbuffer iova was refcounted every time the GPU started. It isn't harmful but it sticks out like a sore thumb when debugging.

Jordan Crouse (9):
drm/msm: Add a common function to free kernel buffer objects drm/msm: Remove sgt from the mmu unmap function drm/msm: Split msm_gem_get_iova into two steps
drm/msm: Clean up and enhance the output of the 'gem' debugfs node drm/msm: Add msm_gem_get_and_pin_iova()
drm/msm: Count how many times iova memory is pinned drm/msm: Add a name field for gem objects
drm/msm: Add a name field to struct drm_msm_gem_new drm/msm/gpu: Map the ringbuffer in the iova at create time

 drivers/gpu/drm/msm/adreno/a5xx_debugfs.c |   6 +-
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c     |  33 ++--
 drivers/gpu/drm/msm/adreno/a5xx_power.c   |  15 +-
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c |  16 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c     |   5 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c   |   8 -
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c |   6 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c  |   4 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c |   4 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c        |   6 +-
 drivers/gpu/drm/msm/msm_drv.c             |   9 +-
 drivers/gpu/drm/msm/msm_drv.h             |  20 ++-
 drivers/gpu/drm/msm/msm_fb.c              |   6 +-
 drivers/gpu/drm/msm/msm_fbdev.c           |   2 +-
 drivers/gpu/drm/msm/msm_gem.c             | 193 ++++++++++++++++------
 drivers/gpu/drm/msm/msm_gem.h             |   4 +
 drivers/gpu/drm/msm/msm_gem_submit.c      |   4 +-
 drivers/gpu/drm/msm/msm_gem_vma.c         |  95 ++++++++---
 drivers/gpu/drm/msm/msm_gpu.c             |  18 +-
 drivers/gpu/drm/msm/msm_iommu.c           |   3 +-
 drivers/gpu/drm/msm/msm_mmu.h             |   3 +-
 drivers/gpu/drm/msm/msm_ringbuffer.c      |  14 +-
 include/uapi/drm/msm_drm.h                |   1 +
 23 files changed, 302 insertions(+), 173 deletions(-)
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

A message that is not in the archive (sent off-list or not yet received): 20181107223554.27308-1-jcrouse-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

#2 lore raw

PATCH v2 1/9 drm/msm: Add a common function to free kernel buffer objects

Buffer objects allocated with msm_gem_kernel_new() are mostly freed the same way so we can save a few lines of code with a common function.

---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c     | 13 ++-----------
 drivers/gpu/drm/msm/adreno/a5xx_power.c   | 13 +------------
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 14 ++------------
 drivers/gpu/drm/msm/msm_drv.h             |  2 ++
 drivers/gpu/drm/msm/msm_gem.c             | 15 +++++++++++++++
 drivers/gpu/drm/msm/msm_gpu.c             | 12 ++----------
 drivers/gpu/drm/msm/msm_ringbuffer.c      |  7 ++-----
 7 files changed, 26 insertions(+), 50 deletions(-)
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +2 -11
index 2d34643ef2e2..d6f8dedc028a 100644
@@ -1228,15 +1228,6 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu,
 	return 0;
 }
 
-static void a5xx_crashdumper_free(struct msm_gpu *gpu,
-		struct a5xx_crashdumper *dumper)
-{
-	msm_gem_put_iova(dumper->bo, gpu->aspace);
-	msm_gem_put_vaddr(dumper->bo);
-
-	drm_gem_object_put(dumper->bo);
-}
-
 static int a5xx_crashdumper_run(struct msm_gpu *gpu,
 		struct a5xx_crashdumper *dumper)
 {
@@ -1329,7 +1320,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu,
 
 	if (a5xx_crashdumper_run(gpu, &dumper)) {
 		kfree(a5xx_state->hlsqregs);
-		a5xx_crashdumper_free(gpu, &dumper);
+		msm_gem_kernel_put(dumper.bo, gpu->aspace, true);
 		return;
 	}
 
@@ -1337,7 +1328,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu,
 	memcpy(a5xx_state->hlsqregs, dumper.ptr + (256 * SZ_1K),
 		count * sizeof(u32));
 
-	a5xx_crashdumper_free(gpu, &dumper);
+	msm_gem_kernel_put(dumper.bo, gpu->aspace, true);
 }
 
 static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
drivers/gpu/drm/msm/adreno/a5xx_power.c +1 -12
index 7a41e1c147e4..66bcd88dd8c0 100644
@@ -298,7 +298,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
 		MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
 		&a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
 	if (IS_ERR(ptr))
-		goto err;
+		return;
 
 	while (cmds_size > 0) {
 		int i;
@@ -317,15 +317,4 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
 
 	msm_gem_put_vaddr(a5xx_gpu->gpmu_bo);
 	a5xx_gpu->gpmu_dwords = dwords;
-
-	return;
-err:
-	if (a5xx_gpu->gpmu_iova)
-		msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
-	if (a5xx_gpu->gpmu_bo)
-		drm_gem_object_put(a5xx_gpu->gpmu_bo);
-
-	a5xx_gpu->gpmu_bo = NULL;
-	a5xx_gpu->gpmu_iova = 0;
-	a5xx_gpu->gpmu_dwords = 0;
 }
drivers/gpu/drm/msm/adreno/a5xx_preempt.c +2 -12
index fdb08fc68c2c..48481e663685 100644
@@ -267,18 +267,8 @@ void a5xx_preempt_fini(struct msm_gpu *gpu)
 	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
 	int i;
 
-	for (i = 0; i < gpu->nr_rings; i++) {
-		if (!a5xx_gpu->preempt_bo[i])
-			continue;
-
-		msm_gem_put_vaddr(a5xx_gpu->preempt_bo[i]);
-
-		if (a5xx_gpu->preempt_iova[i])
-			msm_gem_put_iova(a5xx_gpu->preempt_bo[i], gpu->aspace);
-
-		drm_gem_object_put(a5xx_gpu->preempt_bo[i]);
-		a5xx_gpu->preempt_bo[i] = NULL;
-	}
+	for (i = 0; i < gpu->nr_rings; i++)
+		msm_gem_kernel_put(a5xx_gpu->preempt_bo[i], gpu->aspace, true);
 }
 
 void a5xx_preempt_init(struct msm_gpu *gpu)
drivers/gpu/drm/msm/msm_drv.h +2 -0
index 9d11f321f5a9..3225f8fbd8c9 100644
@@ -312,6 +312,8 @@ void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
 void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
 		uint32_t flags, struct msm_gem_address_space *aspace,
 		struct drm_gem_object **bo, uint64_t *iova);
+void msm_gem_kernel_put(struct drm_gem_object *bo,
+		struct msm_gem_address_space *aspace, bool locked);
 struct drm_gem_object *msm_gem_import(struct drm_device *dev,
 		struct dma_buf *dmabuf, struct sg_table *sgt);
 
drivers/gpu/drm/msm/msm_gem.c +15 -0
index 00c795ced02c..855f5721a14e 100644
@@ -1073,3 +1073,18 @@ void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
 {
 	return _msm_gem_kernel_new(dev, size, flags, aspace, bo, iova, true);
 }
+
+void msm_gem_kernel_put(struct drm_gem_object *bo,
+		struct msm_gem_address_space *aspace, bool locked)
+{
+	if (IS_ERR_OR_NULL(bo))
+		return;
+
+	msm_gem_put_vaddr(bo);
+	msm_gem_put_iova(bo, aspace);
+
+	if (locked)
+		drm_gem_object_put(bo);
+	else
+		drm_gem_object_put_unlocked(bo);
+}
drivers/gpu/drm/msm/msm_gpu.c +2 -10
index ff958486819b..71a2d431663f 100644
@@ -961,11 +961,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		gpu->rb[i] = NULL;
 	}
 
-	if (gpu->memptrs_bo) {
-		msm_gem_put_vaddr(gpu->memptrs_bo);
-		msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace);
-		drm_gem_object_put_unlocked(gpu->memptrs_bo);
-	}
+	msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace, false);
 
 	platform_set_drvdata(pdev, NULL);
 	return ret;
@@ -984,11 +980,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
 		gpu->rb[i] = NULL;
 	}
 
-	if (gpu->memptrs_bo) {
-		msm_gem_put_vaddr(gpu->memptrs_bo);
-		msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace);
-		drm_gem_object_put_unlocked(gpu->memptrs_bo);
-	}
+	msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace, false);
 
 	if (!IS_ERR_OR_NULL(gpu->aspace)) {
 		gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
drivers/gpu/drm/msm/msm_ringbuffer.c +2 -5
index 6f5295b3f2f6..9fa9525c5293 100644
@@ -73,10 +73,7 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
 
 	msm_fence_context_free(ring->fctx);
 
-	if (ring->bo) {
-		msm_gem_put_iova(ring->bo, ring->gpu->aspace);
-		msm_gem_put_vaddr(ring->bo);
-		drm_gem_object_put_unlocked(ring->bo);
-	}
+	msm_gem_kernel_put(ring->bo, ring->gpu->aspace, false);
+
 	kfree(ring);
 }
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#3 lore raw

PATCH v2 2/9 drm/msm: Remove sgt from the mmu unmap function

In reply to a message not in the archive

The scatter gather table doesn't need to be passed in for the MMU unmap function.

---
 drivers/gpu/drm/msm/msm_drv.h     | 2 +-
 drivers/gpu/drm/msm/msm_gem.c     | 2 +-
 drivers/gpu/drm/msm/msm_gem_vma.c | 4 ++--
 drivers/gpu/drm/msm/msm_iommu.c   | 3 +--
 drivers/gpu/drm/msm/msm_mmu.h     | 3 +--
 5 files changed, 6 insertions(+), 8 deletions(-)
drivers/gpu/drm/msm/msm_drv.h +1 -1
index 3225f8fbd8c9..3a0f2119127b 100644
@@ -242,7 +242,7 @@ void msm_atomic_state_clear(struct drm_atomic_state *state);
 void msm_atomic_state_free(struct drm_atomic_state *state);
 
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
-		struct msm_gem_vma *vma, struct sg_table *sgt);
+		struct msm_gem_vma *vma);
 int msm_gem_map_vma(struct msm_gem_address_space *aspace,
 		struct msm_gem_vma *vma, struct sg_table *sgt, int npages);
 
drivers/gpu/drm/msm/msm_gem.c +1 -1
index 855f5721a14e..ff75e557b708 100644
@@ -352,7 +352,7 @@ put_iova(struct drm_gem_object *obj)
 	WARN_ON(!mutex_is_locked(&msm_obj->lock));
 
 	list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) {
-		msm_gem_unmap_vma(vma->aspace, vma, msm_obj->sgt);
+		msm_gem_unmap_vma(vma->aspace, vma);
 		del_vma(vma);
 	}
 }
drivers/gpu/drm/msm/msm_gem_vma.c +2 -2
index ffbec224551b..704ae7e69500 100644
@@ -40,14 +40,14 @@ void msm_gem_address_space_put(struct msm_gem_address_space *aspace)
 
 void
 msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
-		struct msm_gem_vma *vma, struct sg_table *sgt)
+		struct msm_gem_vma *vma)
 {
 	if (!aspace || !vma->iova)
 		return;
 
 	if (aspace->mmu) {
 		unsigned size = vma->node.size << PAGE_SHIFT;
-		aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt, size);
+		aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, size);
 	}
 
 	spin_lock(&aspace->lock);
drivers/gpu/drm/msm/msm_iommu.c +1 -2
index b23d33622f37..9c313cb129ee 100644
@@ -71,8 +71,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	return (ret == len) ? 0 : -EINVAL;
 }
 
-static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
-		struct sg_table *sgt, unsigned len)
+static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len)
 {
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 
drivers/gpu/drm/msm/msm_mmu.h +1 -2
index aa2c5d4580c8..94c0b83d8026 100644
@@ -25,8 +25,7 @@ struct msm_mmu_funcs {
 	void (*detach)(struct msm_mmu *mmu, const char * const *names, int cnt);
 	int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
 			unsigned len, int prot);
-	int (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
-			unsigned len);
+	int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len);
 	void (*destroy)(struct msm_mmu *mmu);
 };
 
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#4 lore raw

PATCH v2 3/9 drm/msm: Split msm_gem_get_iova into two steps

In reply to a message not in the archive

Split the operation of msm_gem_get_iova into two operations:
1) allocate an iova and 2) map (pin) the backing memory int the iommu. This is the first step toward allowing memory pinning to occur independently of the iova management.

---
 drivers/gpu/drm/msm/msm_drv.h     |  2 +
 drivers/gpu/drm/msm/msm_gem.c     | 80 ++++++++++++++++++++-----------
 drivers/gpu/drm/msm/msm_gem.h     |  1 +
 drivers/gpu/drm/msm/msm_gem_vma.c | 44 ++++++++++++-----
 4 files changed, 86 insertions(+), 41 deletions(-)
drivers/gpu/drm/msm/msm_drv.h +2 -0
index 3a0f2119127b..63b28b69b2ab 100644
@@ -241,6 +241,8 @@ struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
 void msm_atomic_state_clear(struct drm_atomic_state *state);
 void msm_atomic_state_free(struct drm_atomic_state *state);
 
+int msm_gem_init_vma(struct msm_gem_address_space *aspace,
+		struct msm_gem_vma *vma, int npages);
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
 		struct msm_gem_vma *vma);
 int msm_gem_map_vma(struct msm_gem_address_space *aspace,
drivers/gpu/drm/msm/msm_gem.c +52 -28

104 lines not on this page · raw message

drivers/gpu/drm/msm/msm_gem.h +1 -0
index c5d9bd3e47a8..32c13e6559b5 100644
@@ -41,6 +41,7 @@ struct msm_gem_vma {
 	uint64_t iova;
 	struct msm_gem_address_space *aspace;
 	struct list_head list;    /* node in msm_gem_object::vmas */
+	bool mapped;
 };
 
 struct msm_gem_object {
drivers/gpu/drm/msm/msm_gem_vma.c +31 -13

68 lines not on this page · raw message

Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#5 lore raw

PATCH v2 4/9 drm/msm: Clean up and enhance the output of the 'gem' debugfs node

In reply to a message not in the archive

Add headers for the 'gem' debugfs file to make it easier to remember what all the values mean and move the list of virtual address regions to the next line and add the name and map status to make it clearer what we are looking at.

---
 drivers/gpu/drm/msm/msm_gem.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/gpu/drm/msm/msm_gem.c +14 -6
index 189d7f0f1aad..136179de2cca 100644
@@ -763,16 +763,23 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
 		break;
 	}
 
-	seq_printf(m, "%08x: %c %2d (%2d) %08llx %p\t",
+	seq_printf(m, "%08x: %c %2d (%2d) %08llx %p",
 			msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
 			obj->name, kref_read(&obj->refcount),
 			off, msm_obj->vaddr);
 
-	/* FIXME: we need to print the address space here too */
-	list_for_each_entry(vma, &msm_obj->vmas, list)
-		seq_printf(m, " %08llx", vma->iova);
+	seq_printf(m, " %08zu%9s\n", obj->size, madv);
 
-	seq_printf(m, " %zu%s\n", obj->size, madv);
+	if (!list_empty(&msm_obj->vmas)) {
+
+		seq_puts(m, "   vmas:");
+
+		list_for_each_entry(vma, &msm_obj->vmas, list)
+			seq_printf(m, " [%s: %08llx,%s]", vma->aspace->name,
+				vma->iova, vma->mapped ? "mapped" : "unmapped");
+
+		seq_puts(m, "\n");
+	}
 
 	rcu_read_lock();
 	fobj = rcu_dereference(robj->fence);
@@ -799,9 +806,10 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m)
 	int count = 0;
 	size_t size = 0;
 
+	seq_puts(m, "   flags       id ref  offset   kaddr            size     madv\n");
 	list_for_each_entry(msm_obj, list, mm_list) {
 		struct drm_gem_object *obj = &msm_obj->base;
-		seq_printf(m, "   ");
+		seq_puts(m, "   ");
 		msm_gem_describe(obj, m);
 		count++;
 		size += obj->size;
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#6 lore raw

PATCH v2 5/9 drm/msm: Add msm_gem_get_and_pin_iova()

In reply to a message not in the archive

Add a new function to get and pin the iova memory in one step (basically renaming the old msm_gem_get_iova function) and switch msm_gem_get_iova() to only allocate an iova but not map it in the IOMMU. This is only currently used by msm_ioctl_gem_info() since all other users of of the iova expect that the memory be immediately available.

---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c   |  3 ++-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c |  4 ++--
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c  |  2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c |  2 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c        |  2 +-
 drivers/gpu/drm/msm/msm_drv.c             |  4 ++++
 drivers/gpu/drm/msm/msm_drv.h             |  2 ++
 drivers/gpu/drm/msm/msm_fb.c              |  2 +-
 drivers/gpu/drm/msm/msm_fbdev.c           |  2 +-
 drivers/gpu/drm/msm/msm_gem.c             | 24 ++++++++++++++++++-----
 drivers/gpu/drm/msm/msm_gem_submit.c      |  2 +-
 drivers/gpu/drm/msm/msm_gpu.c             |  2 +-
 12 files changed, 36 insertions(+), 15 deletions(-)
drivers/gpu/drm/msm/adreno/adreno_gpu.c +2 -1
index 141062fbb4c8..3c2988514fc5 100644
@@ -209,7 +209,8 @@ int adreno_hw_init(struct msm_gpu *gpu)
 		if (!ring)
 			continue;
 
-		ret = msm_gem_get_iova(ring->bo, gpu->aspace, &ring->iova);
+		ret = msm_gem_get_and_pin_iova(ring->bo, gpu->aspace,
+			&ring->iova);
 		if (ret) {
 			ring->iova = 0;
 			DRM_DEV_ERROR(gpu->dev->dev,
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +2 -2
index b91706cee2b8..ef6884f1fc34 100644
@@ -384,7 +384,7 @@ static void update_cursor(struct drm_crtc *crtc)
 		if (next_bo) {
 			/* take a obj ref + iova ref when we start scanning out: */
 			drm_gem_object_get(next_bo);
-			msm_gem_get_iova(next_bo, kms->aspace, &iova);
+			msm_gem_get_and_pin_iova(next_bo, kms->aspace, &iova);
 
 			/* enable cursor: */
 			mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma),
@@ -442,7 +442,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
 	}
 
 	if (cursor_bo) {
-		ret = msm_gem_get_iova(cursor_bo, kms->aspace, &iova);
+		ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &iova);
 		if (ret)
 			goto fail;
 	} else {
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +1 -1
index 481c0d231149..9fd6b9b2dbcb 100644
@@ -538,7 +538,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
 		goto fail;
 	}
 
-	ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, kms->aspace,
+	ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->aspace,
 			&mdp4_kms->blank_cursor_iova);
 	if (ret) {
 		DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +1 -1
index 413b52211017..c7cc276575fb 100644
@@ -903,7 +903,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
 	if (!cursor_bo)
 		return -ENOENT;
 
-	ret = msm_gem_get_iova(cursor_bo, kms->aspace,
+	ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace,
 			&mdp5_crtc->cursor.iova);
 	if (ret)
 		return -EINVAL;
drivers/gpu/drm/msm/dsi/dsi_host.c +1 -1
index eba901584035..99122767abf4 100644
@@ -1248,7 +1248,7 @@ int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base)
 	if (!dma_base)
 		return -EINVAL;
 
-	return msm_gem_get_iova(msm_host->tx_gem_obj,
+	return msm_gem_get_and_pin_iova(msm_host->tx_gem_obj,
 				priv->kms->aspace, dma_base);
 }
 
drivers/gpu/drm/msm/msm_drv.c +4 -0
index 9c9f7ff6960b..f2ebfb9ba0e4 100644
@@ -849,6 +849,10 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev,
 	if (!priv->gpu)
 		return -EINVAL;
 
+	/*
+	 * Don't pin the memory here - just get an address so that userspace can
+	 * be productive
+	 */
 	return msm_gem_get_iova(obj, priv->gpu->aspace, iova);
 }
 
drivers/gpu/drm/msm/msm_drv.h +2 -0
index 63b28b69b2ab..4372505a0bda 100644
@@ -271,6 +271,8 @@ vm_fault_t msm_gem_fault(struct vm_fault *vmf);
 uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
 int msm_gem_get_iova(struct drm_gem_object *obj,
 		struct msm_gem_address_space *aspace, uint64_t *iova);
+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova);
 uint64_t msm_gem_iova(struct drm_gem_object *obj,
 		struct msm_gem_address_space *aspace);
 struct page **msm_gem_get_pages(struct drm_gem_object *obj);
drivers/gpu/drm/msm/msm_fb.c +1 -1
index 475191fcf412..4e1e435db5a6 100644
@@ -66,7 +66,7 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb,
 	uint64_t iova;
 
 	for (i = 0; i < n; i++) {
-		ret = msm_gem_get_iova(fb->obj[i], aspace, &iova);
+		ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &iova);
 		DBG("FB[%u]: iova[%d]: %08llx (%d)", fb->base.id, i, iova, ret);
 		if (ret)
 			return ret;
drivers/gpu/drm/msm/msm_fbdev.c +1 -1
index f94cbbbf3834..c03e860ba737 100644
@@ -104,7 +104,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
 	 * in panic (ie. lock-safe, etc) we could avoid pinning the
 	 * buffer now:
 	 */
-	ret = msm_gem_get_iova(bo, priv->kms->aspace, &paddr);
+	ret = msm_gem_get_and_pin_iova(bo, priv->kms->aspace, &paddr);
 	if (ret) {
 		DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret);
 		goto fail_unlock;
drivers/gpu/drm/msm/msm_gem.c +19 -5
index 136179de2cca..d427d9d3f013 100644
@@ -408,9 +408,8 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj,
 			obj->size >> PAGE_SHIFT);
 }
 
-
-/* get iova, taking a reference.  Should have a matching put */
-int msm_gem_get_iova(struct drm_gem_object *obj,
+/* get iova and pin it. Should have a matching put */
+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
 		struct msm_gem_address_space *aspace, uint64_t *iova)
 {
 	struct msm_gem_object *msm_obj = to_msm_bo(obj);
@@ -431,8 +430,23 @@ int msm_gem_get_iova(struct drm_gem_object *obj,
 	return ret;
 }
 
+/* Get an iova but don't pin the memory behind it */
+int msm_gem_get_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	int ret;
+
+	mutex_lock(&msm_obj->lock);
+	ret = msm_gem_get_iova_locked(obj, aspace, iova);
+	mutex_unlock(&msm_obj->lock);
+
+	return ret;
+}
+
+
 /* get iova without taking a reference, used in places where you have
- * already done a 'msm_gem_get_iova()'.
+ * already done a 'msm_gem_get_and_pin_iova' or 'msm_gem_get_iova'
  */
 uint64_t msm_gem_iova(struct drm_gem_object *obj,
 		struct msm_gem_address_space *aspace)
@@ -1072,7 +1086,7 @@ static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
 		return ERR_CAST(obj);
 
 	if (iova) {
-		ret = msm_gem_get_iova(obj, aspace, iova);
+		ret = msm_gem_get_and_pin_iova(obj, aspace, iova);
 		if (ret) {
 			drm_gem_object_put(obj);
 			return ERR_PTR(ret);
drivers/gpu/drm/msm/msm_gem_submit.c +1 -1
index 66673ea9bf6f..da907260660c 100644
@@ -269,7 +269,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit)
 		uint64_t iova;
 
 		/* if locking succeeded, pin bo: */
-		ret = msm_gem_get_iova(&msm_obj->base,
+		ret = msm_gem_get_and_pin_iova(&msm_obj->base,
 				submit->gpu->aspace, &iova);
 
 		if (ret)
drivers/gpu/drm/msm/msm_gpu.c +1 -1
index 71a2d431663f..13dab9527bda 100644
@@ -754,7 +754,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
 
 		/* submit takes a reference to the bo and iova until retired: */
 		drm_gem_object_get(&msm_obj->base);
-		msm_gem_get_iova(&msm_obj->base,
+		msm_gem_get_and_pin_iova(&msm_obj->base,
 				submit->gpu->aspace, &iova);
 
 		if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE)
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#7 lore raw

PATCH v2 7/9 drm/msm: Add a name field for gem objects

In reply to a message not in the archive

For debugging purposes it is useful to assign descriptions to buffers so that we know what they are used for. Add a field to the buffer object and use that to name the various kernel side allocations which ends up looking like like this in /d/dri/X/gem:

flags id ref offset kaddr size madv name
00040000: I 0 ( 1) 00000000 0000000070b79eca 00004096 memptrs

      vmas: [gpu: 01000000,mapped,inuse=1]

00020000: I 0 ( 1) 00000000 0000000031ed4074 00032768 ring0

---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c     | 11 ++++++++---
 drivers/gpu/drm/msm/adreno/a5xx_power.c   |  2 ++
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c |  2 ++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c     |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c        |  2 ++
 drivers/gpu/drm/msm/msm_drv.h             |  2 ++
 drivers/gpu/drm/msm/msm_fb.c              |  2 ++
 drivers/gpu/drm/msm/msm_gem.c             | 19 ++++++++++++++++---
 drivers/gpu/drm/msm/msm_gem.h             |  2 ++
 drivers/gpu/drm/msm/msm_gpu.c             |  2 ++
 drivers/gpu/drm/msm/msm_ringbuffer.c      |  3 +++
 11 files changed, 43 insertions(+), 6 deletions(-)
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +8 -3
index 135496393cf3..b632b5c82898 100644
@@ -511,6 +511,7 @@ static int a5xx_ucode_init(struct msm_gpu *gpu)
 		a5xx_gpu->pm4_bo = adreno_fw_create_bo(gpu,
 			adreno_gpu->fw[ADRENO_FW_PM4], &a5xx_gpu->pm4_iova);
 
+
 		if (IS_ERR(a5xx_gpu->pm4_bo)) {
 			ret = PTR_ERR(a5xx_gpu->pm4_bo);
 			a5xx_gpu->pm4_bo = NULL;
@@ -518,6 +519,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu)
 				ret);
 			return ret;
 		}
+
+		msm_gem_object_set_name(a5xx_gpu->pm4_bo, "pm4fw");
 	}
 
 	if (!a5xx_gpu->pfp_bo) {
@@ -531,6 +534,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu)
 				ret);
 			return ret;
 		}
+
+		msm_gem_object_set_name(a5xx_gpu->pfp_bo, "pfpfw");
 	}
 
 	gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO,
@@ -1219,10 +1224,10 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu,
 		SZ_1M, MSM_BO_UNCACHED, gpu->aspace,
 		&dumper->bo, &dumper->iova);
 
-	if (IS_ERR(dumper->ptr))
-		return PTR_ERR(dumper->ptr);
+	if (!IS_ERR(dumper->ptr))
+		msm_gem_object_set_name(dumper->bo, "crashdump");
 
-	return 0;
+	return PTR_ERR_OR_ZERO(dumper->ptr);
 }
 
 static int a5xx_crashdumper_run(struct msm_gpu *gpu,
drivers/gpu/drm/msm/adreno/a5xx_power.c +2 -0
index 66bcd88dd8c0..70e65c94e525 100644
@@ -300,6 +300,8 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
 	if (IS_ERR(ptr))
 		return;
 
+	msm_gem_object_set_name(a5xx_gpu->gpmu_bo, "gpmufw");
+
 	while (cmds_size > 0) {
 		int i;
 		uint32_t _size = cmds_size > TYPE4_MAX_PAYLOAD ?
drivers/gpu/drm/msm/adreno/a5xx_preempt.c +2 -0
index 48481e663685..3d62310a535f 100644
@@ -245,6 +245,8 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
 	if (IS_ERR(ptr))
 		return PTR_ERR(ptr);
 
+	msm_gem_object_set_name(bo, "preempt");
+
 	a5xx_gpu->preempt_bo[ring->id] = bo;
 	a5xx_gpu->preempt_iova[ring->id] = iova;
 	a5xx_gpu->preempt[ring->id] = ptr;
drivers/gpu/drm/msm/adreno/a6xx_gpu.c +2 -0
index 9acf12c21b23..a1ba6205fee3 100644
@@ -300,6 +300,8 @@ static int a6xx_ucode_init(struct msm_gpu *gpu)
 
 			return ret;
 		}
+
+		msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw");
 	}
 
 	gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE_LO,
drivers/gpu/drm/msm/dsi/dsi_host.c +2 -0
index 3b7092e1dcc7..38e481d2d606 100644
@@ -1083,6 +1083,8 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
 		return PTR_ERR(data);
 	}
 
+	msm_gem_object_set_name(msm_host->tx_gem_obj, "tx_gem");
+
 	msm_host->tx_size = msm_host->tx_gem_obj->size;
 
 	return 0;
drivers/gpu/drm/msm/msm_drv.h +2 -0
index 955c2f522db6..df920b13a8a4 100644
@@ -325,6 +325,8 @@ void msm_gem_kernel_put(struct drm_gem_object *bo,
 struct drm_gem_object *msm_gem_import(struct drm_device *dev,
 		struct dma_buf *dmabuf, struct sg_table *sgt);
 
+void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
+
 int msm_framebuffer_prepare(struct drm_framebuffer *fb,
 		struct msm_gem_address_space *aspace);
 void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
drivers/gpu/drm/msm/msm_fb.c +2 -0
index 1224739094f2..67dfd8d3dc12 100644
@@ -237,6 +237,8 @@ msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format
 		return ERR_CAST(bo);
 	}
 
+	msm_gem_object_set_name(bo, "stolenfb");
+
 	fb = msm_framebuffer_init(dev, &mode_cmd, &bo);
 	if (IS_ERR(fb)) {
 		DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
drivers/gpu/drm/msm/msm_gem.c +16 -3
index 96ff698ddee4..35c9d4048b37 100644
@@ -491,7 +491,7 @@ int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
 	args->pitch = align_pitch(args->width, args->bpp);
 	args->size  = PAGE_ALIGN(args->pitch * args->height);
 	return msm_gem_new_handle(dev, file, args->size,
-			MSM_BO_SCANOUT | MSM_BO_WC, &args->handle);
+			MSM_BO_SCANOUT | MSM_BO_WC, &args->handle, "dumb");
 }
 
 int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
@@ -794,7 +794,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
 			obj->name, kref_read(&obj->refcount),
 			off, msm_obj->vaddr);
 
-	seq_printf(m, " %08zu%9s\n", obj->size, madv);
+	seq_printf(m, " %08zu %9s %-32s\n", obj->size, madv, msm_obj->name);
 
 	if (!list_empty(&msm_obj->vmas)) {
 
@@ -833,7 +833,7 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m)
 	int count = 0;
 	size_t size = 0;
 
-	seq_puts(m, "   flags       id ref  offset   kaddr            size     madv\n");
+	seq_puts(m, "   flags       id ref  offset   kaddr            size     madv      name\n");
 	list_for_each_entry(msm_obj, list, mm_list) {
 		struct drm_gem_object *obj = &msm_obj->base;
 		seq_puts(m, "   ");
@@ -1147,3 +1147,16 @@ void msm_gem_kernel_put(struct drm_gem_object *bo,
 	else
 		drm_gem_object_put_unlocked(bo);
 }
+
+void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(bo);
+	va_list ap;
+
+	if (!fmt)
+		return;
+
+	va_start(ap, fmt);
+	vsnprintf(msm_obj->name, sizeof(msm_obj->name), fmt, ap);
+	va_end(ap);
+}
drivers/gpu/drm/msm/msm_gem.h +2 -0
index 53d3bf49a9fa..f4336238a96b 100644
@@ -93,6 +93,8 @@ struct msm_gem_object {
 	 */
 	struct drm_mm_node *vram_node;
 	struct mutex lock; /* Protects resources associated with bo */
+
+	char name[32]; /* Identifier to print for the debugfs files */
 };
 #define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
 
drivers/gpu/drm/msm/msm_gpu.c +2 -0
index e6ce24bfb9b1..53a89f075a4c 100644
@@ -930,6 +930,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		goto fail;
 	}
 
+	msm_gem_object_set_name(gpu->memptrs_bo, "memptrs");
+
 	if (nr_rings > ARRAY_SIZE(gpu->rb)) {
 		DRM_DEV_INFO_ONCE(drm->dev, "Only creating %zu ringbuffers\n",
 			ARRAY_SIZE(gpu->rb));
drivers/gpu/drm/msm/msm_ringbuffer.c +3 -0
index 9fa9525c5293..6169bd6ca153 100644
@@ -45,6 +45,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
 		ring->start = 0;
 		goto fail;
 	}
+
+	msm_gem_object_set_name(ring->bo, "ring%d", id);
+
 	ring->end   = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2);
 	ring->next  = ring->start;
 	ring->cur   = ring->start;
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#8 lore raw

PATCH v2 8/9 drm/msm: Add a name field to struct drm_msm_gem_new

In reply to a message not in the archive

Add a name field to struct drm_msm_gem_new to allow userspace to specify a name/description for gem buffers to improve debugging and tracking.

---
 drivers/gpu/drm/msm/msm_drv.c |  5 +++--
 drivers/gpu/drm/msm/msm_drv.h |  2 +-
 drivers/gpu/drm/msm/msm_gem.c | 16 ++++++++++++++--
 include/uapi/drm/msm_drm.h    |  1 +
 4 files changed, 19 insertions(+), 5 deletions(-)
drivers/gpu/drm/msm/msm_drv.c +3 -2
index f2ebfb9ba0e4..8fb86edd30fa 100644
@@ -35,9 +35,10 @@
  * - 1.3.0 - adds GMEM_BASE + NR_RINGS params, SUBMITQUEUE_NEW +
  *           SUBMITQUEUE_CLOSE ioctls, and MSM_INFO_IOVA flag for
  *           MSM_GEM_INFO ioctl.
+ * - 1.4.0 - Add char name[32] to MSM_GEM_BO_NEW for tracking purposes
  */
 #define MSM_VERSION_MAJOR	1
-#define MSM_VERSION_MINOR	3
+#define MSM_VERSION_MINOR	4
 #define MSM_VERSION_PATCHLEVEL	0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -791,7 +792,7 @@ static int msm_ioctl_gem_new(struct drm_device *dev, void *data,
 	}
 
 	return msm_gem_new_handle(dev, file, args->size,
-			args->flags, &args->handle);
+			args->flags, &args->handle, args->name);
 }
 
 static inline ktime_t to_ktime(struct drm_msm_timespec timeout)
drivers/gpu/drm/msm/msm_drv.h +1 -1
index df920b13a8a4..71a03ce21da5 100644
@@ -309,7 +309,7 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout);
 int msm_gem_cpu_fini(struct drm_gem_object *obj);
 void msm_gem_free_object(struct drm_gem_object *obj);
 int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
-		uint32_t size, uint32_t flags, uint32_t *handle);
+		uint32_t size, uint32_t flags, uint32_t *handle, char *name);
 struct drm_gem_object *msm_gem_new(struct drm_device *dev,
 		uint32_t size, uint32_t flags);
 struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev,
drivers/gpu/drm/msm/msm_gem.c +14 -2
index 35c9d4048b37..3d53e8765a7f 100644
@@ -890,16 +890,28 @@ void msm_gem_free_object(struct drm_gem_object *obj)
 
 /* convenience method to construct a GEM buffer object, and userspace handle */
 int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
-		uint32_t size, uint32_t flags, uint32_t *handle)
+		uint32_t size, uint32_t flags, uint32_t *handle,
+		char *name)
 {
 	struct drm_gem_object *obj;
-	int ret;
+	struct msm_gem_object *msm_obj;
+	int ret, i;
 
 	obj = msm_gem_new(dev, size, flags);
 
 	if (IS_ERR(obj))
 		return PTR_ERR(obj);
 
+	msm_obj = to_msm_bo(obj);
+
+	/* Copy the buffer name stopping at the first non printable character */
+	for(i = 0; i < sizeof(msm_obj->name) - 1; i++) {
+		if (!isprint(name[i]))
+			break;
+
+		msm_obj->name[i] = name[i];
+	}
+
 	ret = drm_gem_handle_create(file, obj, handle);
 
 	/* drop reference from allocate - handle holds it now */
include/uapi/drm/msm_drm.h +1 -0
index c06d0a5bdd80..0d89e9875faf 100644
@@ -103,6 +103,7 @@ struct drm_msm_gem_new {
 	__u64 size;           /* in */
 	__u32 flags;          /* in, mask of MSM_BO_x */
 	__u32 handle;         /* out */
+	char name[32];        /* in, name of the bo for tracking */
 };
 
 #define MSM_INFO_IOVA	0x01
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#9 lore raw

PATCH v2 9/9 drm/msm/gpu: Map the ringbuffer in the iova at create time

In reply to a message not in the archive

For reasons that I'm sure made perfect sense at the time we were opting to defer the iova alloc / pin on the ringbuffer until HW init time so when we moved to iova reference counting we ended up adding a reference count every time the hardware started. Not that it mattered (because the ring is always around) but it did make the debug output look odd. Allocate and pin the iova at create time instead.

---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 9 ---------
 drivers/gpu/drm/msm/msm_ringbuffer.c    | 4 ++--
 2 files changed, 2 insertions(+), 11 deletions(-)
drivers/gpu/drm/msm/adreno/adreno_gpu.c +0 -9
index 3c2988514fc5..05092ca12193 100644
@@ -209,15 +209,6 @@ int adreno_hw_init(struct msm_gpu *gpu)
 		if (!ring)
 			continue;
 
-		ret = msm_gem_get_and_pin_iova(ring->bo, gpu->aspace,
-			&ring->iova);
-		if (ret) {
-			ring->iova = 0;
-			DRM_DEV_ERROR(gpu->dev->dev,
-				"could not map ringbuffer %d: %d\n", i, ret);
-			return ret;
-		}
-
 		ring->cur = ring->start;
 		ring->next = ring->start;
 
drivers/gpu/drm/msm/msm_ringbuffer.c +2 -2
index 6169bd6ca153..20a96fe69dcd 100644
@@ -36,9 +36,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
 
 	ring->gpu = gpu;
 	ring->id = id;
-	/* Pass NULL for the iova pointer - we will map it later */
+
 	ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ,
-		MSM_BO_WC, gpu->aspace, &ring->bo, NULL);
+		MSM_BO_WC, gpu->aspace, &ring->bo, &ring->iova);
 
 	if (IS_ERR(ring->start)) {
 		ret = PTR_ERR(ring->start);
Signature · 6 lines
2.18.0

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#10 lore raw

PATCH 6/9 drm/msm: Count how many times iova memory is pinned

In reply to Jordan Crouse

Add a reference count to track how many times a particular chunk of iova memory is pinned (mapped) in the iomu and add msm_gem_unpin_iova to give up references.

It is important to note that msm_gem_unpin_iova replaces msm_gem_put_iova because the new implicit behavior that an assigned iova in a given vma is now valid for the life of the buffer and what we are really focusing on is the use of that iova.

For now the unmappings are lazy; once the reference counts go to zero they *COULD* be unmapped dynamically but that will require an outside force such as a shrinker or mm_notifiers. For now, we're just focusing on getting the counting right and setting ourselves up to be ready for the future.

---
 drivers/gpu/drm/msm/adreno/a5xx_debugfs.c |  6 +--
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c     |  9 ++--
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c     |  3 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c |  2 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c  |  2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c |  2 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c        |  2 +-
 drivers/gpu/drm/msm/msm_drv.h             |  8 +++-
 drivers/gpu/drm/msm/msm_fb.c              |  2 +-
 drivers/gpu/drm/msm/msm_gem.c             | 43 ++++++++++++-------
 drivers/gpu/drm/msm/msm_gem.h             |  1 +
 drivers/gpu/drm/msm/msm_gem_submit.c      |  2 +-
 drivers/gpu/drm/msm/msm_gem_vma.c         | 51 +++++++++++++++++------
 drivers/gpu/drm/msm/msm_gpu.c             |  2 +-
 14 files changed, 87 insertions(+), 48 deletions(-)
drivers/gpu/drm/msm/adreno/a5xx_debugfs.c +2 -4
index 6983cd9102bd..d9af3aff690f 100644
@@ -130,15 +130,13 @@ reset_set(void *data, u64 val)
 	adreno_gpu->fw[ADRENO_FW_PFP] = NULL;
 
 	if (a5xx_gpu->pm4_bo) {
-		if (a5xx_gpu->pm4_iova)
-			msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
+		msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
 		drm_gem_object_put(a5xx_gpu->pm4_bo);
 		a5xx_gpu->pm4_bo = NULL;
 	}
 
 	if (a5xx_gpu->pfp_bo) {
-		if (a5xx_gpu->pfp_iova)
-			msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace);
+		msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
 		drm_gem_object_put(a5xx_gpu->pfp_bo);
 		a5xx_gpu->pfp_bo = NULL;
 	}
drivers/gpu/drm/msm/adreno/a5xx_gpu.c +3 -6
index d6f8dedc028a..135496393cf3 100644
@@ -841,20 +841,17 @@ static void a5xx_destroy(struct msm_gpu *gpu)
 	a5xx_preempt_fini(gpu);
 
 	if (a5xx_gpu->pm4_bo) {
-		if (a5xx_gpu->pm4_iova)
-			msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
+		msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
 		drm_gem_object_put_unlocked(a5xx_gpu->pm4_bo);
 	}
 
 	if (a5xx_gpu->pfp_bo) {
-		if (a5xx_gpu->pfp_iova)
-			msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace);
+		msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
 		drm_gem_object_put_unlocked(a5xx_gpu->pfp_bo);
 	}
 
 	if (a5xx_gpu->gpmu_bo) {
-		if (a5xx_gpu->gpmu_iova)
-			msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
+		msm_gem_unpin_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
 		drm_gem_object_put_unlocked(a5xx_gpu->gpmu_bo);
 	}
 
drivers/gpu/drm/msm/adreno/a6xx_gpu.c +1 -2
index 38b7a5a92bfb..9acf12c21b23 100644
@@ -746,8 +746,7 @@ static void a6xx_destroy(struct msm_gpu *gpu)
 	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
 
 	if (a6xx_gpu->sqe_bo) {
-		if (a6xx_gpu->sqe_iova)
-			msm_gem_put_iova(a6xx_gpu->sqe_bo, gpu->aspace);
+		msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
 		drm_gem_object_put_unlocked(a6xx_gpu->sqe_bo);
 	}
 
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +1 -1
index ef6884f1fc34..8f2359dc87b4 100644
@@ -128,7 +128,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val)
 	struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base);
 	struct msm_kms *kms = &mdp4_kms->base.base;
 
-	msm_gem_put_iova(val, kms->aspace);
+	msm_gem_unpin_iova(val, kms->aspace);
 	drm_gem_object_put_unlocked(val);
 }
 
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +1 -1
index 9fd6b9b2dbcb..934a49818ea4 100644
@@ -165,7 +165,7 @@ static void mdp4_destroy(struct msm_kms *kms)
 	struct msm_gem_address_space *aspace = kms->aspace;
 
 	if (mdp4_kms->blank_cursor_iova)
-		msm_gem_put_iova(mdp4_kms->blank_cursor_bo, kms->aspace);
+		msm_gem_unpin_iova(mdp4_kms->blank_cursor_bo, kms->aspace);
 	drm_gem_object_put_unlocked(mdp4_kms->blank_cursor_bo);
 
 	if (aspace) {
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +1 -1
index c7cc276575fb..c5fde1a4191a 100644
@@ -173,7 +173,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val)
 	struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
 	struct msm_kms *kms = &mdp5_kms->base.base;
 
-	msm_gem_put_iova(val, kms->aspace);
+	msm_gem_unpin_iova(val, kms->aspace);
 	drm_gem_object_put_unlocked(val);
 }
 
drivers/gpu/drm/msm/dsi/dsi_host.c +1 -1
index 99122767abf4..3b7092e1dcc7 100644
@@ -1118,7 +1118,7 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
 
 	priv = dev->dev_private;
 	if (msm_host->tx_gem_obj) {
-		msm_gem_put_iova(msm_host->tx_gem_obj, priv->kms->aspace);
+		msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace);
 		drm_gem_object_put_unlocked(msm_host->tx_gem_obj);
 		msm_host->tx_gem_obj = NULL;
 	}
drivers/gpu/drm/msm/msm_drv.h +6 -2
index 4372505a0bda..955c2f522db6 100644
@@ -243,10 +243,14 @@ void msm_atomic_state_free(struct drm_atomic_state *state);
 
 int msm_gem_init_vma(struct msm_gem_address_space *aspace,
 		struct msm_gem_vma *vma, int npages);
+void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
+		struct msm_gem_vma *vma);
 void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
 		struct msm_gem_vma *vma);
 int msm_gem_map_vma(struct msm_gem_address_space *aspace,
 		struct msm_gem_vma *vma, struct sg_table *sgt, int npages);
+void msm_gem_close_vma(struct msm_gem_address_space *aspace,
+		struct msm_gem_vma *vma);
 
 void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
 
@@ -275,10 +279,10 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
 		struct msm_gem_address_space *aspace, uint64_t *iova);
 uint64_t msm_gem_iova(struct drm_gem_object *obj,
 		struct msm_gem_address_space *aspace);
+void msm_gem_unpin_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace);
 struct page **msm_gem_get_pages(struct drm_gem_object *obj);
 void msm_gem_put_pages(struct drm_gem_object *obj);
-void msm_gem_put_iova(struct drm_gem_object *obj,
-		struct msm_gem_address_space *aspace);
 int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
 		struct drm_mode_create_dumb *args);
 int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
drivers/gpu/drm/msm/msm_fb.c +1 -1
index 4e1e435db5a6..1224739094f2 100644
@@ -81,7 +81,7 @@ void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
 	int i, n = fb->format->num_planes;
 
 	for (i = 0; i < n; i++)
-		msm_gem_put_iova(fb->obj[i], aspace);
+		msm_gem_unpin_iova(fb->obj[i], aspace);
 }
 
 uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
drivers/gpu/drm/msm/msm_gem.c +28 -15

89 lines not on this page · raw message

drivers/gpu/drm/msm/msm_gem.h +1 -0
index 32c13e6559b5..53d3bf49a9fa 100644
@@ -42,6 +42,7 @@ struct msm_gem_vma {
 	struct msm_gem_address_space *aspace;
 	struct list_head list;    /* node in msm_gem_object::vmas */
 	bool mapped;
+	int inuse;
 };
 
 struct msm_gem_object {
drivers/gpu/drm/msm/msm_gem_submit.c +1 -1
index da907260660c..9c78521ee08a 100644
@@ -167,7 +167,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit,
 	struct msm_gem_object *msm_obj = submit->bos[i].obj;
 
 	if (submit->bos[i].flags & BO_PINNED)
-		msm_gem_put_iova(&msm_obj->base, submit->gpu->aspace);
+		msm_gem_unpin_iova(&msm_obj->base, submit->gpu->aspace);
 
 	if (submit->bos[i].flags & BO_LOCKED)
 		ww_mutex_unlock(&msm_obj->resv->lock);
drivers/gpu/drm/msm/msm_gem_vma.c +39 -12

83 lines not on this page · raw message

drivers/gpu/drm/msm/msm_gpu.c +1 -1
index 13dab9527bda..e6ce24bfb9b1 100644
@@ -670,7 +670,7 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
 		struct msm_gem_object *msm_obj = submit->bos[i].obj;
 		/* move to inactive: */
 		msm_gem_move_to_inactive(&msm_obj->base);
-		msm_gem_put_iova(&msm_obj->base, gpu->aspace);
+		msm_gem_unpin_iova(&msm_obj->base, gpu->aspace);
 		drm_gem_object_put(&msm_obj->base);
 	}
 
Signature · 6 lines
2.18.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel