From: Ye Bin <yebi...@huawei.com>

[ Upstream commit 70022da804f0f3f152115688885608c39182082e ]

As we test disk offline/online with running fsstress, we find fsstress
process is keeping running state.
kworker/u32:3-262   [004] ...1   140.787471: ext4_mb_discard_preallocations: 
dev 8,32 needed 114
....
kworker/u32:3-262   [004] ...1   140.787471: ext4_mb_discard_preallocations: 
dev 8,32 needed 114

ext4_mb_new_blocks
repeat:
        ext4_mb_discard_preallocations_should_retry(sb, ac, &seq)
                freed = ext4_mb_discard_preallocations
                        ext4_mb_discard_group_preallocations
                                this_cpu_inc(discard_pa_seq);
                ---> freed == 0
                seq_retry = ext4_get_discard_pa_seq_sum
                        for_each_possible_cpu(__cpu)
                                __seq += per_cpu(discard_pa_seq, __cpu);
                if (seq_retry != *seq) {
                        *seq = seq_retry;
                        ret = true;
                }

As we see seq_retry is sum of discard_pa_seq every cpu, if
ext4_mb_discard_group_preallocations return zero discard_pa_seq in this
cpu maybe increase one, so condition "seq_retry != *seq" have always
been met.
Ritesh Harjani suggest to in ext4_mb_discard_group_preallocations function we
only increase discard_pa_seq when there is some PA to free.

Fixes: 07b5b8e1ac40 ("ext4: mballoc: introduce pcpu seqcnt for freeing PA to 
improve ENOSPC handling")
Signed-off-by: Ye Bin <yebi...@huawei.com>
Reviewed-by: Jan Kara <j...@suse.cz>
Reviewed-by: Ritesh Harjani <rite...@linux.ibm.com>
Link: https://lore.kernel.org/r/20200916113859.1556397-3-yebi...@huawei.com
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 fs/ext4/mballoc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index e88eff999bd15..787a894f5d1da 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -4066,7 +4066,6 @@ ext4_mb_discard_group_preallocations(struct super_block 
*sb,
        INIT_LIST_HEAD(&list);
 repeat:
        ext4_lock_group(sb, group);
-       this_cpu_inc(discard_pa_seq);
        list_for_each_entry_safe(pa, tmp,
                                &grp->bb_prealloc_list, pa_group_list) {
                spin_lock(&pa->pa_lock);
@@ -4083,6 +4082,9 @@ ext4_mb_discard_group_preallocations(struct super_block 
*sb,
                /* seems this one can be freed ... */
                ext4_mb_mark_pa_deleted(sb, pa);
 
+               if (!free)
+                       this_cpu_inc(discard_pa_seq);
+
                /* we can trust pa_free ... */
                free += pa->pa_free;
 
-- 
2.25.1



Reply via email to