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: <20170426093955.48144-1-yuchao0@huawei.com>
Date:   Wed, 26 Apr 2017 17:39:54 +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 1/2] f2fs: don't hold cmd_lock during waiting discard command

Previously, with protection of cmd_lock, we will wait for end io of
discard command which potentially may lead long latency, making worse
concurrency.

So, in this patch, we try to add reference into discard entry to prevent
the entry being released by other thread, then we can avoid holding
global cmd_lock during waiting discard to finish.

Signed-off-by: Chao Yu <yuchao0@...wei.com>
---
 fs/f2fs/f2fs.h    |  1 +
 fs/f2fs/segment.c | 25 ++++++++++++++++++++-----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 95fb347e7abe..e0c8e0074224 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -219,6 +219,7 @@ struct discard_cmd {
 	struct list_head list;		/* command list */
 	struct completion wait;		/* compleation */
 	struct block_device *bdev;	/* bdev */
+	unsigned short ref;		/* reference count */
 	int state;			/* state */
 	int error;			/* bio error */
 };
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c95673c54b4e..6a1581ed4ea8 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -689,6 +689,7 @@ static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi,
 	dc->lstart = lstart;
 	dc->start = start;
 	dc->len = len;
+	dc->ref = 0;
 	dc->state = D_PREP;
 	dc->error = 0;
 	init_completion(&dc->wait);
@@ -1009,6 +1010,8 @@ static void __wait_discard_cmd(struct f2fs_sb_info *sbi, bool wait_cond)
 	mutex_lock(&dcc->cmd_lock);
 	list_for_each_entry_safe(dc, tmp, wait_list, list) {
 		if (!wait_cond || dc->state == D_DONE) {
+			if (dc->ref)
+				continue;
 			wait_for_completion_io(&dc->wait);
 			__remove_discard_cmd(sbi, dc);
 		}
@@ -1021,17 +1024,29 @@ void f2fs_wait_discard_bio(struct f2fs_sb_info *sbi, block_t blkaddr)
 {
 	struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
 	struct discard_cmd *dc;
+	bool need_wait = false;
 
 	mutex_lock(&dcc->cmd_lock);
-
 	dc = (struct discard_cmd *)__lookup_rb_tree(&dcc->root, NULL, blkaddr);
 	if (dc) {
-		if (dc->state != D_PREP)
-			wait_for_completion_io(&dc->wait);
-		__punch_discard_cmd(sbi, dc, blkaddr);
+		if (dc->state == D_PREP) {
+			__punch_discard_cmd(sbi, dc, blkaddr);
+		} else {
+			dc->ref++;
+			need_wait = true;
+		}
 	}
-
 	mutex_unlock(&dcc->cmd_lock);
+
+	if (need_wait) {
+		wait_for_completion_io(&dc->wait);
+		mutex_lock(&dcc->cmd_lock);
+		f2fs_bug_on(sbi, dc->state != D_DONE);
+		dc->ref--;
+		if (!dc->ref)
+			__remove_discard_cmd(sbi, dc);
+		mutex_unlock(&dcc->cmd_lock);
+	}
 }
 
 /* This comes from f2fs_put_super */
-- 
2.12.2.510.ge1104a5ee539

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