From e39689e3e3f73d94dc6f66626fdef31f6074ca15 Mon Sep 17 00:00:00 2001 From: Kairui Song Date: Thu, 1 Aug 2024 17:59:17 +0800 Subject: [PATCH] mm-swap-add-a-adaptive-full-cluster-cache-reclaim-fix fix discard of full cluster Link: https://lkml.kernel.org/r/CAMgjq7CWwK75_2Zi5P40K08pk9iqOcuWKL6khu=x4Yg_nXaQag@mail.gmail.com Signed-off-by: Kairui Song Reported-by: David Hildenbrand Closes: https://lkml.kernel.org/r/3c79021a-e9a0-4669-a4e7-7060edf12d58@redhat.com Cc: Barry Song <21cnbao@gmail.com> Cc: Chris Li Cc: "Huang, Ying" Cc: Hugh Dickins Cc: Kalesh Singh Cc: Ryan Roberts Signed-off-by: Andrew Morton --- include/linux/swap.h | 1 + mm/swapfile.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/linux/swap.h b/include/linux/swap.h index 476354391a24..1c8f844a9f0f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -260,6 +260,7 @@ struct swap_cluster_info { #define CLUSTER_FLAG_FREE 1 /* This cluster is free */ #define CLUSTER_FLAG_NONFULL 2 /* This cluster is on nonfull list */ #define CLUSTER_FLAG_FRAG 4 /* This cluster is on nonfull list */ +#define CLUSTER_FLAG_FULL 8 /* This cluster is on full list */ /* * The first page in the swap file is the swap header, which is always marked diff --git a/mm/swapfile.c b/mm/swapfile.c index 38f35aaf1fc2..6de12d712c7e 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -450,7 +450,10 @@ static void __free_cluster(struct swap_info_struct *si, struct swap_cluster_info lockdep_assert_held(&si->lock); lockdep_assert_held(&ci->lock); - list_move_tail(&ci->list, &si->free_clusters); + if (ci->flags) + list_move_tail(&ci->list, &si->free_clusters); + else + list_add_tail(&ci->list, &si->free_clusters); ci->flags = CLUSTER_FLAG_FREE; ci->order = 0; } @@ -474,7 +477,6 @@ static void swap_do_scheduled_discard(struct swap_info_struct *si) SWAPFILE_CLUSTER); spin_lock(&si->lock); - spin_lock(&ci->lock); __free_cluster(si, ci); memset(si->swap_map + idx * SWAPFILE_CLUSTER, @@ -666,7 +668,7 @@ static void cluster_alloc_range(struct swap_info_struct *si, struct swap_cluster if (ci->flags & CLUSTER_FLAG_FRAG) si->frag_cluster_nr[ci->order]--; list_move_tail(&ci->list, &si->full_clusters); - ci->flags = 0; + ci->flags = CLUSTER_FLAG_FULL; } } -- 2.50.1