Skip to content

Commit

Permalink
dlm: always use GFP_NOFS
Browse files Browse the repository at this point in the history
Replace all GFP_KERNEL and ls_allocation with GFP_NOFS.
ls_allocation would be GFP_KERNEL for userland lockspaces
and GFP_NOFS for file system lockspaces.

It was discovered that any lockspaces on the system can
affect all others by triggering memory reclaim in the
file system which could in turn call back into the dlm
to acquire locks, deadlocking dlm threads that were
shared by all lockspaces, like dlm_recv.

Signed-off-by: David Teigland <[email protected]>
  • Loading branch information
teigland committed Nov 30, 2009
1 parent a8a8a66 commit 573c24c
Show file tree
Hide file tree
Showing 14 changed files with 46 additions and 53 deletions.
24 changes: 12 additions & 12 deletions fs/dlm/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,10 +410,10 @@ static struct config_group *make_cluster(struct config_group *g,
struct dlm_comms *cms = NULL;
void *gps = NULL;

cl = kzalloc(sizeof(struct dlm_cluster), GFP_KERNEL);
gps = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
sps = kzalloc(sizeof(struct dlm_spaces), GFP_KERNEL);
cms = kzalloc(sizeof(struct dlm_comms), GFP_KERNEL);
cl = kzalloc(sizeof(struct dlm_cluster), GFP_NOFS);
gps = kcalloc(3, sizeof(struct config_group *), GFP_NOFS);
sps = kzalloc(sizeof(struct dlm_spaces), GFP_NOFS);
cms = kzalloc(sizeof(struct dlm_comms), GFP_NOFS);

if (!cl || !gps || !sps || !cms)
goto fail;
Expand Down Expand Up @@ -482,9 +482,9 @@ static struct config_group *make_space(struct config_group *g, const char *name)
struct dlm_nodes *nds = NULL;
void *gps = NULL;

sp = kzalloc(sizeof(struct dlm_space), GFP_KERNEL);
gps = kcalloc(2, sizeof(struct config_group *), GFP_KERNEL);
nds = kzalloc(sizeof(struct dlm_nodes), GFP_KERNEL);
sp = kzalloc(sizeof(struct dlm_space), GFP_NOFS);
gps = kcalloc(2, sizeof(struct config_group *), GFP_NOFS);
nds = kzalloc(sizeof(struct dlm_nodes), GFP_NOFS);

if (!sp || !gps || !nds)
goto fail;
Expand Down Expand Up @@ -536,7 +536,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name)
{
struct dlm_comm *cm;

cm = kzalloc(sizeof(struct dlm_comm), GFP_KERNEL);
cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS);
if (!cm)
return ERR_PTR(-ENOMEM);

Expand Down Expand Up @@ -569,7 +569,7 @@ static struct config_item *make_node(struct config_group *g, const char *name)
struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
struct dlm_node *nd;

nd = kzalloc(sizeof(struct dlm_node), GFP_KERNEL);
nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS);
if (!nd)
return ERR_PTR(-ENOMEM);

Expand Down Expand Up @@ -705,7 +705,7 @@ static ssize_t comm_addr_write(struct dlm_comm *cm, const char *buf, size_t len)
if (cm->addr_count >= DLM_MAX_ADDR_COUNT)
return -ENOSPC;

addr = kzalloc(sizeof(*addr), GFP_KERNEL);
addr = kzalloc(sizeof(*addr), GFP_NOFS);
if (!addr)
return -ENOMEM;

Expand Down Expand Up @@ -868,7 +868,7 @@ int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,

ids_count = sp->members_count;

ids = kcalloc(ids_count, sizeof(int), GFP_KERNEL);
ids = kcalloc(ids_count, sizeof(int), GFP_NOFS);
if (!ids) {
rv = -ENOMEM;
goto out;
Expand All @@ -886,7 +886,7 @@ int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
if (!new_count)
goto out_ids;

new = kcalloc(new_count, sizeof(int), GFP_KERNEL);
new = kcalloc(new_count, sizeof(int), GFP_NOFS);
if (!new) {
kfree(ids);
rv = -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion fs/dlm/debug_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos)
if (bucket >= ls->ls_rsbtbl_size)
return NULL;

ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_KERNEL);
ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_NOFS);
if (!ri)
return NULL;
if (n == 0)
Expand Down
7 changes: 3 additions & 4 deletions fs/dlm/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len)
spin_unlock(&ls->ls_recover_list_lock);

if (!found)
de = kzalloc(sizeof(struct dlm_direntry) + len,
ls->ls_allocation);
de = kzalloc(sizeof(struct dlm_direntry) + len, GFP_NOFS);
return de;
}

Expand Down Expand Up @@ -212,7 +211,7 @@ int dlm_recover_directory(struct dlm_ls *ls)

dlm_dir_clear(ls);

last_name = kmalloc(DLM_RESNAME_MAXLEN, ls->ls_allocation);
last_name = kmalloc(DLM_RESNAME_MAXLEN, GFP_NOFS);
if (!last_name)
goto out;

Expand Down Expand Up @@ -323,7 +322,7 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
if (namelen > DLM_RESNAME_MAXLEN)
return -EINVAL;

de = kzalloc(sizeof(struct dlm_direntry) + namelen, ls->ls_allocation);
de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_NOFS);
if (!de)
return -ENOMEM;

Expand Down
1 change: 0 additions & 1 deletion fs/dlm/dlm_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,6 @@ struct dlm_ls {
int ls_low_nodeid;
int ls_total_weight;
int *ls_node_array;
gfp_t ls_allocation;

struct dlm_rsb ls_stub_rsb; /* for returning errors */
struct dlm_lkb ls_stub_lkb; /* for returning errors */
Expand Down
6 changes: 3 additions & 3 deletions fs/dlm/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2689,7 +2689,7 @@ static int _create_message(struct dlm_ls *ls, int mb_len,
pass into lowcomms_commit and a message buffer (mb) that we
write our data into */

mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
if (!mh)
return -ENOBUFS;

Expand Down Expand Up @@ -4512,7 +4512,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
}

if (flags & DLM_LKF_VALBLK) {
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
if (!ua->lksb.sb_lvbptr) {
kfree(ua);
__put_lkb(ls, lkb);
Expand Down Expand Up @@ -4582,7 +4582,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
ua = lkb->lkb_ua;

if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS);
if (!ua->lksb.sb_lvbptr) {
error = -ENOMEM;
goto out_put;
Expand Down
15 changes: 5 additions & 10 deletions fs/dlm/lockspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ static int new_lockspace(const char *name, int namelen, void **lockspace,

error = -ENOMEM;

ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL);
ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_NOFS);
if (!ls)
goto out;
memcpy(ls->ls_name, name, namelen);
Expand All @@ -443,11 +443,6 @@ static int new_lockspace(const char *name, int namelen, void **lockspace,
if (flags & DLM_LSFL_TIMEWARN)
set_bit(LSFL_TIMEWARN, &ls->ls_flags);

if (flags & DLM_LSFL_FS)
ls->ls_allocation = GFP_NOFS;
else
ls->ls_allocation = GFP_KERNEL;

/* ls_exflags are forced to match among nodes, and we don't
need to require all nodes to have some flags set */
ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS |
Expand All @@ -456,7 +451,7 @@ static int new_lockspace(const char *name, int namelen, void **lockspace,
size = dlm_config.ci_rsbtbl_size;
ls->ls_rsbtbl_size = size;

ls->ls_rsbtbl = kmalloc(sizeof(struct dlm_rsbtable) * size, GFP_KERNEL);
ls->ls_rsbtbl = kmalloc(sizeof(struct dlm_rsbtable) * size, GFP_NOFS);
if (!ls->ls_rsbtbl)
goto out_lsfree;
for (i = 0; i < size; i++) {
Expand All @@ -468,7 +463,7 @@ static int new_lockspace(const char *name, int namelen, void **lockspace,
size = dlm_config.ci_lkbtbl_size;
ls->ls_lkbtbl_size = size;

ls->ls_lkbtbl = kmalloc(sizeof(struct dlm_lkbtable) * size, GFP_KERNEL);
ls->ls_lkbtbl = kmalloc(sizeof(struct dlm_lkbtable) * size, GFP_NOFS);
if (!ls->ls_lkbtbl)
goto out_rsbfree;
for (i = 0; i < size; i++) {
Expand All @@ -480,7 +475,7 @@ static int new_lockspace(const char *name, int namelen, void **lockspace,
size = dlm_config.ci_dirtbl_size;
ls->ls_dirtbl_size = size;

ls->ls_dirtbl = kmalloc(sizeof(struct dlm_dirtable) * size, GFP_KERNEL);
ls->ls_dirtbl = kmalloc(sizeof(struct dlm_dirtable) * size, GFP_NOFS);
if (!ls->ls_dirtbl)
goto out_lkbfree;
for (i = 0; i < size; i++) {
Expand Down Expand Up @@ -527,7 +522,7 @@ static int new_lockspace(const char *name, int namelen, void **lockspace,
mutex_init(&ls->ls_requestqueue_mutex);
mutex_init(&ls->ls_clear_proc_locks);

ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS);
if (!ls->ls_recover_buf)
goto out_dirfree;

Expand Down
6 changes: 3 additions & 3 deletions fs/dlm/lowcomms.c
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ static void init_local(void)
if (dlm_our_addr(&sas, i))
break;

addr = kmalloc(sizeof(*addr), GFP_KERNEL);
addr = kmalloc(sizeof(*addr), GFP_NOFS);
if (!addr)
break;
memcpy(addr, &sas, sizeof(*addr));
Expand Down Expand Up @@ -1099,7 +1099,7 @@ static int sctp_listen_for_all(void)
struct sockaddr_storage localaddr;
struct sctp_event_subscribe subscribe;
int result = -EINVAL, num = 1, i, addr_len;
struct connection *con = nodeid2con(0, GFP_KERNEL);
struct connection *con = nodeid2con(0, GFP_NOFS);
int bufsize = NEEDED_RMEM;

if (!con)
Expand Down Expand Up @@ -1171,7 +1171,7 @@ static int sctp_listen_for_all(void)
static int tcp_listen_for_all(void)
{
struct socket *sock = NULL;
struct connection *con = nodeid2con(0, GFP_KERNEL);
struct connection *con = nodeid2con(0, GFP_NOFS);
int result = -EINVAL;

if (!con)
Expand Down
8 changes: 4 additions & 4 deletions fs/dlm/member.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static int dlm_add_member(struct dlm_ls *ls, int nodeid)
struct dlm_member *memb;
int w, error;

memb = kzalloc(sizeof(struct dlm_member), ls->ls_allocation);
memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS);
if (!memb)
return -ENOMEM;

Expand Down Expand Up @@ -143,7 +143,7 @@ static void make_member_array(struct dlm_ls *ls)

ls->ls_total_weight = total;

array = kmalloc(sizeof(int) * total, ls->ls_allocation);
array = kmalloc(sizeof(int) * total, GFP_NOFS);
if (!array)
return;

Expand Down Expand Up @@ -226,7 +226,7 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
continue;
log_debug(ls, "new nodeid %d is a re-added member", rv->new[i]);

memb = kzalloc(sizeof(struct dlm_member), ls->ls_allocation);
memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS);
if (!memb)
return -ENOMEM;
memb->nodeid = rv->new[i];
Expand Down Expand Up @@ -341,7 +341,7 @@ int dlm_ls_start(struct dlm_ls *ls)
int *ids = NULL, *new = NULL;
int error, ids_count = 0, new_count = 0;

rv = kzalloc(sizeof(struct dlm_recover), ls->ls_allocation);
rv = kzalloc(sizeof(struct dlm_recover), GFP_NOFS);
if (!rv)
return -ENOMEM;

Expand Down
6 changes: 3 additions & 3 deletions fs/dlm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ char *dlm_allocate_lvb(struct dlm_ls *ls)
{
char *p;

p = kzalloc(ls->ls_lvblen, ls->ls_allocation);
p = kzalloc(ls->ls_lvblen, GFP_NOFS);
return p;
}

Expand All @@ -57,7 +57,7 @@ struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)

DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,);

r = kzalloc(sizeof(*r) + namelen, ls->ls_allocation);
r = kzalloc(sizeof(*r) + namelen, GFP_NOFS);
return r;
}

Expand All @@ -72,7 +72,7 @@ struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
{
struct dlm_lkb *lkb;

lkb = kmem_cache_zalloc(lkb_cache, ls->ls_allocation);
lkb = kmem_cache_zalloc(lkb_cache, GFP_NOFS);
return lkb;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/dlm/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size)
struct sk_buff *skb;
void *data;

skb = genlmsg_new(size, GFP_KERNEL);
skb = genlmsg_new(size, GFP_NOFS);
if (!skb)
return -ENOMEM;

Expand Down
6 changes: 3 additions & 3 deletions fs/dlm/plock.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
if (!ls)
return -EINVAL;

xop = kzalloc(sizeof(*xop), GFP_KERNEL);
xop = kzalloc(sizeof(*xop), GFP_NOFS);
if (!xop) {
rv = -ENOMEM;
goto out;
Expand Down Expand Up @@ -211,7 +211,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
if (!ls)
return -EINVAL;

op = kzalloc(sizeof(*op), GFP_KERNEL);
op = kzalloc(sizeof(*op), GFP_NOFS);
if (!op) {
rv = -ENOMEM;
goto out;
Expand Down Expand Up @@ -266,7 +266,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
if (!ls)
return -EINVAL;

op = kzalloc(sizeof(*op), GFP_KERNEL);
op = kzalloc(sizeof(*op), GFP_NOFS);
if (!op) {
rv = -ENOMEM;
goto out;
Expand Down
2 changes: 1 addition & 1 deletion fs/dlm/rcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static int create_rcom(struct dlm_ls *ls, int to_nodeid, int type, int len,
char *mb;
int mb_len = sizeof(struct dlm_rcom) + len;

mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, ls->ls_allocation, &mb);
mh = dlm_lowcomms_get_buffer(to_nodeid, mb_len, GFP_NOFS, &mb);
if (!mh) {
log_print("create_rcom to %d type %d len %d ENOBUFS",
to_nodeid, type, len);
Expand Down
2 changes: 1 addition & 1 deletion fs/dlm/requestqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms)
struct rq_entry *e;
int length = ms->m_header.h_length - sizeof(struct dlm_message);

e = kmalloc(sizeof(struct rq_entry) + length, ls->ls_allocation);
e = kmalloc(sizeof(struct rq_entry) + length, GFP_NOFS);
if (!e) {
log_print("dlm_add_requestqueue: out of memory len %d", length);
return;
Expand Down
12 changes: 6 additions & 6 deletions fs/dlm/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static int device_user_lock(struct dlm_user_proc *proc,
goto out;
}

ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS);
if (!ua)
goto out;
ua->proc = proc;
Expand Down Expand Up @@ -307,7 +307,7 @@ static int device_user_unlock(struct dlm_user_proc *proc,
if (!ls)
return -ENOENT;

ua = kzalloc(sizeof(struct dlm_user_args), GFP_KERNEL);
ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS);
if (!ua)
goto out;
ua->proc = proc;
Expand Down Expand Up @@ -352,7 +352,7 @@ static int dlm_device_register(struct dlm_ls *ls, char *name)

error = -ENOMEM;
len = strlen(name) + strlen(name_prefix) + 2;
ls->ls_device.name = kzalloc(len, GFP_KERNEL);
ls->ls_device.name = kzalloc(len, GFP_NOFS);
if (!ls->ls_device.name)
goto fail;

Expand Down Expand Up @@ -520,7 +520,7 @@ static ssize_t device_write(struct file *file, const char __user *buf,
#endif
return -EINVAL;

kbuf = kzalloc(count + 1, GFP_KERNEL);
kbuf = kzalloc(count + 1, GFP_NOFS);
if (!kbuf)
return -ENOMEM;

Expand All @@ -546,7 +546,7 @@ static ssize_t device_write(struct file *file, const char __user *buf,

/* add 1 after namelen so that the name string is terminated */
kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1,
GFP_KERNEL);
GFP_NOFS);
if (!kbuf) {
kfree(k32buf);
return -ENOMEM;
Expand Down Expand Up @@ -648,7 +648,7 @@ static int device_open(struct inode *inode, struct file *file)
if (!ls)
return -ENOENT;

proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
proc = kzalloc(sizeof(struct dlm_user_proc), GFP_NOFS);
if (!proc) {
dlm_put_lockspace(ls);
return -ENOMEM;
Expand Down

0 comments on commit 573c24c

Please sign in to comment.