Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func()
@ 2026-09-02 13:16 Kefeng Wang
  2026-09-02 13:16 ` [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker Kefeng Wang
                   ` (5 more replies)
  0 siblings, 6 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-02 13:16 UTC (permalink / raw)
  To: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm, Kefeng Wang

The task_struct->flags field is a limited 32-bit resource. Two flag bits,
PF_KCOMPACTD and PF_KSWAPD, are used to identify whether a kernel thread
is kcompactd or kswapd. Converting these to use kthread_func() frees up
two valuable flag bits for future use.

Kefeng Wang (4):
  xfs: remove dead kswapd flag inheritance from btree split worker
  iomap: simplify writepages reclaim guard
  mm: replace PF_KSWAPD flag with kthread_func() check
  mm: replace PF_KCOMPACTD flag with kthread_func() check

 fs/iomap/buffered-io.c                   |  3 +--
 fs/xfs/libxfs/xfs_btree.c                | 18 +-----------------
 fs/xfs/xfs_platform.h                    |  4 ----
 include/linux/compaction.h               | 11 ++++++-----
 include/linux/sched.h                    |  4 ++--
 include/linux/swap.h                     |  7 +------
 mm/compaction.c                          |  9 ++++++---
 mm/vmscan.c                              | 10 ++++++++--
 tools/sched_ext/include/scx/common.bpf.h |  2 --
 9 files changed, 25 insertions(+), 43 deletions(-)

-- 
2.55.0



^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker
  2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
@ 2026-09-02 13:16 ` Kefeng Wang
  2026-09-02 14:32   ` Christoph Hellwig
  2026-09-02 15:33   ` Shakeel Butt
  2026-09-02 13:16 ` [PATCH 2/4] iomap: simplify writepages reclaim guard Kefeng Wang
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-02 13:16 UTC (permalink / raw)
  To: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm, Kefeng Wang

Commit 1f6d64829db7 ("xfs: block allocation work needs to be kswapd
aware") added PF_MEMALLOC | PF_KSWAPD inheritance to
xfs_btree_split_worker() so that block allocation offloaded from
kswapd to a workqueue thread could access emergency memory reserves
and avoid reclaim throttling.

pageout() no longer calls ->writepage() for filesystem folios -- it
returns PAGE_ACTIVATE for non-shmem, non-anon pages.  kswapd therefore
never enters XFS writeback and cannot reach btree split.  The only
path that offloads btree splits is unwritten extent conversion at IO
completion (xfs_end_io -> xfs_iomap_write_unwritten), which runs in
a workqueue context where current_is_kswapd() is always false.

Let's remove the dead kswapd flag and related codes.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/xfs/libxfs/xfs_btree.c | 18 +-----------------
 fs/xfs/xfs_platform.h     |  4 ----
 2 files changed, 1 insertion(+), 21 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 60ef7f08b1d3..6738d9d1511b 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -2994,7 +2994,6 @@ struct xfs_btree_split_args {
 	struct xfs_btree_cur	**curp;
 	int			*stat;		/* success/failure */
 	int			result;
-	bool			kswapd;	/* allocation in kswapd context */
 	struct completion	*done;
 	struct work_struct	work;
 };
@@ -3008,33 +3007,18 @@ xfs_btree_split_worker(
 {
 	struct xfs_btree_split_args	*args = container_of(work,
 						struct xfs_btree_split_args, work);
-	unsigned long		pflags;
-	unsigned long		new_pflags = 0;
-
-	/*
-	 * we are in a transaction context here, but may also be doing work
-	 * in kswapd context, and hence we may need to inherit that state
-	 * temporarily to ensure that we don't block waiting for memory reclaim
-	 * in any way.
-	 */
-	if (args->kswapd)
-		new_pflags |= PF_MEMALLOC | PF_KSWAPD;
-
-	current_set_flags_nested(&pflags, new_pflags);
 	xfs_trans_set_context(args->cur->bc_tp);
 
 	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
 					 args->key, args->curp, args->stat);
 
 	xfs_trans_clear_context(args->cur->bc_tp);
-	current_restore_flags_nested(&pflags, new_pflags);
 
 	/*
 	 * Do not access args after complete() has run here. We don't own args
 	 * and the owner may run and free args before we return here.
 	 */
 	complete(args->done);
-
 }
 
 /*
@@ -3078,7 +3062,7 @@ xfs_btree_split(
 	args.curp = curp;
 	args.stat = stat;
 	args.done = &done;
-	args.kswapd = current_is_kswapd();
+
 	INIT_WORK_ONSTACK(&args.work, xfs_btree_split_worker);
 	queue_work(xfs_alloc_wq, &args.work);
 	wait_for_completion(&done);
diff --git a/fs/xfs/xfs_platform.h b/fs/xfs/xfs_platform.h
index 5d542e95fe44..a49fa159894d 100644
--- a/fs/xfs/xfs_platform.h
+++ b/fs/xfs/xfs_platform.h
@@ -115,10 +115,6 @@ typedef __u32			xfs_nlink_t;
 #define xfs_blockgc_secs	xfs_params.blockgc_timer.val
 
 #define current_cpu()		(raw_smp_processor_id())
-#define current_set_flags_nested(sp, f)		\
-		(*(sp) = current->flags, current->flags |= (f))
-#define current_restore_flags_nested(sp, f)	\
-		(current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
 
 #define NBBY		8		/* number of bits per byte */
 
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/4] iomap: simplify writepages reclaim guard
  2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
  2026-09-02 13:16 ` [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker Kefeng Wang
@ 2026-09-02 13:16 ` Kefeng Wang
  2026-09-02 14:32   ` Christoph Hellwig
  2026-09-02 15:34   ` Shakeel Butt
  2026-09-02 13:16 ` [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check Kefeng Wang
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-02 13:16 UTC (permalink / raw)
  To: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm, Kefeng Wang

Now that kswapd can no longer reach filesystem writeback (pageout()
returns PAGE_ACTIVATE for non-shmem, non-anon folios), any PF_MEMALLOC
context in iomap_writepages() indicates a VM regression, simplify
the check by removing PF_KSWAPD.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/iomap/buffered-io.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index 0a5ebfda90f1..6306ca747f3b 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -2077,8 +2077,7 @@ iomap_writepages(struct iomap_writepage_ctx *wpc)
 	 * Writeback from reclaim context should never happen except in the case
 	 * of a VM regression so warn about it and refuse to write the data.
 	 */
-	if (WARN_ON_ONCE((current->flags & (PF_MEMALLOC | PF_KSWAPD)) ==
-			PF_MEMALLOC))
+	if (WARN_ON_ONCE((current->flags & PF_MEMALLOC)))
 		return -EIO;
 
 	while ((folio = writeback_iter(mapping, wpc->wbc, folio, &error))) {
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check
  2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
  2026-09-02 13:16 ` [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker Kefeng Wang
  2026-09-02 13:16 ` [PATCH 2/4] iomap: simplify writepages reclaim guard Kefeng Wang
@ 2026-09-02 13:16 ` Kefeng Wang
  2026-09-02 15:36   ` Shakeel Butt
                     ` (2 more replies)
  2026-09-02 13:16 ` [PATCH 4/4] mm: replace PF_KCOMPACTD " Kefeng Wang
                   ` (2 subsequent siblings)
  5 siblings, 3 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-02 13:16 UTC (permalink / raw)
  To: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm, Kefeng Wang

The preceding commits removed the last consumer that propagated
PF_KSWAPD beyond kswapd itself (XFS btree split worker inheritance).
The only remaining setter of PF_KSWAPD is kswapd(), and every
current_is_kswapd() caller only needs to check whether the current
task *is* the kswapd thread, not whether it inherited the flag.

Replace the flag-based test with kthread_func(current) == kswapd,
freeing the 0x00020000 PF flag bit.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 include/linux/sched.h                    |  2 +-
 include/linux/swap.h                     |  7 +------
 mm/vmscan.c                              | 10 ++++++++--
 tools/sched_ext/include/scx/common.bpf.h |  1 -
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8b3d47a325cc..86394121b6c0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1809,7 +1809,7 @@ extern struct pid *cad_pid;
 #define PF_USER_WORKER		0x00004000	/* Kernel thread cloned from userspace thread */
 #define PF_NOFREEZE		0x00008000	/* This thread should not be frozen */
 #define PF_KCOMPACTD		0x00010000	/* I am kcompactd */
-#define PF_KSWAPD		0x00020000	/* I am kswapd */
+#define PF__HOLE__00020000	0x00020000
 #define PF_MEMALLOC_NOFS	0x00040000	/* All allocations inherit GFP_NOFS. See memalloc_nfs_save() */
 #define PF_MEMALLOC_NOIO	0x00080000	/* All allocations inherit GFP_NOIO. See memalloc_noio_save() */
 #define PF_LOCAL_THROTTLE	0x00100000	/* Throttle writes only against the bdi I write to,
diff --git a/include/linux/swap.h b/include/linux/swap.h
index a72ecf12c00d..fc290e29e4a9 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -25,12 +25,6 @@
 #define SWAP_FLAGS_VALID	(SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \
 				 SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \
 				 SWAP_FLAG_DISCARD_PAGES)
