ocfs2: calculate lockid hash values outside of the spinlock
Fixes a performance bug - pointed out by Andrew. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
This commit is contained in:
parent
65c491d833
commit
a3d3329159
|
@ -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,
|
||||||
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,
|
||||||
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 */
|
||||||
|
@ -100,10 +99,10 @@ 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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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 @@ top:
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue