[sheepdog] [PATCH v4 8/9] sbd: improve memory allocation when memory hit low

Liu Yuan namei.unix at gmail.com
Mon May 26 08:52:49 CEST 2014


From: Liu Yuan <tailai.ly at taobao.com>

Let's try our best to allocate memory and make use of reserve memory to avoid
the memory allocation deadlock:

- when out of memory, ditry pages need to be written out, but need to allocate
memory for internal data structures to do the writeout.

PF_MEMALLOC and __GFP_MEMALLOC will try its best effort to allocate new memory.

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 sbd/sbd.h                | 11 +++++++++++
 sbd/sheep.c              |  9 +++++----
 sbd/sheep_block_device.c |  2 ++
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/sbd/sbd.h b/sbd/sbd.h
index b95031f..e2940f8 100644
--- a/sbd/sbd.h
+++ b/sbd/sbd.h
@@ -23,6 +23,17 @@
 #define SBD_MINORS_SHIFT 5 /* at most 31 partitions for a single device */
 #define SECTOR_SIZE 512
 
+/* __GFP_MEMALLOC was introduced since v3.6, if not defined, nullify it */
+#ifndef __GFP_MEMALLOC
+# define __GFP_MEMALLOC GFP_NOIO
+#endif
+
+/*
+ * Try our best to handle low memory situation, when dirty pages should be
+ * written out over network, not local disks.
+ */
+#define SBD_GFP_FLAGS (GFP_NOIO | __GFP_MEMALLOC)
+
 struct sheep_vdi {
 	struct sd_inode *inode;
 	u32 vid;
diff --git a/sbd/sheep.c b/sbd/sheep.c
index f2b7431..9644907 100644
--- a/sbd/sheep.c
+++ b/sbd/sheep.c
@@ -71,6 +71,8 @@ static int socket_create(struct socket **sock, const char *ip_addr, int port)
 		goto shutdown;
 	}
 
+	(*sock)->sk->sk_allocation = SBD_GFP_FLAGS;
+
 	return ret;
 shutdown:
 	socket_shutdown(*sock);
@@ -94,7 +96,6 @@ static int socket_xmit(struct socket *sock, void *buf, int size, bool send,
 	sigprocmask(SIG_SETMASK, &blocked, &oldset);
 
 	do {
-		sock->sk->sk_allocation = GFP_NOIO;
 		iov.iov_base = buf;
 		iov.iov_len = size;
 		msg.msg_name = NULL;
@@ -348,7 +349,7 @@ static void aio_read_done(struct sheep_aiocb *aiocb)
 
 struct sheep_aiocb *sheep_aiocb_setup(struct request *req)
 {
-	struct sheep_aiocb *aiocb = kmalloc(sizeof(*aiocb), GFP_KERNEL);
+	struct sheep_aiocb *aiocb = kmalloc(sizeof(*aiocb), SBD_GFP_FLAGS);
 	struct req_iterator iter;
 	struct bio_vec *bvec;
 	int len = 0;
@@ -400,7 +401,7 @@ static struct sheep_request *alloc_sheep_request(struct sheep_aiocb *aiocb,
 						 u64 oid, int len,
 						 int offset)
 {
-	struct sheep_request *req = kmalloc(sizeof(*req), GFP_KERNEL);
+	struct sheep_request *req = kmalloc(sizeof(*req), SBD_GFP_FLAGS);
 	struct sbd_device *dev = sheep_aiocb_to_device(aiocb);
 
 	if (!req)
@@ -616,7 +617,7 @@ int sheep_handle_reply(struct sbd_device *dev)
 	switch (req->type) {
 	case SHEEP_CREATE:
 		/* We need to update inode for create */
-		new = kmalloc(sizeof(*new), GFP_KERNEL);
+		new = kmalloc(sizeof(*new), SBD_GFP_FLAGS);
 		if (!new) {
 			ret = -ENOMEM;
 			req->aiocb->ret = EIO;
diff --git a/sbd/sheep_block_device.c b/sbd/sheep_block_device.c
index deeafeb..a34ad7e 100644
--- a/sbd/sheep_block_device.c
+++ b/sbd/sheep_block_device.c
@@ -241,6 +241,8 @@ static ssize_t sbd_add(struct bus_type *bus, const char *buf,
 	dev->submiter = kthread_run(sbd_request_submiter, dev, "sbd_submiter");
 	if (IS_ERR(dev->submiter))
 		goto err_stop_reaper;
+	dev->reaper->flags = PF_MEMALLOC;
+	dev->submiter->flags = PF_MEMALLOC;
 
 	ret = sbd_add_disk(dev);
 	if (ret < 0)
-- 
1.8.1.2




More information about the sheepdog mailing list