-
-static inline int current_is_kswapd(void)
-{
-	return current->flags & PF_KSWAPD;
-}
-
 /*
  * MAX_SWAPFILES defines the maximum number of swaptypes: things which can
  * be swapped to.  The swap type and the offset into that swap type are
@@ -339,6 +333,7 @@ void check_move_unevictable_folios(struct folio_batch *fbatch);
 
 extern void __meminit kswapd_run(int nid);
 extern void __meminit kswapd_stop(int nid);
+bool current_is_kswapd(void);
 
 #ifdef CONFIG_SWAP
 int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 07ba86634b84..775d3f71a9de 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -7468,7 +7468,7 @@ static int kswapd(void *p)
 	 * us from recursively trying to free more memory as we're
 	 * trying to free the first piece of memory in the first place).
 	 */
-	tsk->flags |= PF_MEMALLOC | PF_KSWAPD;
+	tsk->flags |= PF_MEMALLOC;
 	set_freezable();
 
 	WRITE_ONCE(pgdat->kswapd_order, 0);
@@ -7518,11 +7518,17 @@ static int kswapd(void *p)
 			goto kswapd_try_sleep;
 	}
 
-	tsk->flags &= ~(PF_MEMALLOC | PF_KSWAPD);
+	tsk->flags &= ~PF_MEMALLOC;
 
 	return 0;
 }
 
+bool current_is_kswapd(void)
+{
+	return kthread_func(current) == kswapd;
+}
+EXPORT_SYMBOL_GPL(current_is_kswapd);
+
 /*
  * A zone is low on free memory or too fragmented for high-order memory.  If
  * kswapd should reclaim (direct reclaim is deferred), wake it up for the zone's
diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
index 76f5e025e107..3e095343ae84 100644
--- a/tools/sched_ext/include/scx/common.bpf.h
+++ b/tools/sched_ext/include/scx/common.bpf.h
@@ -32,7 +32,6 @@
 #define PF_IO_WORKER			0x00000010	/* Task is an IO worker */
 #define PF_WQ_WORKER			0x00000020	/* I'm a workqueue worker */
 #define PF_KCOMPACTD			0x00010000      /* I am kcompactd */
