* FAILED: patch "[PATCH] ext4: fix the might_sleep() warnings in kvfree()" failed to apply to 6.1-stable tree
@ 2026-03-30 11:05 gregkh
2026-04-02 16:31 ` [PATCH 6.1.y 1/4] ext4: factor out ext4_percpu_param_init() and ext4_percpu_param_destroy() Sasha Levin
0 siblings, 1 reply; 5+ messages in thread
From: gregkh @ 2026-03-30 11:05 UTC (permalink / raw)
To: qiang.zhang, libaokun, tytso; +Cc: stable
The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 496bb99b7e66f48b178126626f47e9ba79e2d0fa
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026033016-eagle-gangrene-7fc7@gregkh' --subject-prefix 'PATCH 6.1.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 496bb99b7e66f48b178126626f47e9ba79e2d0fa Mon Sep 17 00:00:00 2001
From: Zqiang <qiang.zhang@linux.dev>
Date: Thu, 19 Mar 2026 17:45:45 +0800
Subject: [PATCH] ext4: fix the might_sleep() warnings in kvfree()
Use the kvfree() in the RCU read critical section can trigger
the following warnings:
EXT4-fs (vdb): unmounting filesystem cd983e5b-3c83-4f5a-a136-17b00eb9d018.
WARNING: suspicious RCU usage
./include/linux/rcupdate.h:409 Illegal context switch in RCU read-side critical section!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
Call Trace:
<TASK>
dump_stack_lvl+0xbb/0xd0
dump_stack+0x14/0x20
lockdep_rcu_suspicious+0x15a/0x1b0
__might_resched+0x375/0x4d0
? put_object.part.0+0x2c/0x50
__might_sleep+0x108/0x160
vfree+0x58/0x910
? ext4_group_desc_free+0x27/0x270
kvfree+0x23/0x40
ext4_group_desc_free+0x111/0x270
ext4_put_super+0x3c8/0xd40
generic_shutdown_super+0x14c/0x4a0
? __pfx_shrinker_free+0x10/0x10
kill_block_super+0x40/0x90
ext4_kill_sb+0x6d/0xb0
deactivate_locked_super+0xb4/0x180
deactivate_super+0x7e/0xa0
cleanup_mnt+0x296/0x3e0
__cleanup_mnt+0x16/0x20
task_work_run+0x157/0x250
? __pfx_task_work_run+0x10/0x10
? exit_to_user_mode_loop+0x6a/0x550
exit_to_user_mode_loop+0x102/0x550
do_syscall_64+0x44a/0x500
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
BUG: sleeping function called from invalid context at mm/vmalloc.c:3441
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 556, name: umount
preempt_count: 1, expected: 0
CPU: 3 UID: 0 PID: 556 Comm: umount
Call Trace:
<TASK>
dump_stack_lvl+0xbb/0xd0
dump_stack+0x14/0x20
__might_resched+0x275/0x4d0
? put_object.part.0+0x2c/0x50
__might_sleep+0x108/0x160
vfree+0x58/0x910
? ext4_group_desc_free+0x27/0x270
kvfree+0x23/0x40
ext4_group_desc_free+0x111/0x270
ext4_put_super+0x3c8/0xd40
generic_shutdown_super+0x14c/0x4a0
? __pfx_shrinker_free+0x10/0x10
kill_block_super+0x40/0x90
ext4_kill_sb+0x6d/0xb0
deactivate_locked_super+0xb4/0x180
deactivate_super+0x7e/0xa0
cleanup_mnt+0x296/0x3e0
__cleanup_mnt+0x16/0x20
task_work_run+0x157/0x250
? __pfx_task_work_run+0x10/0x10
? exit_to_user_mode_loop+0x6a/0x550
exit_to_user_mode_loop+0x102/0x550
do_syscall_64+0x44a/0x500
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The above scenarios occur in initialization failures and teardown
paths, there are no parallel operations on the resources released
by kvfree(), this commit therefore remove rcu_read_lock/unlock() and
use rcu_access_pointer() instead of rcu_dereference() operations.
Fixes: 7c990728b99e ("ext4: fix potential race between s_flex_groups online resizing and access")
Fixes: df3da4ea5a0f ("ext4: fix potential race between s_group_info online resizing and access")
Signed-off-by: Zqiang <qiang.zhang@linux.dev>
Reviewed-by: Baokun Li <libaokun@linux.alibaba.com>
Link: https://patch.msgid.link/20260319094545.19291-1-qiang.zhang@linux.dev
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 93d37f6cf9c3..bb6faebf9b6d 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3584,9 +3584,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
rcu_read_unlock();
iput(sbi->s_buddy_cache);
err_freesgi:
- rcu_read_lock();
- kvfree(rcu_dereference(sbi->s_group_info));
- rcu_read_unlock();
+ kvfree(rcu_access_pointer(sbi->s_group_info));
return -ENOMEM;
}
@@ -3901,7 +3899,8 @@ void ext4_mb_release(struct super_block *sb)
WARN_ON_ONCE(!list_empty(&sbi->s_discard_list));
}
- if (sbi->s_group_info) {
+ group_info = rcu_access_pointer(sbi->s_group_info);
+ if (group_info) {
for (i = 0; i < ngroups; i++) {
cond_resched();
grinfo = ext4_get_group_info(sb, i);
@@ -3919,12 +3918,9 @@ void ext4_mb_release(struct super_block *sb)
num_meta_group_infos = (ngroups +
EXT4_DESC_PER_BLOCK(sb) - 1) >>
EXT4_DESC_PER_BLOCK_BITS(sb);
- rcu_read_lock();
- group_info = rcu_dereference(sbi->s_group_info);
for (i = 0; i < num_meta_group_infos; i++)
kfree(group_info[i]);
kvfree(group_info);
- rcu_read_unlock();
}
ext4_mb_avg_fragment_size_destroy(sbi);
ext4_mb_largest_free_orders_destroy(sbi);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 152c58fe8e01..baa067eb8cf4 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1254,12 +1254,10 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
struct buffer_head **group_desc;
int i;
- rcu_read_lock();
- group_desc = rcu_dereference(sbi->s_group_desc);
+ group_desc = rcu_access_pointer(sbi->s_group_desc);
for (i = 0; i < sbi->s_gdb_count; i++)
brelse(group_desc[i]);
kvfree(group_desc);
- rcu_read_unlock();
}
static void ext4_flex_groups_free(struct ext4_sb_info *sbi)
@@ -1267,14 +1265,12 @@ static void ext4_flex_groups_free(struct ext4_sb_info *sbi)
struct flex_groups **flex_groups;
int i;
- rcu_read_lock();
- flex_groups = rcu_dereference(sbi->s_flex_groups);
+ flex_groups = rcu_access_pointer(sbi->s_flex_groups);
if (flex_groups) {
for (i = 0; i < sbi->s_flex_groups_allocated; i++)
kvfree(flex_groups[i]);
kvfree(flex_groups);
}
- rcu_read_unlock();
}
static void ext4_put_super(struct super_block *sb)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 1/4] ext4: factor out ext4_percpu_param_init() and ext4_percpu_param_destroy()
2026-03-30 11:05 FAILED: patch "[PATCH] ext4: fix the might_sleep() warnings in kvfree()" failed to apply to 6.1-stable tree gregkh
@ 2026-04-02 16:31 ` Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 2/4] ext4: use ext4_group_desc_free() in ext4_put_super() to save some duplicated code Sasha Levin
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Sasha Levin @ 2026-04-02 16:31 UTC (permalink / raw)
To: stable; +Cc: Jason Yan, Theodore Ts'o, Sasha Levin
From: Jason Yan <yanaijie@huawei.com>
[ Upstream commit 1f79467c8a6be64940a699de1bd43338a6dd9fdd ]
Factor out ext4_percpu_param_init() and ext4_percpu_param_destroy(). And
also use ext4_percpu_param_destroy() in ext4_put_super() to avoid
duplicated code. No functional change.
Signed-off-by: Jason Yan <yanaijie@huawei.com>
Link: https://lore.kernel.org/r/20230323140517.1070239-3-yanaijie@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Stable-dep-of: 496bb99b7e66 ("ext4: fix the might_sleep() warnings in kvfree()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 85 ++++++++++++++++++++++++++-----------------------
1 file changed, 46 insertions(+), 39 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index fa5642838c79c..31d7df1560158 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1193,6 +1193,49 @@ static inline void ext4_quota_off_umount(struct super_block *sb)
}
#endif
+static int ext4_percpu_param_init(struct ext4_sb_info *sbi)
+{
+ ext4_fsblk_t block;
+ int err;
+
+ block = ext4_count_free_clusters(sbi->s_sb);
+ ext4_free_blocks_count_set(sbi->s_es, EXT4_C2B(sbi, block));
+ err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
+ GFP_KERNEL);
+ if (!err) {
+ unsigned long freei = ext4_count_free_inodes(sbi->s_sb);
+ sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
+ err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
+ GFP_KERNEL);
+ }
+ if (!err)
+ err = percpu_counter_init(&sbi->s_dirs_counter,
+ ext4_count_dirs(sbi->s_sb), GFP_KERNEL);
+ if (!err)
+ err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0,
+ GFP_KERNEL);
+ if (!err)
+ err = percpu_counter_init(&sbi->s_sra_exceeded_retry_limit, 0,
+ GFP_KERNEL);
+ if (!err)
+ err = percpu_init_rwsem(&sbi->s_writepages_rwsem);
+
+ if (err)
+ ext4_msg(sbi->s_sb, KERN_ERR, "insufficient memory");
+
+ return err;
+}
+
+static void ext4_percpu_param_destroy(struct ext4_sb_info *sbi)
+{
+ percpu_counter_destroy(&sbi->s_freeclusters_counter);
+ percpu_counter_destroy(&sbi->s_freeinodes_counter);
+ percpu_counter_destroy(&sbi->s_dirs_counter);
+ percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
+ percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit);
+ percpu_free_rwsem(&sbi->s_writepages_rwsem);
+}
+
static void ext4_put_super(struct super_block *sb)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -1259,12 +1302,7 @@ static void ext4_put_super(struct super_block *sb)
kvfree(flex_groups);
}
rcu_read_unlock();
- percpu_counter_destroy(&sbi->s_freeclusters_counter);
- percpu_counter_destroy(&sbi->s_freeinodes_counter);
- percpu_counter_destroy(&sbi->s_dirs_counter);
- percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
- percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit);
- percpu_free_rwsem(&sbi->s_writepages_rwsem);
+ ext4_percpu_param_destroy(sbi);
#ifdef CONFIG_QUOTA
for (i = 0; i < EXT4_MAXQUOTAS; i++)
kfree(get_qf_name(sb, sbi, i));
@@ -5081,7 +5119,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
struct ext4_super_block *es = NULL;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct flex_groups **flex_groups;
- ext4_fsblk_t block;
ext4_fsblk_t logical_sb_block;
struct inode *root;
int ret = -ENOMEM;
@@ -5488,33 +5525,8 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
sbi->s_journal->j_commit_callback =
ext4_journal_commit_callback;
- block = ext4_count_free_clusters(sb);
- ext4_free_blocks_count_set(sbi->s_es,
- EXT4_C2B(sbi, block));
- err = percpu_counter_init(&sbi->s_freeclusters_counter, block,
- GFP_KERNEL);
- if (!err) {
- unsigned long freei = ext4_count_free_inodes(sb);
- sbi->s_es->s_free_inodes_count = cpu_to_le32(freei);
- err = percpu_counter_init(&sbi->s_freeinodes_counter, freei,
- GFP_KERNEL);
- }
- if (!err)
- err = percpu_counter_init(&sbi->s_dirs_counter,
- ext4_count_dirs(sb), GFP_KERNEL);
- if (!err)
- err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0,
- GFP_KERNEL);
- if (!err)
- err = percpu_counter_init(&sbi->s_sra_exceeded_retry_limit, 0,
- GFP_KERNEL);
- if (!err)
- err = percpu_init_rwsem(&sbi->s_writepages_rwsem);
-
- if (err) {
- ext4_msg(sb, KERN_ERR, "insufficient memory");
+ if (ext4_percpu_param_init(sbi))
goto failed_mount6;
- }
if (ext4_has_feature_flex_bg(sb))
if (!ext4_fill_flex_info(sb)) {
@@ -5605,12 +5617,7 @@ failed_mount9: __maybe_unused
kvfree(flex_groups);
}
rcu_read_unlock();
- percpu_counter_destroy(&sbi->s_freeclusters_counter);
- percpu_counter_destroy(&sbi->s_freeinodes_counter);
- percpu_counter_destroy(&sbi->s_dirs_counter);
- percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
- percpu_counter_destroy(&sbi->s_sra_exceeded_retry_limit);
- percpu_free_rwsem(&sbi->s_writepages_rwsem);
+ ext4_percpu_param_destroy(sbi);
failed_mount5:
ext4_ext_release(sb);
ext4_release_system_zone(sb);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 2/4] ext4: use ext4_group_desc_free() in ext4_put_super() to save some duplicated code
2026-04-02 16:31 ` [PATCH 6.1.y 1/4] ext4: factor out ext4_percpu_param_init() and ext4_percpu_param_destroy() Sasha Levin
@ 2026-04-02 16:31 ` Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 3/4] ext4: factor out ext4_flex_groups_free() Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 4/4] ext4: fix the might_sleep() warnings in kvfree() Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-04-02 16:31 UTC (permalink / raw)
To: stable; +Cc: Jason Yan, Theodore Ts'o, Sasha Levin
From: Jason Yan <yanaijie@huawei.com>
[ Upstream commit 6ef684988816fdfa29ceff260c97d725a489a942 ]
The only difference here is that ->s_group_desc and ->s_flex_groups share
the same rcu read lock here but it is not necessary. In other places they
do not share the lock at all.
Signed-off-by: Jason Yan <yanaijie@huawei.com>
Link: https://lore.kernel.org/r/20230323140517.1070239-4-yanaijie@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Stable-dep-of: 496bb99b7e66 ("ext4: fix the might_sleep() warnings in kvfree()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 31d7df1560158..25d8422d9a1f8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1236,11 +1236,23 @@ static void ext4_percpu_param_destroy(struct ext4_sb_info *sbi)
percpu_free_rwsem(&sbi->s_writepages_rwsem);
}
+static void ext4_group_desc_free(struct ext4_sb_info *sbi)
+{
+ struct buffer_head **group_desc;
+ int i;
+
+ rcu_read_lock();
+ group_desc = rcu_dereference(sbi->s_group_desc);
+ for (i = 0; i < sbi->s_gdb_count; i++)
+ brelse(group_desc[i]);
+ kvfree(group_desc);
+ rcu_read_unlock();
+}
+
static void ext4_put_super(struct super_block *sb)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_super_block *es = sbi->s_es;
- struct buffer_head **group_desc;
struct flex_groups **flex_groups;
int aborted = 0;
int i, err;
@@ -1290,11 +1302,8 @@ static void ext4_put_super(struct super_block *sb)
if (!sb_rdonly(sb))
ext4_commit_super(sb);
+ ext4_group_desc_free(sbi);
rcu_read_lock();
- group_desc = rcu_dereference(sbi->s_group_desc);
- for (i = 0; i < sbi->s_gdb_count; i++)
- brelse(group_desc[i]);
- kvfree(group_desc);
flex_groups = rcu_dereference(sbi->s_flex_groups);
if (flex_groups) {
for (i = 0; i < sbi->s_flex_groups_allocated; i++)
@@ -4763,19 +4772,6 @@ static int ext4_geometry_check(struct super_block *sb,
return 0;
}
-static void ext4_group_desc_free(struct ext4_sb_info *sbi)
-{
- struct buffer_head **group_desc;
- int i;
-
- rcu_read_lock();
- group_desc = rcu_dereference(sbi->s_group_desc);
- for (i = 0; i < sbi->s_gdb_count; i++)
- brelse(group_desc[i]);
- kvfree(group_desc);
- rcu_read_unlock();
-}
-
static int ext4_group_desc_init(struct super_block *sb,
struct ext4_super_block *es,
ext4_fsblk_t logical_sb_block,
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 3/4] ext4: factor out ext4_flex_groups_free()
2026-04-02 16:31 ` [PATCH 6.1.y 1/4] ext4: factor out ext4_percpu_param_init() and ext4_percpu_param_destroy() Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 2/4] ext4: use ext4_group_desc_free() in ext4_put_super() to save some duplicated code Sasha Levin
@ 2026-04-02 16:31 ` Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 4/4] ext4: fix the might_sleep() warnings in kvfree() Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-04-02 16:31 UTC (permalink / raw)
To: stable; +Cc: Jason Yan, Theodore Ts'o, Sasha Levin
From: Jason Yan <yanaijie@huawei.com>
[ Upstream commit dcbf87589d90e3bd5a5a4cf832517f22f3c55efb ]
Factor out ext4_flex_groups_free() and it can be used both in
__ext4_fill_super() and ext4_put_super().
Signed-off-by: Jason Yan <yanaijie@huawei.com>
Link: https://lore.kernel.org/r/20230323140517.1070239-5-yanaijie@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Stable-dep-of: 496bb99b7e66 ("ext4: fix the might_sleep() warnings in kvfree()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/super.c | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 25d8422d9a1f8..85286a50dcb2f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1249,11 +1249,25 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
rcu_read_unlock();
}
+static void ext4_flex_groups_free(struct ext4_sb_info *sbi)
+{
+ struct flex_groups **flex_groups;
+ int i;
+
+ rcu_read_lock();
+ flex_groups = rcu_dereference(sbi->s_flex_groups);
+ if (flex_groups) {
+ for (i = 0; i < sbi->s_flex_groups_allocated; i++)
+ kvfree(flex_groups[i]);
+ kvfree(flex_groups);
+ }
+ rcu_read_unlock();
+}
+
static void ext4_put_super(struct super_block *sb)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_super_block *es = sbi->s_es;
- struct flex_groups **flex_groups;
int aborted = 0;
int i, err;
@@ -1303,14 +1317,7 @@ static void ext4_put_super(struct super_block *sb)
ext4_commit_super(sb);
ext4_group_desc_free(sbi);
- rcu_read_lock();
- flex_groups = rcu_dereference(sbi->s_flex_groups);
- if (flex_groups) {
- for (i = 0; i < sbi->s_flex_groups_allocated; i++)
- kvfree(flex_groups[i]);
- kvfree(flex_groups);
- }
- rcu_read_unlock();
+ ext4_flex_groups_free(sbi);
ext4_percpu_param_destroy(sbi);
#ifdef CONFIG_QUOTA
for (i = 0; i < EXT4_MAXQUOTAS; i++)
@@ -5114,7 +5121,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
{
struct ext4_super_block *es = NULL;
struct ext4_sb_info *sbi = EXT4_SB(sb);
- struct flex_groups **flex_groups;
ext4_fsblk_t logical_sb_block;
struct inode *root;
int ret = -ENOMEM;
@@ -5605,14 +5611,7 @@ failed_mount9: __maybe_unused
ext4_unregister_li_request(sb);
failed_mount6:
ext4_mb_release(sb);
- rcu_read_lock();
- flex_groups = rcu_dereference(sbi->s_flex_groups);
- if (flex_groups) {
- for (i = 0; i < sbi->s_flex_groups_allocated; i++)
- kvfree(flex_groups[i]);
- kvfree(flex_groups);
- }
- rcu_read_unlock();
+ ext4_flex_groups_free(sbi);
ext4_percpu_param_destroy(sbi);
failed_mount5:
ext4_ext_release(sb);
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.1.y 4/4] ext4: fix the might_sleep() warnings in kvfree()
2026-04-02 16:31 ` [PATCH 6.1.y 1/4] ext4: factor out ext4_percpu_param_init() and ext4_percpu_param_destroy() Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 2/4] ext4: use ext4_group_desc_free() in ext4_put_super() to save some duplicated code Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 3/4] ext4: factor out ext4_flex_groups_free() Sasha Levin
@ 2026-04-02 16:31 ` Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-04-02 16:31 UTC (permalink / raw)
To: stable; +Cc: Zqiang, Baokun Li, Theodore Ts'o, stable, Sasha Levin
From: Zqiang <qiang.zhang@linux.dev>
[ Upstream commit 496bb99b7e66f48b178126626f47e9ba79e2d0fa ]
Use the kvfree() in the RCU read critical section can trigger
the following warnings:
EXT4-fs (vdb): unmounting filesystem cd983e5b-3c83-4f5a-a136-17b00eb9d018.
WARNING: suspicious RCU usage
./include/linux/rcupdate.h:409 Illegal context switch in RCU read-side critical section!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
Call Trace:
<TASK>
dump_stack_lvl+0xbb/0xd0
dump_stack+0x14/0x20
lockdep_rcu_suspicious+0x15a/0x1b0
__might_resched+0x375/0x4d0
? put_object.part.0+0x2c/0x50
__might_sleep+0x108/0x160
vfree+0x58/0x910
? ext4_group_desc_free+0x27/0x270
kvfree+0x23/0x40
ext4_group_desc_free+0x111/0x270
ext4_put_super+0x3c8/0xd40
generic_shutdown_super+0x14c/0x4a0
? __pfx_shrinker_free+0x10/0x10
kill_block_super+0x40/0x90
ext4_kill_sb+0x6d/0xb0
deactivate_locked_super+0xb4/0x180
deactivate_super+0x7e/0xa0
cleanup_mnt+0x296/0x3e0
__cleanup_mnt+0x16/0x20
task_work_run+0x157/0x250
? __pfx_task_work_run+0x10/0x10
? exit_to_user_mode_loop+0x6a/0x550
exit_to_user_mode_loop+0x102/0x550
do_syscall_64+0x44a/0x500
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
BUG: sleeping function called from invalid context at mm/vmalloc.c:3441
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 556, name: umount
preempt_count: 1, expected: 0
CPU: 3 UID: 0 PID: 556 Comm: umount
Call Trace:
<TASK>
dump_stack_lvl+0xbb/0xd0
dump_stack+0x14/0x20
__might_resched+0x275/0x4d0
? put_object.part.0+0x2c/0x50
__might_sleep+0x108/0x160
vfree+0x58/0x910
? ext4_group_desc_free+0x27/0x270
kvfree+0x23/0x40
ext4_group_desc_free+0x111/0x270
ext4_put_super+0x3c8/0xd40
generic_shutdown_super+0x14c/0x4a0
? __pfx_shrinker_free+0x10/0x10
kill_block_super+0x40/0x90
ext4_kill_sb+0x6d/0xb0
deactivate_locked_super+0xb4/0x180
deactivate_super+0x7e/0xa0
cleanup_mnt+0x296/0x3e0
__cleanup_mnt+0x16/0x20
task_work_run+0x157/0x250
? __pfx_task_work_run+0x10/0x10
? exit_to_user_mode_loop+0x6a/0x550
exit_to_user_mode_loop+0x102/0x550
do_syscall_64+0x44a/0x500
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The above scenarios occur in initialization failures and teardown
paths, there are no parallel operations on the resources released
by kvfree(), this commit therefore remove rcu_read_lock/unlock() and
use rcu_access_pointer() instead of rcu_dereference() operations.
Fixes: 7c990728b99e ("ext4: fix potential race between s_flex_groups online resizing and access")
Fixes: df3da4ea5a0f ("ext4: fix potential race between s_group_info online resizing and access")
Signed-off-by: Zqiang <qiang.zhang@linux.dev>
Reviewed-by: Baokun Li <libaokun@linux.alibaba.com>
Link: https://patch.msgid.link/20260319094545.19291-1-qiang.zhang@linux.dev
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext4/mballoc.c | 10 +++-------
fs/ext4/super.c | 8 ++------
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index e204f16e33ad3..9127e5184c1ae 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3294,9 +3294,7 @@ static int ext4_mb_init_backend(struct super_block *sb)
rcu_read_unlock();
iput(sbi->s_buddy_cache);
err_freesgi:
- rcu_read_lock();
- kvfree(rcu_dereference(sbi->s_group_info));
- rcu_read_unlock();
+ kvfree(rcu_access_pointer(sbi->s_group_info));
return -ENOMEM;
}
@@ -3595,7 +3593,8 @@ int ext4_mb_release(struct super_block *sb)
WARN_ON_ONCE(!list_empty(&sbi->s_discard_list));
}
- if (sbi->s_group_info) {
+ group_info = rcu_access_pointer(sbi->s_group_info);
+ if (group_info) {
for (i = 0; i < ngroups; i++) {
cond_resched();
grinfo = ext4_get_group_info(sb, i);
@@ -3613,12 +3612,9 @@ int ext4_mb_release(struct super_block *sb)
num_meta_group_infos = (ngroups +
EXT4_DESC_PER_BLOCK(sb) - 1) >>
EXT4_DESC_PER_BLOCK_BITS(sb);
- rcu_read_lock();
- group_info = rcu_dereference(sbi->s_group_info);
for (i = 0; i < num_meta_group_infos; i++)
kfree(group_info[i]);
kvfree(group_info);
- rcu_read_unlock();
}
kfree(sbi->s_mb_avg_fragment_size);
kfree(sbi->s_mb_avg_fragment_size_locks);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 85286a50dcb2f..c004aaa722201 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1241,12 +1241,10 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
struct buffer_head **group_desc;
int i;
- rcu_read_lock();
- group_desc = rcu_dereference(sbi->s_group_desc);
+ group_desc = rcu_access_pointer(sbi->s_group_desc);
for (i = 0; i < sbi->s_gdb_count; i++)
brelse(group_desc[i]);
kvfree(group_desc);
- rcu_read_unlock();
}
static void ext4_flex_groups_free(struct ext4_sb_info *sbi)
@@ -1254,14 +1252,12 @@ static void ext4_flex_groups_free(struct ext4_sb_info *sbi)
struct flex_groups **flex_groups;
int i;
- rcu_read_lock();
- flex_groups = rcu_dereference(sbi->s_flex_groups);
+ flex_groups = rcu_access_pointer(sbi->s_flex_groups);
if (flex_groups) {
for (i = 0; i < sbi->s_flex_groups_allocated; i++)
kvfree(flex_groups[i]);
kvfree(flex_groups);
}
- rcu_read_unlock();
}
static void ext4_put_super(struct super_block *sb)
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-02 16:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-30 11:05 FAILED: patch "[PATCH] ext4: fix the might_sleep() warnings in kvfree()" failed to apply to 6.1-stable tree gregkh
2026-04-02 16:31 ` [PATCH 6.1.y 1/4] ext4: factor out ext4_percpu_param_init() and ext4_percpu_param_destroy() Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 2/4] ext4: use ext4_group_desc_free() in ext4_put_super() to save some duplicated code Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 3/4] ext4: factor out ext4_flex_groups_free() Sasha Levin
2026-04-02 16:31 ` [PATCH 6.1.y 4/4] ext4: fix the might_sleep() warnings in kvfree() Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox