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

Commit a3d33291 authored by Mark Fasheh's avatar Mark Fasheh
Browse files

ocfs2: calculate lockid hash values outside of the spinlock



Fixes a performance bug - pointed out by Andrew.

Signed-off-by: default avatarMark Fasheh <mark.fasheh@oracle.com>
parent 65c491d8
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@

#define DLM_HASH_BUCKETS     (PAGE_SIZE / sizeof(struct hlist_head))

/* Intended to make it easier for us to switch out hash functions */
#define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l)

enum dlm_ast_type {
	DLM_AST = 0,
	DLM_BAST,
@@ -694,7 +697,8 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
			  struct dlm_lock_resource *res);
struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
						const char *name,
						unsigned int len);
						unsigned int len,
						unsigned int hash);
struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
					      const char *name,
					      unsigned int len);
+5 −7
Original line number Diff line number Diff line
@@ -90,7 +90,6 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
	assert_spin_locked(&dlm->spinlock);

	q = &res->lockname;
	q->hash = full_name_hash(q->name, q->len);
	bucket = &(dlm->lockres_hash[q->hash % DLM_HASH_BUCKETS]);

	/* get a reference for our hashtable */
@@ -101,9 +100,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,

struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
						const char *name,
					 unsigned int len)
						unsigned int len,
						unsigned int hash)
{
	unsigned int hash;
	struct hlist_node *iter;
	struct dlm_lock_resource *tmpres=NULL;
	struct hlist_head *bucket;
@@ -112,8 +111,6 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,

	assert_spin_locked(&dlm->spinlock);

	hash = full_name_hash(name, len);

	bucket = &(dlm->lockres_hash[hash % DLM_HASH_BUCKETS]);

	/* check for pre-existing lock */
@@ -135,9 +132,10 @@ struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
				    unsigned int len)
{
	struct dlm_lock_resource *res;
	unsigned int hash = dlm_lockid_hash(name, len);

	spin_lock(&dlm->spinlock);
	res = __dlm_lookup_lockres(dlm, name, len);
	res = __dlm_lookup_lockres(dlm, name, len, hash);
	spin_unlock(&dlm->spinlock);
	return res;
}
+16 −10
Original line number Diff line number Diff line
@@ -603,7 +603,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
	memcpy(qname, name, namelen);

	res->lockname.len = namelen;
	res->lockname.hash = full_name_hash(name, namelen);
	res->lockname.hash = dlm_lockid_hash(name, namelen);

	init_waitqueue_head(&res->wq);
	spin_lock_init(&res->spinlock);
@@ -677,19 +677,20 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
	int blocked = 0;
	int ret, nodenum;
	struct dlm_node_iter iter;
	unsigned int namelen;
	unsigned int namelen, hash;
	int tries = 0;
	int bit, wait_on_recovery = 0;

	BUG_ON(!lockid);

	namelen = strlen(lockid);
	hash = dlm_lockid_hash(lockid, namelen);

	mlog(0, "get lockres %s (len %d)\n", lockid, namelen);

lookup:
	spin_lock(&dlm->spinlock);
	tmpres = __dlm_lookup_lockres(dlm, lockid, namelen);
	tmpres = __dlm_lookup_lockres(dlm, lockid, namelen, hash);
	if (tmpres) {
		spin_unlock(&dlm->spinlock);
		mlog(0, "found in hash!\n");
@@ -1316,7 +1317,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data)
	struct dlm_master_request *request = (struct dlm_master_request *) msg->buf;
	struct dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
	char *name;
	unsigned int namelen;
	unsigned int namelen, hash;
	int found, ret;
	int set_maybe;
	int dispatch_assert = 0;
@@ -1331,6 +1332,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data)

	name = request->name;
	namelen = request->namelen;
	hash = dlm_lockid_hash(name, namelen);

	if (namelen > DLM_LOCKID_NAME_MAX) {
		response = DLM_IVBUFLEN;
@@ -1339,7 +1341,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data)

