Commit a3d33291 authored by Mark Fasheh's avatar Mark Fasheh

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
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
#define DLM_HASH_BUCKETS (PAGE_SIZE / sizeof(struct hlist_head)) #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 { enum dlm_ast_type {
DLM_AST = 0, DLM_AST = 0,
DLM_BAST, DLM_BAST,
...@@ -694,7 +697,8 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, ...@@ -694,7 +697,8 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res); struct dlm_lock_resource *res);
struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
const char *name, const char *name,
unsigned int len); unsigned int len,
unsigned int hash);
struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
const char *name, const char *name,
unsigned int len); unsigned int len);
......
...@@ -90,7 +90,6 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, ...@@ -90,7 +90,6 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
assert_spin_locked(&dlm->spinlock); assert_spin_locked(&dlm->spinlock);
q = &res->lockname; q = &res->lockname;
q->hash = full_name_hash(q->name, q->len);
bucket = &(dlm->lockres_hash[q->hash % DLM_HASH_BUCKETS]); bucket = &(dlm->lockres_hash[q->hash % DLM_HASH_BUCKETS]);
/* get a reference for our hashtable */ /* get a reference for our hashtable */
...@@ -101,9 +100,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, ...@@ -101,9 +100,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
const char *name, const char *name,
unsigned int len) unsigned int len,
unsigned int hash)
{ {
unsigned int hash;
struct hlist_node *iter; struct hlist_node *iter;
struct dlm_lock_resource *tmpres=NULL; struct dlm_lock_resource *tmpres=NULL;
struct hlist_head *bucket; struct hlist_head *bucket;
...@@ -112,8 +111,6 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, ...@@ -112,8 +111,6 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
assert_spin_locked(&dlm->spinlock); assert_spin_locked(&dlm->spinlock);
hash = full_name_hash(name, len);
bucket = &(dlm->lockres_hash[hash % DLM_HASH_BUCKETS]); bucket = &(dlm->lockres_hash[hash % DLM_HASH_BUCKETS]);
/* check for pre-existing lock */ /* check for pre-existing lock */
...@@ -135,9 +132,10 @@ struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm, ...@@ -135,9 +132,10 @@ struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
unsigned int len) unsigned int len)
{ {
struct dlm_lock_resource *res; struct dlm_lock_resource *res;
unsigned int hash = dlm_lockid_hash(name, len);
spin_lock(&dlm->spinlock); spin_lock(&dlm->spinlock);
res = __dlm_lookup_lockres(dlm, name, len); res = __dlm_lookup_lockres(dlm, name, len, hash);
spin_unlock(&dlm->spinlock); spin_unlock(&dlm->spinlock);
return res; return res;
} }
......
...@@ -603,7 +603,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, ...@@ -603,7 +603,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm,
memcpy(qname, name, namelen); memcpy(qname, name, namelen);
res->lockname.len = 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); init_waitqueue_head(&res->wq);
spin_lock_init(&res->spinlock); spin_lock_init(&res->spinlock);
...@@ -677,19 +677,20 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, ...@@ -677,19 +677,20 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
int blocked = 0; int blocked = 0;
int ret, nodenum; int ret, nodenum;
struct dlm_node_iter iter; struct dlm_node_iter iter;
unsigned int namelen; unsigned int namelen, hash;
int tries = 0; int tries = 0;
int bit, wait_on_recovery = 0; int bit, wait_on_recovery = 0;
BUG_ON(!lockid); BUG_ON(!lockid);
namelen = strlen(lockid); namelen = strlen(lockid);
hash = dlm_lockid_hash(lockid, namelen);
mlog(0, "get lockres %s (len %d)\n", lockid, namelen); mlog(0, "get lockres %s (len %d)\n", lockid, namelen);
lookup: lookup:
spin_lock(&dlm->spinlock); spin_lock(&dlm->spinlock);
tmpres = __dlm_lookup_lockres(dlm, lockid, namelen); tmpres = __dlm_lookup_lockres(dlm, lockid, namelen, hash);
if (tmpres) { if (tmpres) {
spin_unlock(&dlm->spinlock); spin_unlock(&dlm->spinlock);
mlog(0, "found in hash!\n"); mlog(0, "found in hash!\n");
...@@ -1316,7 +1317,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -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_request *request = (struct dlm_master_request *) msg->buf;
struct dlm_master_list_entry *mle = NULL, *tmpmle = NULL; struct dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
char *name; char *name;
unsigned int namelen; unsigned int namelen, hash;
int found, ret; int found, ret;
int set_maybe; int set_maybe;
int dispatch_assert = 0; int dispatch_assert = 0;
...@@ -1331,6 +1332,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -1331,6 +1332,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data)
name = request->name; name = request->name;
namelen = request->namelen; namelen = request->namelen;
hash = dlm_lockid_hash(name, namelen);
if (namelen > DLM_LOCKID_NAME_MAX) { if (namelen > DLM_LOCKID_NAME_MAX) {
response = DLM_IVBUFLEN; response = DLM_IVBUFLEN;
...@@ -1339,7 +1341,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -1339,7 +1341,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data)
way_up_top: way_up_top:
spin_lock(&dlm->spinlock); spin_lock(&dlm->spinlock);
res = __dlm_lookup_lockres(dlm, name, namelen); res = __dlm_lookup_lockres(dlm, name, namelen, hash);
if (res) { if (res) {
spin_unlock(&dlm->spinlock); spin_unlock(&dlm->spinlock);
...@@ -1612,7 +1614,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -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_assert_master *assert = (struct dlm_assert_master *)msg->buf;
struct dlm_lock_resource *res = NULL; struct dlm_lock_resource *res = NULL;
char *name; char *name;
unsigned int namelen; unsigned int namelen, hash;
u32 flags; u32 flags;
int master_request = 0; int master_request = 0;
int ret = 0; int ret = 0;
...@@ -1622,6 +1624,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -1622,6 +1624,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data)
name = assert->name; name = assert->name;
namelen = assert->namelen; namelen = assert->namelen;
hash = dlm_lockid_hash(name, namelen);
flags = be32_to_cpu(assert->flags); flags = be32_to_cpu(assert->flags);
if (namelen > DLM_LOCKID_NAME_MAX) { if (namelen > DLM_LOCKID_NAME_MAX) {
...@@ -1670,7 +1673,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -1670,7 +1673,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data)
/* ok everything checks out with the MLE /* ok everything checks out with the MLE
* now check to see if there is a lockres */ * 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) { if (res) {
spin_lock(&res->spinlock); spin_lock(&res->spinlock);
if (res->state & DLM_LOCK_RES_RECOVERING) { if (res->state & DLM_LOCK_RES_RECOVERING) {
...@@ -2462,7 +2465,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -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_migrate_request *migrate = (struct dlm_migrate_request *) msg->buf;
struct dlm_master_list_entry *mle = NULL, *oldmle = NULL; struct dlm_master_list_entry *mle = NULL, *oldmle = NULL;
const char *name; const char *name;
unsigned int namelen; unsigned int namelen, hash;
int ret = 0; int ret = 0;
if (!dlm_grab(dlm)) if (!dlm_grab(dlm))
...@@ -2470,6 +2473,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -2470,6 +2473,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data)
name = migrate->name; name = migrate->name;
namelen = migrate->namelen; namelen = migrate->namelen;
hash = dlm_lockid_hash(name, namelen);
/* preallocate.. if this fails, abort */ /* preallocate.. if this fails, abort */
mle = (struct dlm_master_list_entry *) kmem_cache_alloc(dlm_mle_cache, 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) ...@@ -2482,7 +2486,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data)
/* check for pre-existing lock */ /* check for pre-existing lock */
spin_lock(&dlm->spinlock); spin_lock(&dlm->spinlock);
res = __dlm_lookup_lockres(dlm, name, namelen); res = __dlm_lookup_lockres(dlm, name, namelen, hash);
spin_lock(&dlm->master_lock); spin_lock(&dlm->master_lock);
if (res) { if (res) {
...@@ -2601,6 +2605,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node) ...@@ -2601,6 +2605,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
struct list_head *iter, *iter2; struct list_head *iter, *iter2;
struct dlm_master_list_entry *mle; struct dlm_master_list_entry *mle;
struct dlm_lock_resource *res; struct dlm_lock_resource *res;
unsigned int hash;
mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node); mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
top: top:
...@@ -2684,8 +2689,9 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node) ...@@ -2684,8 +2689,9 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
mle->master, mle->new_master); mle->master, mle->new_master);
/* if there is a lockres associated with this /* if there is a lockres associated with this
* mle, find it and set its owner to UNKNOWN */ * 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, res = __dlm_lookup_lockres(dlm, mle->u.name.name,
mle->u.name.len); mle->u.name.len, hash);
if (res) { if (res) {
/* unfortunately if we hit this rare case, our /* unfortunately if we hit this rare case, our
* lock ordering is messed. we need to drop * lock ordering is messed. we need to drop
......
...@@ -1404,6 +1404,7 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -1404,6 +1404,7 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data)
struct dlm_ctxt *dlm = data; struct dlm_ctxt *dlm = data;
struct dlm_master_requery *req = (struct dlm_master_requery *)msg->buf; struct dlm_master_requery *req = (struct dlm_master_requery *)msg->buf;
struct dlm_lock_resource *res = NULL; struct dlm_lock_resource *res = NULL;
unsigned int hash;
int master = DLM_LOCK_RES_OWNER_UNKNOWN; int master = DLM_LOCK_RES_OWNER_UNKNOWN;
u32 flags = DLM_ASSERT_MASTER_REQUERY; u32 flags = DLM_ASSERT_MASTER_REQUERY;
...@@ -1413,8 +1414,10 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data) ...@@ -1413,8 +1414,10 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data)
return master; return master;
} }
hash = dlm_lockid_hash(req->name, req->namelen);
spin_lock(&dlm->spinlock); 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) { if (res) {
spin_lock(&res->spinlock); spin_lock(&res->spinlock);
master = res->owner; master = res->owner;
......
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