summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2019-04-18 20:50:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-04-19 12:46:04 -0400
commitdd862deb151aad2548e72b077a82ad3aa91b715f (patch)
treed756b2e12e163387da4a07d8c7dc5ab304015ce7 /mm
parent87039546544479d4bedb19d0ea525270c43c1c9b (diff)
mm: swapoff: remove too limiting SWAP_UNUSE_MAX_TRIES
SWAP_UNUSE_MAX_TRIES 3 appeared to work well in earlier testing, but further testing has proved it to be a source of unnecessary swapoff EBUSY failures (which can then be followed by unmount EBUSY failures). When mmget_not_zero() or shmem's igrab() fails, there is an mm exiting or inode being evicted, freeing up swap independent of try_to_unuse(). Those typically completed much sooner than the old quadratic swapoff, but now it's more common that swapoff may need to wait for them. It's possible to move those cases from init_mm.mmlist and shmem_swaplist to separate "exiting" swaplists, and try_to_unuse() then wait for those lists to be emptied; but we've not bothered with that in the past, and don't want to risk missing some other forgotten case. So just revert to cycling around until the swap is gone, without any retries limit. Link: http://lkml.kernel.org/r/alpine.LSU.2.11.1904081256170.1523@eggly.anvils Fixes: b56a2d8af914 ("mm: rid swapoff of quadratic complexity") Signed-off-by: Hugh Dickins <hughd@google.com> Cc: "Alex Xu (Hello71)" <alex_y_xu@yahoo.ca> Cc: Huang Ying <ying.huang@intel.com> Cc: Kelley Nielsen <kelleynnn@gmail.com> Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Cc: Rik van Riel <riel@surriel.com> Cc: Vineeth Pillai <vpillai@digitalocean.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/swapfile.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 2b8d9c3fbb47..bf4ef2e40f23 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2023,7 +2023,6 @@ static unsigned int find_next_to_unuse(struct swap_info_struct *si,
2023 * If the boolean frontswap is true, only unuse pages_to_unuse pages; 2023 * If the boolean frontswap is true, only unuse pages_to_unuse pages;
2024 * pages_to_unuse==0 means all pages; ignored if frontswap is false 2024 * pages_to_unuse==0 means all pages; ignored if frontswap is false
2025 */ 2025 */
2026#define SWAP_UNUSE_MAX_TRIES 3
2027int try_to_unuse(unsigned int type, bool frontswap, 2026int try_to_unuse(unsigned int type, bool frontswap,
2028 unsigned long pages_to_unuse) 2027 unsigned long pages_to_unuse)
2029{ 2028{
@@ -2035,7 +2034,6 @@ int try_to_unuse(unsigned int type, bool frontswap,
2035 struct page *page; 2034 struct page *page;
2036 swp_entry_t entry; 2035 swp_entry_t entry;
2037 unsigned int i; 2036 unsigned int i;
2038 int retries = 0;
2039 2037
2040 if (!si->inuse_pages) 2038 if (!si->inuse_pages)
2041 return 0; 2039 return 0;
@@ -2117,14 +2115,16 @@ retry:
2117 * If yes, we would need to do retry the unuse logic again. 2115 * If yes, we would need to do retry the unuse logic again.
2118 * Under global memory pressure, swap entries can be reinserted back 2116 * Under global memory pressure, swap entries can be reinserted back
2119 * into process space after the mmlist loop above passes over them. 2117 * into process space after the mmlist loop above passes over them.
2120 * Its not worth continuosuly retrying to unuse the swap in this case. 2118 *
2121 * So we try SWAP_UNUSE_MAX_TRIES times. 2119 * Limit the number of retries? No: when shmem_unuse()'s igrab() fails,
2120 * a shmem inode using swap is being evicted; and when mmget_not_zero()
2121 * above fails, that mm is likely to be freeing swap from exit_mmap().
2122 * Both proceed at their own independent pace: we could move them to
2123 * separate lists, and wait for those lists to be emptied; but it's
2124 * easier and more robust (though cpu-intensive) just to keep retrying.
2122 */ 2125 */
2123 if (++retries >= SWAP_UNUSE_MAX_TRIES) 2126 if (si->inuse_pages)
2124 retval = -EBUSY;
2125 else if (si->inuse_pages)
2126 goto retry; 2127 goto retry;
2127
2128out: 2128out:
2129 return (retval == FRONTSWAP_PAGES_UNUSED) ? 0 : retval; 2129 return (retval == FRONTSWAP_PAGES_UNUSED) ? 0 : retval;
2130} 2130}