From: Matthew Wilcox Date: Wed, 26 Sep 2018 12:14:59 +0000 (-0400) Subject: xfs: Convert mru cache to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7cbc487c8bb3818d44a1f5e65083d7151100d80e;p=users%2Fwilly%2Fxarray.git xfs: Convert mru cache to XArray This eliminates a call to radix_tree_preload() and a personal spinlock. Signed-off-by: Matthew Wilcox --- diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c index 74738813f60d8..8b05febd494e4 100644 --- a/fs/xfs/xfs_mru_cache.c +++ b/fs/xfs/xfs_mru_cache.c @@ -89,10 +89,9 @@ * 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); }