aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2015-02-24 20:10:35 -0500
committerNeilBrown <neilb@suse.de>2015-04-21 18:00:42 -0400
commit486f0644c3482cbf64fe804499836e1f05abec14 (patch)
tree1cb95a03d09942e04af8ec716652180b35c4f1ef /drivers/md
parenta9683a795bcca6d0e7fe4c4c00e071218f3f4428 (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.c57
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
1966static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp) 1966static 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
2213static int drop_one_stripe(struct r5conf *conf, int hash) 2211static 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
2229static void shrink_stripes(struct r5conf *conf) 2229static 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}
5851EXPORT_SYMBOL(raid5_set_cache_size); 5842EXPORT_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)) {