dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] fdinfo memory stats
@ 2023-06-08 14:51 Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 1/5] drm/i915: Track buffer objects belonging to clients Tvrtko Ursulin
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-08 14:51 UTC (permalink / raw)
  To: Intel-gfx, dri-devel; +Cc: Tvrtko Ursulin

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Second try, this time actually per client! :)

I added tracking of most classes of objects which contribute to clients memory
footprint and accouting along the similar lines as in Rob's msm code. Then
printing it out to fdinfo using the drm helper Rob added.

Example fdinfo with the series applied:

# cat /proc/1383/fdinfo/8
pos:    0
flags:  02100002
mnt_id: 21
ino:    397
drm-driver:     i915
drm-client-id:  18
drm-pdev:       0000:00:02.0
drm-total-system:       125 MiB
drm-shared-system:      16 MiB
drm-active-system:      110 MiB
drm-resident-system:    125 MiB
drm-purgeable-system:   2 MiB
drm-total-stolen-system:        0
drm-shared-stolen-system:       0
drm-active-stolen-system:       0
drm-resident-stolen-system:     0
drm-purgeable-stolen-system:    0
drm-engine-render:      25662044495 ns
drm-engine-copy:        0 ns
drm-engine-video:       0 ns
drm-engine-video-enhance:       0 ns

Tvrtko Ursulin (5):
  drm/i915: Track buffer objects belonging to clients
  drm/i915: Record which clients own a VM
  drm/i915: Track page table backing store usage
  drm/i915: Account ring buffer and context state storage
  drm/i915: Implement fdinfo memory stats printing

 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  17 ++-
 .../gpu/drm/i915/gem/i915_gem_context_types.h |   3 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c    |  32 ++++-
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |   6 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  12 ++
 drivers/gpu/drm/i915/gt/intel_gtt.c           |   6 +
 drivers/gpu/drm/i915/gt/intel_gtt.h           |   1 +
 drivers/gpu/drm/i915/i915_drm_client.c        | 110 +++++++++++++++++-
 drivers/gpu/drm/i915/i915_drm_client.h        |  46 +++++++-
 drivers/gpu/drm/i915/i915_gem.c               |   2 +-
 10 files changed, 226 insertions(+), 9 deletions(-)

-- 
2.39.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/5] drm/i915: Track buffer objects belonging to clients
  2023-06-08 14:51 [PATCH v2 0/5] fdinfo memory stats Tvrtko Ursulin
