Skip to content

Commit

Permalink
xfs: place the CIL under nofs allocation context
Browse files Browse the repository at this point in the history
This is core code that needs to run in low memory conditions and
can be triggered from memory reclaim. While it runs in a workqueue,
it really shouldn't be recursing back into the filesystem during
any memory allocation it needs to function.

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>
  • Loading branch information
Dave Chinner authored and Chandan Babu R committed Feb 13, 2024
1 parent 2c1e31e commit c704ecb
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion fs/xfs/xfs_log_cil.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ xlog_cil_ctx_alloc(void)
{
struct xfs_cil_ctx *ctx;

ctx = kzalloc(sizeof(*ctx), GFP_NOFS | __GFP_NOFAIL);
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL);
INIT_LIST_HEAD(&ctx->committing);
INIT_LIST_HEAD(&ctx->busy_extents.extent_list);
INIT_LIST_HEAD(&ctx->log_items);
Expand Down Expand Up @@ -1116,11 +1116,18 @@ xlog_cil_cleanup_whiteouts(
* same sequence twice. If we get a race between multiple pushes for the same
* sequence they will block on the first one and then abort, hence avoiding
* needless pushes.
*
* This runs from a workqueue so it does not inherent any specific memory
* allocation context. However, we do not want to block on memory reclaim
* recursing back into the filesystem because this push may have been triggered
* by memory reclaim itself. Hence we really need to run under full GFP_NOFS
* contraints here.
*/
static void
xlog_cil_push_work(
struct work_struct *work)
{
unsigned int nofs_flags = memalloc_nofs_save();
struct xfs_cil_ctx *ctx =
container_of(work, struct xfs_cil_ctx, push_work);
struct xfs_cil *cil = ctx->cil;
Expand Down Expand Up @@ -1334,12 +1341,14 @@ xlog_cil_push_work(
spin_unlock(&log->l_icloglock);
xlog_cil_cleanup_whiteouts(&whiteouts);
xfs_log_ticket_ungrant(log, ticket);
memalloc_nofs_restore(nofs_flags);
return;

out_skip:
up_write(&cil->xc_ctx_lock);
xfs_log_ticket_put(new_ctx->ticket);
kfree(new_ctx);
memalloc_nofs_restore(nofs_flags);
return;

out_abort_free_ticket:
Expand All @@ -1348,6 +1357,7 @@ xlog_cil_push_work(
if (!ctx->commit_iclog) {
xfs_log_ticket_ungrant(log, ctx->ticket);
xlog_cil_committed(ctx);
memalloc_nofs_restore(nofs_flags);
return;
}
spin_lock(&log->l_icloglock);
Expand All @@ -1356,6 +1366,7 @@ xlog_cil_push_work(
/* Not safe to reference ctx now! */
spin_unlock(&log->l_icloglock);
xfs_log_ticket_ungrant(log, ticket);
memalloc_nofs_restore(nofs_flags);
}

/*
Expand Down

0 comments on commit c704ecb

Please sign in to comment.