Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 646

kernel-2.6.18-238.el5.src.rpm

From: David Teigland <teigland@redhat.com>
Date: Tue, 18 Nov 2008 12:57:15 -0600
Subject: [dlm] fix up memory allocation flags
Message-id: 20081118185715.GC10717@redhat.com
O-Subject: [RHEL5.3 PATCH] dlm: fix up memory allocation flags
Bugzilla: 471871
RH-Acked-by: Abhijith Das <adas@redhat.com>
RH-Acked-by: Bob Peterson <rpeterso@redhat.com>
RH-Acked-by: Steven Whitehouse <swhiteho@redhat.com>

bz 471871 dlm: fix up memory allocation flags

Memory allocations in the dlm should use GFP_NOFS to avoid looping back
into gfs to free memory, which may require dlm operations, causing
deadlock.  Most dlm allocations already use GFP_NOFS (usually via
ls_allocation), but this patch fixes up some that have been missed.

AFAIK, no one has actually observed deadlock between dlm and gfs due to
any of the allocations changed by this patch.  But apparently the patch
still has an effect somehow, in delaying the onset of gfs2 bug 460218.

brew build including this patch
https://brewweb.devel.redhat.com/taskinfo?taskID=1578524

upstream commit (in linux-next for 2.6.29)

Use ls_allocation for memory allocations, which a cluster fs sets to
GFP_NOFS.  Use GFP_NOFS for allocations when no lockspace struct is
available.  Taking dlm locks needs to avoid calling back into the
cluster fs because write-out can require taking dlm locks.

Signed-off-by: David Teigland <teigland@redhat.com>

diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 222867d..e79c18d 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -294,6 +294,7 @@ static int add_sock(struct socket *sock, struct connection *con)
 	con->sock->sk->sk_write_space = lowcomms_write_space;
 	con->sock->sk->sk_state_change = lowcomms_state_change;
 	con->sock->sk->sk_user_data = con;
+	con->sock->sk->sk_allocation = GFP_NOFS;
 	return 0;
 }
 
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c
index 55416ae..38f525c 100644
--- a/fs/dlm/memory.c
+++ b/fs/dlm/memory.c
@@ -39,7 +39,7 @@ char *dlm_allocate_lvb(struct dlm_ls *ls)
 {
 	char *p;
 
-	p = kmalloc(ls->ls_lvblen, GFP_KERNEL);
+	p = kmalloc(ls->ls_lvblen, ls->ls_allocation);
 	if (p)
 		memset(p, 0, ls->ls_lvblen);
 	return p;
@@ -59,7 +59,7 @@ struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls, int namelen)
 
 	DLM_ASSERT(namelen <= DLM_RESNAME_MAXLEN,);
 
-	r = kmalloc(sizeof(*r) + namelen, GFP_KERNEL);
+	r = kmalloc(sizeof(*r) + namelen, ls->ls_allocation);
 	if (r)
 		memset(r, 0, sizeof(*r) + namelen);
 	return r;
@@ -76,7 +76,7 @@ struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
 {
 	struct dlm_lkb *lkb;
 
-	lkb = kmem_cache_alloc(lkb_cache, GFP_KERNEL);
+	lkb = kmem_cache_alloc(lkb_cache, ls->ls_allocation);
 	if (lkb)
 		memset(lkb, 0, sizeof(*lkb));
 	return lkb;
diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c
index e69926e..8e32381 100644
--- a/fs/dlm/midcomms.c
+++ b/fs/dlm/midcomms.c
@@ -105,7 +105,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
 		   ordinary messages). */
 
 		if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) {
-			msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
+			msg = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS);
 			if (msg == NULL)
 				return ret;
 		}