Skip to content

Commit 551836d

Browse files
Jaegeuk Kimpundiramit
authored andcommitted
f2fs: relax async discard commands more
commit 4e6a8d9b224f886362ea6e8f6046b541437c944f upstream. This patch relaxes async discard commands to avoid waiting its end_io during checkpoint. Instead of waiting them during checkpoint, it will be done when actually reusing them. Test on initial partition of nvme drive. # time fstrim /mnt/test Before : 6.158s After : 4.822s Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 3e60c84 commit 551836d

4 files changed

Lines changed: 27 additions & 11 deletions

File tree

fs/f2fs/checkpoint.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,6 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
12551255
f2fs_bug_on(sbi, prefree_segments(sbi));
12561256
flush_sit_entries(sbi, cpc);
12571257
clear_prefree_segments(sbi, cpc);
1258-
f2fs_wait_all_discard_bio(sbi);
12591258
unblock_operations(sbi);
12601259
goto out;
12611260
}
@@ -1274,12 +1273,10 @@ int write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
12741273

12751274
/* unlock all the fs_lock[] in do_checkpoint() */
12761275
err = do_checkpoint(sbi, cpc);
1277-
if (err) {
1276+
if (err)
12781277
release_discard_addrs(sbi);
1279-
} else {
1278+
else
12801279
clear_prefree_segments(sbi, cpc);
1281-
f2fs_wait_all_discard_bio(sbi);
1282-
}
12831280

12841281
unblock_operations(sbi);
12851282
stat_inc_cp_count(sbi->stat_info);

fs/f2fs/f2fs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ struct discard_entry {
250250

251251
struct bio_entry {
252252
struct list_head list;
253+
block_t lstart;
254+
block_t len;
253255
struct bio *bio;
254256
struct completion event;
255257
int error;
@@ -2178,7 +2180,7 @@ void destroy_flush_cmd_control(struct f2fs_sb_info *, bool);
21782180
void invalidate_blocks(struct f2fs_sb_info *, block_t);
21792181
bool is_checkpointed_data(struct f2fs_sb_info *, block_t);
21802182
void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t);
2181-
void f2fs_wait_all_discard_bio(struct f2fs_sb_info *);
2183+
void f2fs_wait_discard_bio(struct f2fs_sb_info *, block_t);
21822184
void clear_prefree_segments(struct f2fs_sb_info *, struct cp_control *);
21832185
void release_discard_addrs(struct f2fs_sb_info *);
21842186
int npages_for_summary_flush(struct f2fs_sb_info *, bool);

fs/f2fs/segment.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -625,20 +625,23 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
625625
}
626626

627627
static struct bio_entry *__add_bio_entry(struct f2fs_sb_info *sbi,
628-
struct bio *bio)
628+
struct bio *bio, block_t lstart, block_t len)
629629
{
630630
struct list_head *wait_list = &(SM_I(sbi)->wait_list);
631631
struct bio_entry *be = f2fs_kmem_cache_alloc(bio_entry_slab, GFP_NOFS);
632632

633633
INIT_LIST_HEAD(&be->list);
634634
be->bio = bio;
635+
be->lstart = lstart;
636+
be->len = len;
635637
init_completion(&be->event);
636638
list_add_tail(&be->list, wait_list);
637639

638640
return be;
639641
}
640642

641-
void f2fs_wait_all_discard_bio(struct f2fs_sb_info *sbi)
643+
/* This should be covered by global mutex, &sit_i->sentry_lock */
644+
void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
642645
{
643646
struct list_head *wait_list = &(SM_I(sbi)->wait_list);
644647
struct bio_entry *be, *tmp;
@@ -647,7 +650,15 @@ void f2fs_wait_all_discard_bio(struct f2fs_sb_info *sbi)
647650
struct bio *bio = be->bio;
648651
int err;
649652

650-
wait_for_completion_io(&be->event);
653+
if (!completion_done(&be->event)) {
654+
if ((be->lstart <= blkaddr &&
655+
blkaddr < be->lstart + be->len) ||
656+
blkaddr == NULL_ADDR)
657+
wait_for_completion_io(&be->event);
658+
else
659+
continue;
660+
}
661+
651662
err = be->error;
652663
if (err == -EOPNOTSUPP)
653664
err = 0;
@@ -756,6 +767,7 @@ static int __f2fs_issue_discard_async(struct f2fs_sb_info *sbi,
756767
struct block_device *bdev, block_t blkstart, block_t blklen)
757768
{
758769
struct bio *bio = NULL;
770+
block_t lblkstart = blkstart;
759771
int err;
760772

761773
trace_f2fs_issue_discard(sbi->sb, blkstart, blklen);
@@ -770,13 +782,13 @@ static int __f2fs_issue_discard_async(struct f2fs_sb_info *sbi,
770782
SECTOR_FROM_BLOCK(blklen),
771783
GFP_NOFS, 0, &bio);
772784
if (!err && bio) {
773-
struct bio_entry *be = __add_bio_entry(sbi, bio);
785+
struct bio_entry *be = __add_bio_entry(sbi, bio,
786+
lblkstart, blklen);
774787

775788
bio->bi_private = be;
776789
bio->bi_end_io = f2fs_submit_bio_wait_endio;
777790
submit_bio(REQ_SYNC, bio);
778791
}
779-
780792
return err;
781793
}
782794

@@ -1655,6 +1667,8 @@ void allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
16551667

16561668
*new_blkaddr = NEXT_FREE_BLKADDR(sbi, curseg);
16571669

1670+
f2fs_wait_discard_bio(sbi, *new_blkaddr);
1671+
16581672
/*
16591673
* __add_sum_entry should be resided under the curseg_mutex
16601674
* because, this function updates a summary entry in the

fs/f2fs/super.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,9 @@ static void f2fs_put_super(struct super_block *sb)
770770
write_checkpoint(sbi, &cpc);
771771
}
772772

773+
/* be sure to wait for any on-going discard commands */
774+
f2fs_wait_discard_bio(sbi, NULL_ADDR);
775+
773776
/* write_checkpoint can update stat informaion */
774777
f2fs_destroy_stats(sbi);
775778

0 commit comments

Comments
 (0)