Skip to content

Commit

Permalink
z3fold: fix potential race in z3fold_reclaim_page
Browse files Browse the repository at this point in the history
It is possible that on a (partially) unsuccessful page reclaim,
kref_put() called in z3fold_reclaim_page() does not yield page release,
but the page is released shortly afterwards by another thread.  Then
z3fold_reclaim_page() would try to list_add() that (released) page again
which is obviously a bug.

To avoid that, spin_lock() has to be taken earlier, before the
kref_put() call mentioned earlier.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Vitaly Wool <[email protected]>
Cc: Dan Streetman <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
vwool authored and torvalds committed Oct 4, 2017
1 parent d9d73e8 commit d5567c9
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion mm/z3fold.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,16 +875,18 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries)
goto next;
}
next:
spin_lock(&pool->lock);
if (test_bit(PAGE_HEADLESS, &page->private)) {
if (ret == 0) {
spin_unlock(&pool->lock);
free_z3fold_page(page);
return 0;
}
} else if (kref_put(&zhdr->refcount, release_z3fold_page)) {
atomic64_dec(&pool->pages_nr);
spin_unlock(&pool->lock);
return 0;
}
spin_lock(&pool->lock);

/*
* Add to the beginning of LRU.
Expand Down

0 comments on commit d5567c9

Please sign in to comment.