way_up_top:
	spin_lock(&dlm->spinlock);
	res = __dlm_lookup_lockres(dlm, name, namelen);
	res = __dlm_lookup_lockres(dlm, name, namelen, hash);
	if (res) {
		spin_unlock(&dlm->spinlock);

@@ -1612,7 +1614,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data)
	struct dlm_assert_master *assert = (struct dlm_assert_master *)msg->buf;
	struct dlm_lock_resource *res = NULL;
	char *name;
	unsigned int namelen;
	unsigned int namelen, hash;
	u32 flags;
	int master_request = 0;
	int ret = 0;
@@ -1622,6 +1624,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data)

	name = assert->name;
	namelen = assert->namelen;
	hash = dlm_lockid_hash(name, namelen);
	flags = be32_to_cpu(assert->flags);

	if (namelen > DLM_LOCKID_NAME_MAX) {
@@ -1670,7 +1673,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data)

	/* ok everything checks out with the MLE
	 * now check to see if there is a lockres */
	res = __dlm_lookup_lockres(dlm, name, namelen);
	res = __dlm_lookup_lockres(dlm, name, namelen, hash);
	if (res) {
		spin_lock(&res->spinlock);
		if (res->state & DLM_LOCK_RES_RECOVERING)  {
@@ -2462,7 +2465,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data)
	struct dlm_migrate_request *migrate = (struct dlm_migrate_request *) msg->buf;
	struct dlm_master_list_entry *mle = NULL, *oldmle = NULL;
	const char *name;
	unsigned int namelen;
	unsigned int namelen, hash;
	int ret = 0;

	if (!dlm_grab(dlm))
@@ -2470,6 +2473,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data)

	name = migrate->name;
	namelen = migrate->namelen;
	hash = dlm_lockid_hash(name, namelen);

	/* preallocate.. if this fails, abort */
	mle = (struct dlm_master_list_entry *) kmem_cache_alloc(dlm_mle_cache,
@@ -2482,7 +2486,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data)

	/* check for pre-existing lock */
	spin_lock(&dlm->spinlock);
	res = __dlm_lookup_lockres(dlm, name, namelen);
	res = __dlm_lookup_lockres(dlm, name, namelen, hash);
	spin_lock(&dlm->master_lock);

	if (res) {
@@ -2601,6 +2605,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
	struct list_head *iter, *iter2;
	struct dlm_master_list_entry *mle;
	struct dlm_lock_resource *res;
	unsigned int hash;

	mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
top:
@@ -2684,8 +2689,9 @@ top:
		     mle->master, mle->new_master);
		/* if there is a lockres associated with this
	 	 * mle, find it and set its owner to UNKNOWN */
		hash = dlm_lockid_hash(mle->u.name.name, mle->u.name.len);
		res = __dlm_lookup_lockres(dlm, mle->u.name.name,
					mle->u.name.len);
					   mle->u.name.len, hash);
		if (res) {
			/* unfortunately if we hit this rare case, our
		 	 * lock ordering is messed.  we need to drop
+4 −1
Original line number Diff line number Diff line
@@ -1404,6 +1404,7 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data)
	struct dlm_ctxt *dlm = data;
	struct dlm_master_requery *req = (struct dlm_master_requery *)msg->buf;
	struct dlm_lock_resource *res = NULL;
	unsigned int hash;
	int master = DLM_LOCK_RES_OWNER_UNKNOWN;
	u32 flags = DLM_ASSERT_MASTER_REQUERY;

@@ -1413,8 +1414,10 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data)
		return master;
	}

	hash = dlm_lockid_hash(req->name, req->namelen);

	spin_lock(&dlm->spinlock);
	res = __dlm_lookup_lockres(dlm, req->name, req->namelen);
	res = __dlm_lookup_lockres(dlm, req->name, req->namelen, hash);
	if (res) {
		spin_lock(&res->spinlock);
		master = res->owner;