From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
To: Al Viro <viro@ZenIV.linux.org.uk>, Jens Axboe <jens.axboe@oracle.com>
Cc: linux-fsdevel@vger.kernel.org,
Artem Bityutskiy <Artem.Bityutskiy@nokia.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH v3 18/18] writeback: optimize periodic sync_supers
Date: Thu, 09 Jul 2009 11:50:26 +0300 [thread overview]
Message-ID: <20090709085026.12122.11937.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20090709084822.12122.79749.sendpatchset@localhost.localdomain>
The sync_supers thread wakes up every 5 seconds (by default) and
writes back all super blocks. It keeps waking up even if there
are no dirty super-blocks.
This patch improves it and makes sleep if there is nothing to do.
This optimization is quite important for small battery-powered
devices.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
include/linux/fs.h | 5 +----
mm/backing-dev.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7882a61..ae626b7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1793,10 +1793,7 @@ int __put_super_and_need_restart(struct super_block *sb);
* Note, VFS does not provide any protection for the super block clean/dirty
* state. File-systems should take care of this.
*/
-static inline void mark_sb_dirty(struct super_block *sb)
-{
- sb->s_dirty = 1;
-}
+void mark_sb_dirty(struct super_block *sb);
static inline void mark_sb_clean(struct super_block *sb)
{
sb->s_dirty = 0;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 75e6c47..96f4b2a 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -32,6 +32,8 @@ LIST_HEAD(bdi_pending_list);
static struct task_struct *sync_supers_tsk;
static struct timer_list sync_supers_timer;
+static int supers_timer_armed;
+static DEFINE_SPINLOCK(supers_timer_lock);
static int bdi_sync_supers(void *);
static void sync_supers_timer_fn(unsigned long);
@@ -440,6 +442,11 @@ static void bdi_flush_io(struct backing_dev_info *bdi)
* or we risk deadlocking on ->s_umount. The longer term solution would be
* to implement sync_supers_bdi() or similar and simply do it from the
* bdi writeback tasks individually.
+ *
+ * Historically this thread woke up periodically, regardless of whether
+ * there was any dirty super block. However, nowadays it is optimized to
+ * wake up only when there is something to sync - this is better from the
+ * power management point of view.
*/
static int bdi_sync_supers(void *unused)
{
@@ -449,10 +456,24 @@ static int bdi_sync_supers(void *unused)
set_current_state(TASK_INTERRUPTIBLE);
schedule();
+ spin_lock(&supers_timer_lock);
+ /* Indicate that 'sync_supers' is in progress */
+ supers_timer_armed = -1;
+ spin_unlock(&supers_timer_lock);
+
/*
* Do this periodically, like kupdated() did before.
*/
sync_supers();
+
+ spin_lock(&supers_timer_lock);
+ if (supers_timer_armed == 1)
+ /* A super block was marked as dirty meanwhile */
+ arm_supers_timer();
+ else
+ /* No more dirty super blocks - we've synced'em all */
+ supers_timer_armed = 0;
+ spin_unlock(&supers_timer_lock);
}
return 0;
@@ -469,9 +490,32 @@ static void arm_supers_timer(void)
static void sync_supers_timer_fn(unsigned long unused)
{
wake_up_process(sync_supers_tsk);
- arm_supers_timer();
}
+void mark_sb_dirty(struct super_block *sb)
+{
+ sb->s_dirty = 1;
+
+ /*
+ * A super block has been marked dirty - arm the 'sync_supers' kernel
+ * thread timer to make sure the super block is synchronized later.
+ */
+ spin_lock(&supers_timer_lock);
+ if (!supers_timer_armed) {
+ arm_supers_timer();
+ supers_timer_armed = 1;
+ } else if (supers_timer_armed == -1) {
+ /*
+ * The super-blocks are being synchronized at the moment,
+ * indicate that a new super block has been marked as dirty and
+ * the timer should be armed again.
+ */
+ supers_timer_armed = 1;
+ }
+ spin_unlock(&supers_timer_lock);
+}
+EXPORT_SYMBOL(mark_sb_dirty);
+
static int bdi_forker_task(void *ptr)
{
struct bdi_writeback *me = ptr;
--
1.6.0.6
next prev parent reply other threads:[~2009-07-09 7:03 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-09 8:48 [PATCH v3 00/18] periodic write-back timer optimization Artem Bityutskiy
2009-07-09 8:48 ` Artem Bityutskiy
2009-07-09 8:48 ` [PATCH v3 01/18] VFS: introduce helpers for manipulation s_dirty flag Artem Bityutskiy
2009-07-09 8:48 ` [PATCH v3 02/18] AFFS: do not manipulate s_dirt directly Artem Bityutskiy
2009-07-09 8:48 ` [PATCH v3 03/18] BFS: " Artem Bityutskiy
2009-07-09 8:48 ` [PATCH v3 04/18] EXOFS: " Artem Bityutskiy
2009-07-12 9:53 ` Boaz Harrosh
2009-07-12 14:02 ` Artem Bityutskiy
2009-07-12 14:02 ` Artem Bityutskiy
2009-07-09 8:48 ` [PATCH v3 05/18] EXT2: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 06/18] EXT4: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 07/18] FAT: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 08/18] HFS: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 09/18] HFSPLUS: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 10/18] JFFS2: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 11/18] NILFS: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 12/18] reiserfs: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 13/18] SYSV: " Artem Bityutskiy
2009-07-09 8:49 ` [PATCH v3 14/18] UDF: " Artem Bityutskiy
2009-07-09 8:50 ` [PATCH v3 15/18] UFS: " Artem Bityutskiy
2009-07-09 8:50 ` [PATCH v3 16/18] VFS: use is_sb_dirty helper Artem Bityutskiy
2009-07-09 8:50 ` [PATCH v3 17/18] rename s_dirt to s_dirty Artem Bityutskiy
2009-07-09 8:50 ` Artem Bityutskiy [this message]
2009-07-09 12:37 ` [PATCH v3 00/18] periodic write-back timer optimization Andi Kleen
2009-07-09 13:04 ` Artem Bityutskiy
2009-07-09 13:04 ` Artem Bityutskiy
2009-07-15 6:21 ` Artem Bityutskiy
2009-07-15 6:21 ` Artem Bityutskiy
2009-07-24 15:45 ` Artem Bityutskiy
2009-07-24 15:45 ` Artem Bityutskiy
2009-09-14 15:27 ` Artem Bityutskiy
2009-09-14 15:27 ` Artem Bityutskiy
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=20090709085026.12122.11937.sendpatchset@localhost.localdomain \
--to=artem.bityutskiy@nokia.com \
--cc=jens.axboe@oracle.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@ZenIV.linux.org.uk \
/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.