@ 2023-06-08 14:51 ` Tvrtko Ursulin
  2023-06-09  4:16   ` [Intel-gfx] " Iddamsetty, Aravind
  2023-06-08 14:51 ` [PATCH 2/5] drm/i915: Record which clients own a VM Tvrtko Ursulin
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-08 14:51 UTC (permalink / raw)
  To: Intel-gfx, dri-devel; +Cc: Tvrtko Ursulin

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

In order to show per client memory usage lets start tracking which
objects belong to which clients.

We start with objects explicitly created by object creation UAPI and
track it on a new per client lists, protected by a new per client lock.
In order for delayed destruction (post client exit), we make tracked
objects hold references to the owning client.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c    | 32 ++++++++++++++--
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 +++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  | 12 ++++++
 drivers/gpu/drm/i915/i915_drm_client.c        | 36 +++++++++++++++++-
 drivers/gpu/drm/i915/i915_drm_client.h        | 37 ++++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem.c               |  2 +-
 6 files changed, 119 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index d24c0ce8805c..4f1957638207 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -11,6 +11,7 @@
 #include "gem/i915_gem_region.h"
 #include "pxp/intel_pxp.h"
 
+#include "i915_drm_client.h"
 #include "i915_drv.h"
 #include "i915_gem_create.h"
 #include "i915_trace.h"
@@ -164,6 +165,14 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
 						 n_placements, 0);
 }
 
+static void add_file_obj(struct drm_file *file,
+			 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_file_private *fpriv = file->driver_priv;
+
+	i915_drm_client_add_object(fpriv->client, obj);
+}
+
 int
 i915_gem_dumb_create(struct drm_file *file,
 		     struct drm_device *dev,
@@ -174,6 +183,7 @@ i915_gem_dumb_create(struct drm_file *file,
 	enum intel_memory_type mem_type;
 	int cpp = DIV_ROUND_UP(args->bpp, 8);
 	u32 format;
+	int ret;
 
 	switch (cpp) {
 	case 1:
@@ -212,7 +222,12 @@ i915_gem_dumb_create(struct drm_file *file,
 	if (IS_ERR(obj))
 		return PTR_ERR(obj);
 
-	return i915_gem_publish(obj, file, &args->size, &args->handle);
+	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
+
+	if (!ret)
+		add_file_obj(file, obj);
+
+	return ret;
 }
 
 /**
@@ -229,6 +244,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 	struct drm_i915_gem_create *args = data;
 	struct drm_i915_gem_object *obj;
 	struct intel_memory_region *mr;
+	int ret;
 
 	mr = intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
 
@@ -236,7 +252,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 	if (IS_ERR(obj))
 		return PTR_ERR(obj);
 
-	return i915_gem_publish(obj, file, &args->size, &args->handle);
+	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
+
+	if (!ret)
+		add_file_obj(file, obj);
+
+	return ret;
 }
 
 struct create_ext {
@@ -494,5 +515,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
 		obj->pat_set_by_user = true;
 	}
 
-	return i915_gem_publish(obj, file, &args->size, &args->handle);
+	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
+
+	if (!ret)
+		add_file_obj(file, obj);
+
+	return ret;
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 97ac6fb37958..46de9b1b3f1d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -105,6 +105,10 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 
 	INIT_LIST_HEAD(&obj->mm.link);
 
+#ifdef CONFIG_PROC_FS
+	INIT_LIST_HEAD(&obj->client_link);
+#endif
+
 	INIT_LIST_HEAD(&obj->lut_list);
 	spin_lock_init(&obj->lut_lock);
 
@@ -441,6 +445,8 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
 	GEM_BUG_ON(i915_gem_object_is_framebuffer(obj));
 
+	i915_drm_client_remove_object(obj);
+
 	/*
 	 * Before we free the object, make sure any pure RCU-only
 	 * read-side critical sections are complete, e.g.
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index e72c57716bee..8de2b91b3edf 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -300,6 +300,18 @@ struct drm_i915_gem_object {
 	 */
 	struct i915_address_space *shares_resv_from;
 
+#ifdef CONFIG_PROC_FS
+	/**
+	 * @client: @i915_drm_client which created the object
+	 */
+	struct i915_drm_client *client;
+
+	/**
+	 * @client_link: Link into @i915_drm_client.objects_list
+	 */
+	struct list_head client_link;
+#endif
+
 	union {
 		struct rcu_head rcu;
 		struct llist_node freed;
diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c
index 2a44b3876cb5..4cacca568375 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -17,7 +17,8 @@
 #include "i915_gem.h"
 #include "i915_utils.h"
 
-struct i915_drm_client *i915_drm_client_alloc(void)
+struct i915_drm_client *
+i915_drm_client_alloc(struct drm_i915_file_private *fpriv)
 {
 	struct i915_drm_client *client;
 
@@ -28,6 +29,12 @@ struct i915_drm_client *i915_drm_client_alloc(void)
 	kref_init(&client->kref);
 	spin_lock_init(&client->ctx_lock);
 	INIT_LIST_HEAD(&client->ctx_list);
+#ifdef CONFIG_PROC_FS
+	mutex_init(&client->objects_lock);
+	INIT_LIST_HEAD(&client->objects_list);
+
+	client->fpriv = fpriv;
+#endif
 
 	return client;
 }
@@ -108,4 +115,31 @@ void i915_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file)
 	for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++)
 		show_client_class(p, i915, file_priv->client, i);
 }
+
+void i915_drm_client_add_object(struct i915_drm_client *client,
+				struct drm_i915_gem_object *obj)
+{
+	GEM_WARN_ON(obj->client);
+	GEM_WARN_ON(!list_empty(&obj->client_link));
+
+	mutex_lock(&client->objects_lock);
+	obj->client = i915_drm_client_get(client);
+	list_add_tail(&obj->client_link, &client->objects_list);
+	mutex_unlock(&client->objects_lock);
+}
+
+void i915_drm_client_remove_object(struct drm_i915_gem_object *obj)
+{
+	struct i915_drm_client *client = fetch_and_zero(&obj->client);
+
+	/* Object may not be associated with a client. */
+	if (!client || list_empty(&obj->client_link))
+		return;
+
+	mutex_lock(&client->objects_lock);
+	list_del(&obj->client_link);
+	mutex_unlock(&client->objects_lock);
+
+	i915_drm_client_put(client);
+}
 #endif
diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h
index 4c18b99e10a4..0db68b4d7a4f 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.h
+++ b/drivers/gpu/drm/i915/i915_drm_client.h
@@ -8,10 +8,14 @@
 
 #include <linux/kref.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
 
 #include <uapi/drm/i915_drm.h>
 
+#include "i915_file_private.h"
+#include "gem/i915_gem_object_types.h"
+
 #define I915_LAST_UABI_ENGINE_CLASS I915_ENGINE_CLASS_COMPUTE
 
 struct drm_file;
@@ -25,6 +29,22 @@ struct i915_drm_client {
 	spinlock_t ctx_lock; /* For add/remove from ctx_list. */
 	struct list_head ctx_list; /* List of contexts belonging to client. */
 
+#ifdef CONFIG_PROC_FS
+	struct drm_i915_file_private *fpriv;
+
+	/**
+	 * @objects_lock: lock protecting @objects_list
+	 */
+	struct mutex objects_lock;
+
+	/**
+	 * @objects_list: list of objects created by this client
+	 *
+	 * Protected by @objects_lock.
+	 */
+	struct list_head objects_list;
+#endif
+
 	/**
 	 * @past_runtime: Accumulation of pphwsp runtimes from closed contexts.
 	 */
@@ -45,10 +65,25 @@ static inline void i915_drm_client_put(struct i915_drm_client *client)
 	kref_put(&client->kref, __i915_drm_client_free);
 }
 
-struct i915_drm_client *i915_drm_client_alloc(void);
+struct i915_drm_client *i915_drm_client_alloc(struct drm_i915_file_private *fpriv);
 
 #ifdef CONFIG_PROC_FS
 void i915_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file);
+
+void i915_drm_client_add_object(struct i915_drm_client *client,
+				struct drm_i915_gem_object *obj);
+void i915_drm_client_remove_object(struct drm_i915_gem_object *obj);
+#else
+static inline void i915_drm_client_add_object(struct i915_drm_client *client,
+					      struct drm_i915_gem_object *obj)
+{
+
+}
+
+static inline void i915_drm_client_remove_object(struct drm_i915_gem_object *obj)
+{
+
+}
 #endif
 
 #endif /* !__I915_DRM_CLIENT_H__ */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1f65bb33dd21..7ae42f746cc2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1325,7 +1325,7 @@ int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
 	if (!file_priv)
 		goto err_alloc;
 
-	client = i915_drm_client_alloc();
+	client = i915_drm_client_alloc(file_priv);
 	if (!client)
 		goto err_client;
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/5] drm/i915: Record which clients own a VM
  2023-06-08 14:51 [PATCH v2 0/5] fdinfo memory stats Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 1/5] drm/i915: Track buffer objects belonging to clients Tvrtko Ursulin
@ 2023-06-08 14:51 ` Tvrtko Ursulin
  2023-06-08 17:48   ` kernel test robot
  2023-06-08 14:51 ` [PATCH 3/5] drm/i915: Track page table backing store usage Tvrtko Ursulin
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-08 14:51 UTC (permalink / raw)
  To: Intel-gfx, dri-devel; +Cc: Tvrtko Ursulin

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