-#define PF_KSWAPD			0x00020000      /* I am kswapd */
 #define PF_KTHREAD			0x00200000	/* I am a kernel thread */
 #define PF_EXITING			0x00000004
 #define CLOCK_MONOTONIC			1
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/4] mm: replace PF_KCOMPACTD flag with kthread_func() check
  2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
                   ` (2 preceding siblings ...)
  2026-09-02 13:16 ` [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check Kefeng Wang
@ 2026-09-02 13:16 ` Kefeng Wang
  2026-09-02 15:37   ` Shakeel Butt
                     ` (2 more replies)
  2026-09-02 15:31 ` [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Shakeel Butt
  2026-09-02 20:44 ` Andrew Morton
  5 siblings, 3 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-02 13:16 UTC (permalink / raw)
  To: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm, Kefeng Wang

PF_KCOMPACTD was introduced by commit ce6d9c1c2b5c ("NFS: fix
nfs_release_folio() to not deadlock via kcompactd writeback") so
nfs_release_folio() could detect kcompactd context and skip
writeback.  The flag is only consumed by current_is_kcompactd(),
whose sole caller is nfs_release_folio().

Replace the flag-based check with kthread_func(current) == kcompactd,
freeing the 0x00010000 PF flag bit.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 include/linux/compaction.h               | 11 ++++++-----
 include/linux/sched.h                    |  2 +-
 mm/compaction.c                          |  9 ++++++---
 tools/sched_ext/include/scx/common.bpf.h |  1 -
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index 66a2f70e9e01..691c09f0a697 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -81,10 +81,6 @@ static inline unsigned long compact_gap(unsigned int order)
 	return min(2UL << order, COMPACT_CLUSTER_MAX);
 }
 
-static inline int current_is_kcompactd(void)
-{
-	return current->flags & PF_KCOMPACTD;
-}
 
 #ifdef CONFIG_COMPACTION
 
@@ -103,7 +99,7 @@ extern void compaction_defer_reset(struct zone *zone, int order,
 
 bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
 					int alloc_flags, gfp_t gfp_mask);
-
+bool current_is_kcompactd(void);
 extern void __meminit kcompactd_run(int nid);
 extern void __meminit kcompactd_stop(int nid);
 extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx);
@@ -120,6 +116,11 @@ static inline bool compaction_suitable(struct zone *zone, int order,
 	return false;
 }
 
+static inline bool current_is_kcompactd(void)
+{
+	return false;
+}
+
 static inline void kcompactd_run(int nid)
 {
 }
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 86394121b6c0..eb12ff4cea6c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1808,7 +1808,7 @@ extern struct pid *cad_pid;
 #define PF_USED_MATH		0x00002000	/* If unset the fpu must be initialized before use */
 #define PF_USER_WORKER		0x00004000	/* Kernel thread cloned from userspace thread */
 #define PF_NOFREEZE		0x00008000	/* This thread should not be frozen */
-#define PF_KCOMPACTD		0x00010000	/* I am kcompactd */
+#define PF__HOLE__00010000	0x00010000
 #define PF__HOLE__00020000	0x00020000
 #define PF_MEMALLOC_NOFS	0x00040000	/* All allocations inherit GFP_NOFS. See memalloc_nfs_save() */
 #define PF_MEMALLOC_NOIO	0x00080000	/* All allocations inherit GFP_NOIO. See memalloc_noio_save() */
diff --git a/mm/compaction.c b/mm/compaction.c
index a049415512c6..4994e200bbec 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -3197,7 +3197,6 @@ static int kcompactd(void *p)
 	long default_timeout = msecs_to_jiffies(HPAGE_FRAG_CHECK_INTERVAL_MSEC);
 	long timeout = default_timeout;
 
-	current->flags |= PF_KCOMPACTD;
 	set_freezable();
 
 	pgdat->kcompactd_max_order = 0;
@@ -3254,11 +3253,15 @@ static int kcompactd(void *p)
 			pgdat->proactive_compact_trigger = false;
 	}
 
-	current->flags &= ~PF_KCOMPACTD;
-
 	return 0;
 }
 
+bool current_is_kcompactd(void)
+{
+	return kthread_func(current) == kcompactd;
+}
+EXPORT_SYMBOL_GPL(current_is_kcompactd);
+
 /*
  * This kcompactd start function will be called by init and node-hot-add.
  * On node-hot-add, kcompactd will moved to proper cpus if cpus are hot-added.
diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
index 3e095343ae84..807ef881ce2d 100644
--- a/tools/sched_ext/include/scx/common.bpf.h
+++ b/tools/sched_ext/include/scx/common.bpf.h
@@ -31,7 +31,6 @@
 #define PF_IDLE				0x00000002	/* I am an IDLE thread */
 #define PF_IO_WORKER			0x00000010	/* Task is an IO worker */
 #define PF_WQ_WORKER			0x00000020	/* I'm a workqueue worker */
-#define PF_KCOMPACTD			0x00010000      /* I am kcompactd */
 #define PF_KTHREAD			0x00200000	/* I am a kernel thread */
 #define PF_EXITING			0x00000004
 #define CLOCK_MONOTONIC			1
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker
  2026-09-02 13:16 ` [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker Kefeng Wang
@ 2026-09-02 14:32   ` Christoph Hellwig
  2026-09-02 15:33   ` Shakeel Butt
  1 sibling, 0 replies; 23+ messages in thread
From: Christoph Hellwig @ 2026-09-02 14:32 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs,
	linux-xfs, linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:50PM +0800, Kefeng Wang wrote:
> Commit 1f6d64829db7 ("xfs: block allocation work needs to be kswapd
> aware") added PF_MEMALLOC | PF_KSWAPD inheritance to
> xfs_btree_split_worker() so that block allocation offloaded from
> kswapd to a workqueue thread could access emergency memory reserves
> and avoid reclaim throttling.
> 
> pageout() no longer calls ->writepage() for filesystem folios -- it
> returns PAGE_ACTIVATE for non-shmem, non-anon pages.  kswapd therefore
> never enters XFS writeback and cannot reach btree split.  The only
> path that offloads btree splits is unwritten extent conversion at IO
> completion (xfs_end_io -> xfs_iomap_write_unwritten), which runs in
> a workqueue context where current_is_kswapd() is always false.
> 
> Let's remove the dead kswapd flag and related codes.

Nice!

Reviewed-by: Christoph Hellwig <hch@lst.de>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] iomap: simplify writepages reclaim guard
  2026-09-02 13:16 ` [PATCH 2/4] iomap: simplify writepages reclaim guard Kefeng Wang
@ 2026-09-02 14:32   ` Christoph Hellwig
  2026-09-03 13:46     ` Kefeng Wang
  2026-09-02 15:34   ` Shakeel Butt
  1 sibling, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2026-09-02 14:32 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs,
	linux-xfs, linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:51PM +0800, Kefeng Wang wrote:
> index 0a5ebfda90f1..6306ca747f3b 100644
> --- a/fs/iomap/buffered-io.c
> +++ b/fs/iomap/buffered-io.c
> @@ -2077,8 +2077,7 @@ iomap_writepages(struct iomap_writepage_ctx *wpc)
>  	 * Writeback from reclaim context should never happen except in the case
>  	 * of a VM regression so warn about it and refuse to write the data.
>  	 */
> -	if (WARN_ON_ONCE((current->flags & (PF_MEMALLOC | PF_KSWAPD)) ==
> -			PF_MEMALLOC))
> +	if (WARN_ON_ONCE((current->flags & PF_MEMALLOC)))

You can drop one set of braces here.  Otherwise this looks good.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func()
  2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
                   ` (3 preceding siblings ...)
  2026-09-02 13:16 ` [PATCH 4/4] mm: replace PF_KCOMPACTD " Kefeng Wang
@ 2026-09-02 15:31 ` Shakeel Butt
  2026-09-02 20:44 ` Andrew Morton
  5 siblings, 0 replies; 23+ messages in thread
From: Shakeel Butt @ 2026-09-02 15:31 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, ljs, linux-xfs,
	linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:49PM +0800, Kefeng Wang wrote:
> The task_struct->flags field is a limited 32-bit resource. Two flag bits,
> PF_KCOMPACTD and PF_KSWAPD, are used to identify whether a kernel thread
> is kcompactd or kswapd. Converting these to use kthread_func() frees up
> two valuable flag bits for future use.

I wouldn't call it a limited resource. We can have more fields in task_struct
but I like the cleanups.

> 
> Kefeng Wang (4):
>   xfs: remove dead kswapd flag inheritance from btree split worker
>   iomap: simplify writepages reclaim guard
>   mm: replace PF_KSWAPD flag with kthread_func() check
>   mm: replace PF_KCOMPACTD flag with kthread_func() check
> 
>  fs/iomap/buffered-io.c                   |  3 +--
>  fs/xfs/libxfs/xfs_btree.c                | 18 +-----------------
>  fs/xfs/xfs_platform.h                    |  4 ----
>  include/linux/compaction.h               | 11 ++++++-----
>  include/linux/sched.h                    |  4 ++--
>  include/linux/swap.h                     |  7 +------
>  mm/compaction.c                          |  9 ++++++---
>  mm/vmscan.c                              | 10 ++++++++--
>  tools/sched_ext/include/scx/common.bpf.h |  2 --
>  9 files changed, 25 insertions(+), 43 deletions(-)
> 
> -- 
> 2.55.0
> 


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker
  2026-09-02 13:16 ` [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker Kefeng Wang
  2026-09-02 14:32   ` Christoph Hellwig
@ 2026-09-02 15:33   ` Shakeel Butt
  1 sibling, 0 replies; 23+ messages in thread
From: Shakeel Butt @ 2026-09-02 15:33 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, ljs, linux-xfs,
	linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:50PM +0800, Kefeng Wang wrote:
> Commit 1f6d64829db7 ("xfs: block allocation work needs to be kswapd
> aware") added PF_MEMALLOC | PF_KSWAPD inheritance to
> xfs_btree_split_worker() so that block allocation offloaded from
> kswapd to a workqueue thread could access emergency memory reserves
> and avoid reclaim throttling.
> 
> pageout() no longer calls ->writepage() for filesystem folios -- it
> returns PAGE_ACTIVATE for non-shmem, non-anon pages.  kswapd therefore
> never enters XFS writeback and cannot reach btree split.  The only
> path that offloads btree splits is unwritten extent conversion at IO
> completion (xfs_end_io -> xfs_iomap_write_unwritten), which runs in
> a workqueue context where current_is_kswapd() is always false.
> 
> Let's remove the dead kswapd flag and related codes.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] iomap: simplify writepages reclaim guard
  2026-09-02 13:16 ` [PATCH 2/4] iomap: simplify writepages reclaim guard Kefeng Wang
  2026-09-02 14:32   ` Christoph Hellwig
@ 2026-09-02 15:34   ` Shakeel Butt
  1 sibling, 0 replies; 23+ messages in thread
From: Shakeel Butt @ 2026-09-02 15:34 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, ljs, linux-xfs,
	linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:51PM +0800, Kefeng Wang wrote:
> Now that kswapd can no longer reach filesystem writeback (pageout()
> returns PAGE_ACTIVATE for non-shmem, non-anon folios), any PF_MEMALLOC
> context in iomap_writepages() indicates a VM regression, simplify
> the check by removing PF_KSWAPD.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check
  2026-09-02 13:16 ` [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check Kefeng Wang
@ 2026-09-02 15:36   ` Shakeel Butt
  2026-09-02 16:35   ` Vlastimil Babka (SUSE)
  2026-09-02 16:39   ` Zi Yan
  2 siblings, 0 replies; 23+ messages in thread
From: Shakeel Butt @ 2026-09-02 15:36 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, ljs, linux-xfs,
	linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:52PM +0800, Kefeng Wang wrote:
> The preceding commits removed the last consumer that propagated
> PF_KSWAPD beyond kswapd itself (XFS btree split worker inheritance).
> The only remaining setter of PF_KSWAPD is kswapd(), and every
> current_is_kswapd() caller only needs to check whether the current
> task *is* the kswapd thread, not whether it inherited the flag.
> 
> Replace the flag-based test with kthread_func(current) == kswapd,
> freeing the 0x00020000 PF flag bit.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Acked-by: Shakeel Butt <shakeel.butt@linux.dev>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 4/4] mm: replace PF_KCOMPACTD flag with kthread_func() check
  2026-09-02 13:16 ` [PATCH 4/4] mm: replace PF_KCOMPACTD " Kefeng Wang
@ 2026-09-02 15:37   ` Shakeel Butt
  2026-09-02 16:36   ` Vlastimil Babka (SUSE)
  2026-09-02 16:40   ` Zi Yan
  2 siblings, 0 replies; 23+ messages in thread
From: Shakeel Butt @ 2026-09-02 15:37 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, ljs, linux-xfs,
	linux-fsdevel, linux-mm

On Wed, Sep 02, 2026 at 09:16:53PM +0800, Kefeng Wang wrote:
> PF_KCOMPACTD was introduced by commit ce6d9c1c2b5c ("NFS: fix
> nfs_release_folio() to not deadlock via kcompactd writeback") so
> nfs_release_folio() could detect kcompactd context and skip
> writeback.  The flag is only consumed by current_is_kcompactd(),
> whose sole caller is nfs_release_folio().
> 
> Replace the flag-based check with kthread_func(current) == kcompactd,
> freeing the 0x00010000 PF flag bit.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Acked-by: Shakeel Butt <shakeel.butt@linux.dev>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check
  2026-09-02 13:16 ` [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check Kefeng Wang
  2026-09-02 15:36   ` Shakeel Butt
@ 2026-09-02 16:35   ` Vlastimil Babka (SUSE)
  2026-09-02 16:39   ` Zi Yan
  2 siblings, 0 replies; 23+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-09-02 16:35 UTC (permalink / raw)
  To: Kefeng Wang, brauner, djwong, cem, akpm, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm

On 9/2/26 15:16, Kefeng Wang wrote:
> The preceding commits removed the last consumer that propagated
> PF_KSWAPD beyond kswapd itself (XFS btree split worker inheritance).
> The only remaining setter of PF_KSWAPD is kswapd(), and every
> current_is_kswapd() caller only needs to check whether the current
> task *is* the kswapd thread, not whether it inherited the flag.
> 
> Replace the flag-based test with kthread_func(current) == kswapd,
> freeing the 0x00020000 PF flag bit.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>

> ---
>  include/linux/sched.h                    |  2 +-
>  include/linux/swap.h                     |  7 +------
>  mm/vmscan.c                              | 10 ++++++++--
>  tools/sched_ext/include/scx/common.bpf.h |  1 -
>  4 files changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 8b3d47a325cc..86394121b6c0 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1809,7 +1809,7 @@ extern struct pid *cad_pid;
>  #define PF_USER_WORKER		0x00004000	/* Kernel thread cloned from userspace thread */
>  #define PF_NOFREEZE		0x00008000	/* This thread should not be frozen */
>  #define PF_KCOMPACTD		0x00010000	/* I am kcompactd */
> -#define PF_KSWAPD		0x00020000	/* I am kswapd */
> +#define PF__HOLE__00020000	0x00020000
>  #define PF_MEMALLOC_NOFS	0x00040000	/* All allocations inherit GFP_NOFS. See memalloc_nfs_save() */
>  #define PF_MEMALLOC_NOIO	0x00080000	/* All allocations inherit GFP_NOIO. See memalloc_noio_save() */
>  #define PF_LOCAL_THROTTLE	0x00100000	/* Throttle writes only against the bdi I write to,
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index a72ecf12c00d..fc290e29e4a9 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -25,12 +25,6 @@
>  #define SWAP_FLAGS_VALID	(SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \
>  				 SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \
>  				 SWAP_FLAG_DISCARD_PAGES)
> -
> -static inline int current_is_kswapd(void)
> -{
> -	return current->flags & PF_KSWAPD;
> -}
> -
>  /*
>   * MAX_SWAPFILES defines the maximum number of swaptypes: things which can
>   * be swapped to.  The swap type and the offset into that swap type are
> @@ -339,6 +333,7 @@ void check_move_unevictable_folios(struct folio_batch *fbatch);
>  
>  extern void __meminit kswapd_run(int nid);
>  extern void __meminit kswapd_stop(int nid);
> +bool current_is_kswapd(void);
>  
>  #ifdef CONFIG_SWAP
>  int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 07ba86634b84..775d3f71a9de 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -7468,7 +7468,7 @@ static int kswapd(void *p)
>  	 * us from recursively trying to free more memory as we're
>  	 * trying to free the first piece of memory in the first place).
>  	 */
> -	tsk->flags |= PF_MEMALLOC | PF_KSWAPD;
> +	tsk->flags |= PF_MEMALLOC;
>  	set_freezable();
>  
>  	WRITE_ONCE(pgdat->kswapd_order, 0);
> @@ -7518,11 +7518,17 @@ static int kswapd(void *p)
>  			goto kswapd_try_sleep;
>  	}
>  
> -	tsk->flags &= ~(PF_MEMALLOC | PF_KSWAPD);
> +	tsk->flags &= ~PF_MEMALLOC;
>  
>  	return 0;
>  }
>  
> +bool current_is_kswapd(void)
> +{
> +	return kthread_func(current) == kswapd;
> +}
> +EXPORT_SYMBOL_GPL(current_is_kswapd);
> +
>  /*
>   * A zone is low on free memory or too fragmented for high-order memory.  If
>   * kswapd should reclaim (direct reclaim is deferred), wake it up for the zone's
> diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h
> index 76f5e025e107..3e095343ae84 100644
> --- a/tools/sched_ext/include/scx/common.bpf.h
> +++ b/tools/sched_ext/include/scx/common.bpf.h
> @@ -32,7 +32,6 @@
>  #define PF_IO_WORKER			0x00000010	/* Task is an IO worker */
>  #define PF_WQ_WORKER			0x00000020	/* I'm a workqueue worker */
>  #define PF_KCOMPACTD			0x00010000      /* I am kcompactd */
> -#define PF_KSWAPD			0x00020000      /* I am kswapd */
>  #define PF_KTHREAD			0x00200000	/* I am a kernel thread */
>  #define PF_EXITING			0x00000004
>  #define CLOCK_MONOTONIC			1



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 4/4] mm: replace PF_KCOMPACTD flag with kthread_func() check
  2026-09-02 13:16 ` [PATCH 4/4] mm: replace PF_KCOMPACTD " Kefeng Wang
  2026-09-02 15:37   ` Shakeel Butt
