Re: [PATCH v2] drm/amdgpu: Add debugfs entry for printing VM info

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 09.10.20 um 13:40 schrieb Mihir Patel:
From: Mihir Bhogilal Patel <Mihir.Patel@xxxxxxx>

Create new debugfs entry to print memory info using VM buffer
objects.

Note: Early upload for discussion and review
Pending:
- Add proper locking
- Print UID information
- Consolidated memory utilization info like total, swap etc.

V2: Added Common function for printing BO info.
     Dump more VM lists for evicted, moved, relocated, invalidated.
     Removed dumping VM mapped BOs.

The locking is not correct and a few nit picks on the coding style, apart from that looks good to me.


Signed-off-by: Mihir Bhogilal Patel <Mihir.Patel@xxxxxxx>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 26 +++++++
  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c     | 69 ++---------------
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c  | 74 ++++++++++++++++++
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.h  |  2 +
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      | 86 +++++++++++++++++++++
  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h      |  4 +
  6 files changed, 199 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 2d125b8b15ee..1986b688f046 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1335,11 +1335,37 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
  	return 0;
  }
+static int amdgpu_debugfs_vm_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *)m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_file *file;
+	int r;
+
+	r = mutex_lock_interruptible(&dev->filelist_mutex);
+	if (r)
+		return r;
+
+	list_for_each_entry(file, &dev->filelist, lhead) {
+		struct amdgpu_fpriv *fpriv = file->driver_priv;
+		struct amdgpu_vm *vm = &fpriv->vm;
+
+		seq_printf(m, "pid:%d\tProcess:%s ----------\n",
+				vm->task_info.pid, vm->task_info.process_name);

Here you need to have something like this:

r = amdgpu_bo_reserve(vm->root.base.bo, true);

+		amdgpu_debugfs_vm_bo_info(vm, m);

And here amdgpu_bo_unreserve(vm->root.base.bo);

Otherwise walking the linked lists could crash badly.

+	}
+
+	mutex_unlock(&dev->filelist_mutex);
+
+	return 0;
+}
+
  static const struct drm_info_list amdgpu_debugfs_list[] = {
  	{"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},
  	{"amdgpu_test_ib", &amdgpu_debugfs_test_ib},
  	{"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram},
  	{"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt},
+	{"amdgpu_vm_info", &amdgpu_debugfs_vm_info},
  };
static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index f4c2e2e75b8f..f009d17c0aca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -826,67 +826,6 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
  }
#if defined(CONFIG_DEBUG_FS)
-
-#define amdgpu_debugfs_gem_bo_print_flag(m, bo, flag)	\
-	if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) {	\
-		seq_printf((m), " " #flag);		\
-	}
-
-static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
-{
-	struct drm_gem_object *gobj = ptr;
-	struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
-	struct seq_file *m = data;
-
-	struct dma_buf_attachment *attachment;
-	struct dma_buf *dma_buf;
-	unsigned domain;
-	const char *placement;
-	unsigned pin_count;
-
-	domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
-	switch (domain) {
-	case AMDGPU_GEM_DOMAIN_VRAM:
-		placement = "VRAM";
-		break;
-	case AMDGPU_GEM_DOMAIN_GTT:
-		placement = " GTT";
-		break;
-	case AMDGPU_GEM_DOMAIN_CPU:
-	default:
-		placement = " CPU";
-		break;
-	}
-	seq_printf(m, "\t0x%08x: %12ld byte %s",
-		   id, amdgpu_bo_size(bo), placement);
-
-	pin_count = READ_ONCE(bo->pin_count);
-	if (pin_count)
-		seq_printf(m, " pin count %d", pin_count);
-
-	dma_buf = READ_ONCE(bo->tbo.base.dma_buf);
-	attachment = READ_ONCE(bo->tbo.base.import_attach);
-
-	if (attachment)
-		seq_printf(m, " imported from %p%s", dma_buf,
-			   attachment->peer2peer ? " P2P" : "");
-	else if (dma_buf)
-		seq_printf(m, " exported as %p", dma_buf);
-
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, NO_CPU_ACCESS);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_GTT_USWC);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CLEARED);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, SHADOW);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, VM_ALWAYS_VALID);
-	amdgpu_debugfs_gem_bo_print_flag(m, bo, EXPLICIT_SYNC);
-
-	seq_printf(m, "\n");
-
-	return 0;
-}
-
  static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
  {
  	struct drm_info_node *node = (struct drm_info_node *)m->private;
@@ -900,6 +839,8 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
list_for_each_entry(file, &dev->filelist, lhead) {
  		struct task_struct *task;
+		struct drm_gem_object *gobj;
+		int id;
/*
  		 * Although we have a valid reference on file->pid, that does
@@ -914,7 +855,11 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
  		rcu_read_unlock();
spin_lock(&file->table_lock);
-		idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m);
+		idr_for_each_entry(&file->object_idr, gobj, id) {
+			struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
+
+			amdgpu_debugfs_print_bo_info(id, bo, m);
+		}
  		spin_unlock(&file->table_lock);
  	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 2ce79bccfc30..c6172a6e6877 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -1528,3 +1528,77 @@ uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev,
  	}
  	return domain;
  }
+
+#if defined(CONFIG_DEBUG_FS)
+#define amdgpu_debugfs_vm_bo_print_flag(m, bo, flag)		\
+	do {							\
+		if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) {	\
+			seq_printf((m), " " #flag);		\
+		}						\
+	} while (0)
+
+/**
+ * amdgpu_debugfs_print_bo_info - print BO info in debugfs file
+ *
+ * @id: Index or Id of the BO
+ * @bo: Requested BO for printing info
+ * @data: debugfs file
+ *
+ * Print BO information in debugfs file
+ *
+ * Returns:
+ * Size of the BO in bytes.
+ */
+unsigned long amdgpu_debugfs_print_bo_info(int id, struct amdgpu_bo *bo, struct seq_file *m)

Better name this amdgpu_bo_print_info().

+{
+	struct dma_buf_attachment *attachment;
+	struct dma_buf *dma_buf;
+	unsigned int domain;
+	const char *placement;
+	unsigned int pin_count;
+	unsigned long size;
+
+	domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
+	switch (domain) {
+	case AMDGPU_GEM_DOMAIN_VRAM:
+		placement = "VRAM";
+		break;
+	case AMDGPU_GEM_DOMAIN_GTT:
+		placement = " GTT";
+		break;
+	case AMDGPU_GEM_DOMAIN_CPU:
+	default:
+		placement = " CPU";
+		break;
+	}
+
+	size = amdgpu_bo_size(bo);
+	seq_printf(m, "\t\t0x%08x: %12ld byte %s",
+			id++, size, placement);
+
+	pin_count = READ_ONCE(bo->pin_count);
+	if (pin_count)
+		seq_printf(m, " pin count %d", pin_count);
+
+	dma_buf = READ_ONCE(bo->tbo.base.dma_buf);
+	attachment = READ_ONCE(bo->tbo.base.import_attach);
+
+	if (attachment)
+		seq_printf(m, " imported from %p", dma_buf);
+	else if (dma_buf)
+		seq_printf(m, " exported as %p", dma_buf);
+
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, NO_CPU_ACCESS);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, CPU_GTT_USWC);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, VRAM_CLEARED);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, SHADOW);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, VM_ALWAYS_VALID);
+	amdgpu_debugfs_vm_bo_print_flag(m, bo, EXPLICIT_SYNC);
+
+	seq_puts(m, "\n");
+
+	return size;
+}
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index afa5189dba7d..3d2a9515f462 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -330,6 +330,8 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev,
  #if defined(CONFIG_DEBUG_FS)
  void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
  					 struct seq_file *m);
+unsigned long amdgpu_debugfs_print_bo_info(int id, struct amdgpu_bo *bo,
+						struct seq_file *m);
  #endif
  int amdgpu_debugfs_sa_init(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 3cd949aad500..820c980467f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3392,3 +3392,89 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
return false;
  }
+
+#if defined(CONFIG_DEBUG_FS)
+/**
+ * amdgpu_debugfs_vm_bo_info  - print BO info for the VM
+ *
+ * @vm: Requested VM for printing BO info
+ * @data: debugfs file
+ *
+ * Print BO information in debugfs file for the VM
+ */
+void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
+{
+	struct amdgpu_bo_va *bo_va, *tmp;
+	unsigned long long total_idle_size = 0;
+	unsigned long long total_evicted_size = 0;
+	unsigned long long total_relocated_size = 0;
+	unsigned long long total_moved_size = 0;
+	unsigned long long total_invalidated_size = 0;

Use u64 here and drop the _size from the name.

+	unsigned int total_idle_objs = 0;
+	unsigned int total_evicted_objs = 0;
+	unsigned int total_relocated_objs = 0;
+	unsigned int total_moved_objs = 0;
+	unsigned int total_invalidated_objs = 0;
+	unsigned int id = 0;
+
+	/* Print info for Idle BOs */
+	seq_puts(m, "\tIdle BOs:\n");
+	list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
+		if (bo_va && bo_va->base.bo)

You don't need to check bo_va here and better code this like:

if (!bo_va->base.bo)
    continue;

Same for all other cases.

+			total_idle_size += amdgpu_debugfs_print_bo_info(id++,
+								bo_va->base.bo, m);
+	}
+	total_idle_objs = id;
+	id = 0;
+
+	/* Print info for Evicted BOs */
+	seq_puts(m, "\tEvicted BOs:\n");
+	list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) {
+		if (bo_va && bo_va->base.bo)
+			total_evicted_size += amdgpu_debugfs_print_bo_info(id++,
+								bo_va->base.bo, m);
+	}
+	total_evicted_objs = id;
+	id = 0;
+
+	/* Print info for Relocated BOs */
+	seq_puts(m, "\tRelocated BOs:\n");
+	list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) {
+		if (bo_va && bo_va->base.bo)
+			total_relocated_size += amdgpu_debugfs_print_bo_info(id++,
+								bo_va->base.bo, m);
+	}
+	total_relocated_objs = id;
+	id = 0;
+
+	/* Print info for Moved BOs */
+	seq_puts(m, "\tMoved BOs:\n");
+	list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
+		if (bo_va && bo_va->base.bo)
+			total_moved_size += amdgpu_debugfs_print_bo_info(id++,
+								bo_va->base.bo, m);
+	}
+	total_moved_objs = id;
+	id = 0;
+
+	/* Print info for Invalidated BOs */
+	seq_puts(m, "\tInvalidated BOs:\n");

