mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
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 <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
This commit is contained in:
parent
5be323b0c6
commit
c846f732b9
@ -295,6 +295,7 @@ struct dlm_lkb {
|
|||||||
void *lkb_astparam; /* caller's ast arg */
|
void *lkb_astparam; /* caller's ast arg */
|
||||||
struct dlm_user_args *lkb_ua;
|
struct dlm_user_args *lkb_ua;
|
||||||
};
|
};
|
||||||
|
struct rcu_head rcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1527,11 +1527,21 @@ static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
|
|||||||
{
|
{
|
||||||
struct dlm_lkb *lkb;
|
struct dlm_lkb *lkb;
|
||||||
|
|
||||||
read_lock_bh(&ls->ls_lkbxa_lock);
|
rcu_read_lock();
|
||||||
lkb = xa_load(&ls->ls_lkbxa, lkid);
|
lkb = xa_load(&ls->ls_lkbxa, lkid);
|
||||||
if (lkb)
|
if (lkb) {
|
||||||
kref_get(&lkb->lkb_ref);
|
/* check if lkb is still part of lkbxa under lkbxa_lock as
|
||||||
read_unlock_bh(&ls->ls_lkbxa_lock);
|
* the lkb_ref is tight to the lkbxa data structure, see
|
||||||
|
* __put_lkb().
|
||||||
|
*/
|
||||||
|
read_lock_bh(&ls->ls_lkbxa_lock);
|
||||||
|
if (kref_read(&lkb->lkb_ref))
|
||||||
|
kref_get(&lkb->lkb_ref);
|
||||||
|
else
|
||||||
|
lkb = NULL;
|
||||||
|
read_unlock_bh(&ls->ls_lkbxa_lock);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
*lkb_ret = lkb;
|
*lkb_ret = lkb;
|
||||||
return lkb ? 0 : -ENOENT;
|
return lkb ? 0 : -ENOENT;
|
||||||
|
@ -115,8 +115,10 @@ struct dlm_lkb *dlm_allocate_lkb(void)
|
|||||||
return kmem_cache_zalloc(lkb_cache, GFP_ATOMIC);
|
return kmem_cache_zalloc(lkb_cache, GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlm_free_lkb(struct dlm_lkb *lkb)
|
static void __free_lkb_rcu(struct rcu_head *rcu)
|
||||||
{
|
{
|
||||||
|
struct dlm_lkb *lkb = container_of(rcu, struct dlm_lkb, rcu);
|
||||||
|
|
||||||
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
|
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
|
||||||
struct dlm_user_args *ua;
|
struct dlm_user_args *ua;
|
||||||
ua = lkb->lkb_ua;
|
ua = lkb->lkb_ua;
|
||||||
@ -129,6 +131,11 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
|
|||||||
kmem_cache_free(lkb_cache, lkb);
|
kmem_cache_free(lkb_cache, lkb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dlm_free_lkb(struct dlm_lkb *lkb)
|
||||||
|
{
|
||||||
|
call_rcu(&lkb->rcu, __free_lkb_rcu);
|
||||||
|
}
|
||||||
|
|
||||||
struct dlm_mhandle *dlm_allocate_mhandle(void)
|
struct dlm_mhandle *dlm_allocate_mhandle(void)
|
||||||
{
|
{
|
||||||
return kmem_cache_alloc(mhandle_cache, GFP_ATOMIC);
|
return kmem_cache_alloc(mhandle_cache, GFP_ATOMIC);
|
||||||
|
Loading…
Reference in New Issue
Block a user