]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
f2fs: run discard jobs when put_super
authorJaegeuk Kim <jaegeuk@kernel.org>
Mon, 14 Jan 2019 18:42:11 +0000 (10:42 -0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 4 Feb 2019 16:55:34 +0000 (08:55 -0800)
When we umount f2fs, we need to avoid long delay due to discard commands, which
is actually taking tens of seconds, if storage is very slow on UNMAP. So, this
patch introduces timeout-based work on it.

By default, let me give 5 seconds for discard.

Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Documentation/ABI/testing/sysfs-fs-f2fs
fs/f2fs/f2fs.h
fs/f2fs/segment.c
fs/f2fs/super.c
fs/f2fs/sysfs.c

index a7ce331994578451759aebd8a080bc38085d1093..91822ce258317df500271f8d28cf540e30cb19da 100644 (file)
@@ -86,6 +86,13 @@ Description:
                The unit size is one block, now only support configuring in range
                of [1, 512].
 
+What:          /sys/fs/f2fs/<disk>/umount_discard_timeout
+Date:          January 2019
+Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+               Set timeout to issue discard commands during umount.
+               Default: 5 secs
+
 What:          /sys/fs/f2fs/<disk>/max_victim_search
 Date:          January 2014
 Contact:       "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
index 0f564883e07804915fd989c2dff3dcd58cc1bd48..6b6ec5600089a350b575630560ef056c1de06c3c 100644 (file)
@@ -191,6 +191,7 @@ enum {
 #define DEF_CP_INTERVAL                        60      /* 60 secs */
 #define DEF_IDLE_INTERVAL              5       /* 5 secs */
 #define DEF_DISABLE_INTERVAL           5       /* 5 secs */
+#define DEF_UMOUNT_DISCARD_TIMEOUT     5       /* 5 secs */
 
 struct cp_control {
        int reason;
@@ -310,6 +311,7 @@ struct discard_policy {
        bool sync;                      /* submit discard with REQ_SYNC flag */
        bool ordered;                   /* issue discard by lba order */
        unsigned int granularity;       /* discard granularity */
+       int timeout;                    /* discard timeout for put_super */
 };
 
 struct discard_cmd_control {
@@ -1110,6 +1112,7 @@ enum {
        DISCARD_TIME,
        GC_TIME,
        DISABLE_TIME,
+       UMOUNT_DISCARD_TIMEOUT,
        MAX_TIME,
 };
 
@@ -3006,7 +3009,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr);
 bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr);
 void f2fs_drop_discard_cmd(struct f2fs_sb_info *sbi);
 void f2fs_stop_discard_thread(struct f2fs_sb_info *sbi);
-bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
+bool f2fs_issue_discard_timeout(struct f2fs_sb_info *sbi);
 void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
                                        struct cp_control *cpc);
 void f2fs_dirty_to_prefree(struct f2fs_sb_info *sbi);
index 9b79056d705d2b2f031eb716de2f030fe77e3a57..5b2b9be6f28db8e6f9fdce0454006943b2ff6ca7 100644 (file)
@@ -1037,6 +1037,7 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
 
        dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
        dpolicy->io_aware_gran = MAX_PLIST_NUM;
+       dpolicy->timeout = 0;
 
        if (discard_type == DPOLICY_BG) {
                dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
@@ -1424,7 +1425,14 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
        int i, issued = 0;
        bool io_interrupted = false;
 
+       if (dpolicy->timeout != 0)
+               f2fs_update_time(sbi, dpolicy->timeout);
+
        for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
+               if (dpolicy->timeout != 0 &&
+                               f2fs_time_over(sbi, dpolicy->timeout))
+                       break;
+
                if (i + 1 < dpolicy->granularity)
                        break;
 
@@ -1611,7 +1619,7 @@ void f2fs_stop_discard_thread(struct f2fs_sb_info *sbi)
 }
 
 /* This comes from f2fs_put_super */
-bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
+bool f2fs_issue_discard_timeout(struct f2fs_sb_info *sbi)
 {
        struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
        struct discard_policy dpolicy;
@@ -1619,6 +1627,7 @@ bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
 
        __init_discard_policy(sbi, &dpolicy, DPOLICY_UMOUNT,
                                        dcc->discard_granularity);
+       dpolicy.timeout = UMOUNT_DISCARD_TIMEOUT;
        __issue_discard_cmd(sbi, &dpolicy);
        dropped = __drop_discard_cmd(sbi);
 
index ea514acede36f09dc42ec82934832d787ae7510f..24efd76ca151365ac37dc5fd501b69eeb7f6ee84 100644 (file)
@@ -1048,7 +1048,7 @@ static void f2fs_put_super(struct super_block *sb)
        }
 
        /* be sure to wait for any on-going discard commands */
-       dropped = f2fs_wait_discard_bios(sbi);
+       dropped = f2fs_issue_discard_timeout(sbi);
 
        if ((f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi)) &&
                                        !sbi->discard_blks && !dropped) {
@@ -2706,6 +2706,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
        sbi->interval_time[DISCARD_TIME] = DEF_IDLE_INTERVAL;
        sbi->interval_time[GC_TIME] = DEF_IDLE_INTERVAL;
        sbi->interval_time[DISABLE_TIME] = DEF_DISABLE_INTERVAL;
+       sbi->interval_time[UMOUNT_DISCARD_TIMEOUT] =
+                               DEF_UMOUNT_DISCARD_TIMEOUT;
        clear_sbi_flag(sbi, SBI_NEED_FSCK);
 
        for (i = 0; i < NR_COUNT_TYPE; i++)
index 5b83e1d66cb3c7885d86848833efa5076b582065..18c627e8fc901ab672f8fa75438d9e2fb7d938a2 100644 (file)
@@ -426,6 +426,8 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, idle_interval, interval_time[REQ_TIME]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, discard_idle_interval,
                                        interval_time[DISCARD_TIME]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle_interval, interval_time[GC_TIME]);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info,
+               umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, iostat_enable, iostat_enable);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, readdir_ra, readdir_ra);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_pin_file_thresh, gc_pin_file_threshold);
@@ -483,6 +485,7 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(idle_interval),
        ATTR_LIST(discard_idle_interval),
        ATTR_LIST(gc_idle_interval),
+       ATTR_LIST(umount_discard_timeout),
        ATTR_LIST(iostat_enable),
        ATTR_LIST(readdir_ra),
        ATTR_LIST(gc_pin_file_thresh),