linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Artem Bityutskiy <dedekind1@gmail.com>
To: Ted Tso <tytso@mit.edu>
Cc: Ext4 Mailing List <linux-ext4@vger.kernel.org>,
	Linux FS Maling List <linux-fsdevel@vger.kernel.org>,
	Linux Kernel Maling List <linux-kernel@vger.kernel.org>
Subject: [PATCH v1 7/9] ext4: stop using VFS for dirty superblock management
Date: Tue, 20 Mar 2012 16:41:27 +0200	[thread overview]
Message-ID: <1332254489-2300-8-git-send-email-dedekind1@gmail.com> (raw)
In-Reply-To: <1332254489-2300-1-git-send-email-dedekind1@gmail.com>

From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>

Do not use VFS for managing dirty superblock but do it inside ext4. Remove the
'ext4_write_super()' VFS callback and instead, schedule a delayed work when the
superblock is marked as dirty. Use the 'dio_unwritten_wq' which we already have
for these purposes.

We add memory barriers to make sure the 's_dirt' flag changes are visible to
other CPUs as soon as possible to avoid queuing unnecessary works.

The big changes comparing to the previous behavior:
1. We use 'dio_unwritten' queue, so the superblock will be written by
   per-filesystem 'ext4-dio-unwrit' thread, instead of 'sync_supers' thread.
2. We allocate memory in 'ext4_mark_super_dirty()'.

Note: the final goal is to get rid of the 'sync_supers()' kernel thread which
wakes up every 5 seconds and even if there is nothing to do. Thus, we are
pushing superblock management from VFS down to file-systems.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
 fs/ext4/super.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d9543f3..7d453f7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -73,7 +73,6 @@ static const char *ext4_decode_error(struct super_block *sb, int errno,
 static int ext4_remount(struct super_block *sb, int *flags, char *data);
 static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int ext4_unfreeze(struct super_block *sb);
-static void ext4_write_super(struct super_block *sb);
 static int ext4_freeze(struct super_block *sb);
 static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
 		       const char *dev_name, void *data);
