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

Commit 4eb788df authored by Shaohua Li's avatar Shaohua Li Committed by NeilBrown
Browse files

raid5: reduce chance release_stripe() taking device_lock



release_stripe() is a place conf->device_lock is heavily contended. We take the
lock even stripe count isn't 1, which isn't required.

Signed-off-by: default avatarShaohua Li <shli@fusionio.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 58e94ae1
Loading
Loading
Loading
Loading
+41 −34
Original line number Diff line number Diff line
@@ -190,9 +190,8 @@ static int stripe_operations_active(struct stripe_head *sh)
	       test_bit(STRIPE_COMPUTE_RUN, &sh->state);
}

static void __release_stripe(struct r5conf *conf, struct stripe_head *sh)
static void do_release_stripe(struct r5conf *conf, struct stripe_head *sh)
{
	if (atomic_dec_and_test(&sh->count)) {
	BUG_ON(!list_empty(&sh->lru));
	BUG_ON(atomic_read(&conf->active_stripes)==0);
	if (test_bit(STRIPE_HANDLE, &sh->state)) {
@@ -223,6 +222,11 @@ static void __release_stripe(struct r5conf *conf, struct stripe_head *sh)
		}
	}
}

static void __release_stripe(struct r5conf *conf, struct stripe_head *sh)
{
	if (atomic_dec_and_test(&sh->count))
		do_release_stripe(conf, sh);
}

static void release_stripe(struct stripe_head *sh)
@@ -230,9 +234,12 @@ static void release_stripe(struct stripe_head *sh)
	struct r5conf *conf = sh->raid_conf;
	unsigned long flags;

	spin_lock_irqsave(&conf->device_lock, flags);
	__release_stripe(conf, sh);
	spin_unlock_irqrestore(&conf->device_lock, flags);
	local_irq_save(flags);
	if (atomic_dec_and_lock(&sh->count, &conf->device_lock)) {
		do_release_stripe(conf, sh);
		spin_unlock(&conf->device_lock);
	}
	local_irq_restore(flags);
}

static inline void remove_hash(struct stripe_head *sh)