diff options
author | NeilBrown <neilb@suse.de> | 2015-02-24 20:10:35 -0500 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2015-04-21 18:00:42 -0400 |
commit | 486f0644c3482cbf64fe804499836e1f05abec14 (patch) | |
tree | 1cb95a03d09942e04af8ec716652180b35c4f1ef /drivers/md | |
parent | a9683a795bcca6d0e7fe4c4c00e071218f3f4428 (diff) |
md/raid5: move max_nr_stripes management into grow_one_stripe and drop_one_stripe
Rather than adjusting max_nr_stripes whenever {grow,drop}_one_stripe()
succeeds, do it inside the functions.
Also choose the correct hash to handle next inside the functions.
This removes duplication and will help with future new uses of
{grow,drop}_one_stripe.
This also fixes a minor bug where the "md/raid:%md: allocate XXkB"
message always said "0kB".
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid5.c | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ed8e34153c3d..78ac7dc853c7 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1963,7 +1963,7 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) | |||
1963 | put_cpu(); | 1963 | put_cpu(); |
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp) | 1966 | static int grow_one_stripe(struct r5conf *conf, gfp_t gfp) |
1967 | { | 1967 | { |
1968 | struct stripe_head *sh; | 1968 | struct stripe_head *sh; |
1969 | sh = kmem_cache_zalloc(conf->slab_cache, gfp); | 1969 | sh = kmem_cache_zalloc(conf->slab_cache, gfp); |
@@ -1979,7 +1979,8 @@ static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp) | |||
1979 | kmem_cache_free(conf->slab_cache, sh); | 1979 | kmem_cache_free(conf->slab_cache, sh); |
1980 | return 0; | 1980 | return 0; |
1981 | } | 1981 | } |
1982 | sh->hash_lock_index = hash; | 1982 | sh->hash_lock_index = |
1983 | conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; | ||
1983 | /* we just created an active stripe so... */ | 1984 | /* we just created an active stripe so... */ |
1984 | atomic_set(&sh->count, 1); | 1985 | atomic_set(&sh->count, 1); |
1985 | atomic_inc(&conf->active_stripes); | 1986 | atomic_inc(&conf->active_stripes); |
@@ -1989,6 +1990,7 @@ static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp) | |||
1989 | INIT_LIST_HEAD(&sh->batch_list); | 1990 | INIT_LIST_HEAD(&sh->batch_list); |
1990 | sh->batch_head = NULL; | 1991 | sh->batch_head = NULL; |
1991 | release_stripe(sh); | 1992 | release_stripe(sh); |
1993 | conf->max_nr_stripes++; | ||
1992 | return 1; | 1994 | return 1; |
1993 | } | 1995 | } |
1994 | 1996 | ||
@@ -1996,7 +1998,6 @@ static int grow_stripes(struct r5conf *conf, int num) | |||
1996 | { | 1998 | { |
1997 | struct kmem_cache *sc; | 1999 | struct kmem_cache *sc; |
1998 | int devs = max(conf->raid_disks, conf->previous_raid_disks); | 2000 | int devs = max(conf->raid_disks, conf->previous_raid_disks); |
1999 | int hash; | ||
2000 | 2001 | ||
2001 | if (conf->mddev->gendisk) | 2002 | if (conf->mddev->gendisk) |
2002 | sprintf(conf->cache_name[0], | 2003 | sprintf(conf->cache_name[0], |
@@ -2014,13 +2015,10 @@ static int grow_stripes(struct r5conf *conf, int num) | |||
2014 | return 1; | 2015 | return 1; |
2015 | conf->slab_cache = sc; | 2016 | conf->slab_cache = sc; |
2016 | conf->pool_size = devs; | 2017 | conf->pool_size = devs; |
2017 | hash = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; | 2018 | while (num--) |
2018 | while (num--) { | 2019 | if (!grow_one_stripe(conf, GFP_KERNEL)) |
2019 | if (!grow_one_stripe(conf, hash, GFP_KERNEL)) | ||
2020 | return 1; | 2020 | return 1; |
2021 | conf->max_nr_stripes++; | 2021 | |
2022 | hash = (hash + 1) % NR_STRIPE_HASH_LOCKS; | ||
2023 | } | ||
2024 | return 0; | 2022 | return 0; |
2025 | } | 2023 | } |
2026 | 2024 | ||
@@ -2210,9 +2208,10 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
2210 | return err; | 2208 | return err; |
2211 | } | 2209 | } |
2212 | 2210 | ||
2213 | static int drop_one_stripe(struct r5conf *conf, int hash) | 2211 | static int drop_one_stripe(struct r5conf *conf) |
2214 | { | 2212 | { |
2215 | struct stripe_head *sh; | 2213 | struct stripe_head *sh; |
2214 | int hash = (conf->max_nr_stripes - 1) % NR_STRIPE_HASH_LOCKS; | ||
2216 | 2215 | ||
2217 | spin_lock_irq(conf->hash_locks + hash); | 2216 | spin_lock_irq(conf->hash_locks + hash); |
2218 | sh = get_free_stripe(conf, hash); | 2217 | sh = get_free_stripe(conf, hash); |
@@ -2223,15 +2222,15 @@ static int drop_one_stripe(struct r5conf *conf, int hash) | |||
2223 | shrink_buffers(sh); | 2222 | shrink_buffers(sh); |
2224 | kmem_cache_free(conf->slab_cache, sh); | 2223 | kmem_cache_free(conf->slab_cache, sh); |
2225 | atomic_dec(&conf->active_stripes); | 2224 | atomic_dec(&conf->active_stripes); |
2225 | conf->max_nr_stripes--; | ||
2226 | return 1; | 2226 | return 1; |
2227 | } | 2227 | } |
2228 | 2228 | ||
2229 | static void shrink_stripes(struct r5conf *conf) | 2229 | static void shrink_stripes(struct r5conf *conf) |
2230 | { | 2230 | { |
2231 | int hash; | 2231 | while (conf->max_nr_stripes && |
2232 | for (hash = 0; hash < NR_STRIPE_HASH_LOCKS; hash++) | 2232 | drop_one_stripe(conf)) |
2233 | while (drop_one_stripe(conf, hash)) | 2233 | ; |
2234 | ; | ||
2235 | 2234 | ||
2236 | if (conf->slab_cache) | 2235 | if (conf->slab_cache) |
2237 | kmem_cache_destroy(conf->slab_cache); | 2236 | kmem_cache_destroy(conf->slab_cache); |
@@ -5822,30 +5821,22 @@ raid5_set_cache_size(struct mddev *mddev, int size) | |||
5822 | { | 5821 | { |
5823 | struct r5conf *conf = mddev->private; | 5822 | struct r5conf *conf = mddev->private; |
5824 | int err; | 5823 | int err; |
5825 | int hash; | ||
5826 | 5824 | ||
5827 | if (size <= 16 || size > 32768) | 5825 | if (size <= 16 || size > 32768) |
5828 | return -EINVAL; | 5826 | return -EINVAL; |
5829 | hash = (conf->max_nr_stripes - 1) % NR_STRIPE_HASH_LOCKS; | 5827 | |
5830 | while (size < conf->max_nr_stripes) { | 5828 | while (size < conf->max_nr_stripes && |
5831 | if (drop_one_stripe(conf, hash)) | 5829 | drop_one_stripe(conf)) |
5832 | conf->max_nr_stripes--; | 5830 | ; |
5833 | else | 5831 | |
5834 | break; | ||
5835 | hash--; | ||
5836 | if (hash < 0) | ||
5837 | hash = NR_STRIPE_HASH_LOCKS - 1; | ||
5838 | } | ||
5839 | err = md_allow_write(mddev); | 5832 | err = md_allow_write(mddev); |
5840 | if (err) | 5833 | if (err) |
5841 | return err; | 5834 | return err; |
5842 | hash = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; | 5835 | |
5843 | while (size > conf->max_nr_stripes) { | 5836 | while (size > conf->max_nr_stripes) |
5844 | if (grow_one_stripe(conf, hash, GFP_KERNEL)) | 5837 | if (!grow_one_stripe(conf, GFP_KERNEL)) |
5845 | conf->max_nr_stripes++; | 5838 | break; |
5846 | else break; | 5839 | |
5847 | hash = (hash + 1) % NR_STRIPE_HASH_LOCKS; | ||
5848 | } | ||
5849 | return 0; | 5840 | return 0; |
5850 | } | 5841 | } |
5851 | EXPORT_SYMBOL(raid5_set_cache_size); | 5842 | EXPORT_SYMBOL(raid5_set_cache_size); |
@@ -6451,7 +6442,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) | |||
6451 | conf->prev_algo = mddev->layout; | 6442 | conf->prev_algo = mddev->layout; |
6452 | } | 6443 | } |
6453 | 6444 | ||
6454 | memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + | 6445 | memory = NR_STRIPES * (sizeof(struct stripe_head) + |
6455 | max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; | 6446 | max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; |
6456 | atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS); | 6447 | atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS); |
6457 | if (grow_stripes(conf, NR_STRIPES)) { | 6448 | if (grow_stripes(conf, NR_STRIPES)) { |