Skip to content

Commit

Permalink
gfs2: Defer deleting inodes under memory pressure
Browse files Browse the repository at this point in the history
When under memory pressure and an inode's link count has dropped to
zero, defer deleting the inode to the delete workqueue.  This avoids
calling into DLM under memory pressure, which can deadlock.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
  • Loading branch information
Andreas Gruenbacher authored and Bob Peterson committed Aug 10, 2017
1 parent 71c1b21 commit 6a1c8f6
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,23 @@ static int gfs2_drop_inode(struct inode *inode)
if (test_bit(GLF_DEMOTE, &gl->gl_flags))
clear_nlink(inode);
}

/*
* When under memory pressure when an inode's link count has dropped to
* zero, defer deleting the inode to the delete workqueue. This avoids
* calling into DLM under memory pressure, which can deadlock.
*/
if (!inode->i_nlink &&
unlikely(current->flags & PF_MEMALLOC) &&
gfs2_holder_initialized(&ip->i_iopen_gh)) {
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;

gfs2_glock_hold(gl);
if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
gfs2_glock_queue_put(gl);
return false;
}

return generic_drop_inode(inode);
}

Expand Down Expand Up @@ -1561,6 +1578,10 @@ static void gfs2_evict_inode(struct inode *inode)
goto alloc_failed;
}

/* Deletes should never happen under memory pressure anymore. */
if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
goto out;

/* Must not read inode block until block type has been verified */
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh);
if (unlikely(error)) {
Expand Down

0 comments on commit 6a1c8f6

Please sign in to comment.