Skip to content

Commit 8a39dcd

Browse files
Alexander Aringteigland
authored andcommitted
fs: dlm: change dflags to use atomic bits
Currently manipulating lkb_dflags assumes to held the rsb lock assigned to the lkb. This is held by dlm message processing after certain time to lookup the right rsb from the received lkb message id. For user space locks flags, which is currently the only use case for lkb_dflags, flags are also being set during dlm character device handling without holding the rsb lock. To minimize the risk that bit operations are getting corrupted we switch to atomic bit operations. This patch will also introduce helpers to snapshot atomic bit values in an non atomic way. There might be still issues with the flag handling e.g. running in case of manipulating bit ops and snapshot them at the same time, but this patch minimize them and will start to use atomic bit operations. Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
1 parent 8c11ba6 commit 8a39dcd

8 files changed

Lines changed: 65 additions & 25 deletions

File tree

fs/dlm/ast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void dlm_add_cb(struct dlm_lkb *lkb, uint32_t flags, int mode, int status,
139139
struct dlm_ls *ls = lkb->lkb_resource->res_ls;
140140
int rv;
141141

142-
if (lkb->lkb_dflags & DLM_DFL_USER) {
142+
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
143143
dlm_user_add_ast(lkb, flags, mode, status, sbflags);
144144
return;
145145
}

fs/dlm/debug_fs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ static void print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
170170
u64 xid = 0;
171171
u64 us;
172172

173-
if (lkb->lkb_dflags & DLM_DFL_USER) {
173+
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
174174
if (lkb->lkb_ua)
175175
xid = lkb->lkb_ua->xid;
176176
}
@@ -230,7 +230,7 @@ static void print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
230230
{
231231
u64 xid = 0;
232232

233-
if (lkb->lkb_dflags & DLM_DFL_USER) {
233+
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
234234
if (lkb->lkb_ua)
235235
xid = lkb->lkb_ua->xid;
236236
}

fs/dlm/dlm_internal.h

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,10 @@ struct dlm_args {
208208

209209
/* lkb_dflags */
210210

211-
#define DLM_DFL_USER 0x00000001
212-
#define DLM_DFL_ORPHAN 0x00000002
211+
#define DLM_DFL_USER_BIT 0
212+
#define __DLM_DFL_MIN_BIT DLM_DFL_USER_BIT
213+
#define DLM_DFL_ORPHAN_BIT 1
214+
#define __DLM_DFL_MAX_BIT DLM_DFL_ORPHAN_BIT
213215

214216
#define DLM_CB_CAST 0x00000001
215217
#define DLM_CB_BAST 0x00000002
@@ -234,7 +236,7 @@ struct dlm_lkb {
234236
uint32_t lkb_exflags; /* external flags from caller */
235237
uint32_t lkb_sbflags; /* lksb flags */
236238
uint32_t lkb_flags; /* internal flags */
237-
uint32_t lkb_dflags; /* distributed flags */
239+
unsigned long lkb_dflags; /* distributed flags */
238240
unsigned long lkb_iflags; /* internal flags */
239241
uint32_t lkb_lvbseq; /* lvb sequence number */
240242

@@ -733,6 +735,44 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
733735
return test_bit(LSFL_NODIR, &ls->ls_flags);
734736
}
735737

738+
/* takes a snapshot from dlm atomic flags */
739+
static inline uint32_t dlm_flags_val(const unsigned long *addr,
740+
uint32_t min, uint32_t max)
741+
{
742+
uint32_t bit = min, val = 0;
743+
744+
for_each_set_bit_from(bit, addr, max + 1) {
745+
val |= BIT(bit);
746+
}
747+
748+
return val;
749+
}
750+
751+
static inline uint32_t dlm_dflags_val(const struct dlm_lkb *lkb)
752+
{
753+
return dlm_flags_val(&lkb->lkb_dflags, __DLM_DFL_MIN_BIT,
754+
__DLM_DFL_MAX_BIT);
755+
}
756+
757+
static inline void dlm_set_flags_val(unsigned long *addr, uint32_t val,
758+
uint32_t min, uint32_t max)
759+
{
760+
uint32_t bit;
761+
762+
for (bit = min; bit < (max + 1); bit++) {
763+
if (val & BIT(bit))
764+
set_bit(bit, addr);
765+
else
766+
clear_bit(bit, addr);
767+
}
768+
}
769+
770+
static inline void dlm_set_dflags_val(struct dlm_lkb *lkb, uint32_t val)
771+
{
772+
dlm_set_flags_val(&lkb->lkb_dflags, val, __DLM_DFL_MIN_BIT,
773+
__DLM_DFL_MAX_BIT);
774+
}
775+
736776
int dlm_plock_init(void);
737777
void dlm_plock_exit(void);
738778

fs/dlm/lock.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,7 +3410,7 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb,
34103410
ms->m_remid = cpu_to_le32(lkb->lkb_remid);
34113411
ms->m_exflags = cpu_to_le32(lkb->lkb_exflags);
34123412
ms->m_sbflags = cpu_to_le32(lkb->lkb_sbflags);
3413-
ms->m_flags = cpu_to_le32(lkb->lkb_flags);
3413+
ms->m_flags = cpu_to_le32(dlm_dflags_val(lkb));
34143414
ms->m_lvbseq = cpu_to_le32(lkb->lkb_lvbseq);
34153415
ms->m_status = cpu_to_le32(lkb->lkb_status);
34163416
ms->m_grmode = cpu_to_le32(lkb->lkb_grmode);
@@ -3675,7 +3675,7 @@ static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms)
36753675
{
36763676
lkb->lkb_exflags = le32_to_cpu(ms->m_exflags);
36773677
lkb->lkb_sbflags = le32_to_cpu(ms->m_sbflags);
3678-
lkb->lkb_dflags = le32_to_cpu(ms->m_flags);
3678+
dlm_set_dflags_val(lkb, le32_to_cpu(ms->m_flags));
36793679
}
36803680

36813681
static void receive_flags_reply(struct dlm_lkb *lkb, struct dlm_message *ms,
@@ -3685,7 +3685,7 @@ static void receive_flags_reply(struct dlm_lkb *lkb, struct dlm_message *ms,
36853685
return;
36863686

36873687
lkb->lkb_sbflags = le32_to_cpu(ms->m_sbflags);
3688-
lkb->lkb_dflags = le32_to_cpu(ms->m_flags);
3688+
dlm_set_dflags_val(lkb, le32_to_cpu(ms->m_flags));
36893689
}
36903690

36913691
static int receive_extralen(struct dlm_message *ms)
@@ -3786,8 +3786,8 @@ static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
37863786
int error = 0;
37873787

37883788
/* currently mixing of user/kernel locks are not supported */
3789-
if (ms->m_flags & cpu_to_le32(DLM_DFL_USER) &&
3790-
~lkb->lkb_dflags & DLM_DFL_USER) {
3789+
if (ms->m_flags & cpu_to_le32(BIT(DLM_DFL_USER_BIT)) &&
3790+
!test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
37913791
log_error(lkb->lkb_resource->res_ls,
37923792
"got user dlm message for a kernel lock");
37933793
error = -EINVAL;
@@ -5345,7 +5345,7 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
53455345
lkb->lkb_ownpid = le32_to_cpu(rl->rl_ownpid);
53465346
lkb->lkb_remid = le32_to_cpu(rl->rl_lkid);
53475347
lkb->lkb_exflags = le32_to_cpu(rl->rl_exflags);
5348-
lkb->lkb_dflags = le32_to_cpu(rl->rl_flags);
5348+
dlm_set_dflags_val(lkb, le32_to_cpu(rl->rl_flags));
53495349
lkb->lkb_flags |= DLM_IFL_MSTCPY;
53505350
lkb->lkb_lvbseq = le32_to_cpu(rl->rl_lvbseq);
53515351
lkb->lkb_rqmode = rl->rl_rqmode;
@@ -5571,9 +5571,9 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
55715571
}
55725572

55735573
/* After ua is attached to lkb it will be freed by dlm_free_lkb().
5574-
When DLM_DFL_USER is set, the dlm knows that this is a userspace
5574+
When DLM_DFL_USER_BIT is set, the dlm knows that this is a userspace
55755575
lock and that lkb_astparam is the dlm_user_args structure. */
5576-
lkb->lkb_dflags |= DLM_DFL_USER;
5576+
set_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags);
55775577
error = request_lock(ls, lkb, name, namelen, &args);
55785578

55795579
switch (error) {
@@ -5688,7 +5688,7 @@ int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
56885688

56895689
lkb = iter;
56905690
list_del_init(&iter->lkb_ownqueue);
5691-
iter->lkb_dflags &= ~DLM_DFL_ORPHAN;
5691+
clear_bit(DLM_DFL_ORPHAN_BIT, &iter->lkb_dflags);
56925692
*lkid = iter->lkb_id;
56935693
break;
56945694
}
@@ -5932,7 +5932,7 @@ static struct dlm_lkb *del_proc_lock(struct dlm_ls *ls,
59325932
list_del_init(&lkb->lkb_ownqueue);
59335933

59345934
if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
5935-
lkb->lkb_dflags |= DLM_DFL_ORPHAN;
5935+
set_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags);
59365936
else
59375937
lkb->lkb_flags |= DLM_IFL_DEAD;
59385938
out:
@@ -6091,7 +6091,7 @@ int dlm_debug_add_lkb(struct dlm_ls *ls, uint32_t lkb_id, char *name, int len,
60916091
int error;
60926092

60936093
/* we currently can't set a valid user lock */
6094-
if (lkb_dflags & DLM_DFL_USER)
6094+
if (lkb_dflags & BIT(DLM_DFL_USER_BIT))
60956095
return -EOPNOTSUPP;
60966096

60976097
lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
@@ -6104,11 +6104,11 @@ int dlm_debug_add_lkb(struct dlm_ls *ls, uint32_t lkb_id, char *name, int len,
61046104
return error;
61056105
}
61066106

6107-
lkb->lkb_dflags = lkb_dflags;
6107+
dlm_set_dflags_val(lkb, lkb_dflags);
61086108
lkb->lkb_nodeid = lkb_nodeid;
61096109
lkb->lkb_lksb = lksb;
61106110
/* user specific pointer, just don't have it NULL for kernel locks */
6111-
if (~lkb_dflags & DLM_DFL_USER)
6111+
if (~lkb_dflags & BIT(DLM_DFL_USER_BIT))
61126112
lkb->lkb_astparam = (void *)0xDEADBEEF;
61136113

61146114
error = find_rsb(ls, name, len, 0, R_REQUEST, &r);

fs/dlm/memory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
118118

119119
void dlm_free_lkb(struct dlm_lkb *lkb)
120120
{
121-
if (lkb->lkb_dflags & DLM_DFL_USER) {
121+
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
122122
struct dlm_user_args *ua;
123123
ua = lkb->lkb_ua;
124124
if (ua) {

fs/dlm/rcom.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ static void pack_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb,
415415
rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid);
416416
rl->rl_lkid = cpu_to_le32(lkb->lkb_id);
417417
rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags);
418-
rl->rl_flags = cpu_to_le32(lkb->lkb_dflags);
418+
rl->rl_flags = cpu_to_le32(dlm_dflags_val(lkb));
419419
rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq);
420420
rl->rl_rqmode = lkb->lkb_rqmode;
421421
rl->rl_grmode = lkb->lkb_grmode;

fs/dlm/user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, uint32_t flags, int mode,
183183
struct dlm_user_proc *proc;
184184
int rv;
185185

186-
if (lkb->lkb_dflags & DLM_DFL_ORPHAN ||
186+
if (test_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags) ||
187187
lkb->lkb_flags & DLM_IFL_DEAD)
188188
return;
189189

@@ -196,7 +196,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, uint32_t flags, int mode,
196196
for cases where a completion ast is received for an operation that
197197
began before clear_proc_locks did its cancel/unlock. */
198198

199-
if (lkb->lkb_dflags & DLM_DFL_ORPHAN ||
199+
if (test_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags) ||
200200
lkb->lkb_flags & DLM_IFL_DEAD)
201201
goto out;
202202

include/trace/events/dlm.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
{ DLM_SBF_ALTMODE, "ALTMODE" })
4848

4949
#define show_lkb_flags(flags) __print_flags(flags, "|", \
50-
{ DLM_DFL_USER, "USER" }, \
51-
{ DLM_DFL_ORPHAN, "ORPHAN" })
50+
{ BIT(DLM_DFL_USER_BIT), "USER" }, \
51+
{ BIT(DLM_DFL_ORPHAN_BIT), "ORPHAN" })
5252

5353
#define show_header_cmd(cmd) __print_symbolic(cmd, \
5454
{ DLM_MSG, "MSG"}, \

0 commit comments

Comments
 (0)