Commit 15fd7e55 authored by Alexander Aring's avatar Alexander Aring Committed by David Teigland
Browse files

dlm: use rwlock for lkbidr



Convert the lock for lkbidr to an rwlock.  Most idr lookups will use
the read lock.

Signed-off-by: default avatarAlexander Aring <aahringo@redhat.com>
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent e9131359
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -582,7 +582,7 @@ struct dlm_ls {
	struct kobject		ls_kobj;

	struct idr		ls_lkbidr;
	spinlock_t		ls_lkbidr_spin;
	rwlock_t		ls_lkbidr_lock;

	struct rhashtable	ls_rsbtbl;
	rwlock_t		ls_rsbtbl_lock;
+7 −37
Original line number Diff line number Diff line
@@ -1522,11 +1522,11 @@ static int _create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret,
	INIT_LIST_HEAD(&lkb->lkb_ownqueue);
	INIT_LIST_HEAD(&lkb->lkb_rsb_lookup);

	spin_lock_bh(&ls->ls_lkbidr_spin);
	write_lock_bh(&ls->ls_lkbidr_lock);
	rv = idr_alloc(&ls->ls_lkbidr, lkb, start, end, GFP_NOWAIT);
	if (rv >= 0)
		lkb->lkb_id = rv;
	spin_unlock_bh(&ls->ls_lkbidr_spin);
	write_unlock_bh(&ls->ls_lkbidr_lock);

	if (rv < 0) {
		log_error(ls, "create_lkb idr error %d", rv);
@@ -1547,11 +1547,11 @@ static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
{
	struct dlm_lkb *lkb;

	spin_lock_bh(&ls->ls_lkbidr_spin);
	read_lock_bh(&ls->ls_lkbidr_lock);
	lkb = idr_find(&ls->ls_lkbidr, lkid);
	if (lkb)
		kref_get(&lkb->lkb_ref);
	spin_unlock_bh(&ls->ls_lkbidr_spin);
	read_unlock_bh(&ls->ls_lkbidr_lock);

	*lkb_ret = lkb;
	return lkb ? 0 : -ENOENT;
@@ -1567,36 +1567,6 @@ static void kill_lkb(struct kref *kref)
	DLM_ASSERT(!lkb->lkb_status, dlm_print_lkb(lkb););
}

/* TODO move this to lib/refcount.c */
static __must_check bool
dlm_refcount_dec_and_lock_bh(refcount_t *r, spinlock_t *lock)
__cond_acquires(lock)
{
	if (refcount_dec_not_one(r))
		return false;

	spin_lock_bh(lock);
	if (!refcount_dec_and_test(r)) {
		spin_unlock_bh(lock);
		return false;
	}

	return true;
}

/* TODO move this to include/linux/kref.h */
static inline int dlm_kref_put_lock_bh(struct kref *kref,
				       void (*release)(struct kref *kref),
				       spinlock_t *lock)
{
	if (dlm_refcount_dec_and_lock_bh(&kref->refcount, lock)) {
		release(kref);
		return 1;
	}

	return 0;
}

/* __put_lkb() is used when an lkb may not have an rsb attached to
   it so we need to provide the lockspace explicitly */

@@ -1605,11 +1575,11 @@ static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)
	uint32_t lkid = lkb->lkb_id;
	int rv;

	rv = dlm_kref_put_lock_bh(&lkb->lkb_ref, kill_lkb,
				  &ls->ls_lkbidr_spin);
	rv = dlm_kref_put_write_lock_bh(&lkb->lkb_ref, kill_lkb,
					&ls->ls_lkbidr_lock);
	if (rv) {
		idr_remove(&ls->ls_lkbidr, lkid);
		spin_unlock_bh(&ls->ls_lkbidr_spin);
		write_unlock_bh(&ls->ls_lkbidr_lock);

		detach_lkb(lkb);

+3 −3
Original line number Diff line number Diff line
@@ -431,7 +431,7 @@ static int new_lockspace(const char *name, const char *cluster,
		goto out_lsfree;

	idr_init(&ls->ls_lkbidr);
	spin_lock_init(&ls->ls_lkbidr_spin);
	rwlock_init(&ls->ls_lkbidr_lock);

	INIT_LIST_HEAD(&ls->ls_waiters);
	spin_lock_init(&ls->ls_waiters_lock);
@@ -676,7 +676,7 @@ static int lockspace_busy(struct dlm_ls *ls, int force)
{
	int rv;

	spin_lock_bh(&ls->ls_lkbidr_spin);
	read_lock_bh(&ls->ls_lkbidr_lock);
	if (force == 0) {
		rv = idr_for_each(&ls->ls_lkbidr, lkb_idr_is_any, ls);
	} else if (force == 1) {
@@ -684,7 +684,7 @@ static int lockspace_busy(struct dlm_ls *ls, int force)
	} else {
		rv = 0;
	}
	spin_unlock_bh(&ls->ls_lkbidr_spin);
	read_unlock_bh(&ls->ls_lkbidr_lock);
	return rv;
}