Now that all users have migrated to dma_resv_alloc(), inline the
initialization code directly into dma_resv_alloc() and remove the
dma_resv_init() function entirely.

Additionally, remove the 'allocated' flag from struct dma_resv since
all dma_resv objects are now dynamically allocated. This simplifies
the reference counting logic - dma_resv_release() now always frees
the object unconditionally.

The last remaining use of dma_resv_init() in dma_resv_lockdep() has
been converted to use dma_resv_alloc() instead.

Signed-off-by: Christian König <[email protected]>
Assisted-by: Claude:Sonnet 4
---
 drivers/dma-buf/dma-resv.c | 43 +++++++++++++++-----------------------
 include/linux/dma-resv.h   | 10 ---------
 2 files changed, 17 insertions(+), 36 deletions(-)

diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 5ae5a4b40ae6..4a421b08cd98 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -132,26 +132,13 @@ static void dma_resv_list_free(struct dma_resv_list *list)
        kfree_rcu(list, rcu);
 }
 
-/**
- * dma_resv_init - initialize a reservation object
- * @obj: the reservation object
- */
-void dma_resv_init(struct dma_resv *obj)
-{
-       kref_init(&obj->refcount);
-       obj->allocated = false;
-       ww_mutex_init(&obj->lock, &reservation_ww_class);
-
-       RCU_INIT_POINTER(obj->fences, NULL);
-}
-EXPORT_SYMBOL(dma_resv_init);
-
 /*
  * dma_resv_release - release function for kref
  * @kref: the kref inside the dma_resv object
  *
  * This is called when the last reference to a dma_resv object is released.
- * Cleans up the object and frees it if it was allocated by dma_resv_alloc().
+ * All dma_resv objects are now dynamically allocated, so this always frees
+ * the object after cleanup.
  */
 static void dma_resv_release(struct kref *kref)
 {
@@ -163,10 +150,7 @@ static void dma_resv_release(struct kref *kref)
         */
        dma_resv_list_free(rcu_dereference_protected(obj->fences, true));
        ww_mutex_destroy(&obj->lock);
-
-       /* TODO: Only as temporary workaround till dma_fence_init() is removed 
*/
-       if (obj->allocated)
-               kfree(obj);
+       kfree(obj);
 }
 
 /**
@@ -187,8 +171,9 @@ struct dma_resv *dma_resv_alloc(void)
        if (!obj)
                return NULL;
 
-       dma_resv_init(obj);
-       obj->allocated = true;
+       kref_init(&obj->refcount);
+       ww_mutex_init(&obj->lock, &reservation_ww_class);
+       RCU_INIT_POINTER(obj->fences, NULL);
 
        return obj;
 }
@@ -844,23 +829,28 @@ static int __init dma_resv_lockdep(void)
 {
        struct mm_struct *mm = mm_alloc();
        struct ww_acquire_ctx ctx;
-       struct dma_resv obj;
+       struct dma_resv *obj;
        struct address_space mapping;
        int ret;
 
        if (!mm)
                return -ENOMEM;
 
-       dma_resv_init(&obj);
+       obj = dma_resv_alloc();
+       if (!obj) {
+               mmput(mm);
+               return -ENOMEM;
+       }
+
        address_space_init_once(&mapping);
 
        mmap_read_lock(mm);
        ww_acquire_init(&ctx, &reservation_ww_class);
-       ret = dma_resv_lock(&obj, &ctx);
+       ret = dma_resv_lock(obj, &ctx);
        if (ret) {
                /* Only EDEADLK from the error injection is possible here */
                WARN_ON(ret != -EDEADLK);
-               dma_resv_lock_slow(&obj, &ctx);
+               dma_resv_lock_slow(obj, &ctx);
        }
        fs_reclaim_acquire(GFP_KERNEL);
        /* for unmap_mapping_range on trylocked buffer objects in shrinkers */
@@ -874,10 +864,11 @@ static int __init dma_resv_lockdep(void)
        __dma_fence_might_wait();
 #endif
        fs_reclaim_release(GFP_KERNEL);
-       ww_mutex_unlock(&obj.lock);
+       ww_mutex_unlock(&obj->lock);
        ww_acquire_fini(&ctx);
        mmap_read_unlock(mm);
 
+       dma_resv_put(obj);
        mmput(mm);
 
        return 0;
diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h
index 4d12519df34e..cf689d3d4ba6 100644
--- a/include/linux/dma-resv.h
+++ b/include/linux/dma-resv.h
@@ -162,15 +162,6 @@ struct dma_resv {
         */
        struct kref refcount;
 
-       /**
-        * @allocated:
-        *
-        * True if this object was allocated by dma_resv_alloc(), false if
-        * embedded in another structure. Used to determine whether to free
-        * the object memory in the release function.
-        */
-       bool allocated;
-
        /**
         * @lock:
         *
@@ -482,7 +473,6 @@ static inline void dma_resv_unlock(struct dma_resv *obj)
        ww_mutex_unlock(&obj->lock);
 }
 
-void dma_resv_init(struct dma_resv *obj);
 struct dma_resv *dma_resv_alloc(void);
 struct dma_resv *dma_resv_get(struct dma_resv *obj);
 void dma_resv_put(struct dma_resv *obj);
-- 
2.43.0

Reply via email to