Loading fs/f2fs/segment.c +30 −33 Original line number Diff line number Diff line Loading @@ -971,6 +971,32 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi, return 0; } static void __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond) { struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; struct list_head *pend_list; struct discard_cmd *dc, *tmp; struct blk_plug plug; int i, iter = 0; mutex_lock(&dcc->cmd_lock); blk_start_plug(&plug); for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state != D_PREP); if (!issue_cond || is_idle(sbi)) __submit_discard_cmd(sbi, dc); if (issue_cond && iter++ > DISCARD_ISSUE_RATE) goto out; } } out: blk_finish_plug(&plug); mutex_unlock(&dcc->cmd_lock); } /* This should be covered by global mutex, &sit_i->sentry_lock */ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr) { Loading @@ -993,27 +1019,16 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr) void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi) { struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; struct list_head *pend_list; struct list_head *wait_list = &(dcc->wait_list); struct discard_cmd *dc, *tmp; struct blk_plug plug; int i; mutex_lock(&dcc->cmd_lock); blk_start_plug(&plug); for (i = 0; i < MAX_PLIST_NUM; i++) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) __submit_discard_cmd(sbi, dc); } blk_finish_plug(&plug); __issue_discard_cmd(sbi, false); mutex_lock(&dcc->cmd_lock); list_for_each_entry_safe(dc, tmp, wait_list, list) { wait_for_completion_io(&dc->wait); __remove_discard_cmd(sbi, dc); } mutex_unlock(&dcc->cmd_lock); } Loading @@ -1022,32 +1037,15 @@ 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 list_head *pend_list; struct list_head *wait_list = &dcc->wait_list; struct discard_cmd *dc, *tmp; struct blk_plug plug; int iter = 0, i; repeat: if (kthread_should_stop()) return 0; mutex_lock(&dcc->cmd_lock); blk_start_plug(&plug); for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state != D_PREP); if (is_idle(sbi)) __submit_discard_cmd(sbi, dc); if (iter++ > DISCARD_ISSUE_RATE) goto next_step; } } next_step: blk_finish_plug(&plug); __issue_discard_cmd(sbi, true); mutex_lock(&dcc->cmd_lock); list_for_each_entry_safe(dc, tmp, wait_list, list) { if (dc->state == D_DONE) { wait_for_completion_io(&dc->wait); Loading @@ -1056,7 +1054,6 @@ static int issue_discard_thread(void *data) } mutex_unlock(&dcc->cmd_lock); iter = 0; congestion_wait(BLK_RW_SYNC, HZ/50); wait_event_interruptible(*q, kthread_should_stop() || Loading Loading
fs/f2fs/segment.c +30 −33 Original line number Diff line number Diff line Loading @@ -971,6 +971,32 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi, return 0; } static void __issue_discard_cmd(struct f2fs_sb_info *sbi, bool issue_cond) { struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; struct list_head *pend_list; struct discard_cmd *dc, *tmp; struct blk_plug plug; int i, iter = 0; mutex_lock(&dcc->cmd_lock); blk_start_plug(&plug); for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state != D_PREP); if (!issue_cond || is_idle(sbi)) __submit_discard_cmd(sbi, dc); if (issue_cond && iter++ > DISCARD_ISSUE_RATE) goto out; } } out: blk_finish_plug(&plug); mutex_unlock(&dcc->cmd_lock); } /* This should be covered by global mutex, &sit_i->sentry_lock */ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr) { Loading @@ -993,27 +1019,16 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr) void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi) { struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; struct list_head *pend_list; struct list_head *wait_list = &(dcc->wait_list); struct discard_cmd *dc, *tmp; struct blk_plug plug; int i; mutex_lock(&dcc->cmd_lock); blk_start_plug(&plug); for (i = 0; i < MAX_PLIST_NUM; i++) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) __submit_discard_cmd(sbi, dc); } blk_finish_plug(&plug); __issue_discard_cmd(sbi, false); mutex_lock(&dcc->cmd_lock); list_for_each_entry_safe(dc, tmp, wait_list, list) { wait_for_completion_io(&dc->wait); __remove_discard_cmd(sbi, dc); } mutex_unlock(&dcc->cmd_lock); } Loading @@ -1022,32 +1037,15 @@ 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 list_head *pend_list; struct list_head *wait_list = &dcc->wait_list; struct discard_cmd *dc, *tmp; struct blk_plug plug; int iter = 0, i; repeat: if (kthread_should_stop()) return 0; mutex_lock(&dcc->cmd_lock); blk_start_plug(&plug); for (i = MAX_PLIST_NUM - 1; i >= 0; i--) { pend_list = &dcc->pend_list[i]; list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state != D_PREP); if (is_idle(sbi)) __submit_discard_cmd(sbi, dc); if (iter++ > DISCARD_ISSUE_RATE) goto next_step; } } next_step: blk_finish_plug(&plug); __issue_discard_cmd(sbi, true); mutex_lock(&dcc->cmd_lock); list_for_each_entry_safe(dc, tmp, wait_list, list) { if (dc->state == D_DONE) { wait_for_completion_io(&dc->wait); Loading @@ -1056,7 +1054,6 @@ static int issue_discard_thread(void *data) } mutex_unlock(&dcc->cmd_lock); iter = 0; congestion_wait(BLK_RW_SYNC, HZ/50); wait_event_interruptible(*q, kthread_should_stop() || Loading