summaryrefslogtreecommitdiff
path: root/fs/f2fs/segment.c
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2017-10-04 09:08:33 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2017-10-26 10:44:07 +0200
commitecc9aa00dbb10416d3c1d8ef44ee38d20a36d172 (patch)
tree26777da62be0b8b69522755be29284d4255f7e84 /fs/f2fs/segment.c
parent8412663d177d95beff799c8bb256fccef86d09e6 (diff)
f2fs: wrap discard policy
This patch wraps scattered optional parameters into discard policy as below, later, with it we expect that we can adjust these parameters with proper strategy in different scenario. struct discard_policy { unsigned int min_interval; /* used for candidates exist */ unsigned int max_interval; /* used for candidates not exist */ unsigned int max_requests; /* # of discards issued per round */ unsigned int io_aware_gran; /* minimum granularity discard not be aware of I/O */ bool io_aware; /* issue discard in idle time */ bool sync; /* submit discard with REQ_SYNC flag */ }; This patch doesn't change any logic of codes. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/segment.c')
-rw-r--r--fs/f2fs/segment.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index a0a0a887fc31..5853187230e7 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -879,6 +879,7 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
struct list_head *wait_list = fstrim ? &(dcc->fstrim_list) :
&(dcc->wait_list);
struct bio *bio = NULL;
+ int flag = dcc->dpolicy.sync ? REQ_SYNC : 0;
if (dc->state != D_PREP)
return;
@@ -897,7 +898,7 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
if (bio) {
bio->bi_private = dc;
bio->bi_end_io = f2fs_submit_discard_endio;
- bio->bi_opf |= REQ_SYNC;
+ bio->bi_opf |= flag;
submit_bio(bio);
list_move_tail(&dc->list, wait_list);
__check_sit_bitmap(sbi, dc->start, dc->start + dc->len);
@@ -1092,6 +1093,7 @@ static void __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
struct discard_cmd *prev_dc = NULL, *next_dc = NULL;
struct rb_node **insert_p = NULL, *insert_parent = NULL;
struct discard_cmd *dc;
+ struct discard_policy *dpolicy = &dcc->dpolicy;
struct blk_plug plug;
int issued;
@@ -1124,7 +1126,7 @@ next:
__submit_discard_cmd(sbi, dc, true);
- if (++issued >= DISCARD_ISSUE_RATE) {
+ if (++issued >= dpolicy->max_requests) {
start = dc->lstart + dc->len;
blk_finish_plug(&plug);
@@ -1152,6 +1154,7 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond)
struct list_head *pend_list;
struct discard_cmd *dc, *tmp;
struct blk_plug plug;
+ struct discard_policy *dpolicy = &dcc->dpolicy;
int iter = 0, issued = 0;
int i;
bool io_interrupted = false;
@@ -1179,14 +1182,16 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond)
continue;
}
- if (is_idle(sbi)) {
- __submit_discard_cmd(sbi, dc, false);
- issued++;
- } else {
+ if (dpolicy->io_aware && i < dpolicy->io_aware_gran &&
+ !is_idle(sbi)) {
io_interrupted = true;
+ goto skip;
}
- if (++iter >= DISCARD_ISSUE_RATE)
+ __submit_discard_cmd(sbi, dc, false);
+ issued++;
+skip:
+ if (++iter >= dpolicy->max_requests)
goto out;
}
if (list_empty(pend_list) && dcc->pend_list_tag[i] & P_TRIM)
@@ -1335,6 +1340,7 @@ static int issue_discard_thread(void *data)
struct f2fs_sb_info *sbi = data;
struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
wait_queue_head_t *q = &dcc->discard_wait_queue;
+ struct discard_policy *dpolicy = &dcc->dpolicy;
unsigned int wait_ms = DEF_MIN_DISCARD_ISSUE_TIME;
int issued;
@@ -1361,9 +1367,9 @@ static int issue_discard_thread(void *data)
issued = __issue_discard_cmd(sbi, true);
if (issued) {
__wait_all_discard_cmd(sbi, true);
- wait_ms = DEF_MIN_DISCARD_ISSUE_TIME;
+ wait_ms = dpolicy->min_interval;
} else {
- wait_ms = DEF_MAX_DISCARD_ISSUE_TIME;
+ wait_ms = dpolicy->max_interval;
}
sb_end_intwrite(sbi->sb);
@@ -1648,6 +1654,18 @@ skip:
wake_up_discard_thread(sbi, false);
}
+static void inline init_discard_policy(struct discard_cmd_control *dcc)
+{
+ struct discard_policy *dpolicy = &dcc->dpolicy;
+
+ dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME;
+ dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
+ dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
+ dpolicy->io_aware_gran = MAX_PLIST_NUM;
+ dpolicy->io_aware = true;
+ dpolicy->sync = true;
+}
+
static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
{
dev_t dev = sbi->sb->s_bdev->bd_dev;
@@ -1681,6 +1699,8 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
dcc->undiscard_blks = 0;
dcc->root = RB_ROOT;
+ init_discard_policy(dcc);
+
init_waitqueue_head(&dcc->discard_wait_queue);
SM_I(sbi)->dcc_info = dcc;
init_thread: