Skip to content

Commit 2d90354

Browse files
Alexander Aringteigland
authored andcommitted
dlm: merge toss and keep hash table lists into one list
There are several places where lock processing can perform two hash table lookups, first in the "keep" list, and if not found, in the "toss" list. This patch introduces a new rsb state flag "RSB_TOSS" to represent the difference between the state of being on keep vs toss list, so that the two lists can be combined. This avoids cases of two lookups. Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent dcdaad0 commit 2d90354

File tree

7 files changed

+98
-76
lines changed

7 files changed

+98
-76
lines changed

fs/dlm/debug_fs.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,12 +450,20 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos)
450450
if (seq->op == &format4_seq_ops)
451451
ri->format = 4;
452452

453-
tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
453+
tree = &ls->ls_rsbtbl[bucket].r;
454454

455455
spin_lock_bh(&ls->ls_rsbtbl_lock);
456456
if (!RB_EMPTY_ROOT(tree)) {
457457
for (node = rb_first(tree); node; node = rb_next(node)) {
458458
r = rb_entry(node, struct dlm_rsb, res_hashnode);
459+
if (toss) {
460+
if (!rsb_flag(r, RSB_TOSS))
461+
continue;
462+
} else {
463+
if (rsb_flag(r, RSB_TOSS))
464+
continue;
465+
}
466+
459467
if (!entry--) {
460468
dlm_hold_rsb(r);
461469
ri->rsb = r;
@@ -482,12 +490,20 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos)
482490
kfree(ri);
483491
return NULL;
484492
}
485-
tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
493+
tree = &ls->ls_rsbtbl[bucket].r;
486494

487495
spin_lock_bh(&ls->ls_rsbtbl_lock);
488496
if (!RB_EMPTY_ROOT(tree)) {
489497
node = rb_first(tree);
490498
r = rb_entry(node, struct dlm_rsb, res_hashnode);
499+
if (toss) {
500+
if (!rsb_flag(r, RSB_TOSS))
501+
continue;
502+
} else {
503+
if (rsb_flag(r, RSB_TOSS))
504+
continue;
505+
}
506+
491507
dlm_hold_rsb(r);
492508
ri->rsb = r;
493509
ri->bucket = bucket;
@@ -548,12 +564,19 @@ static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)
548564
++*pos;
549565
return NULL;
550566
}
551-
tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
567+
tree = &ls->ls_rsbtbl[bucket].r;
552568

553569
spin_lock_bh(&ls->ls_rsbtbl_lock);
554570
if (!RB_EMPTY_ROOT(tree)) {
555571
next = rb_first(tree);
556572
r = rb_entry(next, struct dlm_rsb, res_hashnode);
573+
if (toss) {
574+
if (!rsb_flag(r, RSB_TOSS))
575+
continue;
576+
} else {
577+
if (rsb_flag(r, RSB_TOSS))
578+
continue;
579+
}
557580
dlm_hold_rsb(r);
558581
ri->rsb = r;
559582
ri->bucket = bucket;

fs/dlm/dir.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,8 @@ static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, const char *name,
205205
bucket = hash & (ls->ls_rsbtbl_size - 1);
206206

207207
spin_lock_bh(&ls->ls_rsbtbl_lock);
208-
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].keep, name, len, &r);
209-
if (rv)
210-
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].toss,
211-
name, len, &r);
208+
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].r, name, len, &r);
212209
spin_unlock_bh(&ls->ls_rsbtbl_lock);
213-
214210
if (!rv)
215211
return r;
216212

fs/dlm/dlm_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ do { \
103103
#define DLM_RTF_SHRINK_BIT 0
104104

105105
struct dlm_rsbtable {
106-
struct rb_root keep;
107-
struct rb_root toss;
106+
struct rb_root r;
108107
unsigned long flags;
109108
};
110109

@@ -376,6 +375,7 @@ enum rsb_flags {
376375
RSB_RECOVER_CONVERT,
377376
RSB_RECOVER_GRANT,
378377
RSB_RECOVER_LVB_INVAL,
378+
RSB_TOSS,
379379
};
380380

381381
static inline void rsb_set_flag(struct dlm_rsb *r, enum rsb_flags flag)

fs/dlm/lock.c

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -616,23 +616,22 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
616616

617617
spin_lock_bh(&ls->ls_rsbtbl_lock);
618618

619-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
619+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].r, name, len, &r);
620620
if (error)
621-
goto do_toss;
621+
goto do_new;
622622

