[PATCH] drm/vmwgfx: Add debugfs file for displaying buffer information

Maaz Mombasawala maaz.mombasawala at broadcom.com
Wed Aug 14 22:57:29 UTC 2024


Information about userspace allocated buffers can already be seen with
debugfs file vmwgfx_gem_info.
Add a debugfs file vmwgfx_buffer_info that also displays information about
vmwgfx buffers allocated by the kernel.
Also display name of the original process that allocated the buffer object
in both of these files.

Signed-off-by: Maaz Mombasawala <maaz.mombasawala at broadcom.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c  | 120 ++++++++++++++++++++++++++++
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h  |   8 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c |  51 ------------
 4 files changed, 131 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index f42ebc4a7c22..2d6922ada481 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -31,6 +31,7 @@
 #include "vmwgfx_resource_priv.h"
 
 #include <drm/ttm/ttm_placement.h>
+#include <linux/debugfs.h>
 
 static void vmw_bo_release(struct vmw_bo *vbo)
 {
@@ -436,6 +437,8 @@ static int vmw_bo_init(struct vmw_private *dev_priv,
 		ttm_bo_pin(&vmw_bo->tbo);
 	ttm_bo_unreserve(&vmw_bo->tbo);
 
+	get_task_comm(vmw_bo->origin_comm, current);
+
 	return 0;
 }
 
@@ -878,3 +881,120 @@ struct vmw_surface *vmw_bo_surface(struct vmw_bo *vbo)
 		surf = vmw_res_to_srf(res);
 	return surf;
 }
+
+#if defined(CONFIG_DEBUG_FS)
+
+void vmw_bo_print_info(int id, struct vmw_bo *bo, struct seq_file *m)
+{
+	const char *placement;
+	const char *type;
+
+	switch (bo->tbo.resource->mem_type) {
+	case TTM_PL_SYSTEM:
+		placement = " CPU";
+		break;
+	case VMW_PL_GMR:
+		placement = " GMR";
+		break;
+	case VMW_PL_MOB:
+		placement = " MOB";
+		break;
+	case VMW_PL_SYSTEM:
+		placement = "VCPU";
+		break;
+	case TTM_PL_VRAM:
+		placement = "VRAM";
+		break;
+	default:
+		placement = "None";
+		break;
+	}
+
+	switch (bo->tbo.type) {
+	case ttm_bo_type_device:
+		type = "device";
+		break;
+	case ttm_bo_type_kernel:
+		type = "kernel";
+		break;
+	case ttm_bo_type_sg:
+		type = "sg    ";
+		break;
+	default:
+		type = "none  ";
+		break;
+	}
+
+	if (id)
+		seq_printf(m, "\t\t0x%08x: %12zu bytes %s, type = %s", id,
+		bo->tbo.base.size, placement, type);
+	else
+		seq_printf(m, "\t%12zu bytes, placement = %s, type = %s",
+		bo->tbo.base.size, placement, type);
+	seq_printf(m, ", priority = %u, pin_count = %u, GEM refs = %d, TTM refs = %d, Origin proc: %16s",
+		   bo->tbo.priority,
+		   bo->tbo.pin_count,
+		   kref_read(&bo->tbo.base.refcount),
+		   kref_read(&bo->tbo.kref),
+		   bo->origin_comm);
+	seq_puts(m, "\n");
+}
+
+static void vmw_debugfs_print_ttm_list_info(struct seq_file *m,
+					    struct list_head *ttm_list)
+{
+	struct ttm_resource *res;
+	struct ttm_lru_item *lru, *tmp;
+
+	list_for_each_entry_safe(lru, tmp, ttm_list, link) {
+		struct ttm_buffer_object *tbo;
+		struct vmw_bo *bo;
+
+		if (lru->type != TTM_LRU_RESOURCE)
+			continue;
+		res = container_of(lru, struct ttm_resource, lru);
+		tbo = res->bo;
+		bo = container_of(tbo, struct vmw_bo, tbo);
+		vmw_bo_print_info(0, bo, m);
+	}
+}
+
+static int vmw_debugfs_buffer_info_show(struct seq_file *m, void *unused)
+{
+	struct vmw_private *vdev = (struct vmw_private *)m->private;
+	struct ttm_device *bdev = &vdev->bdev;
+	struct ttm_resource_manager *man;
+	int man_itr, pr_itr;
+
+	seq_puts(m, "LRU buffers -\n");
+	for (man_itr = 0; man_itr < TTM_NUM_MEM_TYPES; man_itr++) {
+		man = ttm_manager_type(&vdev->bdev, man_itr);
+		if (!man)
+			continue;
+		for (pr_itr = 0; pr_itr < TTM_MAX_BO_PRIORITY; pr_itr++) {
+			spin_lock(&bdev->lru_lock);
+			vmw_debugfs_print_ttm_list_info(m, &man->lru[pr_itr]);
+			spin_unlock(&bdev->lru_lock);
+		}
+	}
+	seq_puts(m, "Pinned buffers -\n");
+	spin_lock(&bdev->lru_lock);
+	vmw_debugfs_print_ttm_list_info(m, &bdev->pinned);
+	spin_unlock(&bdev->lru_lock);
+	return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(vmw_debugfs_buffer_info);
+
+#endif
+
+void vmw_debugfs_buffer_init(struct vmw_private *vdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+	struct drm_minor *minor = vdev->drm.primary;
+	struct dentry *root = minor->debugfs_root;
+
+	debugfs_create_file("vmwgfx_buffer_info", 0444, root, vdev,
+			    &vmw_debugfs_buffer_info_fops);
+#endif
+}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
index 62b4342d5f7c..3e197a7b8d53 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
@@ -97,6 +97,8 @@ struct vmw_bo {
 
 	bool is_dumb;
 	struct vmw_surface *dumb_surface;
+
+	char origin_comm[TASK_COMM_LEN];
 };
 
 void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain);
