Skip to content

Commit 5be323b

Browse files
Alexander Aringteigland
authored andcommitted
dlm: move dlm_search_rsb_tree() out of lock
The rhashtable structure is lockless for readers such as rhashtable_lookup_fast(). It should be save to call this lookup functionality out of holding ls_rsbtbl_lock to get the rsb pointer out of the hash. This reduce the contention time of ls_rsbtbl_lock in some cases. We still need to check if the rsb is part of the check as this state can be changed while ls_rsbtbl_lock is not held. If its part of the rhashtable data structure we take a reference to be sure it will not be freed after we drop the ls_rsbtbl_lock read lock. Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent 98ff7d9 commit 5be323b

File tree

1 file changed

+47
-30
lines changed

1 file changed

+47
-30
lines changed

fs/dlm/lock.c

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -733,11 +733,13 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
733733
}
734734

735735
retry:
736+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
737+
if (error)
738+
goto do_new;
736739

737740
/* check if the rsb is active under read lock - likely path */
738741
read_lock_bh(&ls->ls_rsbtbl_lock);
739-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
740-
if (error) {
742+
if (!rsb_flag(r, RSB_HASHED)) {
741743
read_unlock_bh(&ls->ls_rsbtbl_lock);
742744
goto do_new;
743745
}
@@ -918,11 +920,13 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
918920
int error;
919921

920922
retry:
923+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
924+
if (error)
925+
goto do_new;
921926

922927
/* check if the rsb is in active state under read lock - likely path */
923928
read_lock_bh(&ls->ls_rsbtbl_lock);
924-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
925-
if (error) {
929+
if (!rsb_flag(r, RSB_HASHED)) {
926930
read_unlock_bh(&ls->ls_rsbtbl_lock);
927931
goto do_new;
928932
}
@@ -1276,36 +1280,38 @@ static int _dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *na
12761280
}
12771281

12781282
retry:
1283+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
1284+
if (error)
1285+
goto not_found;
12791286

12801287
/* check if the rsb is active under read lock - likely path */
12811288
read_lock_bh(&ls->ls_rsbtbl_lock);
1282-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
1283-
if (!error) {
1284-
if (rsb_flag(r, RSB_INACTIVE)) {
1285-
read_unlock_bh(&ls->ls_rsbtbl_lock);
1286-
goto do_inactive;
1287-
}
1288-
1289-
/* because the rsb is active, we need to lock_rsb before
1290-
* checking/changing re_master_nodeid
1291-
*/
1289+
if (!rsb_flag(r, RSB_HASHED)) {
1290+
read_unlock_bh(&ls->ls_rsbtbl_lock);
1291+
goto not_found;
1292+
}
12921293

1293-
hold_rsb(r);
1294+
if (rsb_flag(r, RSB_INACTIVE)) {
12941295
read_unlock_bh(&ls->ls_rsbtbl_lock);
1295-
lock_rsb(r);
1296+
goto do_inactive;
1297+
}
12961298

1297-
__dlm_master_lookup(ls, r, our_nodeid, from_nodeid, false,
1298-
flags, r_nodeid, result);
1299+
/* because the rsb is active, we need to lock_rsb before
1300+
* checking/changing re_master_nodeid
1301+
*/
12991302

1300-
/* the rsb was active */
1301-
unlock_rsb(r);
1302-
put_rsb(r);
1303+
hold_rsb(r);
1304+
read_unlock_bh(&ls->ls_rsbtbl_lock);
1305+
lock_rsb(r);
13031306

1304-
return 0;
1305-
} else {
1306-
read_unlock_bh(&ls->ls_rsbtbl_lock);
1307-
goto not_found;
1308-
}
1307+
__dlm_master_lookup(ls, r, our_nodeid, from_nodeid, false,
1308+
flags, r_nodeid, result);
1309+
1310+
/* the rsb was active */
1311+
unlock_rsb(r);
1312+
put_rsb(r);
1313+
1314+
return 0;
13091315

13101316
do_inactive:
13111317
/* unlikely path - check if still part of ls_rsbtbl */
@@ -1403,14 +1409,14 @@ void dlm_dump_rsb_name(struct dlm_ls *ls, const char *name, int len)
14031409
struct dlm_rsb *r = NULL;
14041410
int error;
14051411

1406-
read_lock_bh(&ls->ls_rsbtbl_lock);
1412+
rcu_read_lock();
14071413
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
14081414
if (!error)
14091415
goto out;
14101416

14111417
dlm_dump_rsb(r);
14121418
out:
1413-
read_unlock_bh(&ls->ls_rsbtbl_lock);
1419+
rcu_read_unlock();
14141420
}
14151421

14161422
static void deactivate_rsb(struct kref *kref)
@@ -4309,16 +4315,27 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
43094315
memset(name, 0, sizeof(name));
43104316
memcpy(name, ms->m_extra, len);
43114317

4312-
write_lock_bh(&ls->ls_rsbtbl_lock);
4313-
4318+
rcu_read_lock();
43144319
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
43154320
if (rv) {
4321+
rcu_read_unlock();
43164322
/* should not happen */
43174323
log_error(ls, "%s from %d not found %s", __func__,
43184324
from_nodeid, name);
4325+
return;
4326+
}
4327+
4328+
write_lock_bh(&ls->ls_rsbtbl_lock);
4329+
if (!rsb_flag(r, RSB_HASHED)) {
4330+
rcu_read_unlock();
43194331
write_unlock_bh(&ls->ls_rsbtbl_lock);
4332+
/* should not happen */
4333+
log_error(ls, "%s from %d got removed during removal %s",
4334+
__func__, from_nodeid, name);
43204335
return;
43214336
}
4337+
/* at this stage the rsb can only being freed here */
4338+
rcu_read_unlock();
43224339

43234340
if (!rsb_flag(r, RSB_INACTIVE)) {
43244341
if (r->res_master_nodeid != from_nodeid) {

0 commit comments

Comments
 (0)