aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-06-26 03:27:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:37 -0400
commit16f17b39f385212b73278a76d482cdcaaebe6c02 (patch)
treeb7b79b380257e7438516a8b38cd9fbd33284f64f
parent9443a1d1f72c688646278c06d0a9a3c79e895325 (diff)
[PATCH] md: increase the delay before marking metadata clean, and make it configurable
When a md array has been idle (no writes) for 20msecs it is marked as 'clean'. This delay turns out to be too short for some real workloads. So increase it to 200msec (the time to update the metadata should be a tiny fraction of that) and make it sysfs-configurable. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--Documentation/md.txt9
-rw-r--r--drivers/md/md.c54
2 files changed, 61 insertions, 2 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 03a13c462cf2..b19978e035fc 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -207,6 +207,15 @@ All md devices contain:
207 available. It will then appear at md/dev-XXX (depending on the 207 available. It will then appear at md/dev-XXX (depending on the
208 name of the device) and further configuration is then possible. 208 name of the device) and further configuration is then possible.
209 209
210 safe_mode_delay
211 When an md array has seen no write requests for a certain period
212 of time, it will be marked as 'clean'. When another write
213 request arrive, the array is marked as 'dirty' before the write
214 commenses. This is known as 'safe_mode'.
215 The 'certain period' is controlled by this file which stores the
216 period as a number of seconds. The default is 200msec (0.200).
217 Writing a value of 0 disables safemode.
218
210 sync_speed_min 219 sync_speed_min
211 sync_speed_max 220 sync_speed_max
212 This are similar to /proc/sys/dev/raid/speed_limit_{min,max} 221 This are similar to /proc/sys/dev/raid/speed_limit_{min,max}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 30a93d64921e..ad576ad2ca76 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -44,6 +44,7 @@
44#include <linux/suspend.h> 44#include <linux/suspend.h>
45#include <linux/poll.h> 45#include <linux/poll.h>
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <linux/ctype.h>
47 48
48#include <linux/init.h> 49#include <linux/init.h>
49 50
@@ -1978,6 +1979,54 @@ static void analyze_sbs(mddev_t * mddev)
1978} 1979}
1979 1980
1980static ssize_t 1981static ssize_t
1982safe_delay_show(mddev_t *mddev, char *page)
1983{
1984 int msec = (mddev->safemode_delay*1000)/HZ;
1985 return sprintf(page, "%d.%03d\n", msec/1000, msec%1000);
1986}
1987static ssize_t
1988safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
1989{
1990 int scale=1;
1991 int dot=0;
1992 int i;
1993 unsigned long msec;
1994 char buf[30];
1995 char *e;
1996 /* remove a period, and count digits after it */
1997 if (len >= sizeof(buf))
1998 return -EINVAL;
1999 strlcpy(buf, cbuf, len);
2000 buf[len] = 0;
2001 for (i=0; i<len; i++) {
2002 if (dot) {
2003 if (isdigit(buf[i])) {
2004 buf[i-1] = buf[i];
2005 scale *= 10;
2006 }
2007 buf[i] = 0;
2008 } else if (buf[i] == '.') {
2009 dot=1;
2010 buf[i] = 0;
2011 }
2012 }
2013 msec = simple_strtoul(buf, &e, 10);
2014 if (e == buf || (*e && *e != '\n'))
2015 return -EINVAL;
2016 msec = (msec * 1000) / scale;
2017 if (msec == 0)
2018 mddev->safemode_delay = 0;
2019 else {
2020 mddev->safemode_delay = (msec*HZ)/1000;
2021 if (mddev->safemode_delay == 0)
2022 mddev->safemode_delay = 1;
2023 }
2024 return len;
2025}
2026static struct md_sysfs_entry md_safe_delay =
2027__ATTR(safe_mode_delay, 0644,safe_delay_show, safe_delay_store);
2028
2029static ssize_t
1981level_show(mddev_t *mddev, char *page) 2030level_show(mddev_t *mddev, char *page)
1982{ 2031{
1983 struct mdk_personality *p = mddev->pers; 2032 struct mdk_personality *p = mddev->pers;
@@ -2433,6 +2482,7 @@ static struct attribute *md_default_attrs[] = {
2433 &md_size.attr, 2482 &md_size.attr,
2434 &md_metadata.attr, 2483 &md_metadata.attr,
2435 &md_new_device.attr, 2484 &md_new_device.attr,
2485 &md_safe_delay.attr,
2436 NULL, 2486 NULL,
2437}; 2487};
2438 2488
@@ -2708,7 +2758,7 @@ static int do_md_run(mddev_t * mddev)
2708 mddev->safemode = 0; 2758 mddev->safemode = 0;
2709 mddev->safemode_timer.function = md_safemode_timeout; 2759 mddev->safemode_timer.function = md_safemode_timeout;
2710 mddev->safemode_timer.data = (unsigned long) mddev; 2760 mddev->safemode_timer.data = (unsigned long) mddev;
2711 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ 2761 mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */
2712 mddev->in_sync = 1; 2762 mddev->in_sync = 1;
2713 2763
2714 ITERATE_RDEV(mddev,rdev,tmp) 2764 ITERATE_RDEV(mddev,rdev,tmp)
@@ -4594,7 +4644,7 @@ void md_write_end(mddev_t *mddev)
4594 if (atomic_dec_and_test(&mddev->writes_pending)) { 4644 if (atomic_dec_and_test(&mddev->writes_pending)) {
4595 if (mddev->safemode == 2) 4645 if (mddev->safemode == 2)
4596 md_wakeup_thread(mddev->thread); 4646 md_wakeup_thread(mddev->thread);
4597 else 4647 else if (mddev->safemode_delay)
4598 mod_timer(&mddev->safemode_timer, jiffies + mddev->safemode_delay); 4648 mod_timer(&mddev->safemode_timer, jiffies + mddev->safemode_delay);
4599 } 4649 }
4600} 4650}