[PATCH] f2fs: introduce discard_submit sysfs node
From: Yangtao Li
Date: Mon Nov 21 2022 - 03:28:23 EST
'discard_submit' sysfs node controls whether discard
threads are allowed to submit discard commands. And
writing a non-zero value to this node will force the
discard thread to wake up immediately.
Some scenarios where this node can be used:
1. A large number of unsubmitted discards have accumulated,
and the thread still runs at the max_discard_issue_time
interval, and the thread needs to be woken up.
2. A large number of discards have been accumulated, which
will affect the submission of other commands of the device
when submitting.
3. In some specific scenarios, it is necessary to observe the
regularity and distribution of the discard command to
optimize the discard merging algorithm or other.
Signed-off-by: Yangtao Li <frank.li@xxxxxxxx>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 10 ++++++++++
fs/f2fs/f2fs.h | 1 +
fs/f2fs/segment.c | 8 ++++++++
fs/f2fs/sysfs.c | 11 +++++++++++
4 files changed, 30 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 24e7cb77f265..2f42ce42ab9e 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -646,3 +646,13 @@ Date: October 2022
Contact: "Yangtao Li" <frank.li@xxxxxxxx>
Description: Show the current gc_mode as a string.
This is a read-only entry.
+
+What: /sys/fs/f2fs/<disk>/discard_submit
+Date: November 2022
+Contact: "Yangtao Li" <frank.li@xxxxxxxx>
+Description: Controls whether discard threads are allowed to submit discard commands.
+ When set to 0, the discard thread running time will be changed to max_discard_issue_time,
+ and the discard command will not be sent to the device. Otherwise, writing other
+ values to this node will force the discard thread to wake up immediately, and
+ the discard command will be allowed to be sent to the device.
+ Default: 1
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f0833638f59e..81e5816e4b34 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -420,6 +420,7 @@ struct discard_cmd_control {
atomic_t discard_cmd_cnt; /* # of cached cmd count */
struct rb_root_cached root; /* root of discard rb-tree */
bool rbtree_check; /* config for consistence check */
+ bool discard_submit; /* allow submit discard cmd or not */
};
/* for the list of fsync inodes, used only during recovery */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 8b0b76550578..5b0a67ccdac3 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1115,6 +1115,9 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
return 0;
+ if (!dcc->discard_submit)
+ return 0;
+
trace_f2fs_issue_discard(bdev, dc->start, dc->len);
lstart = dc->lstart;
@@ -1717,6 +1720,10 @@ static int issue_discard_thread(void *data)
wait_ms = dpolicy.max_interval;
continue;
}
+ if (!dcc->discard_submit) {
+ wait_ms = dpolicy.max_interval;
+ continue;
+ }
if (!atomic_read(&dcc->discard_cmd_cnt))
continue;
@@ -2085,6 +2092,7 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
dcc->min_discard_issue_time = DEF_MIN_DISCARD_ISSUE_TIME;
dcc->mid_discard_issue_time = DEF_MID_DISCARD_ISSUE_TIME;
dcc->max_discard_issue_time = DEF_MAX_DISCARD_ISSUE_TIME;
+ dcc->discard_submit = true;
dcc->undiscard_blks = 0;
dcc->next_pos = 0;
dcc->root = RB_ROOT_CACHED;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 33ec467b3772..b6f017b4d565 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -661,6 +661,15 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
return count;
}
+ if (!strcmp(a->attr.name, "discard_submit")) {
+ struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+
+ dcc->discard_submit = !!t;
+ if (dcc->discard_submit)
+ wake_up_discard_thread(sbi, true);
+ return count;
+ }
+
*ui = (unsigned int)t;
return count;
@@ -800,6 +809,7 @@ F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_discard_request, max_discard_req
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, min_discard_issue_time, min_discard_issue_time);
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, mid_discard_issue_time, mid_discard_issue_time);
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_discard_issue_time, max_discard_issue_time);
+F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_submit, discard_submit);
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_ordered_discard, max_ordered_discard);
F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
@@ -930,6 +940,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(min_discard_issue_time),
ATTR_LIST(mid_discard_issue_time),
ATTR_LIST(max_discard_issue_time),
+ ATTR_LIST(discard_submit),
ATTR_LIST(discard_granularity),
ATTR_LIST(max_ordered_discard),
ATTR_LIST(pending_discard),
--
2.25.1