To enable accounting of indirect client memory usage (such as page tables)
in the following patch, lets start recording the creator of each PPGTT.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c       | 11 ++++++++---
 drivers/gpu/drm/i915/gem/i915_gem_context_types.h |  3 +++
 drivers/gpu/drm/i915/gt/intel_gtt.h               |  1 +
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 9a9ff84c90d7..35cf6608180e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -279,7 +279,8 @@ static int proto_context_set_protected(struct drm_i915_private *i915,
 }
 
 static struct i915_gem_proto_context *
-proto_context_create(struct drm_i915_private *i915, unsigned int flags)
+proto_context_create(struct drm_i915_file_private *fpriv,
+		     struct drm_i915_private *i915, unsigned int flags)
 {
 	struct i915_gem_proto_context *pc, *err;
 
@@ -287,6 +288,7 @@ proto_context_create(struct drm_i915_private *i915, unsigned int flags)
 	if (!pc)
 		return ERR_PTR(-ENOMEM);
 
+	pc->fpriv = fpriv;
 	pc->num_user_engines = -1;
 	pc->user_engines = NULL;
 	pc->user_flags = BIT(UCONTEXT_BANNABLE) |
@@ -1621,6 +1623,7 @@ i915_gem_create_context(struct drm_i915_private *i915,
 			err = PTR_ERR(ppgtt);
 			goto err_ctx;
 		}
+		ppgtt->vm.fpriv = pc->fpriv;
 		vm = &ppgtt->vm;
 	}
 	if (vm)
