drm/xe: Add tracking support for bos per client
authorTejas Upadhyay <tejas.upadhyay@intel.com>
Thu, 21 Sep 2023 11:41:34 +0000 (17:11 +0530)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:41:15 +0000 (11:41 -0500)
In order to show per client memory consumption, we
need tracking support APIs to add at every bo consumption
and removal. Adding APIs here to add tracking calls at
places wherever it is applicable.

V5:
  - Rebase
V4:
  - remove client bo before vm_put
  - spin_lock_irqsave not required - Auld
V3:
  - update .h to return xe_drm_client_remove_bo void
  - protect xe_drm_client_remove_bo under CONFIG_PROC_FS check - Himal
  - Fixed Checkpatch error - CI
V2:
  - make xe_drm_client_remove_bo return void - Himal

Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_bo.c
drivers/gpu/drm/xe/xe_bo_types.h
drivers/gpu/drm/xe/xe_drm_client.c
drivers/gpu/drm/xe/xe_drm_client.h

index e812f2b7d5b9c1569cbd2fdf3c163a05f1753083..eb08a8954742286615d70c8f8d633782f4ae4a98 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "xe_device.h"
 #include "xe_dma_buf.h"
+#include "xe_drm_client.h"
 #include "xe_ggtt.h"
 #include "xe_gt.h"
 #include "xe_map.h"
@@ -1054,6 +1055,11 @@ static void xe_ttm_bo_destroy(struct ttm_buffer_object *ttm_bo)
        if (bo->ggtt_node.size)
                xe_ggtt_remove_bo(bo->tile->mem.ggtt, bo);
 
+#ifdef CONFIG_PROC_FS
+       if (bo->client)
+               xe_drm_client_remove_bo(bo);
+#endif
+
        if (bo->vm && xe_bo_is_user(bo))
                xe_vm_put(bo->vm);
 
@@ -1233,6 +1239,9 @@ struct xe_bo *__xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
        bo->props.preferred_mem_type = XE_BO_PROPS_INVALID;
        bo->ttm.priority = DRM_XE_VMA_PRIORITY_NORMAL;
        INIT_LIST_HEAD(&bo->pinned_link);
+#ifdef CONFIG_PROC_FS
+       INIT_LIST_HEAD(&bo->client_link);
+#endif
 
        drm_gem_private_object_init(&xe->drm, &bo->ttm.base, size);
 
index 27fe72129ee6953b54b7bc6fa85567af7d702aeb..c628625c8a899e900dcce294699e44e3cfac9b0d 100644 (file)
@@ -43,6 +43,16 @@ struct xe_bo {
        struct ttm_bo_kmap_obj kmap;
        /** @pinned_link: link to present / evicted list of pinned BO */
        struct list_head pinned_link;
+#ifdef CONFIG_PROC_FS
+       /**
+        * @client: @xe_drm_client which created the bo
+        */
+       struct xe_drm_client *client;
+       /**
+        * @client_link: Link into @xe_drm_client.objects_list
+        */
+       struct list_head client_link;
+#endif
        /** @props: BO user controlled properties */
        struct {
                /** @preferred_mem: preferred memory class for this BO */
index 98c8a0cf2f56505e3bc8b8012debf38371457750..b5ac9bc1f685a0d6eb1b1bfc4f7f2200400bdf25 100644 (file)
@@ -8,8 +8,10 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include "xe_bo_types.h"
 #include "xe_device_types.h"
 #include "xe_drm_client.h"
+#include "xe_trace.h"
 
 /**
  * xe_drm_client_alloc() - Allocate drm client
@@ -31,6 +33,10 @@ struct xe_drm_client *xe_drm_client_alloc(void)
 
        kref_init(&client->kref);
 
+#ifdef CONFIG_PROC_FS
+       spin_lock_init(&client->bos_lock);
+       INIT_LIST_HEAD(&client->bos_list);
+#endif
        return client;
 }
 
@@ -52,6 +58,48 @@ void __xe_drm_client_free(struct kref *kref)
 }
 
 #ifdef CONFIG_PROC_FS
+/**
+ * xe_drm_client_add_bo() - Add BO for tracking client mem usage
+ * @client: The drm client ptr
+ * @bo: The xe BO ptr
+ *
+ * Add all BO created by individual drm client by calling this function.
+ * This helps in tracking client memory usage.
+ *
+ * Return: void
+ */
+void xe_drm_client_add_bo(struct xe_drm_client *client,
+                         struct xe_bo *bo)
+{
+       XE_WARN_ON(bo->client);
+       XE_WARN_ON(!list_empty(&bo->client_link));
+
+       spin_lock(&client->bos_lock);
+       bo->client = xe_drm_client_get(client);
+       list_add_tail_rcu(&bo->client_link, &client->bos_list);
+       spin_unlock(&client->bos_lock);
+}
+
+/**
+ * xe_drm_client_remove_bo() - Remove BO for tracking client mem usage
+ * @bo: The xe BO ptr
+ *
+ * Remove all BO removed by individual drm client by calling this function.
+ * This helps in tracking client memory usage.
+ *
+ * Return: void
+ */
+void xe_drm_client_remove_bo(struct xe_bo *bo)
+{
+       struct xe_drm_client *client = bo->client;
+
+       spin_lock(&client->bos_lock);
+       list_del_rcu(&bo->client_link);
+       spin_unlock(&client->bos_lock);
+
+       xe_drm_client_put(client);
+}
+
 /**
  * xe_drm_client_fdinfo() - Callback for fdinfo interface
  * @p: The drm_printer ptr
index dbe3a083c9df85b3affa070b42e7eb1fbcc4758e..a9649aa360110d3c9ca41f651a8057d5ca4331f6 100644 (file)
 
 struct drm_file;
 struct drm_printer;
+struct xe_bo;
 
 struct xe_drm_client {
        struct kref kref;
        unsigned int id;
+#ifdef CONFIG_PROC_FS
+       /**
+        * @bos_lock: lock protecting @bos_list
+        */
+       spinlock_t bos_lock;
+       /**
+        * @bos_list: list of bos created by this client
+        *
+        * Protected by @bos_lock.
+        */
+       struct list_head bos_list;
+#endif
 };
 
        static inline struct xe_drm_client *
@@ -41,5 +54,17 @@ xe_drm_client_get(struct xe_drm_client *client);
 static inline void xe_drm_client_put(struct xe_drm_client *client);
 #ifdef CONFIG_PROC_FS
 void xe_drm_client_fdinfo(struct drm_printer *p, struct drm_file *file);
+void xe_drm_client_add_bo(struct xe_drm_client *client,
+                         struct xe_bo *bo);
+void xe_drm_client_remove_bo(struct xe_bo *bo);
+#else
+static inline void xe_drm_client_add_bo(struct xe_drm_client *client,
+                                       struct xe_bo *bo)
+{
+}
+
+static inline void xe_drm_client_remove_bo(struct xe_bo *bo)
+{
+}
 #endif
 #endif