lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170405101949.59292-1-yuchao0@huawei.com>
Date:   Wed, 5 Apr 2017 18:19:48 +0800
From:   Chao Yu <yuchao0@...wei.com>
To:     <jaegeuk@...nel.org>
CC:     <linux-f2fs-devel@...ts.sourceforge.net>,
        <linux-kernel@...r.kernel.org>, <chao@...nel.org>,
        Chao Yu <yuchao0@...wei.com>
Subject: [PATCH v3 1/4] f2fs: split discard_cmd_list

Split discard_cmd_list to discard_{pend,wait}_list, so while sending/waiting
discard command, we can avoid traversing unneeded entries in original list.

Signed-off-by: Chao Yu <yuchao0@...wei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@...nel.org>
---
v3: handle discard command correctly in f2fs_wait_discard_bio
 fs/f2fs/f2fs.h    |  3 ++-
 fs/f2fs/segment.c | 47 ++++++++++++++++++++++++++++++-----------------
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 6fbdcac01d9a..68e55bd6b50e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -210,7 +210,8 @@ struct discard_cmd_control {
 	struct task_struct *f2fs_issue_discard;	/* discard thread */
 	struct list_head discard_entry_list;	/* 4KB discard entry list */
 	int nr_discards;			/* # of discards in the list */
-	struct list_head discard_cmd_list;	/* discard cmd list */
+	struct list_head discard_pend_list;	/* store pending entries */
+	struct list_head discard_wait_list;	/* store on-flushing entries */
 	wait_queue_head_t discard_wait_queue;	/* waiting queue for wake-up */
 	struct mutex cmd_lock;
 	int max_discards;			/* max. discards to be issued */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c5f0075764bf..07dddcb0d03d 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -670,7 +670,7 @@ static void __add_discard_cmd(struct f2fs_sb_info *sbi,
 		block_t start, block_t len)
 {
 	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
-	struct list_head *cmd_list = &(dcc->discard_cmd_list);
+	struct list_head *pend_list = &(dcc->discard_pend_list);
 	struct discard_cmd *dc;
 
 	dc = f2fs_kmem_cache_alloc(discard_cmd_slab, GFP_NOFS);
@@ -684,7 +684,7 @@ static void __add_discard_cmd(struct f2fs_sb_info *sbi,
 	init_completion(&dc->wait);
 
 	mutex_lock(&dcc->cmd_lock);
-	list_add_tail(&dc->list, cmd_list);
+	list_add_tail(&dc->list, pend_list);
 	mutex_unlock(&dcc->cmd_lock);
 }
 
@@ -736,6 +736,7 @@ static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
 			bio->bi_end_io = f2fs_submit_discard_endio;
 			bio->bi_opf |= REQ_SYNC;
 			submit_bio(bio);
+			list_move_tail(&dc->list, &dcc->discard_wait_list);
 		}
 	} else {
 		__remove_discard_cmd(sbi, dc);
@@ -782,31 +783,37 @@ static void __punch_discard_cmd(struct f2fs_sb_info *sbi,
 void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
 {
 	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
-	struct list_head *wait_list = &(dcc->discard_cmd_list);
+	struct list_head *pend_list = &(dcc->discard_pend_list);
+	struct list_head *wait_list = &(dcc->discard_wait_list);
 	struct discard_cmd *dc, *tmp;
 	struct blk_plug plug;
 
 	mutex_lock(&dcc->cmd_lock);
 
-	blk_start_plug(&plug);
-
-	list_for_each_entry_safe(dc, tmp, wait_list, list) {
+	if (blkaddr == NULL_ADDR)
+		goto release_discard;
 
-		if (blkaddr == NULL_ADDR) {
-			__submit_discard_cmd(sbi, dc);
-			continue;
-		}
+	list_for_each_entry_safe(dc, tmp, pend_list, list) {
+		if (dc->lstart <= blkaddr && blkaddr < dc->lstart + dc->len)
+			__punch_discard_cmd(sbi, dc, blkaddr);
+	}
 
+	list_for_each_entry_safe(dc, tmp, wait_list, list) {
 		if (dc->lstart <= blkaddr && blkaddr < dc->lstart + dc->len) {
 			if (dc->state == D_SUBMIT)
 				wait_for_completion_io(&dc->wait);
 			__punch_discard_cmd(sbi, dc, blkaddr);
 		}
 	}
-	blk_finish_plug(&plug);
 
+release_discard:
 	/* this comes from f2fs_put_super */
 	if (blkaddr == NULL_ADDR) {
+		blk_start_plug(&plug);
+		list_for_each_entry_safe(dc, tmp, pend_list, list)
+			__submit_discard_cmd(sbi, dc);
+		blk_finish_plug(&plug);
+
 		list_for_each_entry_safe(dc, tmp, wait_list, list) {
 			wait_for_completion_io(&dc->wait);
 			__remove_discard_cmd(sbi, dc);
@@ -820,7 +827,8 @@ 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 *cmd_list = &dcc->discard_cmd_list;
+	struct list_head *pend_list = &dcc->discard_pend_list;
+	struct list_head *wait_list = &dcc->discard_wait_list;
 	struct discard_cmd *dc, *tmp;
 	struct blk_plug plug;
 	int iter = 0;
@@ -831,13 +839,17 @@ static int issue_discard_thread(void *data)
 	blk_start_plug(&plug);
 
 	mutex_lock(&dcc->cmd_lock);
-	list_for_each_entry_safe(dc, tmp, cmd_list, list) {
+	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 (dc->state == D_PREP && iter++ > DISCARD_ISSUE_RATE)
+		if (iter++ > DISCARD_ISSUE_RATE)
 			break;
+	}
+
+	list_for_each_entry_safe(dc, tmp, wait_list, list) {
 		if (dc->state == D_DONE)
 			__remove_discard_cmd(sbi, dc);
 	}
@@ -848,8 +860,8 @@ static int issue_discard_thread(void *data)
 	iter = 0;
 	congestion_wait(BLK_RW_SYNC, HZ/50);
 
-	wait_event_interruptible(*q,
-		kthread_should_stop() || !list_empty(&dcc->discard_cmd_list));
+	wait_event_interruptible(*q, kthread_should_stop() ||
+			!list_empty(pend_list) || !list_empty(wait_list));
 	goto repeat;
 }
 
@@ -1133,7 +1145,8 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&dcc->discard_entry_list);
-	INIT_LIST_HEAD(&dcc->discard_cmd_list);
+	INIT_LIST_HEAD(&dcc->discard_pend_list);
+	INIT_LIST_HEAD(&dcc->discard_wait_list);
 	mutex_init(&dcc->cmd_lock);
 	atomic_set(&dcc->submit_discard, 0);
 	dcc->nr_discards = 0;
-- 
2.12.2.510.ge1104a5ee539

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