@ 2026-09-02 16:36   ` Vlastimil Babka (SUSE)
  2026-09-02 16:40   ` Zi Yan
  2 siblings, 0 replies; 23+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-09-02 16:36 UTC (permalink / raw)
  To: Kefeng Wang, brauner, djwong, cem, akpm, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm

On 9/2/26 15:16, Kefeng Wang wrote:
> PF_KCOMPACTD was introduced by commit ce6d9c1c2b5c ("NFS: fix
> nfs_release_folio() to not deadlock via kcompactd writeback") so
> nfs_release_folio() could detect kcompactd context and skip
> writeback.  The flag is only consumed by current_is_kcompactd(),
> whose sole caller is nfs_release_folio().
> 
> Replace the flag-based check with kthread_func(current) == kcompactd,
> freeing the 0x00010000 PF flag bit.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check
  2026-09-02 13:16 ` [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check Kefeng Wang
  2026-09-02 15:36   ` Shakeel Butt
  2026-09-02 16:35   ` Vlastimil Babka (SUSE)
@ 2026-09-02 16:39   ` Zi Yan
  2 siblings, 0 replies; 23+ messages in thread
From: Zi Yan @ 2026-09-02 16:39 UTC (permalink / raw)
  To: Kefeng Wang, brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm

On Wed Sep 2, 2026 at 9:16 AM EDT, Kefeng Wang wrote:
> The preceding commits removed the last consumer that propagated
> PF_KSWAPD beyond kswapd itself (XFS btree split worker inheritance).
> The only remaining setter of PF_KSWAPD is kswapd(), and every
> current_is_kswapd() caller only needs to check whether the current
> task *is* the kswapd thread, not whether it inherited the flag.
>
> Replace the flag-based test with kthread_func(current) == kswapd,
> freeing the 0x00020000 PF flag bit.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
>  include/linux/sched.h                    |  2 +-
>  include/linux/swap.h                     |  7 +------
>  mm/vmscan.c                              | 10 ++++++++--
>  tools/sched_ext/include/scx/common.bpf.h |  1 -
>  4 files changed, 10 insertions(+), 10 deletions(-)
>
LGTM.

Acked-by: Zi Yan <ziy@nvidia.com>

-- 
Best Regards,
Yan, Zi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 4/4] mm: replace PF_KCOMPACTD flag with kthread_func() check
  2026-09-02 13:16 ` [PATCH 4/4] mm: replace PF_KCOMPACTD " Kefeng Wang
  2026-09-02 15:37   ` Shakeel Butt
  2026-09-02 16:36   ` Vlastimil Babka (SUSE)
@ 2026-09-02 16:40   ` Zi Yan
  2 siblings, 0 replies; 23+ messages in thread
