summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c3
-rw-r--r--include/linux/sunrpc/bc_xprt.h1
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--include/linux/sunrpc/xprt.h6
-rw-r--r--net/sunrpc/backchannel_rqst.c40
-rw-r--r--net/sunrpc/clnt.c13
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/xprtrdma/backchannel.c7
-rw-r--r--net/sunrpc/xprtrdma/transport.c1
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h1
-rw-r--r--net/sunrpc/xprtsock.c1
11 files changed, 55 insertions, 21 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 52de7245a2ee..39896afc6edf 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8380,6 +8380,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args,
8380{ 8380{
8381 unsigned int max_rqst_sz, max_resp_sz; 8381 unsigned int max_rqst_sz, max_resp_sz;
8382 unsigned int max_bc_payload = rpc_max_bc_payload(clnt); 8382 unsigned int max_bc_payload = rpc_max_bc_payload(clnt);
8383 unsigned int max_bc_slots = rpc_num_bc_slots(clnt);
8383 8384
8384 max_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead; 8385 max_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead;
8385 max_resp_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxread_overhead; 8386 max_resp_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxread_overhead;
@@ -8402,6 +8403,8 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args,
8402 args->bc_attrs.max_resp_sz_cached = 0; 8403 args->bc_attrs.max_resp_sz_cached = 0;
8403 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS; 8404 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
8404 args->bc_attrs.max_reqs = max_t(unsigned short, max_session_cb_slots, 1); 8405 args->bc_attrs.max_reqs = max_t(unsigned short, max_session_cb_slots, 1);
8406 if (args->bc_attrs.max_reqs > max_bc_slots)
8407 args->bc_attrs.max_reqs = max_bc_slots;
8405 8408
8406 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u " 8409 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
8407 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n", 8410 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h
index d4229a78524a..87d27e13d885 100644
--- a/include/linux/sunrpc/bc_xprt.h
+++ b/include/linux/sunrpc/bc_xprt.h
@@ -43,6 +43,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
43int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs); 43int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs);
44void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs); 44void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs);
45void xprt_free_bc_rqst(struct rpc_rqst *req); 45void xprt_free_bc_rqst(struct rpc_rqst *req);
46unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt);
46 47
47/* 48/*
48 * Determine if a shared backchannel is in use 49 * Determine if a shared backchannel is in use
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 4e070e00c143..abc63bd1be2b 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -194,6 +194,7 @@ void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
194struct net * rpc_net_ns(struct rpc_clnt *); 194struct net * rpc_net_ns(struct rpc_clnt *);
195size_t rpc_max_payload(struct rpc_clnt *); 195size_t rpc_max_payload(struct rpc_clnt *);
196size_t rpc_max_bc_payload(struct rpc_clnt *); 196size_t rpc_max_bc_payload(struct rpc_clnt *);
197unsigned int rpc_num_bc_slots(struct rpc_clnt *);
197void rpc_force_rebind(struct rpc_clnt *); 198void rpc_force_rebind(struct rpc_clnt *);
198size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t); 199size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
199const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); 200const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index ed76e5fb36c1..13e108bcc9eb 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -158,6 +158,7 @@ struct rpc_xprt_ops {
158 int (*bc_setup)(struct rpc_xprt *xprt, 158 int (*bc_setup)(struct rpc_xprt *xprt,
159 unsigned int min_reqs); 159 unsigned int min_reqs);
160 size_t (*bc_maxpayload)(struct rpc_xprt *xprt); 160 size_t (*bc_maxpayload)(struct rpc_xprt *xprt);
161 unsigned int (*bc_num_slots)(struct rpc_xprt *xprt);
161 void (*bc_free_rqst)(struct rpc_rqst *rqst); 162 void (*bc_free_rqst)(struct rpc_rqst *rqst);
162 void (*bc_destroy)(struct rpc_xprt *xprt, 163 void (*bc_destroy)(struct rpc_xprt *xprt,
163 unsigned int max_reqs); 164 unsigned int max_reqs);
@@ -251,8 +252,9 @@ struct rpc_xprt {
251#if defined(CONFIG_SUNRPC_BACKCHANNEL) 252#if defined(CONFIG_SUNRPC_BACKCHANNEL)
252 struct svc_serv *bc_serv; /* The RPC service which will */ 253 struct svc_serv *bc_serv; /* The RPC service which will */
253 /* process the callback */ 254 /* process the callback */
254 int bc_alloc_count; /* Total number of preallocs */ 255 unsigned int bc_alloc_max;
255 atomic_t bc_free_slots; 256 unsigned int bc_alloc_count; /* Total number of preallocs */
257 atomic_t bc_slot_count; /* Number of allocated slots */
256 spinlock_t bc_pa_lock; /* Protects the preallocated 258 spinlock_t bc_pa_lock; /* Protects the preallocated
257 * items */ 259 * items */
258 struct list_head bc_pa_list; /* List of preallocated 260 struct list_head bc_pa_list; /* List of preallocated
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index c47d82622fd1..339e8c077c2d 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -31,25 +31,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31#define RPCDBG_FACILITY RPCDBG_TRANS 31#define RPCDBG_FACILITY RPCDBG_TRANS
32#endif 32#endif
33 33
34#define BC_MAX_SLOTS 64U
35
36unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt)
37{
38 return BC_MAX_SLOTS;
39}
40
34/* 41/*
35 * Helper routines that track the number of preallocation elements 42 * Helper routines that track the number of preallocation elements
36 * on the transport. 43 * on the transport.
37 */ 44 */
38static inline int xprt_need_to_requeue(struct rpc_xprt *xprt) 45static inline int xprt_need_to_requeue(struct rpc_xprt *xprt)
39{ 46{
40 return xprt->bc_alloc_count < atomic_read(&xprt->bc_free_slots); 47 return xprt->bc_alloc_count < xprt->bc_alloc_max;
41}
42
43static inline void xprt_inc_alloc_count(struct rpc_xprt *xprt, unsigned int n)
44{
45 atomic_add(n, &xprt->bc_free_slots);
46 xprt->bc_alloc_count += n;
47}
48
49static inline int xprt_dec_alloc_count(struct rpc_xprt *xprt, unsigned int n)
50{
51 atomic_sub(n, &xprt->bc_free_slots);
52 return xprt->bc_alloc_count -= n;
53} 48}
54 49
55/* 50/*
@@ -145,6 +140,9 @@ int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs)
145 140
146 dprintk("RPC: setup backchannel transport\n"); 141 dprintk("RPC: setup backchannel transport\n");
147 142
143 if (min_reqs > BC_MAX_SLOTS)
144 min_reqs = BC_MAX_SLOTS;
145
148 /* 146 /*
149 * We use a temporary list to keep track of the preallocated 147 * We use a temporary list to keep track of the preallocated
150 * buffers. Once we're done building the list we splice it 148 * buffers. Once we're done building the list we splice it
@@ -172,7 +170,9 @@ int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs)
172 */ 170 */
173 spin_lock(&xprt->bc_pa_lock); 171 spin_lock(&xprt->bc_pa_lock);
174 list_splice(&tmp_list, &xprt->bc_pa_list); 172 list_splice(&tmp_list, &xprt->bc_pa_list);
175 xprt_inc_alloc_count(xprt, min_reqs); 173 xprt->bc_alloc_count += min_reqs;
174 xprt->bc_alloc_max += min_reqs;
175 atomic_add(min_reqs, &xprt->bc_slot_count);
176 spin_unlock(&xprt->bc_pa_lock); 176 spin_unlock(&xprt->bc_pa_lock);
177 177
178 dprintk("RPC: setup backchannel transport done\n"); 178 dprintk("RPC: setup backchannel transport done\n");
@@ -220,11 +220,13 @@ void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs)
220 goto out; 220 goto out;
221 221
222 spin_lock_bh(&xprt->bc_pa_lock); 222 spin_lock_bh(&xprt->bc_pa_lock);
223 xprt_dec_alloc_count(xprt, max_reqs); 223 xprt->bc_alloc_max -= max_reqs;
224 list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { 224 list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
225 dprintk("RPC: req=%p\n", req); 225 dprintk("RPC: req=%p\n", req);
226 list_del(&req->rq_bc_pa_list); 226 list_del(&req->rq_bc_pa_list);
227 xprt_free_allocation(req); 227 xprt_free_allocation(req);
228 xprt->bc_alloc_count--;
229 atomic_dec(&xprt->bc_slot_count);
228 if (--max_reqs == 0) 230 if (--max_reqs == 0)
229 break; 231 break;
230 } 232 }
@@ -241,13 +243,14 @@ static struct rpc_rqst *xprt_get_bc_request(struct rpc_xprt *xprt, __be32 xid,
241 struct rpc_rqst *req = NULL; 243 struct rpc_rqst *req = NULL;
242 244
243 dprintk("RPC: allocate a backchannel request\n"); 245 dprintk("RPC: allocate a backchannel request\n");
244 if (atomic_read(&xprt->bc_free_slots) <= 0)
245 goto not_found;
246 if (list_empty(&xprt->bc_pa_list)) { 246 if (list_empty(&xprt->bc_pa_list)) {
247 if (!new) 247 if (!new)
248 goto not_found; 248 goto not_found;
249 if (atomic_read(&xprt->bc_slot_count) >= BC_MAX_SLOTS)
250 goto not_found;
249 list_add_tail(&new->rq_bc_pa_list, &xprt->bc_pa_list); 251 list_add_tail(&new->rq_bc_pa_list, &xprt->bc_pa_list);
250 xprt->bc_alloc_count++; 252 xprt->bc_alloc_count++;
253 atomic_inc(&xprt->bc_slot_count);
251 } 254 }
252 req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst, 255 req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst,
253 rq_bc_pa_list); 256 rq_bc_pa_list);
@@ -291,6 +294,7 @@ void xprt_free_bc_rqst(struct rpc_rqst *req)
291 if (xprt_need_to_requeue(xprt)) { 294 if (xprt_need_to_requeue(xprt)) {
292 list_add_tail(&req->rq_bc_pa_list, &xprt->bc_pa_list); 295 list_add_tail(&req->rq_bc_pa_list, &xprt->bc_pa_list);
293 xprt->bc_alloc_count++; 296 xprt->bc_alloc_count++;
297 atomic_inc(&xprt->bc_slot_count);
294 req = NULL; 298 req = NULL;
295 } 299 }
296 spin_unlock_bh(&xprt->bc_pa_lock); 300 spin_unlock_bh(&xprt->bc_pa_lock);
@@ -357,7 +361,7 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
357 361
358 spin_lock(&xprt->bc_pa_lock); 362 spin_lock(&xprt->bc_pa_lock);
359 list_del(&req->rq_bc_pa_list); 363 list_del(&req->rq_bc_pa_list);
360 xprt_dec_alloc_count(xprt, 1); 364 xprt->bc_alloc_count--;
361 spin_unlock(&xprt->bc_pa_lock); 365 spin_unlock(&xprt->bc_pa_lock);
362 366
363 req->rq_private_buf.len = copied; 367 req->rq_private_buf.len = copied;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 383555d2b522..79c849391cb9 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1526,6 +1526,19 @@ size_t rpc_max_bc_payload(struct rpc_clnt *clnt)
1526} 1526}
1527EXPORT_SYMBOL_GPL(rpc_max_bc_payload); 1527EXPORT_SYMBOL_GPL(rpc_max_bc_payload);
1528 1528
1529unsigned int rpc_num_bc_slots(struct rpc_clnt *clnt)
1530{
1531 struct rpc_xprt *xprt;
1532 unsigned int ret;
1533
1534 rcu_read_lock();
1535 xprt = rcu_dereference(clnt->cl_xprt);
1536 ret = xprt->ops->bc_num_slots(xprt);
1537 rcu_read_unlock();
1538 return ret;
1539}
1540EXPORT_SYMBOL_GPL(rpc_num_bc_slots);
1541
1529/** 1542/**
1530 * rpc_force_rebind - force transport to check that remote port is unchanged 1543 * rpc_force_rebind - force transport to check that remote port is unchanged
1531 * @clnt: client to rebind 1544 * @clnt: client to rebind
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e15cb704453e..220b79988000 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1595,7 +1595,7 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
1595 /* Parse and execute the bc call */ 1595 /* Parse and execute the bc call */
1596 proc_error = svc_process_common(rqstp, argv, resv); 1596 proc_error = svc_process_common(rqstp, argv, resv);
1597 1597
1598 atomic_inc(&req->rq_xprt->bc_free_slots); 1598 atomic_dec(&req->rq_xprt->bc_slot_count);
1599 if (!proc_error) { 1599 if (!proc_error) {
1600 /* Processing error: drop the request */ 1600 /* Processing error: drop the request */
1601 xprt_free_bc_request(req); 1601 xprt_free_bc_request(req);
diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c
index ce986591f213..59e624b1d7a0 100644
--- a/net/sunrpc/xprtrdma/backchannel.c
+++ b/net/sunrpc/xprtrdma/backchannel.c
@@ -52,6 +52,13 @@ size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *xprt)
52 return maxmsg - RPCRDMA_HDRLEN_MIN; 52 return maxmsg - RPCRDMA_HDRLEN_MIN;
53} 53}
54 54
55unsigned int xprt_rdma_bc_max_slots(struct rpc_xprt *xprt)
56{
57 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
58
59 return r_xprt->rx_buf.rb_bc_srv_max_requests;
60}
61
55static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst) 62static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
56{ 63{
57 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt); 64 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 4993aa49ecbe..52abddac19e5 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -812,6 +812,7 @@ static const struct rpc_xprt_ops xprt_rdma_procs = {
812#if defined(CONFIG_SUNRPC_BACKCHANNEL) 812#if defined(CONFIG_SUNRPC_BACKCHANNEL)
813 .bc_setup = xprt_rdma_bc_setup, 813 .bc_setup = xprt_rdma_bc_setup,
814 .bc_maxpayload = xprt_rdma_bc_maxpayload, 814 .bc_maxpayload = xprt_rdma_bc_maxpayload,
815 .bc_num_slots = xprt_rdma_bc_max_slots,
815 .bc_free_rqst = xprt_rdma_bc_free_rqst, 816 .bc_free_rqst = xprt_rdma_bc_free_rqst,
816 .bc_destroy = xprt_rdma_bc_destroy, 817 .bc_destroy = xprt_rdma_bc_destroy,
817#endif 818#endif
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 8378f45d2da7..92ce09fcea74 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -605,6 +605,7 @@ void xprt_rdma_cleanup(void);
605#if defined(CONFIG_SUNRPC_BACKCHANNEL) 605#if defined(CONFIG_SUNRPC_BACKCHANNEL)
606int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int); 606int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int);
607size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *); 607size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *);
608unsigned int xprt_rdma_bc_max_slots(struct rpc_xprt *);
608int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int); 609int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int);
609void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *); 610void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *);
610int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst); 611int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst);
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3c2cc96afcaa..6b1fca51028a 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2788,6 +2788,7 @@ static const struct rpc_xprt_ops xs_tcp_ops = {
2788#ifdef CONFIG_SUNRPC_BACKCHANNEL 2788#ifdef CONFIG_SUNRPC_BACKCHANNEL
2789 .bc_setup = xprt_setup_bc, 2789 .bc_setup = xprt_setup_bc,
2790 .bc_maxpayload = xs_tcp_bc_maxpayload, 2790 .bc_maxpayload = xs_tcp_bc_maxpayload,
2791 .bc_num_slots = xprt_bc_max_slots,
2791 .bc_free_rqst = xprt_free_bc_rqst, 2792 .bc_free_rqst = xprt_free_bc_rqst,
2792 .bc_destroy = xprt_destroy_bc, 2793 .bc_destroy = xprt_destroy_bc,
2793#endif 2794#endif