From: Liu Yuan <tailai...@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.u...@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 9f51ca2..5625867 100644 --- a/sbd/sbd.h +++ b/sbd/sbd.h @@ -29,6 +29,17 @@ # define __SPIN_LOCK_UNLOCKED(lockname) __SPIN_LOCK_INITIALIZER(lockname) #endif +/* __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 aa93654..3e81de5 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 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog