From: Baoquan He <baoquan.he@linux.dev>
To: Christoph Hellwig <hch@lst.de>
Cc: akpm@linux-foundation.org, chrisl@kernel.org,
usama.arif@linux.dev, kasong@tencent.com, nphamcs@gmail.com,
shikemeng@huaweicloud.com, youngjun.park@lge.com,
linux-mm@kvack.org
Subject: Re: [PATCH 7/8] mm/swap: remove SWP_FS_OPS
Date: Fri, 5 Jun 2026 13:21:42 +0800 [thread overview]
Message-ID: <aiJc5pPU_kvxs0a7@MiWiFi-R3L-srv> (raw)
In-Reply-To: <20260601113449.3464734-8-hch@lst.de>
On 06/01/26 at 01:34pm, Christoph Hellwig wrote:
...snip...
> diff --git a/mm/swap.h b/mm/swap.h
> index 5119feff0e93..edb512e619ee 100644
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -84,7 +84,11 @@ struct swap_io_ctx {
> struct swap_info_struct *sis;
> };
>
> +#define SWAP_OPS_F_NOFS (1U << 0)
> +
The name of this flag and its usage are a little weird, surely the old
one SWP_FS_OPS is similar. Do you think if we need add some document
as below to make it clearer? Personal opinion and just for reference.
diff --git a/mm/swap.h b/mm/swap.h
index edb512e619ee..3d978382a7d5 100644
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -84,6 +84,18 @@ struct swap_io_ctx {
struct swap_info_struct *sis;
};
+/*
+ * SWAP_OPS_F_NOFS: swap operations that may recurse into the filesystem
+ * (e.g. NFS, CIFS). When set, callers (specifically reclaim) must operate
+ * under GFP_NOFS / !__GFP_FS to avoid deadlock. When clear (block-device
+ * swap), the swap I/O path does not touch the filesystem, so reclaim may
+ * safely enter the filesystem even with only __GFP_IO.
+ *
+ * In may_enter_fs() this appears as a double negative (!SWAP_OPS_F_NOFS)
+ * which reads as "not a nofs swap => may enter fs". This is intentional:
+ * it is bdev swap (the common case) that allows filesystem re-entry, while
+ * filesystem-based swap explicitly forbids it.
+ */
#define SWAP_OPS_F_NOFS (1U << 0)
struct swap_ops {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2d44ebfebdea..a92956de5e10 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1039,7 +1039,9 @@ static bool may_enter_fs(struct folio *folio, gfp_t gfp_mask)
return true;
/*
* We can "enter_fs" for swap-cache with only __GFP_IO unless backed by
- * a swapfile that requires GFP_NOFS I/O.
+ * a swapfile that requires GFP_NOFS I/O (i.e. filesystem-based swap
+ * like NFS/CIFS, which sets SWAP_OPS_F_NOFS). Block-device swap
+ * never touches the filesystem, so it is safe to enter fs here.
*/
if (folio_test_swapcache(folio) && (gfp_mask & __GFP_IO) &&
!(__swap_entry_to_info(folio->swap)->ops->flags & SWAP_OPS_F_NOFS))
> struct swap_ops {
> + unsigned int flags;
> +
> bool (*can_merge)(struct folio *folio, struct folio *prev_folio,
> size_t prev_folio_size, int rw);
> void (*submit_write)(struct swap_io_ctx *ctx);
> @@ -335,11 +339,6 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t flag, unsigned long orders,
> void swap_update_readahead(struct folio *folio, struct vm_area_struct *vma,
> unsigned long addr);
>
> -static inline unsigned int folio_swap_flags(struct folio *folio)
> -{
> - return __swap_entry_to_info(folio->swap)->flags;
> -}
> -
> #else /* CONFIG_SWAP */
> static inline struct swap_cluster_info *swap_cluster_lock(
> struct swap_info_struct *si, pgoff_t offset, bool irq)
> @@ -470,16 +469,9 @@ static inline void __swap_cache_replace_folio(struct swap_cluster_info *ci,
> struct folio *old, struct folio *new)
> {
> }
> -
> -static inline unsigned int folio_swap_flags(struct folio *folio)
> -{
> - return 0;
> -}
> -
> #endif /* CONFIG_SWAP */
>
> extern const struct swap_ops swap_bdev_ops;
> -extern const struct swap_ops swap_fs_ops;
>
> int shmem_writeout(struct swap_io_ctx *ctx, struct folio *folio,
> struct list_head *folio_list);
> diff --git a/mm/swapfile.c b/mm/swapfile.c
> index a670635e0fbe..284eebc40a70 100644
> --- a/mm/swapfile.c
> +++ b/mm/swapfile.c
> @@ -2858,8 +2858,6 @@ static int setup_swap_extents(struct swap_info_struct *sis,
> ret = mapping->a_ops->swap_activate(sis, swap_file, span);
> if (ret < 0)
> return ret;
> - if (sis->flags & SWP_FS_OPS)
> - sis->ops = &swap_fs_ops;
> sis->flags |= SWP_ACTIVATED;
> return ret;
> }
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index c43177a8e4dd..2d44ebfebdea 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -1037,16 +1037,14 @@ static bool may_enter_fs(struct folio *folio, gfp_t gfp_mask)
> {
> if (gfp_mask & __GFP_FS)
> return true;
> - if (!folio_test_swapcache(folio) || !(gfp_mask & __GFP_IO))
> - return false;
> /*
> - * We can "enter_fs" for swap-cache with only __GFP_IO
> - * providing this isn't SWP_FS_OPS.
> - * ->flags can be updated non-atomically,
> - * but that will never affect SWP_FS_OPS, so the data_race
> - * is safe.
> + * We can "enter_fs" for swap-cache with only __GFP_IO unless backed by
> + * a swapfile that requires GFP_NOFS I/O.
> */
> - return !data_race(folio_swap_flags(folio) & SWP_FS_OPS);
> + if (folio_test_swapcache(folio) && (gfp_mask & __GFP_IO) &&
> + !(__swap_entry_to_info(folio->swap)->ops->flags & SWAP_OPS_F_NOFS))
> + return true;
> + return false;
> }
>
> /*
> --
> 2.53.0
>
next prev parent reply other threads:[~2026-06-05 5:21 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-01 11:34 better block swap batching and a different take on swap_ops v2 Christoph Hellwig
2026-06-01 11:34 ` [PATCH 1/8] shmem: provide a shmem_write_folio wrapper Christoph Hellwig
2026-06-04 9:43 ` Baoquan He
2026-06-05 17:07 ` Nhat Pham
2026-06-01 11:34 ` [PATCH 2/8] mm: merge writeout into pageout Christoph Hellwig
2026-06-04 9:44 ` Baoquan He
2026-06-05 17:07 ` Nhat Pham
2026-06-01 11:34 ` [PATCH 3/8] mm/swap: introduce struct swap_io_ctx Christoph Hellwig
2026-06-04 10:58 ` Baoquan He
2026-06-05 17:41 ` Nhat Pham
2026-06-01 11:34 ` [PATCH 4/8] mm/swap: also use struct swap_iocb for block I/O Christoph Hellwig
2026-06-04 10:59 ` Baoquan He
2026-06-04 11:37 ` Baoquan He
2026-06-01 11:34 ` [PATCH 5/8] mm/swap: remove count_swpout_vm_event Christoph Hellwig
2026-06-04 11:37 ` Baoquan He
2026-06-05 17:50 ` Nhat Pham
2026-06-01 11:34 ` [PATCH 6/8] mm/swap: use swap_ops to register swap device's methods Christoph Hellwig
2026-06-05 17:53 ` Nhat Pham
2026-06-01 11:34 ` [PATCH 7/8] mm/swap: remove SWP_FS_OPS Christoph Hellwig
2026-06-05 5:21 ` Baoquan He [this message]
2026-06-05 17:58 ` Nhat Pham
2026-06-01 11:34 ` [PATCH 8/8] mm/vmstat: add NRSWP{IN,OUT} counters Christoph Hellwig
2026-06-05 7:16 ` Baoquan He
2026-06-05 17:48 ` Nhat Pham
2026-06-01 13:29 ` better block swap batching and a different take on swap_ops v2 Baoquan He
2026-06-01 14:50 ` Christoph Hellwig
2026-06-01 15:17 ` Baoquan He
2026-06-01 15:25 ` Christoph Hellwig
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=aiJc5pPU_kvxs0a7@MiWiFi-R3L-srv \
--to=baoquan.he@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=chrisl@kernel.org \
--cc=hch@lst.de \
--cc=kasong@tencent.com \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=shikemeng@huaweicloud.com \
--cc=usama.arif@linux.dev \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.