History

SUNRPC: Fix up backchannel slot table accounting

Add a per-transport maximum limit in the socket case, and add helpers to allow the NFSv4 code to discover that limit.

Trond Myklebust committed 7 years ago

Commit 7402a4f1 parent 9f98eff11 files · +55 −21Browse files

Unified · Split

11 files
  1. fs/nfs/nfs4proc.c +3 −0
  2. include/linux/sunrpc/bc_xprt.h +1 −0
  3. include/linux/sunrpc/clnt.h +1 −0
  4. include/linux/sunrpc/xprt.h +4 −2
  5. net/sunrpc/backchannel_rqst.c +22 −18
  6. net/sunrpc/clnt.c +13 −0
  7. net/sunrpc/svc.c +1 −1
  8. net/sunrpc/xprtrdma/backchannel.c +7 −0
  9. net/sunrpc/xprtrdma/transport.c +1 −0
  10. net/sunrpc/xprtrdma/xprt_rdma.h +1 −0
  11. net/sunrpc/xprtsock.c +1 −0
fs/nfs/nfs4proc.c+3−0
@@ -8380,6 +8380,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args, · 8379 unmodified lines
83808380 {
83818381 unsigned int max_rqst_sz, max_resp_sz;
83828382 unsigned int max_bc_payload = rpc_max_bc_payload(clnt);
8383+ unsigned int max_bc_slots = rpc_num_bc_slots(clnt);
83838384
83848385 max_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead;
83858386 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, · 16 unmodified lines
84028403 args->bc_attrs.max_resp_sz_cached = 0;
84038404 args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
84048405 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;
84058408
84068409 dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
84078410 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
include/linux/sunrpc/bc_xprt.h+1−0
@@ -43,6 +43,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs); · 42 unmodified lines
4343 int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs);
4444 void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs);
4545 void xprt_free_bc_rqst(struct rpc_rqst *req);
46+unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt);
4647
4748 /*
4849 * Determine if a shared backchannel is in use
include/linux/sunrpc/clnt.h+1−0
@@ -194,6 +194,7 @@ void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); · 193 unmodified lines
194194 struct net * rpc_net_ns(struct rpc_clnt *);
195195 size_t rpc_max_payload(struct rpc_clnt *);
196196 size_t rpc_max_bc_payload(struct rpc_clnt *);
197+unsigned int rpc_num_bc_slots(struct rpc_clnt *);
197198 void rpc_force_rebind(struct rpc_clnt *);
198199 size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
199200 const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
include/linux/sunrpc/xprt.h+4−2
@@ -158,6 +158,7 @@ struct rpc_xprt_ops { · 157 unmodified lines
158158 int (*bc_setup)(struct rpc_xprt *xprt,
159159 unsigned int min_reqs);
160160 size_t (*bc_maxpayload)(struct rpc_xprt *xprt);
161+ unsigned int (*bc_num_slots)(struct rpc_xprt *xprt);
161162 void (*bc_free_rqst)(struct rpc_rqst *rqst);
162163 void (*bc_destroy)(struct rpc_xprt *xprt,
163164 unsigned int max_reqs);
@@ -251,8 +252,9 @@ struct rpc_xprt { · 87 unmodified lines
251252 #if defined(CONFIG_SUNRPC_BACKCHANNEL)
252253 struct svc_serv *bc_serv; /* The RPC service which will */
253254 /* process the callback */
254− int bc_alloc_count; /* Total number of preallocs */
255− atomic_t bc_free_slots;
255+ unsigned int bc_alloc_max;
256+ unsigned int bc_alloc_count; /* Total number of preallocs */
257+ atomic_t bc_slot_count; /* Number of allocated slots */
256258 spinlock_t bc_pa_lock; /* Protects the preallocated
257259 * items */
258260 struct list_head bc_pa_list; /* List of preallocated
net/sunrpc/backchannel_rqst.c+22−18
@@ -31,25 +31,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. · 30 unmodified lines
3131 #define RPCDBG_FACILITY RPCDBG_TRANS
3232 #endif
3333
34+#define BC_MAX_SLOTS 64U
35+
36+unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt)
37+{
38+ return BC_MAX_SLOTS;
39+}
40+
3441 /*
3542 * Helper routines that track the number of preallocation elements
3643 * on the transport.
3744 */
3845 static inline int xprt_need_to_requeue(struct rpc_xprt *xprt)
3946 {
40− return xprt->bc_alloc_count < atomic_read(&xprt->bc_free_slots);
41−}
42−
43−static 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−
49−static 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;
47+ return xprt->bc_alloc_count < xprt->bc_alloc_max;
5348 }
5449
5550 /*
@@ -145,6 +140,9 @@ int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs) · 89 unmodified lines
145140
146141 dprintk("RPC: setup backchannel transport\n");
147142
143+ if (min_reqs > BC_MAX_SLOTS)
144+ min_reqs = BC_MAX_SLOTS;
145+
148146 /*
149147 * We use a temporary list to keep track of the preallocated
150148 * 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) · 21 unmodified lines
172170 */
173171 spin_lock(&xprt->bc_pa_lock);
174172 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);
176176 spin_unlock(&xprt->bc_pa_lock);
177177
178178 dprintk("RPC: setup backchannel transport done\n");
@@ -220,11 +220,13 @@ void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs) · 41 unmodified lines
220220 goto out;
221221
222222 spin_lock_bh(&xprt->bc_pa_lock);
223− xprt_dec_alloc_count(xprt, max_reqs);
223+ xprt->bc_alloc_max -= max_reqs;
224224 list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
225225 dprintk("RPC: req=%p\n", req);
226226 list_del(&req->rq_bc_pa_list);
227227 xprt_free_allocation(req);
228+ xprt->bc_alloc_count--;
229+ atomic_dec(&xprt->bc_slot_count);
228230 if (--max_reqs == 0)
229231 break;
230232 }
@@ -241,13 +243,14 @@ static struct rpc_rqst *xprt_get_bc_request(struct rpc_xprt *xprt, __be32 xid, · 10 unmodified lines
241243 struct rpc_rqst *req = NULL;
242244
243245 dprintk("RPC: allocate a backchannel request\n");
244− if (atomic_read(&xprt->bc_free_slots) <= 0)
245− goto not_found;
246246 if (list_empty(&xprt->bc_pa_list)) {
247247 if (!new)
248248 goto not_found;
249+ if (atomic_read(&xprt->bc_slot_count) >= BC_MAX_SLOTS)
250+ goto not_found;
249251 list_add_tail(&new->rq_bc_pa_list, &xprt->bc_pa_list);
250252 xprt->bc_alloc_count++;
253+ atomic_inc(&xprt->bc_slot_count);
251254 }
252255 req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst,
253256 rq_bc_pa_list);
@@ -291,6 +294,7 @@ void xprt_free_bc_rqst(struct rpc_rqst *req) · 37 unmodified lines
291294 if (xprt_need_to_requeue(xprt)) {
292295 list_add_tail(&req->rq_bc_pa_list, &xprt->bc_pa_list);
293296 xprt->bc_alloc_count++;
297+ atomic_inc(&xprt->bc_slot_count);
294298 req = NULL;
295299 }
296300 spin_unlock_bh(&xprt->bc_pa_lock);
@@ -357,7 +361,7 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) · 60 unmodified lines
357361
358362 spin_lock(&xprt->bc_pa_lock);
359363 list_del(&req->rq_bc_pa_list);
360− xprt_dec_alloc_count(xprt, 1);
364+ xprt->bc_alloc_count--;
361365 spin_unlock(&xprt->bc_pa_lock);
362366
363367 req->rq_private_buf.len = copied;
net/sunrpc/clnt.c+13−0
@@ -1526,6 +1526,19 @@ size_t rpc_max_bc_payload(struct rpc_clnt *clnt) · 1525 unmodified lines
15261526 }
15271527 EXPORT_SYMBOL_GPL(rpc_max_bc_payload);
15281528
1529+unsigned 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+}
1540+EXPORT_SYMBOL_GPL(rpc_num_bc_slots);
1541+
15291542 /**
15301543 * rpc_force_rebind - force transport to check that remote port is unchanged
15311544 * @clnt: client to rebind
net/sunrpc/svc.c+1−1
@@ -1595,7 +1595,7 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, · 1594 unmodified lines
15951595 /* Parse and execute the bc call */
15961596 proc_error = svc_process_common(rqstp, argv, resv);
15971597
1598− atomic_inc(&req->rq_xprt->bc_free_slots);
1598+ atomic_dec(&req->rq_xprt->bc_slot_count);
15991599 if (!proc_error) {
16001600 /* Processing error: drop the request */
16011601 xprt_free_bc_request(req);
net/sunrpc/xprtrdma/backchannel.c+7−0
@@ -52,6 +52,13 @@ size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *xprt) · 51 unmodified lines
5252 return maxmsg - RPCRDMA_HDRLEN_MIN;
5353 }
5454
55+unsigned 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+
5562 static int rpcrdma_bc_marshal_reply(struct rpc_rqst *rqst)
5663 {
5764 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
net/sunrpc/xprtrdma/transport.c+1−0
@@ -812,6 +812,7 @@ static const struct rpc_xprt_ops xprt_rdma_procs = { · 811 unmodified lines
812812 #if defined(CONFIG_SUNRPC_BACKCHANNEL)
813813 .bc_setup = xprt_rdma_bc_setup,
814814 .bc_maxpayload = xprt_rdma_bc_maxpayload,
815+ .bc_num_slots = xprt_rdma_bc_max_slots,
815816 .bc_free_rqst = xprt_rdma_bc_free_rqst,
816817 .bc_destroy = xprt_rdma_bc_destroy,
817818 #endif
net/sunrpc/xprtrdma/xprt_rdma.h+1−0
@@ -605,6 +605,7 @@ void xprt_rdma_cleanup(void); · 604 unmodified lines
605605 #if defined(CONFIG_SUNRPC_BACKCHANNEL)
606606 int xprt_rdma_bc_setup(struct rpc_xprt *, unsigned int);
607607 size_t xprt_rdma_bc_maxpayload(struct rpc_xprt *);
608+unsigned int xprt_rdma_bc_max_slots(struct rpc_xprt *);
608609 int rpcrdma_bc_post_recv(struct rpcrdma_xprt *, unsigned int);
609610 void rpcrdma_bc_receive_call(struct rpcrdma_xprt *, struct rpcrdma_rep *);
610611 int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst);
net/sunrpc/xprtsock.c+1−0
@@ -2788,6 +2788,7 @@ static const struct rpc_xprt_ops xs_tcp_ops = { · 2787 unmodified lines
27882788 #ifdef CONFIG_SUNRPC_BACKCHANNEL
27892789 .bc_setup = xprt_setup_bc,
27902790 .bc_maxpayload = xs_tcp_bc_maxpayload,
2791+ .bc_num_slots = xprt_bc_max_slots,
27912792 .bc_free_rqst = xprt_free_bc_rqst,
27922793 .bc_destroy = xprt_destroy_bc,
27932794 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t