@@ -1740,7 +1743,7 @@ int i915_gem_context_open(struct drm_i915_private *i915,
 	/* 0 reserved for invalid/unassigned ppgtt */
 	xa_init_flags(&file_priv->vm_xa, XA_FLAGS_ALLOC1);
 
-	pc = proto_context_create(i915, 0);
+	pc = proto_context_create(file_priv, i915, 0);
 	if (IS_ERR(pc)) {
 		err = PTR_ERR(pc);
 		goto err;
@@ -1822,6 +1825,7 @@ int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data,
 
 	GEM_BUG_ON(id == 0); /* reserved for invalid/unassigned ppgtt */
 	args->vm_id = id;
+	ppgtt->vm.fpriv = file_priv;
 	return 0;
 
 err_put:
@@ -2284,7 +2288,8 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 		return -EIO;
 	}
 
-	ext_data.pc = proto_context_create(i915, args->flags);
+	ext_data.pc = proto_context_create(file->driver_priv, i915,
+					   args->flags);
 	if (IS_ERR(ext_data.pc))
 		return PTR_ERR(ext_data.pc);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
index cb78214a7dcd..c573c067779f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
@@ -188,6 +188,9 @@ struct i915_gem_proto_engine {
  * CONTEXT_CREATE_SET_PARAM during GEM_CONTEXT_CREATE.
  */
 struct i915_gem_proto_context {
+	/** @fpriv: Client which creates the context */
+	struct drm_i915_file_private *fpriv;
+
 	/** @vm: See &i915_gem_context.vm */
 	struct i915_address_space *vm;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
index 4d6296cdbcfd..7192a534a654 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -248,6 +248,7 @@ struct i915_address_space {
 	struct drm_mm mm;
 	struct intel_gt *gt;
 	struct drm_i915_private *i915;
+	struct drm_i915_file_private *fpriv;
 	struct device *dma;
 	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
 	u64 reserved;		/* size addr space reserved */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/5] drm/i915: Track page table backing store usage
  2023-06-08 14:51 [PATCH v2 0/5] fdinfo memory stats Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 1/5] drm/i915: Track buffer objects belonging to clients Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 2/5] drm/i915: Record which clients own a VM Tvrtko Ursulin
@ 2023-06-08 14:51 ` Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 4/5] drm/i915: Account ring buffer and context state storage Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 5/5] drm/i915: Implement fdinfo memory stats printing Tvrtko Ursulin
  4 siblings, 0 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-08 14:51 UTC (permalink / raw)
  To: Intel-gfx, dri-devel; +Cc: Tvrtko Ursulin

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Account page table backing store against the owning client memory usage
stats.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_gtt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 2f6a9be0ffe6..126269a0d728 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -58,6 +58,9 @@ struct drm_i915_gem_object *alloc_pt_lmem(struct i915_address_space *vm, int sz)
 	if (!IS_ERR(obj)) {
 		obj->base.resv = i915_vm_resv_get(vm);
 		obj->shares_resv_from = vm;
+
+		if (vm->fpriv)
+			i915_drm_client_add_object(vm->fpriv->client, obj);
 	}
 
 	return obj;
@@ -79,6 +82,9 @@ struct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz)
 	if (!IS_ERR(obj)) {
 		obj->base.resv = i915_vm_resv_get(vm);
 		obj->shares_resv_from = vm;
+
+		if (vm->fpriv)
+			i915_drm_client_add_object(vm->fpriv->client, obj);
 	}
 
 	return obj;
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/5] drm/i915: Account ring buffer and context state storage
  2023-06-08 14:51 [PATCH v2 0/5] fdinfo memory stats Tvrtko Ursulin
                   ` (2 preceding siblings ...)
  2023-06-08 14:51 ` [PATCH 3/5] drm/i915: Track page table backing store usage Tvrtko Ursulin
@ 2023-06-08 14:51 ` Tvrtko Ursulin
  2023-06-08 14:51 ` [PATCH 5/5] drm/i915: Implement fdinfo memory stats printing Tvrtko Ursulin
  4 siblings, 0 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-08 14:51 UTC (permalink / raw)
  To: Intel-gfx, dri-devel; +Cc: Tvrtko Ursulin

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Account ring buffers and logical context space against the owning client
memory usage stats.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c |  6 ++++++
 drivers/gpu/drm/i915/i915_drm_client.c      | 10 ++++++++++
 drivers/gpu/drm/i915/i915_drm_client.h      |  9 +++++++++
 3 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 35cf6608180e..3f4c74aed3c5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1703,6 +1703,8 @@ static void gem_context_register(struct i915_gem_context *ctx,
 				 u32 id)
 {
 	struct drm_i915_private *i915 = ctx->i915;
+	struct i915_gem_engines_iter it;
+	struct intel_context *ce;
 	void *old;
 
 	ctx->file_priv = fpriv;
@@ -1721,6 +1723,10 @@ static void gem_context_register(struct i915_gem_context *ctx,
 	list_add_tail(&ctx->link, &i915->gem.contexts.list);
 	spin_unlock(&i915->gem.contexts.lock);
 
+	for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
+		i915_drm_client_add_context(fpriv->client, ce);
+	i915_gem_context_unlock_engines(ctx);
+
 	/* And finally expose ourselves to userspace via the idr */
 	old = xa_store(&fpriv->context_xa, id, ctx, GFP_KERNEL);
 	WARN_ON(old);
diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c
index 4cacca568375..777930f4995f 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -142,4 +142,14 @@ void i915_drm_client_remove_object(struct drm_i915_gem_object *obj)
 
 	i915_drm_client_put(client);
 }
+
+void i915_drm_client_add_context(struct i915_drm_client *client,
+				 struct intel_context *ce)
+{
+	if (ce->state)
+		i915_drm_client_add_object(client, ce->state->obj);
+
+	if (ce->ring != ce->engine->legacy.ring && ce->ring->vma)
+		i915_drm_client_add_object(client, ce->ring->vma->obj);
+}
 #endif
diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h
index 0db68b4d7a4f..a5c29a105af3 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.h
+++ b/drivers/gpu/drm/i915/i915_drm_client.h
@@ -15,6 +15,7 @@
 
 #include "i915_file_private.h"
 #include "gem/i915_gem_object_types.h"
+#include "gt/intel_context_types.h"
 
 #define I915_LAST_UABI_ENGINE_CLASS I915_ENGINE_CLASS_COMPUTE
 
@@ -73,6 +74,8 @@ void i915_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file);
 void i915_drm_client_add_object(struct i915_drm_client *client,
 				struct drm_i915_gem_object *obj);
 void i915_drm_client_remove_object(struct drm_i915_gem_object *obj);
+void i915_drm_client_add_context(struct i915_drm_client *client,
+				 struct intel_context *ce);
 #else
 static inline void i915_drm_client_add_object(struct i915_drm_client *client,
 					      struct drm_i915_gem_object *obj)
@@ -83,6 +86,12 @@ static inline void i915_drm_client_add_object(struct i915_drm_client *client,
 static inline void i915_drm_client_remove_object(struct drm_i915_gem_object *obj)
 {
 
+}
+
+static inline void i915_drm_client_add_context(struct i915_drm_client *client,
+					       struct intel_context *ce)
+{
+
 }
 #endif
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/5] drm/i915: Implement fdinfo memory stats printing
  2023-06-08 14:51 [PATCH v2 0/5] fdinfo memory stats Tvrtko Ursulin
                   ` (3 preceding siblings ...)
  2023-06-08 14:51 ` [PATCH 4/5] drm/i915: Account ring buffer and context state storage Tvrtko Ursulin
@ 2023-06-08 14:51 ` Tvrtko Ursulin
  4 siblings, 0 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-08 14:51 UTC (permalink / raw)
  To: Intel-gfx, dri-devel; +Cc: Aravind Iddamsetty, Tvrtko Ursulin

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Use the newly added drm_print_memory_stats helper to show memory
utilisation of our objects in drm/driver specific fdinfo output.

To collect the stats we walk the per memory regions object lists
and accumulate object size into the respective drm_memory_stats
categories.

Objects with multiple possible placements are reported in multiple
regions for total and shared sizes, while other categories are
counted only for the currently active region.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Aravind Iddamsetty <aravind.iddamsetty@intel.com>
Cc: Rob Clark <robdclark@gmail.com>
---
 drivers/gpu/drm/i915/i915_drm_client.c | 64 ++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c
index 777930f4995f..686db139b241 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -48,6 +48,68 @@ void __i915_drm_client_free(struct kref *kref)
 }
 
 #ifdef CONFIG_PROC_FS
