]> www.infradead.org Git - users/willy/xarray.git/commitdiff
xfs: Convert mru cache to XArray
authorMatthew Wilcox <willy@infradead.org>
Wed, 26 Sep 2018 12:14:59 +0000 (08:14 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 8 Aug 2019 02:36:48 +0000 (22:36 -0400)
This eliminates a call to radix_tree_preload() and a personal spinlock.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
fs/xfs/xfs_mru_cache.c

index 74738813f60d8bb6561c3ef9b3cf7ad4923276d5..8b05febd494e4b3ed598999ecb9664158da7e3a5 100644 (file)
  * an infinite loop in the code.
  */
 struct xfs_mru_cache {
-       struct radix_tree_root  store;     /* Core storage data structure.  */
+       struct xarray           store;     /* Core storage data structure.  */
        struct list_head        *lists;    /* Array of lists, one per grp.  */
        struct list_head        reap_list; /* Elements overdue for reaping. */
-       spinlock_t              lock;      /* Lock to protect this struct.  */
        unsigned int            grp_count; /* Number of discrete groups.    */
        unsigned int            grp_time;  /* Time period spanned by grps.  */
        unsigned int            lru_grp;   /* Group containing time zero.   */
@@ -221,22 +220,21 @@ _xfs_mru_cache_list_insert(
  * data store, removing it from the reap list, calling the client's free
  * function and deleting the element from the element zone.
  *
- * We get called holding the mru->lock, which we drop and then reacquire.
- * Sparse need special help with this to tell it we know what we are doing.
+ * We get called holding the mru->store lock, which we drop and then reacquire.
+ * Sparse needs special help with this to tell it we know what we are doing.
  */
 STATIC void
 _xfs_mru_cache_clear_reap_list(
        struct xfs_mru_cache    *mru)
-               __releases(mru->lock) __acquires(mru->lock)
+               __releases(mru->store) __acquires(mru->store)
 {
        struct xfs_mru_cache_elem *elem, *next;
        struct list_head        tmp;
 
        INIT_LIST_HEAD(&tmp);
        list_for_each_entry_safe(elem, next, &mru->reap_list, list_node) {
-
                /* Remove the element from the data store. */
-               radix_tree_delete(&mru->store, elem->key);
+               __xa_erase(&mru->store, elem->key);
 
                /*
                 * remove to temp list so it can be freed without
@@ -244,14 +242,14 @@ _xfs_mru_cache_clear_reap_list(
                 */
                list_move(&elem->list_node, &tmp);
        }
-       spin_unlock(&mru->lock);
+       xa_unlock(&mru->store);
 
        list_for_each_entry_safe(elem, next, &tmp, list_node) {
                list_del_init(&elem->list_node);
                mru->free_func(mru->data, elem);
        }
 
-       spin_lock(&mru->lock);
+       xa_lock(&mru->store);
 }
 
 /*
@@ -273,7 +271,7 @@ _xfs_mru_cache_reap(
        if (!mru || !mru->lists)
                return;
 
-       spin_lock(&mru->lock);
+       xa_lock(&mru->store);
        next = _xfs_mru_cache_migrate(mru, jiffies);
        _xfs_mru_cache_clear_reap_list(mru);
 
@@ -287,7 +285,7 @@ _xfs_mru_cache_reap(
                queue_delayed_work(xfs_mru_reap_wq, &mru->work, next);
        }
 
-       spin_unlock(&mru->lock);
+       xa_unlock(&mru->store);
 }
 
 int
@@ -348,13 +346,8 @@ xfs_mru_cache_create(
        for (grp = 0; grp < mru->grp_count; grp++)
                INIT_LIST_HEAD(mru->lists + grp);
 
-       /*
-        * We use GFP_KERNEL radix tree preload and do inserts under a
-        * spinlock so GFP_ATOMIC is appropriate for the radix tree itself.
-        */
-       INIT_RADIX_TREE(&mru->store, GFP_ATOMIC);
+       xa_init(&mru->store);
        INIT_LIST_HEAD(&mru->reap_list);
-       spin_lock_init(&mru->lock);
        INIT_DELAYED_WORK(&mru->work, _xfs_mru_cache_reap);
 
        mru->grp_time  = grp_time;
@@ -384,17 +377,17 @@ xfs_mru_cache_flush(
        if (!mru || !mru->lists)
                return;
 
-       spin_lock(&mru->lock);
+       xa_lock(&mru->store);
        if (mru->queued) {
-               spin_unlock(&mru->lock);
+               xa_unlock(&mru->store);
                cancel_delayed_work_sync(&mru->work);
-               spin_lock(&mru->lock);
+               xa_lock(&mru->store);
        }
 
        _xfs_mru_cache_migrate(mru, jiffies + mru->grp_count * mru->grp_time);
        _xfs_mru_cache_clear_reap_list(mru);
 
-       spin_unlock(&mru->lock);
+       xa_unlock(&mru->store);
 }
 
 void
@@ -427,18 +420,14 @@ xfs_mru_cache_insert(
        if (!mru || !mru->lists)
                return -EINVAL;
 
-       if (radix_tree_preload(GFP_NOFS))
-               return -ENOMEM;
-
        INIT_LIST_HEAD(&elem->list_node);
        elem->key = key;
 
-       spin_lock(&mru->lock);
-       error = radix_tree_insert(&mru->store, key, elem);
-       radix_tree_preload_end();
+       xa_lock(&mru->store);
+       error = xa_err(__xa_store(&mru->store, key, elem, GFP_NOFS));
        if (!error)
                _xfs_mru_cache_list_insert(mru, elem);
-       spin_unlock(&mru->lock);
+       xa_unlock(&mru->store);
 
        return error;
 }
@@ -460,11 +449,11 @@ xfs_mru_cache_remove(
        if (!mru || !mru->lists)
                return NULL;
 
-       spin_lock(&mru->lock);
-       elem = radix_tree_delete(&mru->store, key);
+       xa_lock(&mru->store);
+       elem = __xa_erase(&mru->store, key);
        if (elem)
                list_del(&elem->list_node);
-       spin_unlock(&mru->lock);
+       xa_unlock(&mru->store);
 
        return elem;
 }
@@ -516,14 +505,14 @@ xfs_mru_cache_lookup(
        if (!mru || !mru->lists)
                return NULL;
 
-       spin_lock(&mru->lock);
-       elem = radix_tree_lookup(&mru->store, key);
+       xa_lock(&mru->store);
+       elem = xa_load(&mru->store, key);
        if (elem) {
                list_del(&elem->list_node);
                _xfs_mru_cache_list_insert(mru, elem);
-               __release(mru_lock); /* help sparse not be stupid */
+               __release(&mru->store); /* help sparse not be stupid */
        } else
-               spin_unlock(&mru->lock);
+               xa_unlock(&mru->store);
 
        return elem;
 }
@@ -536,7 +525,7 @@ xfs_mru_cache_lookup(
 void
 xfs_mru_cache_done(
        struct xfs_mru_cache    *mru)
-               __releases(mru->lock)
+               __releases(mru->store)
 {
-       spin_unlock(&mru->lock);
+       xa_unlock(&mru->store);
 }