]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: place intent recovery under NOFS allocation context
authorDave Chinner <dchinner@redhat.com>
Mon, 15 Jan 2024 22:59:47 +0000 (09:59 +1100)
committerChandan Babu R <chandanbabu@kernel.org>
Tue, 13 Feb 2024 12:37:35 +0000 (18:07 +0530)
When recovery starts processing intents, all of the initial intent
allocations are done outside of transaction contexts. That means
they need to specifically use GFP_NOFS as we do not want memory
reclaim to attempt to run direct reclaim of filesystem objects while
we have lots of objects added into deferred operations.

Rather than use GFP_NOFS for these specific allocations, just place
the entire intent recovery process under NOFS context and we can
then just use GFP_KERNEL for these allocations.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
fs/xfs/xfs_attr_item.c
fs/xfs/xfs_bmap_item.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_refcount_item.c
fs/xfs/xfs_rmap_item.c

index 0bf25a2ba3b678e1d232f1c98fd6276f1c2cf457..e14e229fc7126b2bbf9931f55046375997eca7c9 100644 (file)
@@ -513,7 +513,7 @@ xfs_attri_recover_work(
                return ERR_PTR(error);
 
        attr = kzalloc(sizeof(struct xfs_attr_intent) +
-                       sizeof(struct xfs_da_args), GFP_NOFS | __GFP_NOFAIL);
+                       sizeof(struct xfs_da_args), GFP_KERNEL | __GFP_NOFAIL);
        args = (struct xfs_da_args *)(attr + 1);
 
        attr->xattri_da_args = args;
index 029a6a8d0efd481d813d7458ae917e6f4dbf9915..e3c58090e97652016fd74f801e8ce13d8f6b4cf6 100644 (file)
@@ -445,7 +445,8 @@ xfs_bui_recover_work(
        if (error)
                return ERR_PTR(error);
 
-       bi = kmem_cache_zalloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+       bi = kmem_cache_zalloc(xfs_bmap_intent_cache,
+                       GFP_KERNEL | __GFP_NOFAIL);
        bi->bi_whichfork = (map->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
                        XFS_ATTR_FORK : XFS_DATA_FORK;
        bi->bi_type = map->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
index e9ed43a833af04c4da7db29b6ea6493cc0bf190d..8c1d260bb9e10ed75aeff78b845d3d03da28cf70 100644 (file)
@@ -3443,12 +3443,19 @@ xlog_recover(
  * part of recovery so that the root and real-time bitmap inodes can be read in
  * from disk in between the two stages.  This is necessary so that we can free
  * space in the real-time portion of the file system.
+ *
+ * We run this whole process under GFP_NOFS allocation context. We do a
+ * combination of non-transactional and transactional work, yet we really don't
+ * want to recurse into the filesystem from direct reclaim during any of this
+ * processing. This allows all the recovery code run here not to care about the
+ * memory allocation context it is running in.
  */
 int
 xlog_recover_finish(
        struct xlog     *log)
 {
-       int     error;
+       unsigned int    nofs_flags = memalloc_nofs_save();
+       int             error;
 
        error = xlog_recover_process_intents(log);
        if (error) {
@@ -3462,7 +3469,7 @@ xlog_recover_finish(
                xlog_recover_cancel_intents(log);
                xfs_alert(log->l_mp, "Failed to recover intents");
                xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
-               return error;
+               goto out_error;
        }
 
        /*
@@ -3483,7 +3490,7 @@ xlog_recover_finish(
                if (error < 0) {
                        xfs_alert(log->l_mp,
        "Failed to clear log incompat features on recovery");
-                       return error;
+                       goto out_error;
                }
        }
 
@@ -3508,9 +3515,12 @@ xlog_recover_finish(
                 * and AIL.
                 */
                xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
+               goto out_error;
        }
 
-       return 0;
+out_error:
+       memalloc_nofs_restore(nofs_flags);
+       return error;
 }
 
 void
index d850b9685f7f78146f96276cce281536d62db832..14919b33e4fe2274832b762842488cc70a6dfda7 100644 (file)
@@ -425,7 +425,7 @@ xfs_cui_recover_work(
        struct xfs_refcount_intent      *ri;
 
        ri = kmem_cache_alloc(xfs_refcount_intent_cache,
-                       GFP_NOFS | __GFP_NOFAIL);
+                       GFP_KERNEL | __GFP_NOFAIL);
        ri->ri_type = pmap->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK;
        ri->ri_startblock = pmap->pe_startblock;
        ri->ri_blockcount = pmap->pe_len;
index a40b92ac81e8e79b24affa1af4cd628a0b332680..e473124e29ccbdc87bb7ba97bce09ccffbad813f 100644 (file)
@@ -455,7 +455,7 @@ xfs_rui_recover_work(
 {
        struct xfs_rmap_intent          *ri;
 
-       ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+       ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
 
        switch (map->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {
        case XFS_RMAP_EXTENT_MAP: