All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gu Zheng <guz.fnst@cn.fujitsu.com>
To: Kim <jaegeuk.kim@samsung.com>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
	f2fs <linux-f2fs-devel@lists.sourceforge.net>
Subject: [PATCH 5/5] f2fs: add a wait queue to avoid unnecessary, build_free_nid
Date: Fri, 07 Mar 2014 18:43:39 +0800	[thread overview]
Message-ID: <5319A2DB.8040705@cn.fujitsu.com> (raw)

Previously, when we try to alloc free nid while the build free nid
is going, the allocer will be run into the flow that waiting for
"nm_i->build_lock", see following:
	/* We should not use stale free nids created by build_free_nids */
---->	if (nm_i->fcnt && !on_build_free_nids(nm_i)) {
		f2fs_bug_on(list_empty(&nm_i->free_nid_list));
		list_for_each(this, &nm_i->free_nid_list) {
			i = list_entry(this, struct free_nid, list);
			if (i->state == NID_NEW)
				break;
		}

		f2fs_bug_on(i->state != NID_NEW);
		*nid = i->nid;
		i->state = NID_ALLOC;
		nm_i->fcnt--;
		spin_unlock(&nm_i->free_nid_list_lock);
		return true;
	}
	spin_unlock(&nm_i->free_nid_list_lock);

	/* Let's scan nat pages and its caches to get free nids */
---->	mutex_lock(&nm_i->build_lock);
	build_free_nids(sbi);
	mutex_unlock(&nm_i->build_lock);