+static void
+obj_meminfo(struct drm_i915_gem_object *obj,
+	    struct drm_memory_stats stats[INTEL_REGION_UNKNOWN])
+{
+	struct intel_memory_region *mr;
+	u64 sz = obj->base.size;
+	enum intel_region_id id;
+	unsigned int i;
+
+	/* Attribute size and shared to all possible memory regions. */
+	for (i = 0; i < obj->mm.n_placements; i++) {
+		mr = obj->mm.placements[i];
+		id = mr->id;
+
+		if (obj->base.handle_count > 1)
+			stats[id].shared += sz;
+		else
+			stats[id].private += sz;
+	}
+
+	/* Attribute other categories to only the current region. */
+	mr = obj->mm.region;
+	if (mr)
+		id = mr->id;
+	else
+		id = INTEL_REGION_SMEM;
+
+	if (i915_gem_object_has_pages(obj)) {
+		stats[id].resident += sz;
+
+		if (!dma_resv_test_signaled(obj->base.resv,
+					    dma_resv_usage_rw(true)))
+			stats[id].active += sz;
+		else if (i915_gem_object_is_shrinkable(obj) &&
+			 obj->mm.madv == I915_MADV_DONTNEED)
+			stats[id].purgeable += sz;
+	}
+}
+
+static void show_meminfo(struct drm_printer *p, struct drm_file *file)
+{
+	struct drm_memory_stats stats[INTEL_REGION_UNKNOWN] = {};
+	struct drm_i915_file_private *fpriv = file->driver_priv;
+	struct i915_drm_client *client = fpriv->client;
+	struct drm_i915_private *i915 = fpriv->i915;
+	struct drm_i915_gem_object *obj;
+	struct intel_memory_region *mr;
+	unsigned int id;
+
+	mutex_lock(&client->objects_lock);
+	list_for_each_entry(obj, &client->objects_list, client_link)
+		obj_meminfo(obj, stats);
+	mutex_unlock(&client->objects_lock);
+
+	for_each_memory_region(mr, i915, id)
+		drm_print_memory_stats(p,
+				       &stats[id],
+				       DRM_GEM_OBJECT_RESIDENT |
+				       DRM_GEM_OBJECT_PURGEABLE,
+				       mr->name);
+}
+
 static const char * const uabi_class_names[] = {
 	[I915_ENGINE_CLASS_RENDER] = "render",
 	[I915_ENGINE_CLASS_COPY] = "copy",
@@ -109,6 +171,8 @@ void i915_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file)
 	 * ******************************************************************
 	 */
 
+	show_meminfo(p, file);
+
 	if (GRAPHICS_VER(i915) < 8)
 		return;
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/5] drm/i915: Record which clients own a VM
  2023-06-08 14:51 ` [PATCH 2/5] drm/i915: Record which clients own a VM Tvrtko Ursulin
@ 2023-06-08 17:48   ` kernel test robot
  0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2023-06-08 17:48 UTC (permalink / raw)
  To: Tvrtko Ursulin, Intel-gfx, dri-devel; +Cc: Tvrtko Ursulin, oe-kbuild-all

Hi Tvrtko,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-tip/drm-tip]

url:    https://github.com/intel-lab-lkp/linux/commits/Tvrtko-Ursulin/drm-i915-Track-buffer-objects-belonging-to-clients/20230608-225344
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
patch link:    https://lore.kernel.org/r/20230608145133.1059554-3-tvrtko.ursulin%40linux.intel.com
patch subject: [PATCH 2/5] drm/i915: Record which clients own a VM
config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20230609/202306090149.5gHC8re3-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build):
        git remote add drm-tip git://anongit.freedesktop.org/drm/drm-tip
        git fetch drm-tip drm-tip
        git checkout drm-tip/drm-tip
        b4 shazam https://lore.kernel.org/r/20230608145133.1059554-3-tvrtko.ursulin@linux.intel.com
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 olddefconfig
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/i915/

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202306090149.5gHC8re3-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gem/i915_gem_context.c:2587:
   drivers/gpu/drm/i915/gem/selftests/mock_context.c: In function 'live_context':