From: Zi Yan @ 2026-09-02 16:40 UTC (permalink / raw)
  To: Kefeng Wang, brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm

On Wed Sep 2, 2026 at 9:16 AM EDT, Kefeng Wang wrote:
> PF_KCOMPACTD was introduced by commit ce6d9c1c2b5c ("NFS: fix
> nfs_release_folio() to not deadlock via kcompactd writeback") so
> nfs_release_folio() could detect kcompactd context and skip
> writeback.  The flag is only consumed by current_is_kcompactd(),
> whose sole caller is nfs_release_folio().
>
> Replace the flag-based check with kthread_func(current) == kcompactd,
> freeing the 0x00010000 PF flag bit.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
>  include/linux/compaction.h               | 11 ++++++-----
>  include/linux/sched.h                    |  2 +-
>  mm/compaction.c                          |  9 ++++++---
>  tools/sched_ext/include/scx/common.bpf.h |  1 -
>  4 files changed, 13 insertions(+), 10 deletions(-)
>

Acked-by: Zi Yan <ziy@nvidia.com>

-- 
Best Regards,
Yan, Zi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func()
  2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
                   ` (4 preceding siblings ...)
  2026-09-02 15:31 ` [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Shakeel Butt
@ 2026-09-02 20:44 ` Andrew Morton
  2026-09-03 13:37   ` [PATCH] xfs: fix NOFS state corruption in btree split worker Kefeng Wang
  2026-09-03 13:40   ` [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
  5 siblings, 2 replies; 23+ messages in thread
From: Andrew Morton @ 2026-09-02 20:44 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, vbabka, surenb, mhocko, brendan.jackman,
	hannes, ziy, david, qi.zheng, shakeel.butt, ljs, linux-xfs,
	linux-fsdevel, linux-mm

On Wed, 2 Sep 2026 21:16:49 +0800 Kefeng Wang <wangkefeng.wang@huawei.com> wrote:

> The task_struct->flags field is a limited 32-bit resource. Two flag bits,
> PF_KCOMPACTD and PF_KSWAPD, are used to identify whether a kernel thread
> is kcompactd or kswapd. Converting these to use kthread_func() frees up
> two valuable flag bits for future use.

Well that was popular.

Sashiko might have found a problem in the existing XFS code:

	https://sashiko.dev/#/patchset/20260902131653.1338227-1-wangkefeng.wang@huawei.com




^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH] xfs: fix NOFS state corruption in btree split worker
  2026-09-02 20:44 ` Andrew Morton
@ 2026-09-03 13:37   ` Kefeng Wang
  2026-09-03 13:52     ` Brian Foster
  2026-09-03 13:40   ` [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
  1 sibling, 1 reply; 23+ messages in thread
From: Kefeng Wang @ 2026-09-03 13:37 UTC (permalink / raw)
  To: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs
  Cc: linux-xfs, linux-fsdevel, linux-mm, Kefeng Wang

xfs_btree_split_worker() calls xfs_trans_set_context() and
xfs_trans_clear_context() on the caller's transaction, overwriting
tp->t_pflags with the worker's NOFS state. When the caller already has
PF_MEMALLOC_NOFS set (e.g. xfs_end_ioend_write, xfs_dio_write_end_io),
the corrupted tp->t_pflags causes xfs_trans_free() to erroneously clear
the caller's NOFS protection.

Use memalloc_nofs_save/restore with a local variable instead so
tp->t_pflags is never touched.

Closes: https://sashiko.dev/#/patchset/20260902131653.1338227-1-wangkefeng.wang@huawei.com
Fixes: 756b1c343333 ("xfs: use current->journal_info for detecting transaction recursion")
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 fs/xfs/libxfs/xfs_btree.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 6738d9d1511b..8ae4b94e6995 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -3007,12 +3007,18 @@ xfs_btree_split_worker(
 {
 	struct xfs_btree_split_args	*args = container_of(work,
 						struct xfs_btree_split_args, work);
-	xfs_trans_set_context(args->cur->bc_tp);
+	unsigned int			nofs_flags;
+
+	/*
+	 * Don't use xfs_trans_set_context() here: it would overwrite the
+	 * caller's saved NOFS state in tp->t_pflags.  Use a local scope.
+	 */
+	nofs_flags = memalloc_nofs_save();
 
 	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
 					 args->key, args->curp, args->stat);
 
-	xfs_trans_clear_context(args->cur->bc_tp);
+	memalloc_nofs_restore(nofs_flags);
 
 	/*
 	 * Do not access args after complete() has run here. We don't own args
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func()
  2026-09-02 20:44 ` Andrew Morton
  2026-09-03 13:37   ` [PATCH] xfs: fix NOFS state corruption in btree split worker Kefeng Wang
@ 2026-09-03 13:40   ` Kefeng Wang
  1 sibling, 0 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-03 13:40 UTC (permalink / raw)
  To: Andrew Morton
  Cc: brauner, djwong, cem, vbabka, surenb, mhocko, brendan.jackman,
	hannes, ziy, david, qi.zheng, shakeel.butt, ljs, linux-xfs,
	linux-fsdevel, linux-mm



On 9/3/2026 4:44 AM, Andrew Morton wrote:
> On Wed, 2 Sep 2026 21:16:49 +0800 Kefeng Wang <wangkefeng.wang@huawei.com> wrote:
> 
>> The task_struct->flags field is a limited 32-bit resource. Two flag bits,
>> PF_KCOMPACTD and PF_KSWAPD, are used to identify whether a kernel thread
>> is kcompactd or kswapd. Converting these to use kthread_func() frees up
>> two valuable flag bits for future use.
> 
> Well that was popular.
> 
> Sashiko might have found a problem in the existing XFS code:
> 
> 	https://sashiko.dev/#/patchset/20260902131653.1338227-1-wangkefeng.wang@huawei.com
> 

Sashiko looks correct, I sent a fix patch, hoping it will work properly.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/4] iomap: simplify writepages reclaim guard
  2026-09-02 14:32   ` Christoph Hellwig
@ 2026-09-03 13:46     ` Kefeng Wang
  0 siblings, 0 replies; 23+ messages in thread
From: Kefeng Wang @ 2026-09-03 13:46 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs,
	linux-xfs, linux-fsdevel, linux-mm



On 9/2/2026 10:32 PM, Christoph Hellwig wrote:
> On Wed, Sep 02, 2026 at 09:16:51PM +0800, Kefeng Wang wrote:
>> index 0a5ebfda90f1..6306ca747f3b 100644
>> --- a/fs/iomap/buffered-io.c
>> +++ b/fs/iomap/buffered-io.c
>> @@ -2077,8 +2077,7 @@ iomap_writepages(struct iomap_writepage_ctx *wpc)
>>   	 * Writeback from reclaim context should never happen except in the case
>>   	 * of a VM regression so warn about it and refuse to write the data.
>>   	 */
>> -	if (WARN_ON_ONCE((current->flags & (PF_MEMALLOC | PF_KSWAPD)) ==
>> -			PF_MEMALLOC))
>> +	if (WARN_ON_ONCE((current->flags & PF_MEMALLOC)))
> 
> You can drop one set of braces here.  Otherwise this looks good.
> 
Yes, missing it, thanks for your review.

Hi Andrew, I see that you have merged it into mm-new. Could you help fix
it, or I will send a fix patch.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] xfs: fix NOFS state corruption in btree split worker
  2026-09-03 13:37   ` [PATCH] xfs: fix NOFS state corruption in btree split worker Kefeng Wang
@ 2026-09-03 13:52     ` Brian Foster
  2026-09-04  0:41       ` Kefeng Wang
  0 siblings, 1 reply; 23+ messages in thread
From: Brian Foster @ 2026-09-03 13:52 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs,
	linux-xfs, linux-fsdevel, linux-mm

On Thu, Sep 03, 2026 at 09:37:56PM +0800, Kefeng Wang wrote:
> xfs_btree_split_worker() calls xfs_trans_set_context() and
> xfs_trans_clear_context() on the caller's transaction, overwriting
> tp->t_pflags with the worker's NOFS state. When the caller already has
> PF_MEMALLOC_NOFS set (e.g. xfs_end_ioend_write, xfs_dio_write_end_io),
> the corrupted tp->t_pflags causes xfs_trans_free() to erroneously clear
> the caller's NOFS protection.
> 
> Use memalloc_nofs_save/restore with a local variable instead so
> tp->t_pflags is never touched.
> 
> Closes: https://sashiko.dev/#/patchset/20260902131653.1338227-1-wangkefeng.wang@huawei.com
> Fixes: 756b1c343333 ("xfs: use current->journal_info for detecting transaction recursion")
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---

I agree that the Sashiko analysis looks correct. The only thing I wonder
is whether it might be a bit cleaner to have the set_context() helper
return the context instead of hardcode the assignment to ->t_pflags so
it can be used in both places. The reasoning is just that the current
arrangement kind of makes it easy to repeat this mistake in the future.

Then again, it's a single line helper so maybe another option could be
to just remove and open code it. I suppose the pro of keeping the helper
is that it's a decent spot to document the concern and why it returns a
value, etc. *shrug* Thoughts?

(Please don't change this patch just on my comments alone. Let's see if
others have input first..).

Brian

>  fs/xfs/libxfs/xfs_btree.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
> index 6738d9d1511b..8ae4b94e6995 100644
> --- a/fs/xfs/libxfs/xfs_btree.c
> +++ b/fs/xfs/libxfs/xfs_btree.c
> @@ -3007,12 +3007,18 @@ xfs_btree_split_worker(
>  {
>  	struct xfs_btree_split_args	*args = container_of(work,
>  						struct xfs_btree_split_args, work);
> -	xfs_trans_set_context(args->cur->bc_tp);
> +	unsigned int			nofs_flags;
> +
> +	/*
> +	 * Don't use xfs_trans_set_context() here: it would overwrite the
> +	 * caller's saved NOFS state in tp->t_pflags.  Use a local scope.
> +	 */
> +	nofs_flags = memalloc_nofs_save();
>  
>  	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
>  					 args->key, args->curp, args->stat);
>  
> -	xfs_trans_clear_context(args->cur->bc_tp);
> +	memalloc_nofs_restore(nofs_flags);
>  
>  	/*
>  	 * Do not access args after complete() has run here. We don't own args
> -- 
> 2.55.0
> 
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] xfs: fix NOFS state corruption in btree split worker
  2026-09-03 13:52     ` Brian Foster
