Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 486f0644 authored by NeilBrown's avatar NeilBrown
Browse files

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
Loading
Loading
Loading
Loading
+24 −33
Original line number Diff line number Diff line
@@ -1963,7 +1963,7 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
	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;
	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)
		kmem_cache_free(conf->slab_cache, sh);
		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... */
	atomic_set(&sh->count, 1);
	atomic_inc(&conf->active_stripes);
@@ -1989,6 +1990,7 @@ static int grow_one_stripe(struct r5conf *conf, int hash, gfp_t gfp)
	INIT_LIST_HEAD(&sh->batch_list);
	sh->batch_head = NULL;
	release_stripe(sh);
	conf->max_nr_stripes++;
	return 1;
}

@@ -1996,7 +1998,6 @@ static int grow_stripes(struct r5conf *conf, int num)
{
	struct kmem_cache *sc;
	int devs = max(conf->raid_disks, conf->previous_raid_disks);
	int hash;

	if (conf->mddev->gendisk)
		sprintf(conf->cache_name[0],
@@ -2014,13 +2015,10 @@ static int grow_stripes(struct r5conf *conf, int num)
		return 1;
	conf->slab_cache = sc;
	conf->pool_size = devs;
	hash = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS;
	while (num--) {
		if (!grow_one_stripe(conf, hash, GFP_KERNEL))
	while (num--)
		if (!grow_one_stripe(conf, GFP_KERNEL))
			return 1;
		conf->max_nr_stripes++;
		hash = (hash + 1) % NR_STRIPE_HASH_LOCKS;
	}

	return 0;
}

@@ -2210,9 +2208,10 @@ static int resize_stripes(struct r5conf *conf, int newsize)
	return err;
}

static int drop_one_stripe(struct r5conf *conf, int hash)
static int drop_one_stripe(struct r5conf *conf)
{
	struct stripe_head *sh;
	int hash = (conf->max_nr_stripes - 1) % NR_STRIPE_HASH_LOCKS;

	spin_lock_irq(conf->hash_locks + hash);
	sh = get_free_stripe(conf, hash);
@@ -2223,14 +2222,14 @@ static int drop_one_stripe(struct r5conf *conf, int hash)
	shrink_buffers(sh);
	kmem_cache_free(conf->slab_cache, sh);
	atomic_dec(&conf->active_stripes);
	conf->max_nr_stripes--;
	return 1;
}

static void shrink_stripes(struct r5conf *conf)
{
	int hash;
	for (hash = 0; hash < NR_STRIPE_HASH_LOCKS; hash++)
		while (drop_one_stripe(conf, hash))
	while (conf->max_nr_stripes &&
	       drop_one_stripe(conf))
		;

	if (conf->slab_cache)
@@ -5822,30 +5821,22 @@ raid5_set_cache_size(struct mddev *mddev, int size)
{
	struct r5conf *conf = mddev->private;
	int err;
	int hash;

	if (size <= 16 || size > 32768)
		return -EINVAL;
	hash = (conf->max_nr_stripes - 1) % NR_STRIPE_HASH_LOCKS;
	while (size < conf->max_nr_stripes) {
		if (drop_one_stripe(conf, hash))
			conf->max_nr_stripes--;
		else
			break;
		hash--;
		if (hash < 0)
			hash = NR_STRIPE_HASH_LOCKS - 1;
	}

	while (size < conf->max_nr_stripes &&
	       drop_one_stripe(conf))
		;

	err = md_allow_write(mddev);
	if (err)
		return err;
	hash = conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS;
	while (size > conf->max_nr_stripes) {
		if (grow_one_stripe(conf, hash, GFP_KERNEL))
			conf->max_nr_stripes++;
		else break;
		hash = (hash + 1) % NR_STRIPE_HASH_LOCKS;
	}

	while (size > conf->max_nr_stripes)
		if (!grow_one_stripe(conf, GFP_KERNEL))
			break;

	return 0;
}
EXPORT_SYMBOL(raid5_set_cache_size);
@@ -6451,7 +6442,7 @@ static struct r5conf *setup_conf(struct mddev *mddev)
		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;
	atomic_set(&conf->empty_inactive_list_nr, NR_STRIPE_HASH_LOCKS);
	if (grow_stripes(conf, NR_STRIPES)) {