aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/xprt.h9
-rw-r--r--net/sunrpc/xprt.c70
-rw-r--r--net/sunrpc/xprtrdma/transport.c1
-rw-r--r--net/sunrpc/xprtsock.c49
4 files changed, 109 insertions, 20 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 05047250f218..d02762d1de27 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -22,6 +22,7 @@
22#define RPC_MIN_SLOT_TABLE (2U) 22#define RPC_MIN_SLOT_TABLE (2U)
23#define RPC_DEF_SLOT_TABLE (16U) 23#define RPC_DEF_SLOT_TABLE (16U)
24#define RPC_MAX_SLOT_TABLE (128U) 24#define RPC_MAX_SLOT_TABLE (128U)
25#define RPC_MAX_SLOT_TABLE_LIMIT (65536U)
25 26
26/* 27/*
27 * This describes a timeout strategy 28 * This describes a timeout strategy
@@ -168,7 +169,9 @@ struct rpc_xprt {
168 struct rpc_wait_queue pending; /* requests in flight */ 169 struct rpc_wait_queue pending; /* requests in flight */
169 struct rpc_wait_queue backlog; /* waiting for slot */ 170 struct rpc_wait_queue backlog; /* waiting for slot */
170 struct list_head free; /* free slots */ 171 struct list_head free; /* free slots */
171 unsigned int max_reqs; /* total slots */ 172 unsigned int max_reqs; /* max number of slots */
173 unsigned int min_reqs; /* min number of slots */
174 atomic_t num_reqs; /* total slots */
172 unsigned long state; /* transport state */ 175 unsigned long state; /* transport state */
173 unsigned char shutdown : 1, /* being shut down */ 176 unsigned char shutdown : 1, /* being shut down */
174 resvport : 1; /* use a reserved port */ 177 resvport : 1; /* use a reserved port */
@@ -281,7 +284,9 @@ void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
281void xprt_release(struct rpc_task *task); 284void xprt_release(struct rpc_task *task);
282struct rpc_xprt * xprt_get(struct rpc_xprt *xprt); 285struct rpc_xprt * xprt_get(struct rpc_xprt *xprt);
283void xprt_put(struct rpc_xprt *xprt); 286void xprt_put(struct rpc_xprt *xprt);
284struct rpc_xprt * xprt_alloc(struct net *net, int size, int max_req); 287struct rpc_xprt * xprt_alloc(struct net *net, size_t size,
288 unsigned int num_prealloc,
289 unsigned int max_req);
285void xprt_free(struct rpc_xprt *); 290void xprt_free(struct rpc_xprt *);
286 291
287static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p) 292static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p)
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index ea7b3c16cddd..be85cf04a479 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -935,25 +935,66 @@ void xprt_transmit(struct rpc_task *task)
935 spin_unlock_bh(&xprt->transport_lock); 935 spin_unlock_bh(&xprt->transport_lock);
936} 936}
937 937
938static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt, gfp_t gfp_flags)
939{
940 struct rpc_rqst *req = ERR_PTR(-EAGAIN);
941
942 if (!atomic_add_unless(&xprt->num_reqs, 1, xprt->max_reqs))
943 goto out;
944 req = kzalloc(sizeof(struct rpc_rqst), gfp_flags);
945 if (req != NULL)
946 goto out;
947 atomic_dec(&xprt->num_reqs);
948 req = ERR_PTR(-ENOMEM);
949out:
950 return req;
951}
952
953static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
954{
955 if (atomic_add_unless(&xprt->num_reqs, -1, xprt->min_reqs)) {
956 kfree(req);
957 return true;
958 }
959 return false;
960}
961
938static void xprt_alloc_slot(struct rpc_task *task) 962static void xprt_alloc_slot(struct rpc_task *task)
939{ 963{
940 struct rpc_xprt *xprt = task->tk_xprt; 964 struct rpc_xprt *xprt = task->tk_xprt;
965 struct rpc_rqst *req;
941 966
942 task->tk_status = 0;
943 if (!list_empty(&xprt->free)) { 967 if (!list_empty(&xprt->free)) {
944 struct rpc_rqst *req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); 968 req = list_entry(xprt->free.next, struct rpc_rqst, rq_list);
945 list_del_init(&req->rq_list); 969 list_del(&req->rq_list);
946 task->tk_rqstp = req; 970 goto out_init_req;
947 xprt_request_init(task, xprt); 971 }
948 return; 972 req = xprt_dynamic_alloc_slot(xprt, GFP_NOWAIT);
973 if (!IS_ERR(req))
974 goto out_init_req;
975 switch (PTR_ERR(req)) {
976 case -ENOMEM:
977 rpc_delay(task, HZ >> 2);
978 dprintk("RPC: dynamic allocation of request slot "
979 "failed! Retrying\n");
980 break;
981 case -EAGAIN:
982 rpc_sleep_on(&xprt->backlog, task, NULL);
983 dprintk("RPC: waiting for request slot\n");
949 } 984 }
950 dprintk("RPC: waiting for request slot\n");
951 task->tk_status = -EAGAIN; 985 task->tk_status = -EAGAIN;
952 rpc_sleep_on(&xprt->backlog, task, NULL); 986 return;
987out_init_req:
988 task->tk_status = 0;
989 task->tk_rqstp = req;
990 xprt_request_init(task, xprt);
953} 991}
954 992
955static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) 993static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
956{ 994{
995 if (xprt_dynamic_free_slot(xprt, req))
996 return;
997
957 memset(req, 0, sizeof(*req)); /* mark unused */ 998 memset(req, 0, sizeof(*req)); /* mark unused */
958 999
959 spin_lock(&xprt->reserve_lock); 1000 spin_lock(&xprt->reserve_lock);
@@ -972,7 +1013,9 @@ static void xprt_free_all_slots(struct rpc_xprt *xprt)
972 } 1013 }
973} 1014}
974 1015
975struct rpc_xprt *xprt_alloc(struct net *net, int size, int num_prealloc) 1016struct rpc_xprt *xprt_alloc(struct net *net, size_t size,
1017 unsigned int num_prealloc,
1018 unsigned int max_alloc)
976{ 1019{
977 struct rpc_xprt *xprt; 1020 struct rpc_xprt *xprt;
978 struct rpc_rqst *req; 1021 struct rpc_rqst *req;
@@ -992,7 +1035,12 @@ struct rpc_xprt *xprt_alloc(struct net *net, int size, int num_prealloc)
992 } 1035 }
993 if (i < num_prealloc) 1036 if (i < num_prealloc)
994 goto out_free; 1037 goto out_free;
995 xprt->max_reqs = num_prealloc; 1038 if (max_alloc > num_prealloc)
1039 xprt->max_reqs = max_alloc;
1040 else
1041 xprt->max_reqs = num_prealloc;
1042 xprt->min_reqs = num_prealloc;
1043 atomic_set(&xprt->num_reqs, num_prealloc);
996 1044
997 return xprt; 1045 return xprt;
998 1046
@@ -1036,7 +1084,6 @@ void xprt_reserve(struct rpc_task *task)
1036 if (!xprt_lock_write(xprt, task)) 1084 if (!xprt_lock_write(xprt, task))
1037 return; 1085 return;
1038 1086
1039 task->tk_status = -EIO;
1040 spin_lock(&xprt->reserve_lock); 1087 spin_lock(&xprt->reserve_lock);
1041 xprt_alloc_slot(task); 1088 xprt_alloc_slot(task);
1042 spin_unlock(&xprt->reserve_lock); 1089 spin_unlock(&xprt->reserve_lock);
@@ -1057,6 +1104,7 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
1057{ 1104{
1058 struct rpc_rqst *req = task->tk_rqstp; 1105 struct rpc_rqst *req = task->tk_rqstp;
1059 1106
1107 INIT_LIST_HEAD(&req->rq_list);
1060 req->rq_timeout = task->tk_client->cl_timeout->to_initval; 1108 req->rq_timeout = task->tk_client->cl_timeout->to_initval;
1061 req->rq_task = task; 1109 req->rq_task = task;
1062 req->rq_xprt = xprt; 1110 req->rq_xprt = xprt;
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 674a49224450..b446e100286f 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -283,6 +283,7 @@ xprt_setup_rdma(struct xprt_create *args)
283 } 283 }
284 284
285 xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), 285 xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt),
286 xprt_rdma_slot_table_entries,
286 xprt_rdma_slot_table_entries); 287 xprt_rdma_slot_table_entries);
287 if (xprt == NULL) { 288 if (xprt == NULL) {
288 dprintk("RPC: %s: couldn't allocate rpcrdma_xprt\n", 289 dprintk("RPC: %s: couldn't allocate rpcrdma_xprt\n",
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index adaa54c6a09a..d7f97ef26590 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -54,7 +54,8 @@ static void xs_close(struct rpc_xprt *xprt);
54 * xprtsock tunables 54 * xprtsock tunables
55 */ 55 */
56unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; 56unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE;
57unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; 57unsigned int xprt_tcp_slot_table_entries = RPC_MIN_SLOT_TABLE;
58unsigned int xprt_max_tcp_slot_table_entries = RPC_MAX_SLOT_TABLE;
58 59
59unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; 60unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
60unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; 61unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
@@ -75,6 +76,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO;
75 76
76static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; 77static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
77static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; 78static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
79static unsigned int max_tcp_slot_table_limit = RPC_MAX_SLOT_TABLE_LIMIT;
78static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT; 80static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
79static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT; 81static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
80 82
@@ -104,6 +106,15 @@ static ctl_table xs_tunables_table[] = {
104 .extra2 = &max_slot_table_size 106 .extra2 = &max_slot_table_size
105 }, 107 },
106 { 108 {
109 .procname = "tcp_max_slot_table_entries",
110 .data = &xprt_max_tcp_slot_table_entries,
111 .maxlen = sizeof(unsigned int),
112 .mode = 0644,
113 .proc_handler = proc_dointvec_minmax,
114 .extra1 = &min_slot_table_size,
115 .extra2 = &max_tcp_slot_table_limit
116 },
117 {
107 .procname = "min_resvport", 118 .procname = "min_resvport",
108 .data = &xprt_min_resvport, 119 .data = &xprt_min_resvport,
109 .maxlen = sizeof(unsigned int), 120 .maxlen = sizeof(unsigned int),
@@ -2491,7 +2502,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap)
2491} 2502}
2492 2503
2493static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, 2504static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
2494 unsigned int slot_table_size) 2505 unsigned int slot_table_size,
2506 unsigned int max_slot_table_size)
2495{ 2507{
2496 struct rpc_xprt *xprt; 2508 struct rpc_xprt *xprt;
2497 struct sock_xprt *new; 2509 struct sock_xprt *new;
@@ -2501,7 +2513,8 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
2501 return ERR_PTR(-EBADF); 2513 return ERR_PTR(-EBADF);
2502 } 2514 }
2503 2515
2504 xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size); 2516 xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size,
2517 max_slot_table_size);
2505 if (xprt == NULL) { 2518 if (xprt == NULL) {
2506 dprintk("RPC: xs_setup_xprt: couldn't allocate " 2519 dprintk("RPC: xs_setup_xprt: couldn't allocate "
2507 "rpc_xprt\n"); 2520 "rpc_xprt\n");
@@ -2543,7 +2556,8 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
2543 struct rpc_xprt *xprt; 2556 struct rpc_xprt *xprt;
2544 struct rpc_xprt *ret; 2557 struct rpc_xprt *ret;
2545 2558
2546 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); 2559 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
2560 xprt_max_tcp_slot_table_entries);
2547 if (IS_ERR(xprt)) 2561 if (IS_ERR(xprt))
2548 return xprt; 2562 return xprt;
2549 transport = container_of(xprt, struct sock_xprt, xprt); 2563 transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2607,7 +2621,8 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
2607 struct sock_xprt *transport; 2621 struct sock_xprt *transport;
2608 struct rpc_xprt *ret; 2622 struct rpc_xprt *ret;
2609 2623
2610 xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries); 2624 xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries,
2625 xprt_udp_slot_table_entries);
2611 if (IS_ERR(xprt)) 2626 if (IS_ERR(xprt))
2612 return xprt; 2627 return xprt;
2613 transport = container_of(xprt, struct sock_xprt, xprt); 2628 transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2683,7 +2698,8 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
2683 struct sock_xprt *transport; 2698 struct sock_xprt *transport;
2684 struct rpc_xprt *ret; 2699 struct rpc_xprt *ret;
2685 2700
2686 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); 2701 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
2702 xprt_max_tcp_slot_table_entries);
2687 if (IS_ERR(xprt)) 2703 if (IS_ERR(xprt))
2688 return xprt; 2704 return xprt;
2689 transport = container_of(xprt, struct sock_xprt, xprt); 2705 transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2762,7 +2778,8 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
2762 */ 2778 */
2763 return args->bc_xprt->xpt_bc_xprt; 2779 return args->bc_xprt->xpt_bc_xprt;
2764 } 2780 }
2765 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); 2781 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
2782 xprt_tcp_slot_table_entries);
2766 if (IS_ERR(xprt)) 2783 if (IS_ERR(xprt))
2767 return xprt; 2784 return xprt;
2768 transport = container_of(xprt, struct sock_xprt, xprt); 2785 transport = container_of(xprt, struct sock_xprt, xprt);
@@ -2949,8 +2966,26 @@ static struct kernel_param_ops param_ops_slot_table_size = {
2949#define param_check_slot_table_size(name, p) \ 2966#define param_check_slot_table_size(name, p) \
2950 __param_check(name, p, unsigned int); 2967 __param_check(name, p, unsigned int);
2951 2968
2969static int param_set_max_slot_table_size(const char *val,
2970 const struct kernel_param *kp)
2971{
2972 return param_set_uint_minmax(val, kp,
2973 RPC_MIN_SLOT_TABLE,
2974 RPC_MAX_SLOT_TABLE_LIMIT);
2975}
2976
2977static struct kernel_param_ops param_ops_max_slot_table_size = {
2978 .set = param_set_max_slot_table_size,
2979 .get = param_get_uint,
2980};
2981
2982#define param_check_max_slot_table_size(name, p) \
2983 __param_check(name, p, unsigned int);
2984
2952module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries, 2985module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries,
2953 slot_table_size, 0644); 2986 slot_table_size, 0644);
2987module_param_named(tcp_max_slot_table_entries, xprt_max_tcp_slot_table_entries,
2988 max_slot_table_size, 0644);
2954module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries, 2989module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries,
2955 slot_table_size, 0644); 2990 slot_table_size, 0644);
2956 2991