@ 2026-09-04  0:41       ` Kefeng Wang
  2026-09-04 11:57         ` Brian Foster
  0 siblings, 1 reply; 23+ messages in thread
From: Kefeng Wang @ 2026-09-04  0:41 UTC (permalink / raw)
  To: Brian Foster
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs,
	linux-xfs, linux-fsdevel, linux-mm



On 9/3/2026 9:52 PM, Brian Foster wrote:
> On Thu, Sep 03, 2026 at 09:37:56PM +0800, Kefeng Wang wrote:
>> xfs_btree_split_worker() calls xfs_trans_set_context() and
>> xfs_trans_clear_context() on the caller's transaction, overwriting
>> tp->t_pflags with the worker's NOFS state. When the caller already has
>> PF_MEMALLOC_NOFS set (e.g. xfs_end_ioend_write, xfs_dio_write_end_io),
>> the corrupted tp->t_pflags causes xfs_trans_free() to erroneously clear
>> the caller's NOFS protection.
>>
>> Use memalloc_nofs_save/restore with a local variable instead so
>> tp->t_pflags is never touched.
>>
>> Closes: https://sashiko.dev/#/patchset/20260902131653.1338227-1-wangkefeng.wang@huawei.com
>> Fixes: 756b1c343333 ("xfs: use current->journal_info for detecting transaction recursion")
>> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
>> ---
> 
> I agree that the Sashiko analysis looks correct. The only thing I wonder
> is whether it might be a bit cleaner to have the set_context() helper
> return the context instead of hardcode the assignment to ->t_pflags so
> it can be used in both places. The reasoning is just that the current
> arrangement kind of makes it easy to repeat this mistake in the future.
> 
> Then again, it's a single line helper so maybe another option could be
> to just remove and open code it. I suppose the pro of keeping the helper
> is that it's a decent spot to document the concern and why it returns a
> value, etc. *shrug* Thoughts?