@@ -146,6 +148,12 @@ int vmw_user_bo_lookup(struct drm_file *filp,
 		       u32 handle,
 		       struct vmw_bo **out);
 
+void vmw_debugfs_buffer_init(struct vmw_private *vdev);
+
+#if defined(CONFIG_DEBUG_FS)
+void vmw_bo_print_info(int id, struct vmw_bo *bo, struct seq_file *m);
+#endif
+
 /**
  * vmw_bo_adjust_prio - Adjust the buffer object eviction priority
  * according to attached resources
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 50ad3105c16e..be7763158a5a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2011-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -1682,6 +1683,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	drm_fbdev_ttm_setup(&vmw->drm,  0);
 
 	vmw_debugfs_gem_init(vmw);
+	vmw_debugfs_buffer_init(vmw);
 	vmw_debugfs_resource_managers_init(vmw);
 
 	return 0;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
index b9857f37ca1a..08cb0cddf5ef 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
@@ -254,57 +254,6 @@ int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data,
 
 #if defined(CONFIG_DEBUG_FS)
 
-static void vmw_bo_print_info(int id, struct vmw_bo *bo, struct seq_file *m)
-{
-	const char *placement;
-	const char *type;
-
-	switch (bo->tbo.resource->mem_type) {
-	case TTM_PL_SYSTEM:
-		placement = " CPU";
-		break;
-	case VMW_PL_GMR:
-		placement = " GMR";
-		break;
-	case VMW_PL_MOB:
-		placement = " MOB";
-		break;
-	case VMW_PL_SYSTEM:
-		placement = "VCPU";
-		break;
-	case TTM_PL_VRAM:
-		placement = "VRAM";
-		break;
-	default:
-		placement = "None";
-		break;
-	}
-
-	switch (bo->tbo.type) {
-	case ttm_bo_type_device:
-		type = "device";
-		break;
-	case ttm_bo_type_kernel:
-		type = "kernel";
-		break;
-	case ttm_bo_type_sg:
-		type = "sg    ";
-		break;
-	default:
-		type = "none  ";
-		break;
-	}
-
-	seq_printf(m, "\t\t0x%08x: %12zu bytes %s, type = %s",
-		   id, bo->tbo.base.size, placement, type);
-	seq_printf(m, ", priority = %u, pin_count = %u, GEM refs = %d, TTM refs = %d",
-		   bo->tbo.priority,
-		   bo->tbo.pin_count,
-		   kref_read(&bo->tbo.base.refcount),
-		   kref_read(&bo->tbo.kref));
-	seq_puts(m, "\n");
-}
-
 static int vmw_debugfs_gem_info_show(struct seq_file *m, void *unused)
 {
 	struct vmw_private *vdev = (struct vmw_private *)m->private;
-- 
2.34.1



More information about the dri-devel mailing list