623623
/*
624624
* rsb is active, so we can't check master_nodeid without lock_rsb.
625625
*/
626626

627+
if (rsb_flag(r, RSB_TOSS))
628+
goto do_toss;
629+
627630
kref_get(&r->res_ref);
628631
goto out_unlock;
629632

630633

631634
do_toss:
632-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
633-
if (error)
634-
goto do_new;
635-
636635
/*
637636
* rsb found inactive (master_nodeid may be out of date unless
638637
* we are the dir_nodeid or were the master) No other thread
@@ -669,8 +668,7 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
669668
r->res_first_lkid = 0;
670669
}
671670

672-
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
673-
error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
671+
rsb_clear_flag(r, RSB_TOSS);
674672
goto out_unlock;
675673

676674

@@ -731,7 +729,7 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
731729
}
732730

733731
out_add:
734-
error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
732+
error = rsb_insert(r, &ls->ls_rsbtbl[b].r);
735733
out_unlock:
736734
spin_unlock_bh(&ls->ls_rsbtbl_lock);
737735
out:
@@ -760,8 +758,11 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
760758

761759
spin_lock_bh(&ls->ls_rsbtbl_lock);
762760

763-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
761+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].r, name, len, &r);
764762
if (error)
763+
goto do_new;
764+
765+
if (rsb_flag(r, RSB_TOSS))
765766
goto do_toss;
766767

767768
/*
@@ -773,10 +774,6 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
773774

774775

775776
do_toss:
776-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
777-
if (error)
778-
goto do_new;
779-
780777
/*
781778
* rsb found inactive. No other thread is using this rsb because
782779
* it's on the toss list, so we can look at or update
@@ -804,8 +801,7 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
804801
r->res_nodeid = 0;
805802
}
806803

807-
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
808-
error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
804+
rsb_clear_flag(r, RSB_TOSS);
809805
goto out_unlock;
810806

811807

@@ -829,7 +825,7 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
829825
r->res_nodeid = (dir_nodeid == our_nodeid) ? 0 : dir_nodeid;
830826
kref_init(&r->res_ref);
831827

832-
error = rsb_insert(r, &ls->ls_rsbtbl[b].keep);
828+
error = rsb_insert(r, &ls->ls_rsbtbl[b].r);
833829
out_unlock:
834830
spin_unlock_bh(&ls->ls_rsbtbl_lock);
835831
out:
@@ -1049,8 +1045,11 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
10491045
return error;
10501046

10511047
spin_lock_bh(&ls->ls_rsbtbl_lock);
1052-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
1048+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].r, name, len, &r);
10531049
if (!error) {
1050+
if (rsb_flag(r, RSB_TOSS))
1051+
goto do_toss;
1052+
10541053
/* because the rsb is active, we need to lock_rsb before
10551054
* checking/changing re_master_nodeid
10561055
*/
@@ -1067,12 +1066,11 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
10671066
put_rsb(r);
10681067

10691068
return 0;
1070-
}
1071-
1072-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
1073-
if (error)
1069+
} else {
10741070
goto not_found;
1071+
}
10751072

1073+
do_toss:
10761074
/* because the rsb is inactive (on toss list), it's not refcounted
10771075
* and lock_rsb is not used, but is protected by the rsbtbl lock
10781076
*/
@@ -1102,8 +1100,9 @@ int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
11021100
r->res_nodeid = from_nodeid;
11031101
kref_init(&r->res_ref);
11041102
r->res_toss_time = jiffies;
1103+
rsb_set_flag(r, RSB_TOSS);
11051104

