[sheepdog] [PATCH v3 8/9] sbd: improve memory allocation when memory hit low
Liu Yuan
namei.unix at gmail.com
Mon May 26 07:18:41 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