From: Dan Williams <dan.j.williams@intel.com>
To: linux-raid@vger.kernel.org
Subject: [PATCH RFC 4/4] md: delayed stripe activation
Date: Tue, 10 Apr 2007 23:00:41 -0700 [thread overview]
Message-ID: <20070411060041.15745.24375.stgit@dwillia2-linux.ch.intel.com> (raw)
In-Reply-To: <20070411055729.15745.51513.stgit@dwillia2-linux.ch.intel.com>
based on a patch by: Raz Ben-Jehuda(caro) <raziebe@gmail.com>
---
drivers/md/raid5.c | 92 +++++++++++++++++++++++++++++++++++++++++---
include/linux/raid/raid5.h | 5 ++
2 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1a2d6b5..1b3db16 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -226,6 +226,8 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
sh->sector = sector;
sh->pd_idx = pd_idx;
sh->state = 0;
+ sh->active_preread_jiffies = msecs_to_jiffies(
+ atomic_read(&conf->cache_policy->deadline_ms))+jiffies;
sh->disks = disks;
@@ -1172,6 +1174,7 @@ static int raid5_end_write_request (struct bio *bi, unsigned int bytes_done,
clear_bit(R5_LOCKED, &sh->dev[i].flags);
set_bit(STRIPE_HANDLE, &sh->state);
+ sh->active_preread_jiffies = jiffies;
release_stripe(sh);
return 0;
}
@@ -1741,8 +1744,10 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
bip = &sh->dev[dd_idx].towrite;
if (*bip == NULL && sh->dev[dd_idx].written == NULL)
firstwrite = 1;
- } else
+ } else {
bip = &sh->dev[dd_idx].toread;
+ sh->active_preread_jiffies = jiffies;
+ }
while (*bip && (*bip)->bi_sector < bi->bi_sector) {
if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
goto overlap;
@@ -2160,7 +2165,7 @@ raid5_wt_cache_handle_new_writes(struct stripe_head *sh, struct stripe_head_stat
}
}
-static void raid5_wt_cache_activate_delayed(raid5_conf_t *conf)
+static struct stripe_head *raid5_wt_cache_activate_delayed(raid5_conf_t *conf)
{
struct stripe_cache_policy *cp = conf->cache_policy;
if (atomic_read(&cp->preread_active_stripes) < IO_THRESHOLD) {
@@ -2168,6 +2173,20 @@ static void raid5_wt_cache_activate_delayed(raid5_conf_t *conf)
struct list_head *l = cp->delayed_list.next;
struct stripe_head *sh;
sh = list_entry(l, struct stripe_head, lru);
+
+ if (time_before(jiffies,sh->active_preread_jiffies)) {
+ PRINTK("deadline: no expire sec=%lld %8u %8u\n",
+ (unsigned long long) sh->sector,
+ jiffies_to_msecs(sh->active_preread_jiffies),
+ jiffies_to_msecs(jiffies));
+ return sh;
+ } else {
+ PRINTK("deadline: expire:sec=%lld %8u %8u\n",
+ (unsigned long long)sh->sector,
+ jiffies_to_msecs(sh->active_preread_jiffies),
+ jiffies_to_msecs(jiffies));
+ }
+
list_del_init(l);
clear_bit(STRIPE_DELAYED, &sh->state);
if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
@@ -2175,9 +2194,11 @@ static void raid5_wt_cache_activate_delayed(raid5_conf_t *conf)
list_add_tail(&sh->lru, &conf->handle_list);
}
}
+
+ return NULL;
}
-static void raid5_wt_cache_raid5d(mddev_t *mddev, raid5_conf_t *conf)
+static struct stripe_head *raid5_wt_cache_raid5d(mddev_t *mddev, raid5_conf_t *conf)
{
struct stripe_cache_policy *cp = conf->cache_policy;
@@ -2185,7 +2206,9 @@ static void raid5_wt_cache_raid5d(mddev_t *mddev, raid5_conf_t *conf)
atomic_read(&cp->preread_active_stripes) < IO_THRESHOLD &&
!blk_queue_plugged(mddev->queue) &&
!list_empty(&cp->delayed_list))
- raid5_wt_cache_activate_delayed(conf);
+ return raid5_wt_cache_activate_delayed(conf);
+
+ return NULL;
}
static void raid5_wt_cache_init(raid5_conf_t *conf)
@@ -4339,7 +4362,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
*/
static void raid5d (mddev_t *mddev)
{
- struct stripe_head *sh;
+ struct stripe_head *sh,*delayed_sh=NULL;
raid5_conf_t *conf = mddev_to_conf(mddev);
int handled;
@@ -4363,7 +4386,10 @@ static void raid5d (mddev_t *mddev)
}
if (conf->cache_policy->raid5d)
- conf->cache_policy->raid5d(mddev, conf);
+ delayed_sh = conf->cache_policy->raid5d(mddev, conf);
+
+ if (delayed_sh)
+ break;
while ((bio = remove_bio_from_retry(conf))) {
int ok;
@@ -4401,8 +4427,60 @@ static void raid5d (mddev_t *mddev)
unplug_slaves(mddev);
PRINTK("--- raid5d inactive\n");
+
+ if (delayed_sh) {
+ unsigned long local_jiffies = jiffies, wakeup;
+ if (delayed_sh->active_preread_jiffies > local_jiffies) {
+ wakeup = delayed_sh->active_preread_jiffies - local_jiffies;
+ PRINTK("--- raid5d inactive sleep for %d\n",
+ jiffies_to_msecs(wakeup) );
+ mddev->thread->timeout = wakeup;
+ }
+ }
+}
+
+static ssize_t
+raid5_show_stripe_deadline(mddev_t *mddev, char *page)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ if (conf)
+ return sprintf(page, "%d\n",
+ atomic_read(&conf->cache_policy->deadline_ms));
+ else
+ return 0;
+}
+
+static ssize_t
+raid5_store_stripe_deadline(mddev_t *mddev, const char *page, size_t len)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ char *end;
+ int new;
+
+ if (len >= PAGE_SIZE)
+ return -EINVAL;
+ if (!conf)
+ return -ENODEV;
+
+ new = simple_strtoul(page, &end, 10);
+
+ if (!*page || (*end && *end != '\n') )
+ return -EINVAL;
+
+ if (new < 0 || new > 10000)
+ return -EINVAL;
+
+ atomic_set(&conf->cache_policy->deadline_ms,new);
+
+ return len;
}
+static struct md_sysfs_entry
+raid5_stripe_deadline = __ATTR(stripe_deadline, S_IRUGO | S_IWUSR,
+ raid5_show_stripe_deadline,
+ raid5_store_stripe_deadline);
+
+
static ssize_t
raid5_show_stripe_cache_size(mddev_t *mddev, char *page)
{
@@ -4465,6 +4543,7 @@ raid5_stripecache_active = __ATTR_RO(stripe_cache_active);
static struct attribute *raid5_attrs[] = {
&raid5_stripecache_size.attr,
&raid5_stripecache_active.attr,
+ &raid5_stripe_deadline.attr,
NULL,
};
static struct attribute_group raid5_attrs_group = {
@@ -4581,6 +4660,7 @@ static int run(mddev_t *mddev)
atomic_set(&conf->active_stripes, 0);
atomic_set(&conf->active_aligned_reads, 0);
conf->cache_policy->init(conf);
+ atomic_set(&conf->cache_policy->deadline_ms, 0);
PRINTK("raid5: run(%s) called.\n", mdname(mddev));
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index 560d460..d447807 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -166,6 +166,7 @@ struct stripe_head {
int bm_seq; /* sequence number for bitmap flushes */
int disks; /* disks in stripe */
int write_requests_pending;
+ unsigned long active_preread_jiffies;
struct stripe_operations {
unsigned long pending; /* pending operations (set for request->issue->complete) */
unsigned long ack; /* submitted operations (set for issue->complete */
@@ -353,7 +354,8 @@ struct stripe_cache_policy {
* wt: check for stripes that can be taken off the delayed list
* wb: n/a
*/
- void (*raid5d)(mddev_t *mddev, struct raid5_private_data *conf);
+ struct stripe_head *(*raid5d)(mddev_t *mddev,
+ struct raid5_private_data *conf);
/* init
* wt: initialize 'delayed_list' and 'preread_active_stripes'
* wb: initialize 'dirty_list' and 'dirty_stripes'
@@ -380,6 +382,7 @@ struct stripe_cache_policy {
atomic_t preread_active_stripes;
atomic_t evict_active_stripes;
};
+ atomic_t deadline_ms;
};
struct raid5_private_data {
prev parent reply other threads:[~2007-04-11 6:00 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-11 6:00 [PATCH RFC 0/4] raid5: write-back caching policy and write performance Dan Williams
2007-04-11 6:00 ` [PATCH RFC 1/4] md: introduce struct stripe_head_state Dan Williams
2007-04-11 6:00 ` [PATCH RFC 2/4] md: refactor raid5 cache policy code using 'struct stripe_cache_policy' Dan Williams
2007-04-11 6:00 ` [PATCH RFC 3/4] md: writeback caching policy for raid5 [experimental] Dan Williams
2007-04-11 22:40 ` Mark Hahn
2007-04-12 0:08 ` Williams, Dan J
2007-04-12 6:21 ` Neil Brown
2007-04-12 5:37 ` Al Boldi
2007-04-11 6:00 ` Dan Williams [this message]
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=20070411060041.15745.24375.stgit@dwillia2-linux.ch.intel.com \
--to=dan.j.williams@intel.com \
--cc=linux-raid@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.