I personally tend to remove the helper functions, but let's see what 
others think.

> 
> (Please don't change this patch just on my comments alone. Let's see if
> others have input first..).
> 
> Brian
> 
>>   fs/xfs/libxfs/xfs_btree.c | 10 ++++++++--
>>   1 file changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
>> index 6738d9d1511b..8ae4b94e6995 100644
>> --- a/fs/xfs/libxfs/xfs_btree.c
>> +++ b/fs/xfs/libxfs/xfs_btree.c
>> @@ -3007,12 +3007,18 @@ xfs_btree_split_worker(
>>   {
>>   	struct xfs_btree_split_args	*args = container_of(work,
>>   						struct xfs_btree_split_args, work);
>> -	xfs_trans_set_context(args->cur->bc_tp);
>> +	unsigned int			nofs_flags;
>> +
>> +	/*
>> +	 * Don't use xfs_trans_set_context() here: it would overwrite the
>> +	 * caller's saved NOFS state in tp->t_pflags.  Use a local scope.
>> +	 */
>> +	nofs_flags = memalloc_nofs_save();
>>   
>>   	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
>>   					 args->key, args->curp, args->stat);
>>   
>> -	xfs_trans_clear_context(args->cur->bc_tp);
>> +	memalloc_nofs_restore(nofs_flags);
>>   
>>   	/*
>>   	 * Do not access args after complete() has run here. We don't own args
>> -- 
>> 2.55.0
>>
>>
> 
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] xfs: fix NOFS state corruption in btree split worker
  2026-09-04  0:41       ` Kefeng Wang
@ 2026-09-04 11:57         ` Brian Foster
  0 siblings, 0 replies; 23+ messages in thread
From: Brian Foster @ 2026-09-04 11:57 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: brauner, djwong, cem, akpm, vbabka, surenb, mhocko,
	brendan.jackman, hannes, ziy, david, qi.zheng, shakeel.butt, ljs,
	linux-xfs, linux-fsdevel, linux-mm

On Fri, Sep 04, 2026 at 08:41:26AM +0800, Kefeng Wang wrote:
> 
> 
> On 9/3/2026 9:52 PM, Brian Foster wrote:
> > On Thu, Sep 03, 2026 at 09:37:56PM +0800, Kefeng Wang wrote:
> > > xfs_btree_split_worker() calls xfs_trans_set_context() and
> > > xfs_trans_clear_context() on the caller's transaction, overwriting
> > > tp->t_pflags with the worker's NOFS state. When the caller already has
> > > PF_MEMALLOC_NOFS set (e.g. xfs_end_ioend_write, xfs_dio_write_end_io),
> > > the corrupted tp->t_pflags causes xfs_trans_free() to erroneously clear
> > > the caller's NOFS protection.
> > > 
> > > Use memalloc_nofs_save/restore with a local variable instead so
> > > tp->t_pflags is never touched.
> > > 
> > > Closes: https://sashiko.dev/#/patchset/20260902131653.1338227-1-wangkefeng.wang@huawei.com
> > > Fixes: 756b1c343333 ("xfs: use current->journal_info for detecting transaction recursion")
> > > Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> > > ---
> > 
> > I agree that the Sashiko analysis looks correct. The only thing I wonder
> > is whether it might be a bit cleaner to have the set_context() helper
> > return the context instead of hardcode the assignment to ->t_pflags so
> > it can be used in both places. The reasoning is just that the current
> > arrangement kind of makes it easy to repeat this mistake in the future.
> > 
> > Then again, it's a single line helper so maybe another option could be
> > to just remove and open code it. I suppose the pro of keeping the helper
> > is that it's a decent spot to document the concern and why it returns a
> > value, etc. *shrug* Thoughts?
> 
> 
> I personally tend to remove the helper functions, but let's see what others
> think.
> 

I noticed after writing this that there were many more open coded nofs
calls than I originally thought, so this is a fair point. After some
thought I think this is a reasonable approach regardless:

Reviewed-by: Brian Foster <bfoster@redhat.com>

You might want to send as a standalone patch though..

Brian

> > 
> > (Please don't change this patch just on my comments alone. Let's see if
> > others have input first..).
> > 
> > Brian
> > 
> > >   fs/xfs/libxfs/xfs_btree.c | 10 ++++++++--
> > >   1 file changed, 8 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
> > > index 6738d9d1511b..8ae4b94e6995 100644
> > > --- a/fs/xfs/libxfs/xfs_btree.c
> > > +++ b/fs/xfs/libxfs/xfs_btree.c
> > > @@ -3007,12 +3007,18 @@ xfs_btree_split_worker(
> > >   {
> > >   	struct xfs_btree_split_args	*args = container_of(work,
> > >   						struct xfs_btree_split_args, work);
> > > -	xfs_trans_set_context(args->cur->bc_tp);
> > > +	unsigned int			nofs_flags;
> > > +
> > > +	/*
> > > +	 * Don't use xfs_trans_set_context() here: it would overwrite the
> > > +	 * caller's saved NOFS state in tp->t_pflags.  Use a local scope.
> > > +	 */
> > > +	nofs_flags = memalloc_nofs_save();
> > >   	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
> > >   					 args->key, args->curp, args->stat);
> > > -	xfs_trans_clear_context(args->cur->bc_tp);
> > > +	memalloc_nofs_restore(nofs_flags);
> > >   	/*
> > >   	 * Do not access args after complete() has run here. We don't own args
> > > -- 
> > > 2.55.0
> > > 
> > > 
> > 
> > 
> 



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2026-09-04 11:57 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 13:16 [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang
2026-09-02 13:16 ` [PATCH 1/4] xfs: remove dead kswapd flag inheritance from btree split worker Kefeng Wang
2026-09-02 14:32   ` Christoph Hellwig
2026-09-02 15:33   ` Shakeel Butt
2026-09-02 13:16 ` [PATCH 2/4] iomap: simplify writepages reclaim guard Kefeng Wang
2026-09-02 14:32   ` Christoph Hellwig
2026-09-03 13:46     ` Kefeng Wang
2026-09-02 15:34   ` Shakeel Butt
2026-09-02 13:16 ` [PATCH 3/4] mm: replace PF_KSWAPD flag with kthread_func() check Kefeng Wang
2026-09-02 15:36   ` Shakeel Butt
2026-09-02 16:35   ` Vlastimil Babka (SUSE)
2026-09-02 16:39   ` Zi Yan
2026-09-02 13:16 ` [PATCH 4/4] mm: replace PF_KCOMPACTD " Kefeng Wang
2026-09-02 15:37   ` Shakeel Butt
2026-09-02 16:36   ` Vlastimil Babka (SUSE)
2026-09-02 16:40   ` Zi Yan
2026-09-02 15:31 ` [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Shakeel Butt
2026-09-02 20:44 ` Andrew Morton
2026-09-03 13:37   ` [PATCH] xfs: fix NOFS state corruption in btree split worker Kefeng Wang
2026-09-03 13:52     ` Brian Foster
2026-09-04  0:41       ` Kefeng Wang
2026-09-04 11:57         ` Brian Foster
2026-09-03 13:40   ` [PATCH 0/4] mm: replace PF_KCOMPACTD/PF_KSWAPD with kthread_func() Kefeng Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox