From: Jim Cromie <[email protected]>

Embed a struct folio_scratchpad inside struct drm_gpuvm and route
default gpuva_op allocations in gpuva_op_alloc() to
folio_scratchpad_alloc_obj(), with O(1) bulk teardown in
drm_gpuvm_fini().

Signed-off-by: Jim Cromie <[email protected]>
---
 drivers/gpu/drm/drm_gpuvm.c | 11 +++++++++--
 include/drm/drm_gpuvm.h     |  6 ++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
index c422c5af1f4b..6bb82ac9e2d6 100644
--- a/drivers/gpu/drm/drm_gpuvm.c
+++ b/drivers/gpu/drm/drm_gpuvm.c
@@ -1109,6 +1109,8 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
        spin_lock_init(&gpuvm->evict.lock);
 
        init_llist_head(&gpuvm->bo_defer);
+       folio_scratchpad_init_key(&gpuvm->va_scratchpad, get_order(SZ_64K),
+                                 &gpuvm_scratchpad_key);
 
        kref_init(&gpuvm->kref);
 
@@ -1155,6 +1157,7 @@ drm_gpuvm_fini(struct drm_gpuvm *gpuvm)
        drm_WARN(gpuvm->drm, !llist_empty(&gpuvm->bo_defer),
                 "VM BO cleanup list should be empty.\n");
 
+       folio_scratchpad_free(&gpuvm->va_scratchpad);
        drm_gem_object_put(gpuvm->r_obj);
 }
 
@@ -2849,6 +2852,9 @@ drm_gpuvm_sm_unmap_exec_lock(struct drm_gpuvm *gpuvm, 
struct drm_exec *exec,
 }
 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_exec_lock);
 
+DEFINE_FOLIO_POOL_STATIC_KEY_PARAM(gpuvm_scratchpad_key, va_scratchpad,
+                                  "Toggle DRM GPUVM range folio scratchpad 
allocator");
+
 static struct drm_gpuva_op *
 gpuva_op_alloc(struct drm_gpuvm *gpuvm)
 {
@@ -2858,7 +2864,8 @@ gpuva_op_alloc(struct drm_gpuvm *gpuvm)
        if (fn && fn->op_alloc)
                op = fn->op_alloc();
        else
-               op = kzalloc_obj(*op);
+               op = folio_scratchpad_alloc_obj(gpuvm, va_scratchpad,
+                                               struct drm_gpuva_op, 
GFP_KERNEL);
 
        if (unlikely(!op))
                return NULL;
@@ -2875,7 +2882,7 @@ gpuva_op_free(struct drm_gpuvm *gpuvm,
        if (fn && fn->op_free)
                fn->op_free(op);
        else
-               kfree(op);
+               folio_scratchpad_free_elem(op);
 }
 
 static int
diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index 655bd9104ffb..362b1d88d30d 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -30,6 +30,7 @@
 #include <linux/llist.h>
 #include <linux/rbtree.h>
 #include <linux/types.h>
+#include <linux/folio_pool.h>
 
 #include <drm/drm_device.h>
 #include <drm/drm_gem.h>
@@ -338,6 +339,11 @@ struct drm_gpuvm {
         * @bo_defer: structure holding vm_bos that need to be destroyed
         */
        struct llist_head bo_defer;
+
+       /**
+        * @va_scratchpad: folio scratchpad for transient GPU VA range 
allocations
+        */
+       struct folio_scratchpad va_scratchpad;
 };
 
 void drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,

-- 
2.55.0


Reply via email to