1106-
error = rsb_insert(r, &ls->ls_rsbtbl[b].toss);
1105+
error = rsb_insert(r, &ls->ls_rsbtbl[b].r);
11071106
if (error) {
11081107
/* should never happen */
11091108
dlm_free_rsb(r);
@@ -1127,8 +1126,11 @@ static void dlm_dump_rsb_hash(struct dlm_ls *ls, uint32_t hash)
11271126

11281127
spin_lock_bh(&ls->ls_rsbtbl_lock);
11291128
for (i = 0; i < ls->ls_rsbtbl_size; i++) {
1130-
for (n = rb_first(&ls->ls_rsbtbl[i].keep); n; n = rb_next(n)) {
1129+
for (n = rb_first(&ls->ls_rsbtbl[i].r); n; n = rb_next(n)) {
11311130
r = rb_entry(n, struct dlm_rsb, res_hashnode);
1131+
if (rsb_flag(r, RSB_TOSS))
1132+
continue;
1133+
11321134
if (r->res_hash == hash)
11331135
dlm_dump_rsb(r);
11341136
}
@@ -1146,14 +1148,10 @@ void dlm_dump_rsb_name(struct dlm_ls *ls, const char *name, int len)
11461148
b = hash & (ls->ls_rsbtbl_size - 1);
11471149

11481150
spin_lock_bh(&ls->ls_rsbtbl_lock);
1149-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
1151+
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].r, name, len, &r);
11501152
if (!error)
1151-
goto out_dump;
1152-
1153-
error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
1154-
if (error)
11551153
goto out;
1156-
out_dump:
1154+
11571155
dlm_dump_rsb(r);
11581156
out:
11591157
spin_unlock_bh(&ls->ls_rsbtbl_lock);
@@ -1166,8 +1164,8 @@ static void toss_rsb(struct kref *kref)
11661164

11671165
DLM_ASSERT(list_empty(&r->res_root_list), dlm_print_rsb(r););
11681166
kref_init(&r->res_ref);
1169-
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[r->res_bucket].keep);
1170-
rsb_insert(r, &ls->ls_rsbtbl[r->res_bucket].toss);
1167+
WARN_ON(rsb_flag(r, RSB_TOSS));
1168+
rsb_set_flag(r, RSB_TOSS);
11711169
r->res_toss_time = jiffies;
11721170
set_bit(DLM_RTF_SHRINK_BIT, &ls->ls_rsbtbl[r->res_bucket].flags);
11731171
if (r->res_lvbptr) {
@@ -1627,9 +1625,11 @@ static void shrink_bucket(struct dlm_ls *ls, int b)
16271625
return;
16281626
}
16291627

