diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2006-03-09 20:55:56 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2006-06-26 17:42:39 -0400 |
commit | a3d3329159ea76bae0b3b8680691a1c3ecf5801f (patch) | |
tree | a4521103c45190ff340f918d131649a20b414b27 /fs/ocfs2 | |
parent | 65c491d833a06fd0d1383297590772c75d28155c (diff) |
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>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlm/dlmcommon.h | 6 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 12 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 26 | ||||
-rw-r--r-- | fs/ocfs2/dlm/dlmrecovery.c | 5 |
4 files changed, 30 insertions, 19 deletions
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 1c05d485e019..3b675368762e 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -39,6 +39,9 @@ | |||
39 | 39 | ||
40 | #define DLM_HASH_BUCKETS (PAGE_SIZE / sizeof(struct hlist_head)) | 40 | #define DLM_HASH_BUCKETS (PAGE_SIZE / sizeof(struct hlist_head)) |
41 | 41 | ||
42 | /* Intended to make it easier for us to switch out hash functions */ | ||
43 | #define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l) | ||
44 | |||
42 | enum dlm_ast_type { | 45 | enum dlm_ast_type { |
43 | DLM_AST = 0, | 46 | DLM_AST = 0, |
44 | DLM_BAST, | 47 | DLM_BAST, |
@@ -694,7 +697,8 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, | |||
694 | struct dlm_lock_resource *res); | 697 | struct dlm_lock_resource *res); |
695 | struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, | 698 | struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, |
696 | const char *name, | 699 | const char *name, |
697 | unsigned int len); | 700 | unsigned int len, |
701 | unsigned int hash); | ||
698 | struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm, | 702 | struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm, |
699 | const char *name, | 703 | const char *name, |
700 | unsigned int len); | 704 | unsigned int len); |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 8f3a9e3106fd..a818fde24476 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -90,7 +90,6 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, | |||
90 | assert_spin_locked(&dlm->spinlock); | 90 | assert_spin_locked(&dlm->spinlock); |
91 | 91 | ||
92 | q = &res->lockname; | 92 | q = &res->lockname; |
93 | q->hash = full_name_hash(q->name, q->len); | ||
94 | bucket = &(dlm->lockres_hash[q->hash % DLM_HASH_BUCKETS]); | 93 | bucket = &(dlm->lockres_hash[q->hash % DLM_HASH_BUCKETS]); |
95 | 94 | ||
96 | /* get a reference for our hashtable */ | 95 | /* get a reference for our hashtable */ |
@@ -100,10 +99,10 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, | |||
100 | } | 99 | } |
101 | 100 | ||
102 | struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, | 101 | struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, |
103 | const char *name, | 102 | const char *name, |
104 | unsigned int len) | 103 | unsigned int len, |
104 | unsigned int hash) | ||
105 | { | 105 | { |
106 | unsigned int hash; | ||
107 | struct hlist_node *iter; | 106 | struct hlist_node *iter; |
108 | struct dlm_lock_resource *tmpres=NULL; | 107 | struct dlm_lock_resource *tmpres=NULL; |
109 | struct hlist_head *bucket; | 108 | struct hlist_head *bucket; |
@@ -112,8 +111,6 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, | |||
112 | 111 | ||
113 | assert_spin_locked(&dlm->spinlock); | 112 | assert_spin_locked(&dlm->spinlock); |
114 | 113 | ||
115 | hash = full_name_hash(name, len); | ||
116 | |||
117 | bucket = &(dlm->lockres_hash[hash % DLM_HASH_BUCKETS]); | 114 | bucket = &(dlm->lockres_hash[hash % DLM_HASH_BUCKETS]); |
118 | 115 | ||
119 | /* check for pre-existing lock */ | 116 | /* check for pre-existing lock */ |
@@ -135,9 +132,10 @@ struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm, | |||
135 | unsigned int len) | 132 | unsigned int len) |
136 | { | 133 | { |
137 | struct dlm_lock_resource *res; | 134 | struct dlm_lock_resource *res; |
135 | unsigned int hash = dlm_lockid_hash(name, len); | ||
138 | 136 | ||
139 | spin_lock(&dlm->spinlock); | 137 | spin_lock(&dlm->spinlock); |
140 | res = __dlm_lookup_lockres(dlm, name, len); | 138 | res = __dlm_lookup_lockres(dlm, name, len, hash); |
141 | spin_unlock(&dlm->spinlock); | 139 | spin_unlock(&dlm->spinlock); |
142 | return res; | 140 | return res; |
143 | } | 141 | } |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 940be4c13b1f..953aa8421be4 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -603,7 +603,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, | |||
603 | memcpy(qname, name, namelen); | 603 | memcpy(qname, name, namelen); |
604 | 604 | ||
605 | res->lockname.len = namelen; | 605 | res->lockname.len = namelen; |
606 | res->lockname.hash = full_name_hash(name, namelen); | 606 | res->lockname.hash = dlm_lockid_hash(name, namelen); |
607 | 607 | ||
608 | init_waitqueue_head(&res->wq); | 608 | init_waitqueue_head(&res->wq); |
609 | spin_lock_init(&res->spinlock); | 609 | spin_lock_init(&res->spinlock); |
@@ -677,19 +677,20 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, | |||
677 | int blocked = 0; | 677 | int blocked = 0; |
678 | int ret, nodenum; | 678 | int ret, nodenum; |
679 | struct dlm_node_iter iter; | 679 | struct dlm_node_iter iter; |
680 | unsigned int namelen; | 680 | unsigned int namelen, hash; |
681 | int tries = 0; | 681 | int tries = 0; |
682 | int bit, wait_on_recovery = 0; | 682 | int bit, wait_on_recovery = 0; |
683 | 683 | ||
684 | BUG_ON(!lockid); | 684 | BUG_ON(!lockid); |
685 | 685 | ||
686 | namelen = strlen(lockid); | 686 | namelen = strlen(lockid); |
687 | hash = dlm_lockid_hash(lockid, namelen); | ||
687 | 688 | ||
688 | mlog(0, "get lockres %s (len %d)\n", lockid, namelen); | 689 | mlog(0, "get lockres %s (len %d)\n", lockid, namelen); |
689 | 690 | ||
690 | lookup: | 691 | lookup: |
691 | spin_lock(&dlm->spinlock); | 692 | spin_lock(&dlm->spinlock); |
692 | tmpres = __dlm_lookup_lockres(dlm, lockid, namelen); | 693 | tmpres = __dlm_lookup_lockres(dlm, lockid, namelen, hash); |
693 | if (tmpres) { | 694 | if (tmpres) { |
694 | spin_unlock(&dlm->spinlock); | 695 | spin_unlock(&dlm->spinlock); |
695 | mlog(0, "found in hash!\n"); | 696 | mlog(0, "found in hash!\n"); |
@@ -1316,7 +1317,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1316 | struct dlm_master_request *request = (struct dlm_master_request *) msg->buf; | 1317 | struct dlm_master_request *request = (struct dlm_master_request *) msg->buf; |
1317 | struct dlm_master_list_entry *mle = NULL, *tmpmle = NULL; | 1318 | struct dlm_master_list_entry *mle = NULL, *tmpmle = NULL; |
1318 | char *name; | 1319 | char *name; |
1319 | unsigned int namelen; | 1320 | unsigned int namelen, hash; |
1320 | int found, ret; | 1321 | int found, ret; |
1321 | int set_maybe; | 1322 | int set_maybe; |
1322 | int dispatch_assert = 0; | 1323 | int dispatch_assert = 0; |
@@ -1331,6 +1332,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1331 | 1332 | ||
1332 | name = request->name; | 1333 | name = request->name; |
1333 | namelen = request->namelen; | 1334 | namelen = request->namelen; |
1335 | hash = dlm_lockid_hash(name, namelen); | ||
1334 | 1336 | ||
1335 | if (namelen > DLM_LOCKID_NAME_MAX) { | 1337 | if (namelen > DLM_LOCKID_NAME_MAX) { |
1336 | response = DLM_IVBUFLEN; | 1338 | response = DLM_IVBUFLEN; |
@@ -1339,7 +1341,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1339 | 1341 | ||
1340 | way_up_top: | 1342 | way_up_top: |
1341 | spin_lock(&dlm->spinlock); | 1343 | spin_lock(&dlm->spinlock); |
1342 | res = __dlm_lookup_lockres(dlm, name, namelen); | 1344 | res = __dlm_lookup_lockres(dlm, name, namelen, hash); |
1343 | if (res) { | 1345 | if (res) { |
1344 | spin_unlock(&dlm->spinlock); | 1346 | spin_unlock(&dlm->spinlock); |
1345 | 1347 | ||
@@ -1612,7 +1614,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1612 | struct dlm_assert_master *assert = (struct dlm_assert_master *)msg->buf; | 1614 | struct dlm_assert_master *assert = (struct dlm_assert_master *)msg->buf; |
1613 | struct dlm_lock_resource *res = NULL; | 1615 | struct dlm_lock_resource *res = NULL; |
1614 | char *name; | 1616 | char *name; |
1615 | unsigned int namelen; | 1617 | unsigned int namelen, hash; |
1616 | u32 flags; | 1618 | u32 flags; |
1617 | int master_request = 0; | 1619 | int master_request = 0; |
1618 | int ret = 0; | 1620 | int ret = 0; |
@@ -1622,6 +1624,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1622 | 1624 | ||
1623 | name = assert->name; | 1625 | name = assert->name; |
1624 | namelen = assert->namelen; | 1626 | namelen = assert->namelen; |
1627 | hash = dlm_lockid_hash(name, namelen); | ||
1625 | flags = be32_to_cpu(assert->flags); | 1628 | flags = be32_to_cpu(assert->flags); |
1626 | 1629 | ||
1627 | if (namelen > DLM_LOCKID_NAME_MAX) { | 1630 | if (namelen > DLM_LOCKID_NAME_MAX) { |
@@ -1670,7 +1673,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1670 | 1673 | ||
1671 | /* ok everything checks out with the MLE | 1674 | /* ok everything checks out with the MLE |
1672 | * now check to see if there is a lockres */ | 1675 | * now check to see if there is a lockres */ |
1673 | res = __dlm_lookup_lockres(dlm, name, namelen); | 1676 | res = __dlm_lookup_lockres(dlm, name, namelen, hash); |
1674 | if (res) { | 1677 | if (res) { |
1675 | spin_lock(&res->spinlock); | 1678 | spin_lock(&res->spinlock); |
1676 | if (res->state & DLM_LOCK_RES_RECOVERING) { | 1679 | 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 | struct dlm_migrate_request *migrate = (struct dlm_migrate_request *) msg->buf; | 2465 | struct dlm_migrate_request *migrate = (struct dlm_migrate_request *) msg->buf; |
2463 | struct dlm_master_list_entry *mle = NULL, *oldmle = NULL; | 2466 | struct dlm_master_list_entry *mle = NULL, *oldmle = NULL; |
2464 | const char *name; | 2467 | const char *name; |
2465 | unsigned int namelen; | 2468 | unsigned int namelen, hash; |
2466 | int ret = 0; | 2469 | int ret = 0; |
2467 | 2470 | ||
2468 | if (!dlm_grab(dlm)) | 2471 | if (!dlm_grab(dlm)) |
@@ -2470,6 +2473,7 @@ int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data) | |||
2470 | 2473 | ||
2471 | name = migrate->name; | 2474 | name = migrate->name; |
2472 | namelen = migrate->namelen; | 2475 | namelen = migrate->namelen; |
2476 | hash = dlm_lockid_hash(name, namelen); | ||
2473 | 2477 | ||
2474 | /* preallocate.. if this fails, abort */ | 2478 | /* preallocate.. if this fails, abort */ |
2475 | mle = (struct dlm_master_list_entry *) kmem_cache_alloc(dlm_mle_cache, | 2479 | 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 | 2486 | ||
2483 | /* check for pre-existing lock */ | 2487 | /* check for pre-existing lock */ |
2484 | spin_lock(&dlm->spinlock); | 2488 | spin_lock(&dlm->spinlock); |
2485 | res = __dlm_lookup_lockres(dlm, name, namelen); | 2489 | res = __dlm_lookup_lockres(dlm, name, namelen, hash); |
2486 | spin_lock(&dlm->master_lock); | 2490 | spin_lock(&dlm->master_lock); |
2487 | 2491 | ||
2488 | if (res) { | 2492 | if (res) { |
@@ -2601,6 +2605,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node) | |||
2601 | struct list_head *iter, *iter2; | 2605 | struct list_head *iter, *iter2; |
2602 | struct dlm_master_list_entry *mle; | 2606 | struct dlm_master_list_entry *mle; |
2603 | struct dlm_lock_resource *res; | 2607 | struct dlm_lock_resource *res; |
2608 | unsigned int hash; | ||
2604 | 2609 | ||
2605 | mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node); | 2610 | mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node); |
2606 | top: | 2611 | top: |
@@ -2684,8 +2689,9 @@ top: | |||
2684 | mle->master, mle->new_master); | 2689 | mle->master, mle->new_master); |
2685 | /* if there is a lockres associated with this | 2690 | /* if there is a lockres associated with this |
2686 | * mle, find it and set its owner to UNKNOWN */ | 2691 | * mle, find it and set its owner to UNKNOWN */ |
2692 | hash = dlm_lockid_hash(mle->u.name.name, mle->u.name.len); | ||
2687 | res = __dlm_lookup_lockres(dlm, mle->u.name.name, | 2693 | res = __dlm_lookup_lockres(dlm, mle->u.name.name, |
2688 | mle->u.name.len); | 2694 | mle->u.name.len, hash); |
2689 | if (res) { | 2695 | if (res) { |
2690 | /* unfortunately if we hit this rare case, our | 2696 | /* unfortunately if we hit this rare case, our |
2691 | * lock ordering is messed. we need to drop | 2697 | * lock ordering is messed. we need to drop |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 9962190e7416..4f3d482a7299 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -1404,6 +1404,7 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1404 | struct dlm_ctxt *dlm = data; | 1404 | struct dlm_ctxt *dlm = data; |
1405 | struct dlm_master_requery *req = (struct dlm_master_requery *)msg->buf; | 1405 | struct dlm_master_requery *req = (struct dlm_master_requery *)msg->buf; |
1406 | struct dlm_lock_resource *res = NULL; | 1406 | struct dlm_lock_resource *res = NULL; |
1407 | unsigned int hash; | ||
1407 | int master = DLM_LOCK_RES_OWNER_UNKNOWN; | 1408 | int master = DLM_LOCK_RES_OWNER_UNKNOWN; |
1408 | u32 flags = DLM_ASSERT_MASTER_REQUERY; | 1409 | u32 flags = DLM_ASSERT_MASTER_REQUERY; |
1409 | 1410 | ||
@@ -1413,8 +1414,10 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data) | |||
1413 | return master; | 1414 | return master; |
1414 | } | 1415 | } |
1415 | 1416 | ||
1417 | hash = dlm_lockid_hash(req->name, req->namelen); | ||
1418 | |||
1416 | spin_lock(&dlm->spinlock); | 1419 | spin_lock(&dlm->spinlock); |
1417 | res = __dlm_lookup_lockres(dlm, req->name, req->namelen); | 1420 | res = __dlm_lookup_lockres(dlm, req->name, req->namelen, hash); |
1418 | if (res) { | 1421 | if (res) { |
1419 | spin_lock(&res->spinlock); | 1422 | spin_lock(&res->spinlock); |
1420 | master = res->owner; | 1423 | master = res->owner; |