aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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 /drivers
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/md.c54
1 files changed, 52 insertions, 2 deletions
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}