1630-
for (n = rb_first(&ls->ls_rsbtbl[b].toss); n; n = next) {
1628+
for (n = rb_first(&ls->ls_rsbtbl[b].r); n; n = next) {
16311629
next = rb_next(n);
16321630
r = rb_entry(n, struct dlm_rsb, res_hashnode);
1631+
if (!rsb_flag(r, RSB_TOSS))
1632+
continue;
16331633

16341634
/* If we're the directory record for this rsb, and
16351635
we're not the master of it, then we need to wait
@@ -1672,7 +1672,7 @@ static void shrink_bucket(struct dlm_ls *ls, int b)
16721672
continue;
16731673
}
16741674

1675-
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
1675+
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].r);
16761676
dlm_free_rsb(r);
16771677
}
16781678

@@ -1696,8 +1696,14 @@ static void shrink_bucket(struct dlm_ls *ls, int b)
16961696
len = ls->ls_remove_lens[i];
16971697

16981698
spin_lock_bh(&ls->ls_rsbtbl_lock);
1699-
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
1699+
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].r, name, len, &r);
17001700
if (rv) {
1701+
spin_unlock_bh(&ls->ls_rsbtbl_lock);
1702+
log_error(ls, "remove_name not found %s", name);
1703+
continue;
1704+
}
1705+
1706+
if (!rsb_flag(r, RSB_TOSS)) {
17011707
spin_unlock_bh(&ls->ls_rsbtbl_lock);
17021708
log_debug(ls, "remove_name not toss %s", name);
17031709
continue;
@@ -1734,7 +1740,7 @@ static void shrink_bucket(struct dlm_ls *ls, int b)
17341740
continue;
17351741
}
17361742

1737-
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
1743+
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].r);
17381744
send_remove(r);
17391745
spin_unlock_bh(&ls->ls_rsbtbl_lock);
17401746

@@ -4202,17 +4208,16 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
42024208

42034209
spin_lock_bh(&ls->ls_rsbtbl_lock);
42044210

4205-
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, &r);
4211+
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].r, name, len, &r);
42064212
if (rv) {
4207-
/* verify the rsb is on keep list per comment above */
4208-
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, &r);
4209-
if (rv) {
4210-
/* should not happen */
4211-
log_error(ls, "receive_remove from %d not found %s",
4212-
from_nodeid, name);
4213-
spin_unlock_bh(&ls->ls_rsbtbl_lock);
4214-
return;
4215-
}
4213+
/* should not happen */
4214+
log_error(ls, "%s from %d not found %s", __func__,
4215+
from_nodeid, name);
4216+
spin_unlock_bh(&ls->ls_rsbtbl_lock);
4217+
return;
4218+
}
4219+
4220+
if (!rsb_flag(r, RSB_TOSS)) {
42164221
if (r->res_master_nodeid != from_nodeid) {
42174222
/* should not happen */
42184223
log_error(ls, "receive_remove keep from %d master %d",
@@ -4238,7 +4243,7 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
42384243
}
42394244

42404245
if (kref_put(&r->res_ref, kill_rsb)) {
4241-
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].toss);
4246+
rb_erase(&r->res_hashnode, &ls->ls_rsbtbl[b].r);
42424247
spin_unlock_bh(&ls->ls_rsbtbl_lock);
42434248
dlm_free_rsb(r);
42444249
} else {
@@ -5314,8 +5319,10 @@ static struct dlm_rsb *find_grant_rsb(struct dlm_ls *ls, int bucket)
53145319
struct dlm_rsb *r;
53155320

53165321
spin_lock_bh(&ls->ls_rsbtbl_lock);
5317-
for (n = rb_first(&ls->ls_rsbtbl[bucket].keep); n; n = rb_next(n)) {
5322+
for (n = rb_first(&ls->ls_rsbtbl[bucket].r); n; n = rb_next(n)) {
53185323
r = rb_entry(n, struct dlm_rsb, res_hashnode);
5324+
if (rsb_flag(r, RSB_TOSS))
5325+
continue;
53195326

53205327
if (!rsb_flag(r, RSB_RECOVER_GRANT))
53215328
continue;

fs/dlm/lockspace.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,7 @@ static int new_lockspace(const char *name, const char *cluster,
503503
if (!ls->ls_rsbtbl)
504504
goto out_lsfree;
505505
for (i = 0; i < size; i++) {
506-
ls->ls_rsbtbl[i].keep.rb_node = NULL;
507-
ls->ls_rsbtbl[i].toss.rb_node = NULL;
506+
ls->ls_rsbtbl[i].r.rb_node = NULL;
508507
}
509508

510509
for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
@@ -837,15 +836,9 @@ static int release_lockspace(struct dlm_ls *ls, int force)
837836
*/
838837

839838
for (i = 0; i < ls->ls_rsbtbl_size; i++) {
840-
while ((n = rb_first(&ls->ls_rsbtbl[i].keep))) {
839+
while ((n = rb_first(&ls->ls_rsbtbl[i].r))) {
841840
rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
842-
rb_erase(n, &ls->ls_rsbtbl[i].keep);
843-
dlm_free_rsb(rsb);
844-
}
845-
846-
while ((n = rb_first(&ls->ls_rsbtbl[i].toss))) {
847-
rsb = rb_entry(n, struct dlm_rsb, res_hashnode);
848-
rb_erase(n, &ls->ls_rsbtbl[i].toss);
841+
rb_erase(n, &ls->ls_rsbtbl[i].r);
849842
dlm_free_rsb(rsb);
850843
}
851844
}

0 commit comments

Comments
 (0)