const char reservation_seqcount_string[] = "reservation_seqcount";
 EXPORT_SYMBOL(reservation_seqcount_string);
 
+/**
+ * reservation_object_list_alloc - allocate fence list
+ * @shared_max: number of fences we need space for
+ *
+ * Allocate a new reservation_object_list and make sure to correctly initialize
+ * shared_max.
+ */
+static struct reservation_object_list *
+reservation_object_list_alloc(unsigned int shared_max)
+{
+       struct reservation_object_list *list;
+
+       list = kmalloc(offsetof(typeof(*list), shared[shared_max]), GFP_KERNEL);
+       if (!list)
+               return NULL;
+
+       list->shared_max = (ksize(list) - offsetof(typeof(*list), shared)) /
+               sizeof(*list->shared);
+
+       return list;
+}
+
+/**
+ * reservation_object_list_free - free fence list
+ * @list: list to free
+ *
+ * Free a reservation_object_list and make sure to drop all references.
+ */
+static void reservation_object_list_free(struct reservation_object_list *list)
+{
+       unsigned int i;
+
+       if (!list)
+               return;
+
+       for (i = 0; i < list->shared_count; ++i)
+               dma_fence_put(rcu_dereference_protected(list->shared[i], true));
+
+       kfree_rcu(list, rcu);
+}
+
 /**
  * reservation_object_init - initialize a reservation object
  * @obj: the reservation object
  */
 void reservation_object_fini(struct reservation_object *obj)
 {
-       int i;
        struct reservation_object_list *fobj;
        struct dma_fence *excl;
 
                dma_fence_put(excl);
 
        fobj = rcu_dereference_protected(obj->fence, 1);
-       if (fobj) {
-               for (i = 0; i < fobj->shared_count; ++i)
-                       dma_fence_put(rcu_dereference_protected(fobj->shared[i], 1));
-
-               kfree(fobj);
-       }
-
+       reservation_object_list_free(fobj);
        ww_mutex_destroy(&obj->lock);
 }
 EXPORT_SYMBOL(reservation_object_fini);
                max = 4;
        }
 
-       new = kmalloc(offsetof(typeof(*new), shared[max]), GFP_KERNEL);
+       new = reservation_object_list_alloc(max);
        if (!new)
                return -ENOMEM;
 
                        RCU_INIT_POINTER(new->shared[j++], fence);
        }
        new->shared_count = j;
-       new->shared_max =
-               (ksize(new) - offsetof(typeof(*new), shared)) /
-               sizeof(*new->shared);
 
        /*
         * We are not changing the effective set of fences here so can
 {
        struct reservation_object_list *src_list, *dst_list;
        struct dma_fence *old, *new;
-       size_t size;
        unsigned i;
 
        reservation_object_assert_held(dst);
        if (src_list) {
                unsigned shared_count = src_list->shared_count;
 
-               size = offsetof(typeof(*src_list), shared[shared_count]);
                rcu_read_unlock();
 
-               dst_list = kmalloc(size, GFP_KERNEL);
+               dst_list = reservation_object_list_alloc(shared_count);
                if (!dst_list)
                        return -ENOMEM;
 
                }
 
                dst_list->shared_count = 0;
-               dst_list->shared_max = shared_count;
                for (i = 0; i < src_list->shared_count; ++i) {
                        struct dma_fence *fence;
 
                                continue;
 
                        if (!dma_fence_get_rcu(fence)) {
-                               kfree(dst_list);
+                               reservation_object_list_free(dst_list);
                                src_list = rcu_dereference(src->fence);
                                goto retry;
                        }
        write_seqcount_end(&dst->seq);
        preempt_enable();
 
-       if (src_list)
-               kfree_rcu(src_list, rcu);
+       reservation_object_list_free(src_list);
        dma_fence_put(old);
 
        return 0;