>> drivers/gpu/drm/i915/gem/selftests/mock_context.c:86:35: error: passing argument 1 of 'proto_context_create' from incompatible pointer type [-Werror=incompatible-pointer-types]
      86 |         pc = proto_context_create(i915, 0);
         |                                   ^~~~
         |                                   |
         |                                   struct drm_i915_private *
   drivers/gpu/drm/i915/gem/i915_gem_context.c:282:52: note: expected 'struct drm_i915_file_private *' but argument is of type 'struct drm_i915_private *'
     282 | proto_context_create(struct drm_i915_file_private *fpriv,
         |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
>> drivers/gpu/drm/i915/gem/selftests/mock_context.c:86:14: error: too few arguments to function 'proto_context_create'
      86 |         pc = proto_context_create(i915, 0);
         |              ^~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/i915/gem/i915_gem_context.c:282:1: note: declared here
     282 | proto_context_create(struct drm_i915_file_private *fpriv,
         | ^~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/i915/gem/selftests/mock_context.c: In function 'kernel_context':
   drivers/gpu/drm/i915/gem/selftests/mock_context.c:155:35: error: passing argument 1 of 'proto_context_create' from incompatible pointer type [-Werror=incompatible-pointer-types]
     155 |         pc = proto_context_create(i915, 0);
         |                                   ^~~~
         |                                   |
         |                                   struct drm_i915_private *
   drivers/gpu/drm/i915/gem/i915_gem_context.c:282:52: note: expected 'struct drm_i915_file_private *' but argument is of type 'struct drm_i915_private *'
     282 | proto_context_create(struct drm_i915_file_private *fpriv,
         |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
   drivers/gpu/drm/i915/gem/selftests/mock_context.c:155:14: error: too few arguments to function 'proto_context_create'
     155 |         pc = proto_context_create(i915, 0);
         |              ^~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/i915/gem/i915_gem_context.c:282:1: note: declared here
     282 | proto_context_create(struct drm_i915_file_private *fpriv,
         | ^~~~~~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/proto_context_create +86 drivers/gpu/drm/i915/gem/selftests/mock_context.c

79f0f4724d9c50 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2017-07-21   76  
79f0f4724d9c50 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2017-07-21   77  struct i915_gem_context *
a8c9a7f52ec5a4 drivers/gpu/drm/i915/gem/selftests/mock_context.c Chris Wilson           2019-11-07   78  live_context(struct drm_i915_private *i915, struct file *file)
79f0f4724d9c50 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2017-07-21   79  {
a4c1cdd34e2cda drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   80  	struct drm_i915_file_private *fpriv = to_drm_file(file)->driver_priv;
a34857dc92475a drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   81  	struct i915_gem_proto_context *pc;
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   82  	struct i915_gem_context *ctx;
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   83  	int err;
c100777cc00ce9 drivers/gpu/drm/i915/gem/selftests/mock_context.c Tvrtko Ursulin         2019-12-24   84  	u32 id;
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   85  
a34857dc92475a drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08  @86  	pc = proto_context_create(i915, 0);
a34857dc92475a drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   87  	if (IS_ERR(pc))
a34857dc92475a drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   88  		return ERR_CAST(pc);
a34857dc92475a drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   89  
a34857dc92475a drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   90  	ctx = i915_gem_create_context(i915, pc);
d3ac8d42168a9b drivers/gpu/drm/i915/gem/selftests/mock_context.c Daniele Ceraolo Spurio 2021-09-24   91  	proto_context_close(i915, pc);
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   92  	if (IS_ERR(ctx))
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   93  		return ctx;
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   94  
03d0ed8a8e9300 drivers/gpu/drm/i915/gem/selftests/mock_context.c Chris Wilson           2020-01-28   95  	i915_gem_context_set_no_error_capture(ctx);
03d0ed8a8e9300 drivers/gpu/drm/i915/gem/selftests/mock_context.c Chris Wilson           2020-01-28   96  
a4c1cdd34e2cda drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08   97  	err = xa_alloc(&fpriv->context_xa, &id, NULL, xa_limit_32b, GFP_KERNEL);
3e05531243d032 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   98  	if (err < 0)
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21   99  		goto err_ctx;
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21  100  
a4c1cdd34e2cda drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08  101  	gem_context_register(ctx, fpriv, id);
a4c1cdd34e2cda drivers/gpu/drm/i915/gem/selftests/mock_context.c Faith Ekstrand         2021-07-08  102  
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21  103  	return ctx;
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21  104  
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21  105  err_ctx:
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21  106  	context_close(ctx);
3aa9945a528e76 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2019-03-21  107  	return ERR_PTR(err);
79f0f4724d9c50 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2017-07-21  108  }
8ec21a7c4b5216 drivers/gpu/drm/i915/selftests/mock_context.c     Chris Wilson           2018-02-05  109  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Intel-gfx] [PATCH 1/5] drm/i915: Track buffer objects belonging to clients
  2023-06-08 14:51 ` [PATCH 1/5] drm/i915: Track buffer objects belonging to clients Tvrtko Ursulin
@ 2023-06-09  4:16   ` Iddamsetty, Aravind
  2023-06-09 12:08     ` Tvrtko Ursulin
  0 siblings, 1 reply; 9+ messages in thread
From: Iddamsetty, Aravind @ 2023-06-09  4:16 UTC (permalink / raw)
  To: Tvrtko Ursulin, Intel-gfx, dri-devel



On 08-06-2023 20:21, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> In order to show per client memory usage lets start tracking which
> objects belong to which clients.
> 
> We start with objects explicitly created by object creation UAPI and
> track it on a new per client lists, protected by a new per client lock.
> In order for delayed destruction (post client exit), we make tracked
> objects hold references to the owning client.
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 32 ++++++++++++++--
>  drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 +++
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  | 12 ++++++
>  drivers/gpu/drm/i915/i915_drm_client.c        | 36 +++++++++++++++++-
>  drivers/gpu/drm/i915/i915_drm_client.h        | 37 ++++++++++++++++++-
>  drivers/gpu/drm/i915/i915_gem.c               |  2 +-
>  6 files changed, 119 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> index d24c0ce8805c..4f1957638207 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -11,6 +11,7 @@
>  #include "gem/i915_gem_region.h"
>  #include "pxp/intel_pxp.h"
>  
> +#include "i915_drm_client.h"
>  #include "i915_drv.h"
>  #include "i915_gem_create.h"
>  #include "i915_trace.h"
> @@ -164,6 +165,14 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  						 n_placements, 0);
>  }
>  
> +static void add_file_obj(struct drm_file *file,
> +			 struct drm_i915_gem_object *obj)
> +{
> +	struct drm_i915_file_private *fpriv = file->driver_priv;
> +
> +	i915_drm_client_add_object(fpriv->client, obj);
> +}
> +
>  int
>  i915_gem_dumb_create(struct drm_file *file,
>  		     struct drm_device *dev,
> @@ -174,6 +183,7 @@ i915_gem_dumb_create(struct drm_file *file,
>  	enum intel_memory_type mem_type;
>  	int cpp = DIV_ROUND_UP(args->bpp, 8);
>  	u32 format;
> +	int ret;
>  
>  	switch (cpp) {
>  	case 1:
> @@ -212,7 +222,12 @@ i915_gem_dumb_create(struct drm_file *file,
>  	if (IS_ERR(obj))
>  		return PTR_ERR(obj);
>  
> -	return i915_gem_publish(obj, file, &args->size, &args->handle);
> +	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
> +
> +	if (!ret)
> +		add_file_obj(file, obj);
> +
> +	return ret;
>  }
>  
>  /**
> @@ -229,6 +244,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
>  	struct drm_i915_gem_create *args = data;
>  	struct drm_i915_gem_object *obj;
>  	struct intel_memory_region *mr;
> +	int ret;
>  
>  	mr = intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
>  
> @@ -236,7 +252,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
>  	if (IS_ERR(obj))
>  		return PTR_ERR(obj);

Do we intend to track only client created objects and not imported ?
or is that taken care by this "obj->base.handle_count > 1"

Thanks,
Aravind.
>  
> -	return i915_gem_publish(obj, file, &args->size, &args->handle);
> +	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
> +
> +	if (!ret)
> +		add_file_obj(file, obj);
> +
> +	return ret;
>  }
>  
>  struct create_ext {
> @@ -494,5 +515,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>  		obj->pat_set_by_user = true;
>  	}
>  
> -	return i915_gem_publish(obj, file, &args->size, &args->handle);
> +	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
> +
> +	if (!ret)
> +		add_file_obj(file, obj);
> +
> +	return ret;
>  }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index 97ac6fb37958..46de9b1b3f1d 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -105,6 +105,10 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>  
>  	INIT_LIST_HEAD(&obj->mm.link);
>  
> +#ifdef CONFIG_PROC_FS
> +	INIT_LIST_HEAD(&obj->client_link);
> +#endif
> +
>  	INIT_LIST_HEAD(&obj->lut_list);
>  	spin_lock_init(&obj->lut_lock);
>  
> @@ -441,6 +445,8 @@ static void i915_gem_free_object(struct drm_gem_object *gem_obj)
>  
>  	GEM_BUG_ON(i915_gem_object_is_framebuffer(obj));
>  
> +	i915_drm_client_remove_object(obj);
> +
>  	/*
>  	 * Before we free the object, make sure any pure RCU-only
>  	 * read-side critical sections are complete, e.g.
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index e72c57716bee..8de2b91b3edf 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -300,6 +300,18 @@ struct drm_i915_gem_object {
>  	 */
>  	struct i915_address_space *shares_resv_from;
>  
> +#ifdef CONFIG_PROC_FS
> +	/**
> +	 * @client: @i915_drm_client which created the object
> +	 */
> +	struct i915_drm_client *client;
> +
> +	/**
> +	 * @client_link: Link into @i915_drm_client.objects_list
> +	 */
> +	struct list_head client_link;
> +#endif
> +
>  	union {
>  		struct rcu_head rcu;
>  		struct llist_node freed;
> diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c
> index 2a44b3876cb5..4cacca568375 100644
> --- a/drivers/gpu/drm/i915/i915_drm_client.c
> +++ b/drivers/gpu/drm/i915/i915_drm_client.c
> @@ -17,7 +17,8 @@
>  #include "i915_gem.h"
>  #include "i915_utils.h"
>  
> -struct i915_drm_client *i915_drm_client_alloc(void)
> +struct i915_drm_client *
> +i915_drm_client_alloc(struct drm_i915_file_private *fpriv)
>  {
>  	struct i915_drm_client *client;
>  
> @@ -28,6 +29,12 @@ struct i915_drm_client *i915_drm_client_alloc(void)
>  	kref_init(&client->kref);
>  	spin_lock_init(&client->ctx_lock);
>  	INIT_LIST_HEAD(&client->ctx_list);
> +#ifdef CONFIG_PROC_FS
> +	mutex_init(&client->objects_lock);
> +	INIT_LIST_HEAD(&client->objects_list);
> +
> +	client->fpriv = fpriv;
> +#endif
>  
>  	return client;
>  }
> @@ -108,4 +115,31 @@ void i915_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file)
>  	for (i = 0; i < ARRAY_SIZE(uabi_class_names); i++)
>  		show_client_class(p, i915, file_priv->client, i);
>  }
> +
> +void i915_drm_client_add_object(struct i915_drm_client *client,
> +				struct drm_i915_gem_object *obj)
> +{
> +	GEM_WARN_ON(obj->client);
> +	GEM_WARN_ON(!list_empty(&obj->client_link));
> +
> +	mutex_lock(&client->objects_lock);
> +	obj->client = i915_drm_client_get(client);
> +	list_add_tail(&obj->client_link, &client->objects_list);
> +	mutex_unlock(&client->objects_lock);
> +}
> +
> +void i915_drm_client_remove_object(struct drm_i915_gem_object *obj)
> +{
> +	struct i915_drm_client *client = fetch_and_zero(&obj->client);
> +
> +	/* Object may not be associated with a client. */
> +	if (!client || list_empty(&obj->client_link))
> +		return;
> +
> +	mutex_lock(&client->objects_lock);
> +	list_del(&obj->client_link);
> +	mutex_unlock(&client->objects_lock);
> +
> +	i915_drm_client_put(client);
> +}
>  #endif
> diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h
> index 4c18b99e10a4..0db68b4d7a4f 100644
> --- a/drivers/gpu/drm/i915/i915_drm_client.h
> +++ b/drivers/gpu/drm/i915/i915_drm_client.h
> @@ -8,10 +8,14 @@
>  
>  #include <linux/kref.h>
>  #include <linux/list.h>
> +#include <linux/mutex.h>
>  #include <linux/spinlock.h>
>  
>  #include <uapi/drm/i915_drm.h>
>  
> +#include "i915_file_private.h"
> +#include "gem/i915_gem_object_types.h"
> +
>  #define I915_LAST_UABI_ENGINE_CLASS I915_ENGINE_CLASS_COMPUTE
>  
>  struct drm_file;
> @@ -25,6 +29,22 @@ struct i915_drm_client {
>  	spinlock_t ctx_lock; /* For add/remove from ctx_list. */
>  	struct list_head ctx_list; /* List of contexts belonging to client. */
>  
> +#ifdef CONFIG_PROC_FS
> +	struct drm_i915_file_private *fpriv;
> +
> +	/**
> +	 * @objects_lock: lock protecting @objects_list
> +	 */
> +	struct mutex objects_lock;
> +
> +	/**
> +	 * @objects_list: list of objects created by this client
> +	 *
> +	 * Protected by @objects_lock.
> +	 */
> +	struct list_head objects_list;
> +#endif
> +
>  	/**
>  	 * @past_runtime: Accumulation of pphwsp runtimes from closed contexts.
>  	 */
> @@ -45,10 +65,25 @@ static inline void i915_drm_client_put(struct i915_drm_client *client)
>  	kref_put(&client->kref, __i915_drm_client_free);
>  }
>  
> -struct i915_drm_client *i915_drm_client_alloc(void);
> +struct i915_drm_client *i915_drm_client_alloc(struct drm_i915_file_private *fpriv);
>  
>  #ifdef CONFIG_PROC_FS
>  void i915_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file);
> +
> +void i915_drm_client_add_object(struct i915_drm_client *client,
> +				struct drm_i915_gem_object *obj);
> +void i915_drm_client_remove_object(struct drm_i915_gem_object *obj);
> +#else
> +static inline void i915_drm_client_add_object(struct i915_drm_client *client,
> +					      struct drm_i915_gem_object *obj)
> +{
> +
> +}
> +
> +static inline void i915_drm_client_remove_object(struct drm_i915_gem_object *obj)
> +{
> +
> +}
>  #endif
>  
>  #endif /* !__I915_DRM_CLIENT_H__ */
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 1f65bb33dd21..7ae42f746cc2 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1325,7 +1325,7 @@ int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
>  	if (!file_priv)
>  		goto err_alloc;
>  
> -	client = i915_drm_client_alloc();
> +	client = i915_drm_client_alloc(file_priv);
>  	if (!client)
>  		goto err_client;
>  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Intel-gfx] [PATCH 1/5] drm/i915: Track buffer objects belonging to clients
  2023-06-09  4:16   ` [Intel-gfx] " Iddamsetty, Aravind
@ 2023-06-09 12:08     ` Tvrtko Ursulin
  0 siblings, 0 replies; 9+ messages in thread
From: Tvrtko Ursulin @ 2023-06-09 12:08 UTC (permalink / raw)
  To: Iddamsetty, Aravind, Intel-gfx, dri-devel


On 09/06/2023 05:16, Iddamsetty, Aravind wrote:
> On 08-06-2023 20:21, Tvrtko Ursulin wrote:
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> In order to show per client memory usage lets start tracking which
>> objects belong to which clients.
>>
>> We start with objects explicitly created by object creation UAPI and
>> track it on a new per client lists, protected by a new per client lock.
>> In order for delayed destruction (post client exit), we make tracked
>> objects hold references to the owning client.
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 32 ++++++++++++++--
>>   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 +++
>>   .../gpu/drm/i915/gem/i915_gem_object_types.h  | 12 ++++++
>>   drivers/gpu/drm/i915/i915_drm_client.c        | 36 +++++++++++++++++-
>>   drivers/gpu/drm/i915/i915_drm_client.h        | 37 ++++++++++++++++++-
>>   drivers/gpu/drm/i915/i915_gem.c               |  2 +-
>>   6 files changed, 119 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> index d24c0ce8805c..4f1957638207 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> @@ -11,6 +11,7 @@
>>   #include "gem/i915_gem_region.h"
>>   #include "pxp/intel_pxp.h"
>>   
>> +#include "i915_drm_client.h"
>>   #include "i915_drv.h"
>>   #include "i915_gem_create.h"
>>   #include "i915_trace.h"
>> @@ -164,6 +165,14 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   						 n_placements, 0);
>>   }
>>   
>> +static void add_file_obj(struct drm_file *file,
>> +			 struct drm_i915_gem_object *obj)
>> +{
>> +	struct drm_i915_file_private *fpriv = file->driver_priv;
>> +
>> +	i915_drm_client_add_object(fpriv->client, obj);
>> +}
>> +
>>   int
>>   i915_gem_dumb_create(struct drm_file *file,
>>   		     struct drm_device *dev,
>> @@ -174,6 +183,7 @@ i915_gem_dumb_create(struct drm_file *file,
>>   	enum intel_memory_type mem_type;
>>   	int cpp = DIV_ROUND_UP(args->bpp, 8);
>>   	u32 format;
>> +	int ret;
>>   
>>   	switch (cpp) {
>>   	case 1:
>> @@ -212,7 +222,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>   	if (IS_ERR(obj))
>>   		return PTR_ERR(obj);
>>   
>> -	return i915_gem_publish(obj, file, &args->size, &args->handle);
>> +	ret = i915_gem_publish(obj, file, &args->size, &args->handle);
>> +
>> +	if (!ret)
>> +		add_file_obj(file, obj);
>> +
>> +	return ret;
>>   }
>>   
>>   /**
>> @@ -229,6 +244,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
>>   	struct drm_i915_gem_create *args = data;
>>   	struct drm_i915_gem_object *obj;
>>   	struct intel_memory_region *mr;
>> +	int ret;
>>   
>>   	mr = intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
>>   
>> @@ -236,7 +252,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
>>   	if (IS_ERR(obj))
>>   		return PTR_ERR(obj);
> 
> Do we intend to track only client created objects and not imported ?
> or is that taken care by this "obj->base.handle_count > 1"

I missed the imports, now added in v3 of the series.

They wouldn't have been handled by the above check in the importer - 
only the exporter would have seen (sometimes) changes in the ratio of 
total vs shared.

Regards,

Tvrtko

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-06-09 12:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-08 14:51 [PATCH v2 0/5] fdinfo memory stats Tvrtko Ursulin
2023-06-08 14:51 ` [PATCH 1/5] drm/i915: Track buffer objects belonging to clients Tvrtko Ursulin
2023-06-09  4:16   ` [Intel-gfx] " Iddamsetty, Aravind
2023-06-09 12:08     ` Tvrtko Ursulin
2023-06-08 14:51 ` [PATCH 2/5] drm/i915: Record which clients own a VM Tvrtko Ursulin
2023-06-08 17:48   ` kernel test robot
2023-06-08 14:51 ` [PATCH 3/5] drm/i915: Track page table backing store usage Tvrtko Ursulin
2023-06-08 14:51 ` [PATCH 4/5] drm/i915: Account ring buffer and context state storage Tvrtko Ursulin
2023-06-08 14:51 ` [PATCH 5/5] drm/i915: Implement fdinfo memory stats printing Tvrtko Ursulin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).