2023-09-13 15:55:35

by Jan Kara

[permalink] [raw]
Subject: [PATCH 0/2] ext4: Do not let fstrim block suspend

Hello,

these two patches fix a long standing issue that long running fstrim request
can block a system suspend as reported by Len Brown in [1]. The solution is
quite simple - just report whatever we have trimmed upto now since discard
is an advisory call anyway. What makes things a bit more complex is handling
of group's TRIMMED bit - we deal with that in patch 1.

Honza

[1] https://bugzilla.kernel.org/show_bug.cgi?id=216322


2023-09-14 03:29:13

by Jan Kara

[permalink] [raw]
Subject: [PATCH 2/2] ext4: Do not let fstrim block system suspend

Len Brown has reported that system suspend sometimes fail due to
inability to freeze a task working in ext4_trim_fs() for one minute.
Trimming a large filesystem on a disk that slowly processes discard
requests can indeed take a long time. Since discard is just an advisory
call, it is perfectly fine to interrupt it at any time and the return
number of discarded blocks until that moment. Do that when we detect the
task is being frozen.

Reported-by: Len Brown <[email protected]>
Suggested-by: Dave Chinner <[email protected]>
References: https://bugzilla.kernel.org/show_bug.cgi?id=216322
Signed-off-by: Jan Kara <[email protected]>
---
fs/ext4/mballoc.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 09091adfde64..1e599305d85f 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/nospec.h>
#include <linux/backing-dev.h>
+#include <linux/freezer.h>
#include <trace/events/ext4.h>

/*
@@ -6916,6 +6917,11 @@ static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb,
EXT4_CLUSTER_BITS(sb);
}

+static bool ext4_trim_interrupted(void)
+{
+ return fatal_signal_pending(current) || freezing(current);
+}
+
static int ext4_try_to_trim_range(struct super_block *sb,
struct ext4_buddy *e4b, ext4_grpblk_t start,
ext4_grpblk_t max, ext4_grpblk_t minblocks)
@@ -6949,8 +6955,8 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group))
free_count += next - start;
start = next + 1;

- if (fatal_signal_pending(current))
- return -ERESTARTSYS;
+ if (ext4_trim_interrupted())
+ return count;

if (need_resched()) {
ext4_unlock_group(sb, e4b->bd_group);
@@ -7072,6 +7078,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;

for (group = first_group; group <= last_group; group++) {
+ if (ext4_trim_interrupted())
+ break;
grp = ext4_get_group_info(sb, group);
if (!grp)
continue;
--
2.35.3

2023-09-14 15:18:13

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH 0/2] ext4: Do not let fstrim block suspend


On Wed, 13 Sep 2023 17:04:53 +0200, Jan Kara wrote:
> these two patches fix a long standing issue that long running fstrim request
> can block a system suspend as reported by Len Brown in [1]. The solution is
> quite simple - just report whatever we have trimmed upto now since discard
> is an advisory call anyway. What makes things a bit more complex is handling
> of group's TRIMMED bit - we deal with that in patch 1.
>
> Honza
>
> [...]

Applied, thanks!

[1/2] ext4: Move setting of trimmed bit into ext4_try_to_trim_range()
commit: 5e4a9f11b5d7cb70a4e4474f0ba25d5f1fd2a8ed
[2/2] ext4: Do not let fstrim block system suspend
commit: b016ebb300e514bc46151f8fc006caae141a8bde

Best regards,
--
Theodore Ts'o <[email protected]>