|
Takashi Iwai |
379d25 |
From d130b5fdd42254d92948d06347940276140c927e Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
379d25 |
From: David Howells <dhowells@redhat.com>
|
|
Takashi Iwai |
379d25 |
Date: Wed, 1 Sep 2021 09:15:21 +0100
|
|
Takashi Iwai |
379d25 |
Subject: [PATCH] afs: Fix page leak
|
|
Takashi Iwai |
379d25 |
Git-commit: 581b2027af0018944ba301d68e7af45c6d1128b5
|
|
Takashi Iwai |
379d25 |
Patch-mainline: v5.15-rc3
|
|
Takashi Iwai |
379d25 |
References: stable-5.14.9
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
[ Upstream commit 581b2027af0018944ba301d68e7af45c6d1128b5 ]
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
There's a loop in afs_extend_writeback() that adds extra pages to a write
|
|
Takashi Iwai |
379d25 |
we want to make to improve the efficiency of the writeback by making it
|
|
Takashi Iwai |
379d25 |
larger. This loop stops, however, if we hit a page we can't write back
|
|
Takashi Iwai |
379d25 |
from immediately, but it doesn't get rid of the page ref we speculatively
|
|
Takashi Iwai |
379d25 |
acquired.
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
This was caused by the removal of the cleanup loop when the code switched
|
|
Takashi Iwai |
379d25 |
from using find_get_pages_contig() to xarray scanning as the latter only
|
|
Takashi Iwai |
379d25 |
gets a single page at a time, not a batch.
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
Fix this by putting the page on a ref on an early break from the loop.
|
|
Takashi Iwai |
379d25 |
Unfortunately, we can't just add that page to the pagevec we're employing
|
|
Takashi Iwai |
379d25 |
as we'll go through that and add those pages to the RPC call.
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
This was found by the generic/074 test. It leaks ~4GiB of RAM each time it
|
|
Takashi Iwai |
379d25 |
is run - which can be observed with "top".
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
Fixes: e87b03f5830e ("afs: Prepare for use of THPs")
|
|
Takashi Iwai |
379d25 |
Reported-by: Marc Dionne <marc.dionne@auristor.com>
|
|
Takashi Iwai |
379d25 |
Signed-off-by: David Howells <dhowells@redhat.com>
|
|
Takashi Iwai |
379d25 |
Reviewed-and-tested-by: Marc Dionne <marc.dionne@auristor.com>
|
|
Takashi Iwai |
379d25 |
Cc: linux-afs@lists.infradead.org
|
|
Takashi Iwai |
379d25 |
Link: https://lore.kernel.org/r/163111666635.283156.177701903478910460.stgit@warthog.procyon.org.uk/
|
|
Takashi Iwai |
379d25 |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Takashi Iwai |
379d25 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
---
|
|
Takashi Iwai |
379d25 |
fs/afs/write.c | 10 ++++++++--
|
|
Takashi Iwai |
379d25 |
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
diff --git a/fs/afs/write.c b/fs/afs/write.c
|
|
Takashi Iwai |
379d25 |
index c0534697268e..66b235266893 100644
|
|
Takashi Iwai |
379d25 |
--- a/fs/afs/write.c
|
|
Takashi Iwai |
379d25 |
+++ b/fs/afs/write.c
|
|
Takashi Iwai |
379d25 |
@@ -471,13 +471,18 @@ static void afs_extend_writeback(struct address_space *mapping,
|
|
Takashi Iwai |
379d25 |
}
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
/* Has the page moved or been split? */
|
|
Takashi Iwai |
379d25 |
- if (unlikely(page != xas_reload(&xas)))
|
|
Takashi Iwai |
379d25 |
+ if (unlikely(page != xas_reload(&xas))) {
|
|
Takashi Iwai |
379d25 |
+ put_page(page);
|
|
Takashi Iwai |
379d25 |
break;
|
|
Takashi Iwai |
379d25 |
+ }
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
- if (!trylock_page(page))
|
|
Takashi Iwai |
379d25 |
+ if (!trylock_page(page)) {
|
|
Takashi Iwai |
379d25 |
+ put_page(page);
|
|
Takashi Iwai |
379d25 |
break;
|
|
Takashi Iwai |
379d25 |
+ }
|
|
Takashi Iwai |
379d25 |
if (!PageDirty(page) || PageWriteback(page)) {
|
|
Takashi Iwai |
379d25 |
unlock_page(page);
|
|
Takashi Iwai |
379d25 |
+ put_page(page);
|
|
Takashi Iwai |
379d25 |
break;
|
|
Takashi Iwai |
379d25 |
}
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
@@ -487,6 +492,7 @@ static void afs_extend_writeback(struct address_space *mapping,
|
|
Takashi Iwai |
379d25 |
t = afs_page_dirty_to(page, priv);
|
|
Takashi Iwai |
379d25 |
if (f != 0 && !new_content) {
|
|
Takashi Iwai |
379d25 |
unlock_page(page);
|
|
Takashi Iwai |
379d25 |
+ put_page(page);
|
|
Takashi Iwai |
379d25 |
break;
|
|
Takashi Iwai |
379d25 |
}
|
|
Takashi Iwai |
379d25 |
|
|
Takashi Iwai |
379d25 |
--
|
|
Takashi Iwai |
379d25 |
2.26.2
|
|
Takashi Iwai |
379d25 |
|