From: Lian Wang <lianux.mm@gmail.com>
To: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
Chris Li <chrisl@kernel.org>, Nhat Pham <nphamcs@gmail.com>,
Baoquan He <baoquan.he@linux.dev>, Barry Song <baohua@kernel.org>,
Youngjun Park <youngjun.park@lge.com>,
Kemeng Shi <shikemeng@huaweicloud.com>,
Kairui Song <kasong@tencent.com>, Jihan LIN <linjh22s@gmail.com>,
Kunwu Chan <kunwu.chan@linux.dev>, Kees Cook <kees@kernel.org>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Thomas Gleixner <tglx@kernel.org>,
linux-hardening@vger.kernel.org
Subject: [RFC PATCH v4 07/18] mm/swap: consolidate swap inuse accounting helpers
Date: Sat, 14 Nov 2026 22:50:09 +0800 [thread overview]
Message-ID: <4e554bbb557d0456c953d73f008875f6d983b12f.1794666741.git.lianux.mm@gmail.com> (raw)
In-Reply-To: <cover.1794666741.git.lianux.mm@gmail.com>
From: Kairui Song <kasong@tencent.com>
Inline the swap_usage_add/sub helpers into their only callers and
rename the callers to better reflect what they actually do: track
per-device inuse page counts.
Keep the existing accounting and allocation policy. In the inlined
full-device path, reclaim work is scheduled before availability removal
rather than afterwards. Slot-free notifications and zswap invalidation
retain their existing order.
Signed-off-by: Kairui Song <kasong@tencent.com>
Signed-off-by: Lian Wang <lianux.mm@gmail.com>
---
mm/swapfile.c | 64 ++++++++++++++++++++++-----------------------------
1 file changed, 27 insertions(+), 37 deletions(-)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 277a5c749987..aa020f2706b4 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -49,8 +49,8 @@
#include "internal.h"
#include "swap.h"
-static void swap_range_alloc(struct swap_info_struct *si,
- unsigned int nr_entries);
+static void swap_device_inuse_add(struct swap_info_struct *si,
+ unsigned int nr_entries);
static bool folio_swapcache_freeable(struct folio *folio);
static void move_cluster(struct swap_info_struct *si,
struct swap_cluster_info *ci, struct list_head *list,
@@ -1045,7 +1045,7 @@ static bool __swap_cluster_alloc_entries(struct swap_info_struct *si,
if (cluster_is_empty(ci))
ci->order = order;
ci->count += nr_pages;
- swap_range_alloc(si, nr_pages);
+ swap_device_inuse_add(si, nr_pages);
return true;
}
@@ -1363,53 +1363,36 @@ static void add_to_avail_list(struct swap_info_struct *si)
}
/*
- * swap_usage_add / swap_usage_sub of each slot are serialized by ci->lock
- * within each cluster, so the total contribution to the global counter should
- * always be positive and cannot exceed the total number of usable slots.
+ * swap_device_inuse_add / swap_device_inuse_sub are called within cluster
+ * update critical sections and serialized by ci->lock within each cluster,
+ * so the total contribution to the global counter should always be positive
+ * and cannot exceed the total number of usable slots.
*/
-static bool swap_usage_add(struct swap_info_struct *si, unsigned int nr_entries)
+static void swap_device_inuse_add(struct swap_info_struct *si,
+ unsigned int nr_entries)
{
- long val = atomic_long_add_return_relaxed(nr_entries, &si->inuse_pages);
+ long inuse_pages;
/*
* If device is full, and SWAP_USAGE_OFFLIST_BIT is not set,
* remove it from the plist.
*/
- if (unlikely(val == si->pages)) {
- del_from_avail_list(si, false);
- return true;
- }
-
- return false;
-}
-
-static void swap_usage_sub(struct swap_info_struct *si, unsigned int nr_entries)
-{
- long val = atomic_long_sub_return_relaxed(nr_entries, &si->inuse_pages);
-
- /*
- * If device is not full, and SWAP_USAGE_OFFLIST_BIT is set,
- * add it to the plist.
- */
- if (unlikely(val & SWAP_USAGE_OFFLIST_BIT))
- add_to_avail_list(si);
-}
-
-static void swap_range_alloc(struct swap_info_struct *si,
- unsigned int nr_entries)
-{
- if (swap_usage_add(si, nr_entries)) {
+ inuse_pages = atomic_long_add_return_relaxed(nr_entries, &si->inuse_pages);
+ if (unlikely(inuse_pages == si->pages)) {
if (vm_swap_full())
schedule_work(&si->reclaim_work);
+ del_from_avail_list(si, false);
}
+
atomic_long_sub(nr_entries, &nr_swap_pages);
}
-static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
- unsigned int nr_entries)
+static void swap_device_inuse_sub(struct swap_info_struct *si, unsigned long offset,
+ unsigned int nr_entries)
{
unsigned long end = offset + nr_entries - 1;
void (*swap_slot_free_notify)(struct block_device *, unsigned long);
+ long inuse_pages;
zswap_invalidate(si->type, offset, nr_entries);
@@ -1431,7 +1414,14 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
*/
smp_wmb();
atomic_long_add(nr_entries, &nr_swap_pages);
- swap_usage_sub(si, nr_entries);
+
+ /*
+ * If device is not full, and SWAP_USAGE_OFFLIST_BIT is set,
+ * add it back to the plist.
+ */
+ inuse_pages = atomic_long_sub_return_relaxed(nr_entries, &si->inuse_pages);
+ if (unlikely(inuse_pages & SWAP_USAGE_OFFLIST_BIT))
+ add_to_avail_list(si);
}
static bool get_swap_device_info(struct swap_info_struct *si)
@@ -2059,7 +2049,7 @@ void __swap_cluster_free_entries(struct swap_info_struct *si,
if (batch_id)
mem_cgroup_uncharge_swap(batch_id, ci_off - batch_off);
- swap_range_free(si, ci_head + ci_start, nr_pages);
+ swap_device_inuse_sub(si, ci_head + ci_start, nr_pages);
swap_cluster_assert_empty(ci, ci_start, nr_pages, false);
if (!ci->count)
@@ -2999,7 +2989,7 @@ static int try_to_unuse(unsigned int type)
success:
/*
* Make sure that further cleanups after try_to_unuse() returns happen
- * after swap_range_free() reduces si->inuse_pages to 0.
+ * after swap_device_inuse_sub() reduces si->inuse_pages to 0.
*/
smp_mb();
return 0;
next prev parent reply other threads:[~2026-11-14 14:50 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 14:47 [RFC PATCH v4 00/18] mm/swap: introduce priority queues for swap device allocation Lian Wang
2026-11-14 14:48 ` [RFC PATCH v4 01/18] mm/swap: remove unused parameter for reading swap header Lian Wang
2026-11-14 14:49 ` [RFC PATCH v4 02/18] mm/swap: clean up hibernation error handling Lian Wang
2026-11-14 14:49 ` [RFC PATCH v4 03/18] mm/swap: cleanup and document swap device availability flag usage Lian Wang
2026-11-14 14:49 ` [RFC PATCH v4 04/18] mm/swap: introduce swap device iteration helper Lian Wang
2026-11-14 14:49 ` [RFC PATCH v4 05/18] mm/swap: change the swapon lock into a percpu rwsem Lian Wang
2026-11-14 14:49 ` [RFC PATCH v4 06/18] mm/swap: serialize swap publication before removing swapon mutex Lian Wang
2026-11-14 14:50 ` Lian Wang [this message]
2026-11-14 14:50 ` [RFC PATCH v4 08/18] mm/swap: change back to use each swap device's percpu cluster Lian Wang
2026-11-14 14:50 ` [RFC PATCH v4 09/18] mm/swap: avoid direct reclaim when populating swap cluster metadata Lian Wang
2026-11-14 14:50 ` [RFC PATCH v4 10/18] mm/swap: add priority queue for swap device allocation Lian Wang
2026-11-14 14:51 ` [RFC PATCH v4 11/18] mm/swap: remove available list Lian Wang
2026-11-14 14:51 ` [RFC PATCH v4 12/18] mm/swap: bound synchronous discard outside the allocation reader Lian Wang
2026-11-14 14:51 ` [RFC PATCH v4 13/18] mm/swap: drop swap active plist Lian Wang
2026-11-14 14:51 ` [RFC PATCH v4 14/18] lib/plist.c: remove requeue function Lian Wang
2026-11-14 14:52 ` [RFC PATCH v4 15/18] mm/swap: reuse per-CPU queue readers across priority changes Lian Wang
2026-11-14 14:52 ` [RFC PATCH v4 16/18] mm/swap: advance the global queue cursor directly between priority rings Lian Wang
2026-11-14 14:52 ` [RFC PATCH v4 17/18] mm/swap: skip reader rotation for single-device " Lian Wang
2026-11-14 14:52 ` [RFC PATCH v4 18/18] mm/swap: redistribute queue readers after membership changes Lian Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4e554bbb557d0456c953d73f008875f6d983b12f.1794666741.git.lianux.mm@gmail.com \
--to=lianux.mm@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=baoquan.he@linux.dev \
--cc=chrisl@kernel.org \
--cc=gustavoars@kernel.org \
--cc=kasong@tencent.com \
--cc=kees@kernel.org \
--cc=kunwu.chan@linux.dev \
--cc=linjh22s@gmail.com \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=shikemeng@huaweicloud.com \
--cc=tglx@kernel.org \
--cc=youngjun.park@lge.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®