@@ -1294,7 +1293,6 @@ static const struct super_operations ext4_nojournal_sops = {
 	.dirty_inode	= ext4_dirty_inode,
 	.drop_inode	= ext4_drop_inode,
 	.evict_inode	= ext4_evict_inode,
-	.write_super	= ext4_write_super,
 	.put_super	= ext4_put_super,
 	.statfs		= ext4_statfs,
 	.remount_fs	= ext4_remount,
@@ -4140,6 +4138,14 @@ static int ext4_commit_super(struct super_block *sb, int sync)
 
 	if (!sbh || block_device_ejected(sb))
 		return error;
+
+	sb->s_dirt = 0;
+	/*
+	 * Make sure we first mark the superblock as clean and then start
+	 * writing it out.
+	 */
+	smp_wmb();
+
 	if (buffer_write_io_error(sbh)) {
 		/*
 		 * Oh, dear.  A previous attempt to write the
@@ -4180,7 +4186,6 @@ static int ext4_commit_super(struct super_block *sb, int sync)
 	es->s_free_inodes_count =
 		cpu_to_le32(percpu_counter_sum_positive(
 				&EXT4_SB(sb)->s_freeinodes_counter));
-	sb->s_dirt = 0;
 	BUFFER_TRACE(sbh, "marking dirty");
 	mark_buffer_dirty(sbh);
 	if (sync) {
@@ -4199,9 +4204,64 @@ static int ext4_commit_super(struct super_block *sb, int sync)
 	return error;
 }
 
+struct sb_delayed_work {
+	struct delayed_work dwork;
+	struct super_block *sb;
+};
+
+static struct sb_delayed_work *work_to_sbwork(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+
+	dwork = container_of(work, struct delayed_work, work);
+	return container_of(dwork, struct sb_delayed_work, dwork);
+}
+
+static void write_super(struct work_struct *work)
+{
+	struct sb_delayed_work *sbwork = work_to_sbwork(work);
+	struct super_block *sb = sbwork->sb;
+
+	kfree(sbwork);
+
+	smp_rmb();
+	if (!sb->s_dirt)
+		return;
+
+	lock_super(sb);
+	ext4_commit_super(sb, 1);
+	unlock_super(sb);
+}
+
 void __ext4_mark_super_dirty(struct super_block *sb)
 {
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct sb_delayed_work *sbwork;
+	unsigned long delay;
+
+	/* Make sure we see 's_dirt' changes ASAP */
+	smp_rmb();
+	if (sb->s_dirt == 1)
+		return;
 	sb->s_dirt = 1;
+	/* Make other CPUs see the 's_dirt' change as soon as possible */
+	smp_wmb();
+
+	sbwork = kmalloc(sizeof(struct sb_delayed_work), GFP_NOFS);
+	if (!sbwork) {
+		/*
+		 * Well, should not be a big deal - the system must be in
+		 * trouble anyway, and the SB will be written out on unmount or
+		 * we may be luckier next time it is marked as dirty.
+		 */
+		sb->s_dirt = 2;
+		return;
+	}
+
+	INIT_DELAYED_WORK(&sbwork->dwork, write_super);
+	sbwork->sb = sb;
+	delay = msecs_to_jiffies(dirty_writeback_interval * 10);
+	queue_delayed_work(sbi->dio_unwritten_wq, &sbwork->dwork, delay);
 }
 
 /*
@@ -4291,13 +4351,6 @@ int ext4_force_commit(struct super_block *sb)
 	return ret;
 }
 
-static void ext4_write_super(struct super_block *sb)
-{
-	lock_super(sb);
-	ext4_commit_super(sb, 1);
-	unlock_super(sb);
-}

  parent reply	other threads:[~2012-03-20 14:41 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-20 14:41 [PATCH v1 0/9] do not use s_dirt in ext4 Artem Bityutskiy
2012-03-20 14:41 ` [PATCH v1 1/9] ext4: do not mark superblock as dirty unnecessarily Artem Bityutskiy
2012-03-22  9:58   ` Jan Kara
2012-03-20 14:41 ` [PATCH v1 2/9] ext4: write superblock only once on unmount Artem Bityutskiy
2012-03-22  9:59   ` Jan Kara
2012-03-20 14:41 ` [PATCH v1 3/9] ext4: remove useless s_dirt assignment Artem Bityutskiy
2012-03-22 10:02   ` Jan Kara
2012-03-20 14:41 ` [PATCH v1 4/9] mm: export dirty_writeback_interval Artem Bityutskiy
2012-03-20 14:41 ` [PATCH v1 5/9] VFS: remove unused superblock helpers Artem Bityutskiy
2012-03-20 14:41 ` [PATCH v1 6/9] ext4: introduce __ext4_mark_super_dirty Artem Bityutskiy
2012-03-20 14:41 ` Artem Bityutskiy [this message]
2012-03-21  8:26   ` [PATCH v1 7/9] ext4: stop using VFS for dirty superblock management Artem Bityutskiy
2012-03-20 14:41 ` [PATCH v1 8/9] ext4: small cleanup in ext4_commit_super Artem Bityutskiy
2012-03-22 10:11   ` Jan Kara
2012-03-20 14:41 ` [PATCH v1 9/9] ext4: introduce own superblock dirty flag Artem Bityutskiy
2012-03-22  9:53 ` [PATCH v1 0/9] do not use s_dirt in ext4 Jan Kara
2012-03-22 10:05   ` Artem Bityutskiy
2012-03-22 10:33     ` Jan Kara
2012-03-22 11:25       ` Artem Bityutskiy
2012-03-22 13:42         ` Jan Kara
2012-03-22 13:59           ` Artem Bityutskiy
2012-03-27 13:29       ` Artem Bityutskiy
2012-03-27 20:14         ` Jan Kara
2012-03-28  8:44           ` Artem Bityutskiy
2012-03-28 10:15             ` Jan Kara
2012-03-30 15:23           ` Artem Bityutskiy
2012-03-30 15:35             ` Jan Kara
2012-03-30 15:43               ` Artem Bityutskiy
2012-03-31 11:49                 ` Jan Kara
2012-04-02 13:46                   ` Artem Bityutskiy
2012-03-31 12:25               ` Artem Bityutskiy
2012-03-22 13:35 ` Ted Ts'o
2012-03-22 13:56   ` Artem Bityutskiy
2012-03-22 15:06     ` Ted Ts'o
2012-03-23  8:55       ` Artem Bityutskiy
2012-03-23 14:23         ` Ted Ts'o

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=1332254489-2300-8-git-send-email-dedekind1@gmail.com \
    --to=dedekind1@gmail.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tytso@mit.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).