[PATCH 2/5] drm/i915: Calculate total shmem GFX memory consumed

Nidhi Gupta nidhi1.gupta at intel.com
Tue Feb 6 13:20:19 UTC 2018


From: Sourab Gupta <sourab.gupta at intel.com>

There are some GFX buffers e.g. ringbuffers, ctx buffers, etc. which
are not associated with any drm fd. Thus, the sum of the shmem memory
consumed by processes would be less than the total memory actually
consumed in the system.

This patch keeps track of all shmem memory consumptions in the system
which is given out by the sysfs interface introduced earlier.

Signed-off-by: Sourab Gupta <sourab.gupta at intel.com>
Signed-off-by: Akash Goel <akash.goel at intel.com>
Signed-off-by: Nidhi Gupta <nidhi1.gupta at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h        |  2 ++
 drivers/gpu/drm/i915/i915_gem.c        | 46 ++++++++++++++++++++++++++++------
 drivers/gpu/drm/i915/i915_gem_object.h |  1 +
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 845a170..e823fa5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1135,6 +1135,8 @@ struct i915_gem_mm {
 	spinlock_t object_stat_lock;
 	u64 object_memory;
 	u32 object_count;
+
+	size_t phys_mem_total;
 };
 
 struct drm_i915_error_state_buf {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 57a6d88..a2e970b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2284,6 +2284,17 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
 	 */
 	shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1);
 	obj->mm.madv = __I915_MADV_PURGED;
+
+	/*
+	 * Mark the object as not having backing pages, as physical space
+	 * returned back to kernel
+	 */
+	if (obj->has_backing_pages == 1) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+		dev_priv->mm.phys_mem_total -= obj->base.size;
+		obj->has_backing_pages = 0;
+	}
 	obj->mm.pages = ERR_PTR(-EFAULT);
 }
 
@@ -2571,6 +2582,13 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 
 	__i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
+	if (obj->has_backing_pages == 0) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+		dev_priv->mm.phys_mem_total += obj->base.size;
+		obj->has_backing_pages = 1;
+	}
+
 	return 0;
 
 err_sg:
@@ -4607,6 +4625,11 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	init_request_active(&obj->frontbuffer_write, frontbuffer_retire);
 
 	obj->mm.madv = I915_MADV_WILLNEED;
+	/*
+	 * Mark the object as not having backing pages, as no allocation
+	 * for it yet
+	 */
+	obj->has_backing_pages = 0;
 	INIT_LIST_HEAD(&obj->pid_info);
 	INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN);
 	mutex_init(&obj->mm.get_page.lock);
@@ -4797,6 +4820,12 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 
 		if (obj->base.import_attach)
 			drm_prime_gem_destroy(&obj->base, NULL);
+		if (!obj->stolen && (obj->has_backing_pages == 1)) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+		dev_priv->mm.phys_mem_total -= obj->base.size;
+		obj->has_backing_pages = 0;
+	}
 
 		reservation_object_fini(&obj->__builtin_resv);
 		drm_gem_object_release(&obj->base);
@@ -6332,12 +6361,13 @@ i915_drm_gem_object_per_file_summary(int id, void *ptr, void *data)
 	if (obj->stolen) {
 		stats->num_obj_stolen++;
 		stats->stolen_space_allocated += obj->base.size;
-	} else if (obj->mm.madv == __I915_MADV_PURGED) {
-		stats->num_obj_purged++;
+	} else	if (obj->mm.madv == __I915_MADV_PURGED) {
+			stats->num_obj_purged++;
 	} else {
-		u64 nr_bytes =
-			i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
+		u64 nr_bytes = i915_obj_get_shmem_pages_alloced(obj)*PAGE_SIZE;
 
+		if (obj->has_backing_pages)
+			stats->num_obj_allocated++;
 		if (obj->mm.madv == I915_MADV_DONTNEED) {
 			stats->num_obj_purgeable++;
 			if (nr_bytes != 0)
@@ -6345,11 +6375,10 @@ i915_drm_gem_object_per_file_summary(int id, void *ptr, void *data)
 		}
 
 		if (nr_bytes != 0) {
-			stats->num_obj_allocated++;
 			if (obj_shared_count > 1) {
 				stats->phys_space_allocated_shared += nr_bytes;
 				stats->phys_space_shared_proportion +=
-					nr_bytes/obj_shared_count;
+				       nr_bytes/obj_shared_count;
 			} else
 				stats->phys_space_allocated_priv += nr_bytes;
 		}
@@ -6366,7 +6395,7 @@ __i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
 			struct drm_device *dev)
 {
 	struct drm_file *file;
-
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct name_entry *entry, *next;
 	struct pid_stat_entry *pid_entry, *temp_entry;
 	struct pid_stat_entry *new_pid_entry, *new_temp_entry;
@@ -6504,7 +6533,8 @@ __i915_get_drm_clients_info(struct drm_i915_error_state_buf *m,
 	err_printf(m,
 		"\t\t\t\t\t\t\t\t%13zdK\t%12zdK\tTotal\n",
 			total_shared_prop_space, total_priv_space);
-
+	err_printf(m, "\nTotal used GFX Shmem Physical space %8zdK\n",
+		  dev_priv->mm.phys_mem_total/1024);
 	if (ret)
 		return ret;
 	if (m->bytes == 0 && m->err)
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index ceb0bf7..12c508c 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -147,6 +147,7 @@ struct drm_i915_gem_object {
 #define I915_BO_CACHE_COHERENT_FOR_READ BIT(0)
 #define I915_BO_CACHE_COHERENT_FOR_WRITE BIT(1)
 	unsigned int cache_dirty:1;
+	unsigned int has_backing_pages:1;
 
 	atomic_t frontbuffer_bits;
 	unsigned int frontbuffer_ggtt_origin; /* write once */
-- 
2.7.4



More information about the Intel-gfx-trybot mailing list