* [PATCH v3 0/2] mm/swapfile.c and swap.h cleanup
@ 2025-08-12 7:10 Chris Li
2025-08-12 7:10 ` [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list() Chris Li
2025-08-12 7:10 ` [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments Chris Li
0 siblings, 2 replies; 9+ messages in thread
From: Chris Li @ 2025-08-12 7:10 UTC (permalink / raw)
To: Andrew Morton, Kemeng Shi, Kairui Song, Nhat Pham, Baoquan He,
Barry Song, Huang, Ying
Cc: linux-mm, linux-kernel, Chris Li
This patch series, which builds on Kairui's swap improve cluster scan series.
https://lore.kernel.org/linux-mm/20250806161748.76651-1-ryncsn@gmail.com/
It introduces a new function, alloc_swap_scan_list(), for swapfile.c.
It also cleans up swap.h by removing comments that reference fields that
have been deleted.
There are no functional changes in this two-patch series.
Signed-off-by: Chris Li <chrisl@kernel.org>
---
Changes in v3:
- Fix a few scan_all argument to match having while loop or not.
- Update comment message.
- Add a ptach to clean up the comments in swap.h
- Link to v2: https://lore.kernel.org/r/20250808-swap-scan-list-v2-1-d50e4758ecee@kernel.org
Changes in v2:
- Adjust change base on Andrew's feedback on int type and break out of
loop.
- Link to v1: https://lore.kernel.org/r/20250806-swap-scan-list-v1-1-a5fe2d9340a2@kernel.org
---
Chris Li (2):
mm/swapfile.c: introduce function alloc_swap_scan_list()
mm: swap.h: Remove deleted field from comments
include/linux/swap.h | 7 ++---
mm/swapfile.c | 86 ++++++++++++++++++++++++++++------------------------
2 files changed, 49 insertions(+), 44 deletions(-)
---
base-commit: f89484324d5876ee10765fa61da0332899fa1a6a
change-id: 20250806-swap-scan-list-2b89e3424b0a
Best regards,
--
Chris Li <chrisl@kernel.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list()
2025-08-12 7:10 [PATCH v3 0/2] mm/swapfile.c and swap.h cleanup Chris Li
@ 2025-08-12 7:10 ` Chris Li
2025-08-12 16:56 ` Kairui Song
2025-08-13 14:57 ` Nhat Pham
2025-08-12 7:10 ` [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments Chris Li
1 sibling, 2 replies; 9+ messages in thread
From: Chris Li @ 2025-08-12 7:10 UTC (permalink / raw)
To: Andrew Morton, Kemeng Shi, Kairui Song, Nhat Pham, Baoquan He,
Barry Song, Huang, Ying
Cc: linux-mm, linux-kernel, Chris Li
alloc_swap_scan_list() will scan the whole list or the first cluster.
This reduces the repeat patterns of isolating a cluster then scanning that
cluster. As a result, cluster_alloc_swap_entry() is shorter and shallower.
No functional change.
Signed-off-by: Chris Li <chrisl@kernel.org>
---
mm/swapfile.c | 86 ++++++++++++++++++++++++++++++++---------------------------
1 file changed, 47 insertions(+), 39 deletions(-)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 4a0cf4fb348d..a7ffabbe65ef 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -820,6 +820,29 @@ static unsigned int alloc_swap_scan_cluster(struct swap_info_struct *si,
return found;
}
+static unsigned int alloc_swap_scan_list(struct swap_info_struct *si,
+ struct list_head *list,
+ unsigned int order,
+ unsigned char usage,
+ bool scan_all)
+{
+ unsigned int found = SWAP_ENTRY_INVALID;
+
+ do {
+ struct swap_cluster_info *ci = isolate_lock_cluster(si, list);
+ unsigned long offset;
+
+ if (!ci)
+ break;
+ offset = cluster_offset(si, ci);
+ found = alloc_swap_scan_cluster(si, ci, offset, order, usage);
+ if (found)
+ break;
+ } while (scan_all);
+
+ return found;
+}
+
static void swap_reclaim_full_clusters(struct swap_info_struct *si, bool force)
{
long to_scan = 1;
@@ -913,32 +936,24 @@ static unsigned long cluster_alloc_swap_entry(struct swap_info_struct *si, int o
* to spread out the writes.
*/
if (si->flags & SWP_PAGE_DISCARD) {
- ci = isolate_lock_cluster(si, &si->free_clusters);
- if (ci) {
- found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
- order, usage);
- if (found)
- goto done;
- }
+ found = alloc_swap_scan_list(si, &si->free_clusters, order, usage,
+ false);
+ if (found)
+ goto done;
}
if (order < PMD_ORDER) {
- while ((ci = isolate_lock_cluster(si, &si->nonfull_clusters[order]))) {
- found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
- order, usage);
- if (found)
- goto done;
- }
+ found = alloc_swap_scan_list(si, &si->nonfull_clusters[order],
+ order, usage, true);
+ if (found)
+ goto done;
}
if (!(si->flags & SWP_PAGE_DISCARD)) {
- ci = isolate_lock_cluster(si, &si->free_clusters);
- if (ci) {
- found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
- order, usage);
- if (found)
- goto done;
- }
+ found = alloc_swap_scan_list(si, &si->free_clusters, order, usage,
+ false);
+ if (found)
+ goto done;
}
/* Try reclaim full clusters if free and nonfull lists are drained */
@@ -952,13 +967,10 @@ static unsigned long cluster_alloc_swap_entry(struct swap_info_struct *si, int o
* failure is not critical. Scanning one cluster still
* keeps the list rotated and reclaimed (for HAS_CACHE).
*/
- ci = isolate_lock_cluster(si, &si->frag_clusters[order]);
- if (ci) {
- found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
- order, usage);
- if (found)
- goto done;
- }
+ found = alloc_swap_scan_list(si, &si->frag_clusters[order], order,
+ usage, false);
+ if (found)
+ goto done;
}
/*
@@ -977,19 +989,15 @@ static unsigned long cluster_alloc_swap_entry(struct swap_info_struct *si, int o
* Clusters here have at least one usable slots and can't fail order 0
* allocation, but reclaim may drop si->lock and race with another user.
*/
- while ((ci = isolate_lock_cluster(si, &si->frag_clusters[o]))) {
- found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
- 0, usage);
- if (found)
- goto done;
- }
+ found = alloc_swap_scan_list(si, &si->frag_clusters[o],
+ 0, usage, true);
+ if (found)
+ goto done;
- while ((ci = isolate_lock_cluster(si, &si->nonfull_clusters[o]))) {
- found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
- 0, usage);
- if (found)
- goto done;
- }
+ found = alloc_swap_scan_list(si, &si->nonfull_clusters[o],
+ 0, usage, true);
+ if (found)
+ goto done;
}
done:
if (!(si->flags & SWP_SOLIDSTATE))
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments
2025-08-12 7:10 [PATCH v3 0/2] mm/swapfile.c and swap.h cleanup Chris Li
2025-08-12 7:10 ` [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list() Chris Li
@ 2025-08-12 7:10 ` Chris Li
2025-08-12 17:04 ` Kairui Song
` (2 more replies)
1 sibling, 3 replies; 9+ messages in thread
From: Chris Li @ 2025-08-12 7:10 UTC (permalink / raw)
To: Andrew Morton, Kemeng Shi, Kairui Song, Nhat Pham, Baoquan He,
Barry Song, Huang, Ying
Cc: linux-mm, linux-kernel, Chris Li
The comment for struct swap_info_struct.lock incorrectly mentions fields
that have already been deleted from the structure.
Updates the comments to accurately reflect the current struct
swap_info_struct.
There is no functional change.
Signed-off-by: Chris Li <chrisl@kernel.org>
---
include/linux/swap.h | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/include/linux/swap.h b/include/linux/swap.h
index a060d102e0d1..c2da85cb7fe7 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -320,11 +320,8 @@ struct swap_info_struct {
struct completion comp; /* seldom referenced */
spinlock_t lock; /*
* protect map scan related fields like
- * swap_map, lowest_bit, highest_bit,
- * inuse_pages, cluster_next,
- * cluster_nr, lowest_alloc,
- * highest_alloc, free/discard cluster
- * list. other fields are only changed
+ * swap_map, inuse_pages and all cluster
+ * lists. other fields are only changed
* at swapon/swapoff, so are protected
* by swap_lock. changing flags need
* hold this lock and swap_lock. If
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list()
2025-08-12 7:10 ` [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list() Chris Li
@ 2025-08-12 16:56 ` Kairui Song
2025-08-13 6:13 ` Chris Li
2025-08-13 14:57 ` Nhat Pham
1 sibling, 1 reply; 9+ messages in thread
From: Kairui Song @ 2025-08-12 16:56 UTC (permalink / raw)
To: Chris Li
Cc: Andrew Morton, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Huang, Ying, linux-mm, linux-kernel
On Tue, Aug 12, 2025 at 5:13 PM Chris Li <chrisl@kernel.org> wrote:
>
> alloc_swap_scan_list() will scan the whole list or the first cluster.
>
> This reduces the repeat patterns of isolating a cluster then scanning that
> cluster. As a result, cluster_alloc_swap_entry() is shorter and shallower.
>
> No functional change.
>
> Signed-off-by: Chris Li <chrisl@kernel.org>
> ---
> mm/swapfile.c | 86 ++++++++++++++++++++++++++++++++---------------------------
> 1 file changed, 47 insertions(+), 39 deletions(-)
>
> diff --git a/mm/swapfile.c b/mm/swapfile.c
> index 4a0cf4fb348d..a7ffabbe65ef 100644
> --- a/mm/swapfile.c
> +++ b/mm/swapfile.c
> @@ -820,6 +820,29 @@ static unsigned int alloc_swap_scan_cluster(struct swap_info_struct *si,
> return found;
> }
>
> +static unsigned int alloc_swap_scan_list(struct swap_info_struct *si,
> + struct list_head *list,
> + unsigned int order,
> + unsigned char usage,
> + bool scan_all)
> +{
> + unsigned int found = SWAP_ENTRY_INVALID;
> +
> + do {
> + struct swap_cluster_info *ci = isolate_lock_cluster(si, list);
> + unsigned long offset;
> +
> + if (!ci)
> + break;
> + offset = cluster_offset(si, ci);
> + found = alloc_swap_scan_cluster(si, ci, offset, order, usage);
> + if (found)
> + break;
> + } while (scan_all);
> +
> + return found;
> +}
> +
> static void swap_reclaim_full_clusters(struct swap_info_struct *si, bool force)
> {
> long to_scan = 1;
> @@ -913,32 +936,24 @@ static unsigned long cluster_alloc_swap_entry(struct swap_info_struct *si, int o
> * to spread out the writes.
> */
> if (si->flags & SWP_PAGE_DISCARD) {
> - ci = isolate_lock_cluster(si, &si->free_clusters);
> - if (ci) {
> - found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
> - order, usage);
> - if (found)
> - goto done;
> - }
> + found = alloc_swap_scan_list(si, &si->free_clusters, order, usage,
> + false);
> + if (found)
> + goto done;
> }
>
> if (order < PMD_ORDER) {
> - while ((ci = isolate_lock_cluster(si, &si->nonfull_clusters[order]))) {
> - found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
> - order, usage);
> - if (found)
> - goto done;
> - }
> + found = alloc_swap_scan_list(si, &si->nonfull_clusters[order],
> + order, usage, true);
> + if (found)
> + goto done;
> }
>
> if (!(si->flags & SWP_PAGE_DISCARD)) {
> - ci = isolate_lock_cluster(si, &si->free_clusters);
> - if (ci) {
> - found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
> - order, usage);
> - if (found)
> - goto done;
> - }
> + found = alloc_swap_scan_list(si, &si->free_clusters, order, usage,
> + false);
> + if (found)
> + goto done;
> }
>
> /* Try reclaim full clusters if free and nonfull lists are drained */
> @@ -952,13 +967,10 @@ static unsigned long cluster_alloc_swap_entry(struct swap_info_struct *si, int o
> * failure is not critical. Scanning one cluster still
> * keeps the list rotated and reclaimed (for HAS_CACHE).
> */
> - ci = isolate_lock_cluster(si, &si->frag_clusters[order]);
> - if (ci) {
> - found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
> - order, usage);
> - if (found)
> - goto done;
> - }
> + found = alloc_swap_scan_list(si, &si->frag_clusters[order], order,
> + usage, false);
> + if (found)
> + goto done;
> }
>
> /*
> @@ -977,19 +989,15 @@ static unsigned long cluster_alloc_swap_entry(struct swap_info_struct *si, int o
> * Clusters here have at least one usable slots and can't fail order 0
> * allocation, but reclaim may drop si->lock and race with another user.
> */
> - while ((ci = isolate_lock_cluster(si, &si->frag_clusters[o]))) {
> - found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
> - 0, usage);
> - if (found)
> - goto done;
> - }
> + found = alloc_swap_scan_list(si, &si->frag_clusters[o],
> + 0, usage, true);
> + if (found)
> + goto done;
>
> - while ((ci = isolate_lock_cluster(si, &si->nonfull_clusters[o]))) {
> - found = alloc_swap_scan_cluster(si, ci, cluster_offset(si, ci),
> - 0, usage);
> - if (found)
> - goto done;
> - }
> + found = alloc_swap_scan_list(si, &si->nonfull_clusters[o],
> + 0, usage, true);
> + if (found)
> + goto done;
> }
> done:
> if (!(si->flags & SWP_SOLIDSTATE))
>
> --
> 2.43.0
>
I've been testing on top of a locally updated version of V2 for about
two days, and it's identical to this one. This looks great, thanks!
Reviewed-by: Kairui Song <kasong@tencent.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments
2025-08-12 7:10 ` [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments Chris Li
@ 2025-08-12 17:04 ` Kairui Song
2025-08-13 11:05 ` Barry Song
2025-08-13 14:58 ` Nhat Pham
2 siblings, 0 replies; 9+ messages in thread
From: Kairui Song @ 2025-08-12 17:04 UTC (permalink / raw)
To: Chris Li
Cc: Andrew Morton, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Huang, Ying, linux-mm, linux-kernel
On Tue, Aug 12, 2025 at 3:26 PM Chris Li <chrisl@kernel.org> wrote:
>
> The comment for struct swap_info_struct.lock incorrectly mentions fields
> that have already been deleted from the structure.
>
> Updates the comments to accurately reflect the current struct
> swap_info_struct.
>
> There is no functional change.
>
> Signed-off-by: Chris Li <chrisl@kernel.org>
> ---
> include/linux/swap.h | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index a060d102e0d1..c2da85cb7fe7 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -320,11 +320,8 @@ struct swap_info_struct {
> struct completion comp; /* seldom referenced */
> spinlock_t lock; /*
> * protect map scan related fields like
> - * swap_map, lowest_bit, highest_bit,
> - * inuse_pages, cluster_next,
> - * cluster_nr, lowest_alloc,
> - * highest_alloc, free/discard cluster
> - * list. other fields are only changed
> + * swap_map, inuse_pages and all cluster
> + * lists. other fields are only changed
> * at swapon/swapoff, so are protected
> * by swap_lock. changing flags need
> * hold this lock and swap_lock. If
>
> --
> 2.43.0
>
Thanks.
Reviewed-by: Kairui Song <kasong@tencent.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list()
2025-08-12 16:56 ` Kairui Song
@ 2025-08-13 6:13 ` Chris Li
0 siblings, 0 replies; 9+ messages in thread
From: Chris Li @ 2025-08-13 6:13 UTC (permalink / raw)
To: Kairui Song
Cc: Andrew Morton, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Huang, Ying, linux-mm, linux-kernel
On Tue, Aug 12, 2025 at 9:57 AM Kairui Song <ryncsn@gmail.com> wrote:
>
> I've been testing on top of a locally updated version of V2 for about
> two days, and it's identical to this one. This looks great, thanks!
Thanks for the review.
I have been running the swap stress tests on kernel compile as well.
No issue so far.
Chris
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments
2025-08-12 7:10 ` [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments Chris Li
2025-08-12 17:04 ` Kairui Song
@ 2025-08-13 11:05 ` Barry Song
2025-08-13 14:58 ` Nhat Pham
2 siblings, 0 replies; 9+ messages in thread
From: Barry Song @ 2025-08-13 11:05 UTC (permalink / raw)
To: Chris Li
Cc: Andrew Morton, Kemeng Shi, Kairui Song, Nhat Pham, Baoquan He,
Huang, Ying, linux-mm, linux-kernel
On Tue, Aug 12, 2025 at 3:11 PM Chris Li <chrisl@kernel.org> wrote:
>
> The comment for struct swap_info_struct.lock incorrectly mentions fields
> that have already been deleted from the structure.
>
> Updates the comments to accurately reflect the current struct
> swap_info_struct.
>
> There is no functional change.
>
> Signed-off-by: Chris Li <chrisl@kernel.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Thanks
Barry
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list()
2025-08-12 7:10 ` [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list() Chris Li
2025-08-12 16:56 ` Kairui Song
@ 2025-08-13 14:57 ` Nhat Pham
1 sibling, 0 replies; 9+ messages in thread
From: Nhat Pham @ 2025-08-13 14:57 UTC (permalink / raw)
To: Chris Li
Cc: Andrew Morton, Kemeng Shi, Kairui Song, Baoquan He, Barry Song,
Huang, Ying, linux-mm, linux-kernel
On Tue, Aug 12, 2025 at 12:10 AM Chris Li <chrisl@kernel.org> wrote:
>
> alloc_swap_scan_list() will scan the whole list or the first cluster.
>
> This reduces the repeat patterns of isolating a cluster then scanning that
> cluster. As a result, cluster_alloc_swap_entry() is shorter and shallower.
>
> No functional change.
>
> Signed-off-by: Chris Li <chrisl@kernel.org>
Code seems more readable now, IMO. Thanks, Chris!
Acked-by: Nhat Pham <nphamcs@gmail.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments
2025-08-12 7:10 ` [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments Chris Li
2025-08-12 17:04 ` Kairui Song
2025-08-13 11:05 ` Barry Song
@ 2025-08-13 14:58 ` Nhat Pham
2 siblings, 0 replies; 9+ messages in thread
From: Nhat Pham @ 2025-08-13 14:58 UTC (permalink / raw)
To: Chris Li
Cc: Andrew Morton, Kemeng Shi, Kairui Song, Baoquan He, Barry Song,
Huang, Ying, linux-mm, linux-kernel
On Tue, Aug 12, 2025 at 12:11 AM Chris Li <chrisl@kernel.org> wrote:
>
> The comment for struct swap_info_struct.lock incorrectly mentions fields
> that have already been deleted from the structure.
>
> Updates the comments to accurately reflect the current struct
> swap_info_struct.
>
> There is no functional change.
>
> Signed-off-by: Chris Li <chrisl@kernel.org>
Acked-by: Nhat Pham <nphamcs@gmail.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-08-13 14:58 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-12 7:10 [PATCH v3 0/2] mm/swapfile.c and swap.h cleanup Chris Li
2025-08-12 7:10 ` [PATCH v3 1/2] mm/swapfile.c: introduce function alloc_swap_scan_list() Chris Li
2025-08-12 16:56 ` Kairui Song
2025-08-13 6:13 ` Chris Li
2025-08-13 14:57 ` Nhat Pham
2025-08-12 7:10 ` [PATCH v3 2/2] mm: swap.h: Remove deleted field from comments Chris Li
2025-08-12 17:04 ` Kairui Song
2025-08-13 11:05 ` Barry Song
2025-08-13 14:58 ` Nhat Pham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).