and this will cause another unnecessary building free nid if the current
building free nid job is done.
So here we introduce a wait_queue to avoid this issue.

Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
---
 fs/f2fs/f2fs.h |    1 +
 fs/f2fs/node.c |   10 +++++++++-
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f845e92..7ae193e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -256,6 +256,7 @@ struct f2fs_nm_info {
 	spinlock_t free_nid_list_lock;	/* protect free nid list */
 	unsigned int fcnt;		/* the number of free node id */
 	struct mutex build_lock;	/* lock for build free nids */
+	wait_queue_head_t build_wq;	/* wait queue for build free nids */
 
 	/* for checkpoint */
 	char *nat_bitmap;		/* NAT bitmap pointer */
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 4b7861d..ab44711 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1422,7 +1422,13 @@ retry:
 	spin_lock(&nm_i->free_nid_list_lock);
 
 	/* We should not use stale free nids created by build_free_nids */
-	if (nm_i->fcnt && !on_build_free_nids(nm_i)) {
+	if (on_build_free_nids(nm_i)) {
+		spin_unlock(&nm_i->free_nid_list_lock);
+		wait_event(nm_i->build_wq, !on_build_free_nids(nm_i));
+		goto retry;
+	}
+
+	if (nm_i->fcnt) {
 		f2fs_bug_on(list_empty(&nm_i->free_nid_list));
 		list_for_each(this, &nm_i->free_nid_list) {
 			i = list_entry(this, struct free_nid, list);
@@ -1443,6 +1449,7 @@ retry:
 	mutex_lock(&nm_i->build_lock);
 	build_free_nids(sbi);
 	mutex_unlock(&nm_i->build_lock);
+	wake_up_all(&nm_i->build_wq);
 	goto retry;
 }
 
@@ -1813,6 +1820,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
 	INIT_LIST_HEAD(&nm_i->dirty_nat_entries);
 
 	mutex_init(&nm_i->build_lock);
+	init_waitqueue_head(&nm_i->build_wq);
 	spin_lock_init(&nm_i->free_nid_list_lock);
 	rwlock_init(&nm_i->nat_tree_lock);
 
-- 
1.7.7



------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works. 
Faster operations. Version large binaries.  Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk

WARNING: multiple messages have this Message-ID (diff)
From: Gu Zheng <guz.fnst@cn.fujitsu.com>
To: Kim <jaegeuk.kim@samsung.com>
Cc: f2fs <linux-f2fs-devel@lists.sourceforge.net>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH 5/5] f2fs: add a wait queue to avoid unnecessary, build_free_nid
Date: Fri, 07 Mar 2014 18:43:39 +0800	[thread overview]
Message-ID: <5319A2DB.8040705@cn.fujitsu.com> (raw)

Previously, when we try to alloc free nid while the build free nid
is going, the allocer will be run into the flow that waiting for
"nm_i->build_lock", see following:
	/* We should not use stale free nids created by build_free_nids */
---->	if (nm_i->fcnt && !on_build_free_nids(nm_i)) {
		f2fs_bug_on(list_empty(&nm_i->free_nid_list));
		list_for_each(this, &nm_i->free_nid_list) {
			i = list_entry(this, struct free_nid, list);
			if (i->state == NID_NEW)
				break;
		}

		f2fs_bug_on(i->state != NID_NEW);
		*nid = i->nid;
		i->state = NID_ALLOC;
		nm_i->fcnt--;
		spin_unlock(&nm_i->free_nid_list_lock);
		return true;
	}
	spin_unlock(&nm_i->free_nid_list_lock);

	/* Let's scan nat pages and its caches to get free nids */
---->	mutex_lock(&nm_i->build_lock);
	build_free_nids(sbi);
	mutex_unlock(&nm_i->build_lock);
and this will cause another unnecessary building free nid if the current
building free nid job is done.
So here we introduce a wait_queue to avoid this issue.

Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
---
 fs/f2fs/f2fs.h |    1 +
 fs/f2fs/node.c |   10 +++++++++-
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f845e92..7ae193e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -256,6 +256,7 @@ struct f2fs_nm_info {
 	spinlock_t free_nid_list_lock;	/* protect free nid list */
 	unsigned int fcnt;		/* the number of free node id */
 	struct mutex build_lock;	/* lock for build free nids */
+	wait_queue_head_t build_wq;	/* wait queue for build free nids */
 
 	/* for checkpoint */
 	char *nat_bitmap;		/* NAT bitmap pointer */
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 4b7861d..ab44711 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1422,7 +1422,13 @@ retry:
 	spin_lock(&nm_i->free_nid_list_lock);
 
 	/* We should not use stale free nids created by build_free_nids */
-	if (nm_i->fcnt && !on_build_free_nids(nm_i)) {
+	if (on_build_free_nids(nm_i)) {
+		spin_unlock(&nm_i->free_nid_list_lock);
+		wait_event(nm_i->build_wq, !on_build_free_nids(nm_i));
+		goto retry;
+	}
+
+	if (nm_i->fcnt) {
 		f2fs_bug_on(list_empty(&nm_i->free_nid_list));
 		list_for_each(this, &nm_i->free_nid_list) {
 			i = list_entry(this, struct free_nid, list);
@@ -1443,6 +1449,7 @@ retry:
 	mutex_lock(&nm_i->build_lock);
 	build_free_nids(sbi);
 	mutex_unlock(&nm_i->build_lock);
+	wake_up_all(&nm_i->build_wq);
 	goto retry;
 }
 
@@ -1813,6 +1820,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
 	INIT_LIST_HEAD(&nm_i->dirty_nat_entries);
 
 	mutex_init(&nm_i->build_lock);
+	init_waitqueue_head(&nm_i->build_wq);
 	spin_lock_init(&nm_i->free_nid_list_lock);
 	rwlock_init(&nm_i->nat_tree_lock);
 
-- 
1.7.7



             reply	other threads:[~2014-03-07 10:52 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-07 10:43 Gu Zheng [this message]
2014-03-07 10:43 ` [PATCH 5/5] f2fs: add a wait queue to avoid unnecessary, build_free_nid Gu Zheng
2014-03-10  4:09 ` [f2fs-dev] " Changman Lee
2014-03-10  5:23   ` Gu Zheng
2014-03-10  5:23     ` [f2fs-dev] " Gu Zheng
2014-03-10  4:50 ` Jaegeuk Kim
2014-03-10  5:37   ` Gu Zheng
2014-03-10  5:37     ` Gu Zheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5319A2DB.8040705@cn.fujitsu.com \
    --to=guz.fnst@cn.fujitsu.com \
    --cc=jaegeuk.kim@samsung.com \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.