Commit 486f0644 authored by NeilBrown's avatar NeilBrown

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: default avatarNeilBrown <neilb@suse.de>
parent a9683a79
...@@ -1963,7 +1963,7 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) ...@@ -1963,7 +1963,7 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
put_cpu(); put_cpu();
} }
static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp) static int grow_one_stripe(struct r5conf *conf, gfp_t gfp)
{ {
struct stripe_head *sh; struct stripe_head *sh;
sh = kmem_cache_zalloc(conf->slab_cache, gfp); 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,7 +1979,8 @@ static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp)
kmem_cache_free(conf->slab_cache, sh); kmem_cache_free(conf->slab_cache, sh);
return 0; return 0;
} }
sh->hash_lock_index = hash; sh->hash_lock_index =
conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS;
/* we just created an active stripe so... */ /* we just created an active stripe so... */
atomic_set(&sh->count, 1); atomic_set(&sh->count, 1);
atomic_inc(&conf->active_stripes); atomic_inc(&conf->active_stripes);
...@@ -1989,6 +1990,7 @@ static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp) ...@@ -1989,6 +1990,7 @@ static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp)
INIT_LIST_HEAD(&sh->batch_list); INIT_LIST_HEAD(&sh->batch_list);
sh->batch_head = NULL; sh->batch_head = NULL;
release_stripe(sh); release_stripe(sh);
conf->max_nr_stripes++;
return 1; return 1;
} }
...@@ -1996,7 +1998,6 @@ static int grow_stripes(struct r5conf *conf, int num) ...@@ -1996,7 +1998,6 @@ static int grow_stripes(struct r5conf *conf, int num)
{ {
struct kmem_cache *sc; struct kmem_cache *sc;
int devs = max(conf->raid_disks, conf->previous_raid_disks); int devs = max(conf->raid_disks, conf->previous_raid_disks);
int hash;
if (conf->mddev->gendisk) if (conf->mddev->gendisk)
sprintf(conf->cache_name[0], sprintf(conf->cache_name[0],
...@@ -2014,13 +2015,10 @@ static int grow_stripes(struct r5conf *conf, int num) ...@@ -2014,13 +2015,10 @@ static int grow_stripes(struct r5conf *conf, int num)
return 1; return 1;
conf->slab_cache = sc; conf->slab_cache = sc;
conf->pool_size = devs; conf->pool_size = devs;
hash = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS; while (num--)
while (num--) { if (!grow_one_stripe(conf, GFP_KERNEL))
if (!grow_one_stripe(conf, hash, GFP_KERNEL))
return 1; return 1;
conf->max_nr_stripes++;
hash = (hash + 1) % NR_STRIPE_HASH_LOCKS;
}
return 0; return 0;
} }
...@@ -2210,9 +2208,10 @@ static int resize_stripes(struct r5conf *conf, int newsize) ...@@ -2210,9 +2208,10 @@ static int resize_stripes(struct r5conf *conf, int newsize)
return err; return err;
} }
static int drop_one_stripe(struct r5conf *conf, int hash) static int drop_one_stripe(struct r5conf *conf)
{ {
struct stripe_head *sh; struct stripe_head *sh;
int hash = (conf->max_nr_stripes - 1) % NR_STRIPE_HASH_LOCKS;
spin_lock_irq(conf->hash_locks + hash); spin_lock_irq(conf->hash_locks + hash);
sh = get_free_stripe(conf, hash); sh = get_free_stripe(conf, hash);
...@@ -2223,14 +2222,14 @@ static int drop_one_stripe(struct r5conf *conf, int hash) ...@@ -2223,14 +2222,14 @@ static int drop_one_stripe(struct r5conf *conf, int hash)
shrink_buffers(sh); shrink_buffers(sh);
kmem_cache_free(conf->slab_cache, sh); kmem_cache_free(conf->slab_cache, sh);
atomic_dec(&conf->active_stripes); atomic_dec(&conf->active_stripes);
conf->max_nr_stripes--;
return 1; return 1;
} }
static void shrink_stripes(struct r5conf *conf) static void shrink_stripes(struct r5conf *conf)
{ {
int hash; while (conf->max_nr_stripes &&
for (hash = 0; hash < NR_STRIPE_HASH_LOCKS; hash++) drop_one_stripe(conf))
while (drop_one_stripe(conf, hash))
; ;
if (conf->slab_cache) if (conf->slab_cache)
...@@ -5822,30 +5821,22 @@ raid5_set_cache_size(struct mddev *mddev, int size) ...@@ -5822,30 +5821,22 @@ raid5_set_cache_size(struct mddev *mddev, int size)
{ {
struct r5conf *conf = mddev->private; struct r5conf *conf = mddev->private;
int err; int err;
int hash;
if (size <= 16 || size > 32768) if (size <= 16 || size > 32768)
return -EINVAL; return -EINVAL;
hash = (conf->max_nr_stripes - 1) % NR_STRIPE_HASH_LOCKS;
while (size < conf->max_nr_stripes) { while (size < conf->max_nr_stripes &&
if (drop_one_stripe(conf, hash)) drop_one_stripe(conf))
conf->max_nr_stripes--; ;
else
break;
hash--;
if (hash < 0)
hash = NR_STRIPE_HASH_LOCKS - 1;
}
err = md_allow_write(mddev); err = md_allow_write(mddev);
if (err) if (err)
return err; return err;
hash = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS;
while (size > conf->max_nr_stripes) { while (size > conf->max_nr_stripes)
if (grow_one_stripe(conf, hash, GFP_KERNEL)) if (!grow_one_stripe(conf, GFP_KERNEL))
conf->max_nr_stripes++; break;
else break;
hash = (hash + 1) % NR_STRIPE_HASH_LOCKS;
}
return 0; return 0;
} }
EXPORT_SYMBOL(raid5_set_cache_size); EXPORT_SYMBOL(raid5_set_cache_size);
...@@ -6451,7 +6442,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) ...@@ -6451,7 +6442,7 @@ static struct r5conf *setup_conf(struct mddev *mddev)
conf->prev_algo = mddev->layout; conf->prev_algo = mddev->layout;
} }
memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + memory = NR_STRIPES * (sizeof(struct stripe_head) +
max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS); atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS);
if (grow_stripes(conf, NR_STRIPES)) { if (grow_stripes(conf, NR_STRIPES)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment