aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-07-31 19:45:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:42:48 -0400
commita564b8f0398636ba30b07c0eaebdef7ff7837249 (patch)
tree10478aa5cfb2a3696db34618a479413b358c3831 /net
parent29418aa4bd487c82016733ef5c6a06d656ed3c7d (diff)
nfs: enable swap on NFS
Implement the new swapfile a_ops for NFS and hook up ->direct_IO. This will set the NFS socket to SOCK_MEMALLOC and run socket reconnect under PF_MEMALLOC as well as reset SOCK_MEMALLOC before engaging the protocol ->connect() method. PF_MEMALLOC should allow the allocation of struct socket and related objects and the early (re)setting of SOCK_MEMALLOC should allow us to receive the packets required for the TCP connection buildup. [jlayton@redhat.com: Restore PF_MEMALLOC task flags in all cases] [dfeng@redhat.com: Fix handling of multiple swap files] [a.p.zijlstra@chello.nl: Original patch] Signed-off-by: Mel Gorman <mgorman@suse.de> Acked-by: Rik van Riel <riel@redhat.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: David S. Miller <davem@davemloft.net> Cc: Eric B Munson <emunson@mgebm.net> Cc: Eric Paris <eparis@redhat.com> Cc: James Morris <jmorris@namei.org> Cc: Mel Gorman <mgorman@suse.de> Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: Neil Brown <neilb@suse.de> Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Cc: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: Xiaotian Feng <dfeng@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/Kconfig5
-rw-r--r--net/sunrpc/clnt.c9
-rw-r--r--net/sunrpc/sched.c7
-rw-r--r--net/sunrpc/xprtsock.c43
4 files changed, 62 insertions, 2 deletions
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 9fe8857d8d59..03d03e37a7d5 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -21,6 +21,11 @@ config SUNRPC_XPRT_RDMA
21 21
22 If unsure, say N. 22 If unsure, say N.
23 23
24config SUNRPC_SWAP
25 bool
26 depends on SUNRPC
27 select NETVM
28
24config RPCSEC_GSS_KRB5 29config RPCSEC_GSS_KRB5
25 tristate "Secure RPC: Kerberos V mechanism" 30 tristate "Secure RPC: Kerberos V mechanism"
26 depends on SUNRPC && CRYPTO 31 depends on SUNRPC && CRYPTO
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index b05df36692ff..fa48c60aef23 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -717,6 +717,15 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
717 atomic_inc(&clnt->cl_count); 717 atomic_inc(&clnt->cl_count);
718 if (clnt->cl_softrtry) 718 if (clnt->cl_softrtry)
719 task->tk_flags |= RPC_TASK_SOFT; 719 task->tk_flags |= RPC_TASK_SOFT;
720 if (sk_memalloc_socks()) {
721 struct rpc_xprt *xprt;
722
723 rcu_read_lock();
724 xprt = rcu_dereference(clnt->cl_xprt);
725 if (xprt->swapper)
726 task->tk_flags |= RPC_TASK_SWAPPER;
727 rcu_read_unlock();
728 }
720 /* Add to the client's list of all tasks */ 729 /* Add to the client's list of all tasks */
721 spin_lock(&clnt->cl_lock); 730 spin_lock(&clnt->cl_lock);
722 list_add_tail(&task->tk_task, &clnt->cl_tasks); 731 list_add_tail(&task->tk_task, &clnt->cl_tasks);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 994cfea2bad6..83a4c43cee7f 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -812,7 +812,10 @@ static void rpc_async_schedule(struct work_struct *work)
812void *rpc_malloc(struct rpc_task *task, size_t size) 812void *rpc_malloc(struct rpc_task *task, size_t size)
813{ 813{
814 struct rpc_buffer *buf; 814 struct rpc_buffer *buf;
815 gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT; 815 gfp_t gfp = GFP_NOWAIT;
816
817 if (RPC_IS_SWAPPER(task))
818 gfp |= __GFP_MEMALLOC;
816 819
817 size += sizeof(struct rpc_buffer); 820 size += sizeof(struct rpc_buffer);
818 if (size <= RPC_BUFFER_MAXSIZE) 821 if (size <= RPC_BUFFER_MAXSIZE)
@@ -886,7 +889,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
886static struct rpc_task * 889static struct rpc_task *
887rpc_alloc_task(void) 890rpc_alloc_task(void)
888{ 891{
889 return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); 892 return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOIO);
890} 893}
891 894
892/* 895/*
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 62d0dac8f780..bd59d01f035b 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1927,6 +1927,45 @@ out:
1927 xprt_wake_pending_tasks(xprt, status); 1927 xprt_wake_pending_tasks(xprt, status);
1928} 1928}
1929 1929
1930#ifdef CONFIG_SUNRPC_SWAP
1931static void xs_set_memalloc(struct rpc_xprt *xprt)
1932{
1933 struct sock_xprt *transport = container_of(xprt, struct sock_xprt,
1934 xprt);
1935
1936 if (xprt->swapper)
1937 sk_set_memalloc(transport->inet);
1938}
1939
1940/**
1941 * xs_swapper - Tag this transport as being used for swap.
1942 * @xprt: transport to tag
1943 * @enable: enable/disable
1944 *
1945 */
1946int xs_swapper(struct rpc_xprt *xprt, int enable)
1947{
1948 struct sock_xprt *transport = container_of(xprt, struct sock_xprt,
1949 xprt);
1950 int err = 0;
1951
1952 if (enable) {
1953 xprt->swapper++;
1954 xs_set_memalloc(xprt);
1955 } else if (xprt->swapper) {
1956 xprt->swapper--;
1957 sk_clear_memalloc(transport->inet);
1958 }
1959
1960 return err;
1961}
1962EXPORT_SYMBOL_GPL(xs_swapper);
1963#else
1964static void xs_set_memalloc(struct rpc_xprt *xprt)
1965{
1966}
1967#endif
1968
1930static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) 1969static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1931{ 1970{
1932 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 1971 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
@@ -1951,6 +1990,8 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1951 transport->sock = sock; 1990 transport->sock = sock;
1952 transport->inet = sk; 1991 transport->inet = sk;
1953 1992
1993 xs_set_memalloc(xprt);
1994
1954 write_unlock_bh(&sk->sk_callback_lock); 1995 write_unlock_bh(&sk->sk_callback_lock);
1955 } 1996 }
1956 xs_udp_do_set_buffer_size(xprt); 1997 xs_udp_do_set_buffer_size(xprt);
@@ -2075,6 +2116,8 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
2075 if (!xprt_bound(xprt)) 2116 if (!xprt_bound(xprt))
2076 goto out; 2117 goto out;
2077 2118
2119 xs_set_memalloc(xprt);
2120
2078 /* Tell the socket layer to start connecting... */ 2121 /* Tell the socket layer to start connecting... */
2079 xprt->stat.connect_count++; 2122 xprt->stat.connect_count++;
2080 xprt->stat.connect_start = jiffies; 2123 xprt->stat.connect_start = jiffies;