aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-07-31 19:44:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:42:46 -0400
commit7f338fe4540b1d0600b02314c7d885fd358e9eca (patch)
treedbd0fe3c3d874ae622980dae4b15605bb9e2052a /drivers/block
parent381760eadc393bcb1bb328510ad75cf13431806d (diff)
nbd: set SOCK_MEMALLOC for access to PFMEMALLOC reserves
Set SOCK_MEMALLOC on the NBD socket to allow access to PFMEMALLOC reserves so pages backed by NBD, particularly if swap related, can be cleaned to prevent the machine being deadlocked. It is still possible that the PFMEMALLOC reserves get depleted resulting in deadlock but this can be resolved by the administrator by increasing min_free_kbytes. Signed-off-by: Mel Gorman <mgorman@suse.de> Cc: David Miller <davem@davemloft.net> Cc: Neil Brown <neilb@suse.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: Eric B Munson <emunson@mgebm.net> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Cc: Mel Gorman <mgorman@suse.de> Cc: Christoph Lameter <cl@linux.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/nbd.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 061427a75d3..76bc96fd01c 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -154,6 +154,7 @@ static int sock_xmit(struct nbd_device *nbd, int send, void *buf, int size,
154 struct msghdr msg; 154 struct msghdr msg;
155 struct kvec iov; 155 struct kvec iov;
156 sigset_t blocked, oldset; 156 sigset_t blocked, oldset;
157 unsigned long pflags = current->flags;
157 158
158 if (unlikely(!sock)) { 159 if (unlikely(!sock)) {
159 dev_err(disk_to_dev(nbd->disk), 160 dev_err(disk_to_dev(nbd->disk),
@@ -167,8 +168,9 @@ static int sock_xmit(struct nbd_device *nbd, int send, void *buf, int size,
167 siginitsetinv(&blocked, sigmask(SIGKILL)); 168 siginitsetinv(&blocked, sigmask(SIGKILL));
168 sigprocmask(SIG_SETMASK, &blocked, &oldset); 169 sigprocmask(SIG_SETMASK, &blocked, &oldset);
169 170
171 current->flags |= PF_MEMALLOC;
170 do { 172 do {
171 sock->sk->sk_allocation = GFP_NOIO; 173 sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC;
172 iov.iov_base = buf; 174 iov.iov_base = buf;
173 iov.iov_len = size; 175 iov.iov_len = size;
174 msg.msg_name = NULL; 176 msg.msg_name = NULL;
@@ -214,6 +216,7 @@ static int sock_xmit(struct nbd_device *nbd, int send, void *buf, int size,
214 } while (size > 0); 216 } while (size > 0);
215 217
216 sigprocmask(SIG_SETMASK, &oldset, NULL); 218 sigprocmask(SIG_SETMASK, &oldset, NULL);
219 tsk_restore_flags(current, pflags, PF_MEMALLOC);
217 220
218 return result; 221 return result;
219} 222}
@@ -405,6 +408,7 @@ static int nbd_do_it(struct nbd_device *nbd)
405 408
406 BUG_ON(nbd->magic != NBD_MAGIC); 409 BUG_ON(nbd->magic != NBD_MAGIC);
407 410
411 sk_set_memalloc(nbd->sock->sk);
408 nbd->pid = task_pid_nr(current); 412 nbd->pid = task_pid_nr(current);
409 ret = device_create_file(disk_to_dev(nbd->disk), &pid_attr); 413 ret = device_create_file(disk_to_dev(nbd->disk), &pid_attr);
410 if (ret) { 414 if (ret) {