Skip to content

Commit c846f73

Browse files
Alexander Aringteigland
authored andcommitted
dlm: move lkb xarray lookup out of lock
This patch moves the xarray lookup functionality for the lkb out of the ls_lkbxa_lock read lock handling. We can do that as the xarray should be possible to access lockless in case of reader like xa_load(). We confirm under ls_lkbxa_lock that the lkb is still part of the data structure and take a reference when its still part of ls_lkbxa to avoid being freed after doing the lookup. To do a check if the lkb is still part of the ls_lkbxa data structure we use a kref_read() as the last put will remove it from the ls_lkbxa data structure and any reference taken means it is still part of ls_lkbxa. A similar approach was done with the DLM rsb rhashtable just with a flag instead of the refcounter because the refcounter has a slightly different meaning. Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent 5be323b commit c846f73

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

fs/dlm/dlm_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ struct dlm_lkb {
295295
void *lkb_astparam; /* caller's ast arg */
296296
struct dlm_user_args *lkb_ua;
297297
};
298+
struct rcu_head rcu;
298299
};
299300

300301
/*

fs/dlm/lock.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,11 +1527,21 @@ static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
15271527
{
15281528
struct dlm_lkb *lkb;
15291529

1530-
read_lock_bh(&ls->ls_lkbxa_lock);
1530+
rcu_read_lock();
15311531
lkb = xa_load(&ls->ls_lkbxa, lkid);
1532-
if (lkb)
1533-
kref_get(&lkb->lkb_ref);
1534-
read_unlock_bh(&ls->ls_lkbxa_lock);
1532+
if (lkb) {
1533+
/* check if lkb is still part of lkbxa under lkbxa_lock as
1534+
* the lkb_ref is tight to the lkbxa data structure, see
1535+
* __put_lkb().
1536+
*/
1537+
read_lock_bh(&ls->ls_lkbxa_lock);
1538+
if (kref_read(&lkb->lkb_ref))
1539+
kref_get(&lkb->lkb_ref);
1540+
else
1541+
lkb = NULL;
1542+
read_unlock_bh(&ls->ls_lkbxa_lock);
1543+
}
1544+
rcu_read_unlock();
15351545

15361546
*lkb_ret = lkb;
15371547
return lkb ? 0 : -ENOENT;

fs/dlm/memory.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ struct dlm_lkb *dlm_allocate_lkb(void)
115115
return kmem_cache_zalloc(lkb_cache, GFP_ATOMIC);
116116
}
117117

118-
void dlm_free_lkb(struct dlm_lkb *lkb)
118+
static void __free_lkb_rcu(struct rcu_head *rcu)
119119
{
120+
struct dlm_lkb *lkb = container_of(rcu, struct dlm_lkb, rcu);
121+
120122
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
121123
struct dlm_user_args *ua;
122124
ua = lkb->lkb_ua;
@@ -129,6 +131,11 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
129131
kmem_cache_free(lkb_cache, lkb);
130132
}
131133

134+
void dlm_free_lkb(struct dlm_lkb *lkb)
135+
{
136+
call_rcu(&lkb->rcu, __free_lkb_rcu);
137+
}
138+
132139
struct dlm_mhandle *dlm_allocate_mhandle(void)
133140
{
134141
return kmem_cache_alloc(mhandle_cache, GFP_ATOMIC);

0 commit comments

Comments
 (0)