Here you need to grab the invalidated_lock;

+	list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
+		if (bo_va && bo_va->base.bo)
+			total_invalidated_size += amdgpu_debugfs_print_bo_info(id++,
+								bo_va->base.bo, m);
+	}

And here you can release it.

+	total_invalidated_objs = id;
+
+	seq_printf(m, "\tTotal idle size:        %12lld\tobjs:\t%d\n", total_idle_size,
+									total_idle_objs);

The indentation of the second line is wrong. Please use scripts/check_patch.pl on the patch and fix the coding style as suggested.

Regards,
Christian.

+	seq_printf(m, "\tTotal evicted size:     %12lld\tobjs:\t%d\n", total_evicted_size,
+									total_evicted_objs);
+	seq_printf(m, "\tTotal relocated size:   %12lld\tobjs:\t%d\n", total_relocated_size,
+									total_relocated_objs);
+	seq_printf(m, "\tTotal moved size:       %12lld\tobjs:\t%d\n", total_moved_size,
+									total_moved_objs);
+	seq_printf(m, "\tTotal invalidated size: %12lld\tobjs:\t%d\n", total_invalidated_size,
+									 total_invalidated_objs);
+}
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 7c46937c1c0e..74cc14179c41 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -441,4 +441,8 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
  				struct amdgpu_vm *vm);
  void amdgpu_vm_del_from_lru_notify(struct ttm_buffer_object *bo);
+#if defined(CONFIG_DEBUG_FS)
+void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
+#endif
+
  #endif

_______________________________________________
amd-gfx mailing list
amd-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux