Skip to content

Commit 93bdcf9

Browse files
author
Trond Myklebust
committed
Merge tag 'nfs-rdma-for-4.20-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
NFS RDMA client updates for Linux 4.20 Stable bugfixes: - Reset credit grant properly after a disconnect Other bugfixes and cleanups: - xprt_release_rqst_cong is called outside of transport_lock - Create more MRs at a time and toss out old ones during recovery - Various improvements to the RDMA connection and disconnection code: - Improve naming of trace events, functions, and variables - Add documenting comments - Fix metrics and stats reporting - Fix a tracepoint sparse warning Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2 parents 826799e + 470443e commit 93bdcf9

File tree

11 files changed

+302
-351
lines changed

11 files changed

+302
-351
lines changed

include/trace/events/rpcrdma.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ DECLARE_EVENT_CLASS(xprtrdma_mr,
263263
);
264264

265265
#define DEFINE_MR_EVENT(name) \
266-
DEFINE_EVENT(xprtrdma_mr, name, \
266+
DEFINE_EVENT(xprtrdma_mr, xprtrdma_mr_##name, \
267267
TP_PROTO( \
268268
const struct rpcrdma_mr *mr \
269269
), \
@@ -306,7 +306,7 @@ DECLARE_EVENT_CLASS(xprtrdma_cb_event,
306306
** Connection events
307307
**/
308308

309-
TRACE_EVENT(xprtrdma_conn_upcall,
309+
TRACE_EVENT(xprtrdma_cm_event,
310310
TP_PROTO(
311311
const struct rpcrdma_xprt *r_xprt,
312312
struct rdma_cm_event *event
@@ -377,7 +377,7 @@ DEFINE_RXPRT_EVENT(xprtrdma_reinsert);
377377
DEFINE_RXPRT_EVENT(xprtrdma_reconnect);
378378
DEFINE_RXPRT_EVENT(xprtrdma_inject_dsc);
379379

380-
TRACE_EVENT(xprtrdma_qp_error,
380+
TRACE_EVENT(xprtrdma_qp_event,
381381
TP_PROTO(
382382
const struct rpcrdma_xprt *r_xprt,
383383
const struct ib_event *event
@@ -509,7 +509,7 @@ TRACE_EVENT(xprtrdma_post_send,
509509
TP_STRUCT__entry(
510510
__field(const void *, req)
511511
__field(int, num_sge)
512-
__field(bool, signaled)
512+
__field(int, signaled)
513513
__field(int, status)
514514
),
515515

@@ -651,11 +651,11 @@ DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_fastreg);
651651
DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_li);
652652
DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_li_wake);
653653

654-
DEFINE_MR_EVENT(xprtrdma_localinv);
655-
DEFINE_MR_EVENT(xprtrdma_dma_map);
656-
DEFINE_MR_EVENT(xprtrdma_dma_unmap);
657-
DEFINE_MR_EVENT(xprtrdma_remoteinv);
658-
DEFINE_MR_EVENT(xprtrdma_recover_mr);
654+
DEFINE_MR_EVENT(localinv);
655+
DEFINE_MR_EVENT(map);
656+
DEFINE_MR_EVENT(unmap);
657+
DEFINE_MR_EVENT(remoteinv);
658+
DEFINE_MR_EVENT(recycle);
659659

660660
/**
661661
** Reply events

net/sunrpc/xprt.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -834,17 +834,11 @@ void xprt_connect(struct rpc_task *task)
834834

835835
static void xprt_connect_status(struct rpc_task *task)
836836
{
837-
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
838-
839-
if (task->tk_status == 0) {
840-
xprt->stat.connect_count++;
841-
xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start;
837+
switch (task->tk_status) {
838+
case 0:
842839
dprintk("RPC: %5u xprt_connect_status: connection established\n",
843840
task->tk_pid);
844-
return;
845-
}
846-
847-
switch (task->tk_status) {
841+
break;
848842
case -ECONNREFUSED:
849843
case -ECONNRESET:
850844
case -ECONNABORTED:
@@ -861,7 +855,7 @@ static void xprt_connect_status(struct rpc_task *task)
861855
default:
862856
dprintk("RPC: %5u xprt_connect_status: error %d connecting to "
863857
"server %s\n", task->tk_pid, -task->tk_status,
864-
xprt->servername);
858+
task->tk_rqstp->rq_xprt->servername);
865859
task->tk_status = -EIO;
866860
}
867861
}

net/sunrpc/xprtrdma/backchannel.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ static int rpcrdma_bc_setup_reqs(struct rpcrdma_xprt *r_xprt,
5353
rqst->rq_xprt = xprt;
5454
INIT_LIST_HEAD(&rqst->rq_bc_list);
5555
__set_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state);
56-
spin_lock_bh(&xprt->bc_pa_lock);
56+
spin_lock(&xprt->bc_pa_lock);
5757
list_add(&rqst->rq_bc_pa_list, &xprt->bc_pa_list);
58-
spin_unlock_bh(&xprt->bc_pa_lock);
58+
spin_unlock(&xprt->bc_pa_lock);
5959

6060
size = r_xprt->rx_data.inline_rsize;
6161
rb = rpcrdma_alloc_regbuf(size, DMA_TO_DEVICE, GFP_KERNEL);
@@ -230,16 +230,16 @@ void xprt_rdma_bc_destroy(struct rpc_xprt *xprt, unsigned int reqs)
230230
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
231231
struct rpc_rqst *rqst, *tmp;
232232

233-
spin_lock_bh(&xprt->bc_pa_lock);
233+
spin_lock(&xprt->bc_pa_lock);
234234
list_for_each_entry_safe(rqst, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
235235
list_del(&rqst->rq_bc_pa_list);
236-
spin_unlock_bh(&xprt->bc_pa_lock);
236+
spin_unlock(&xprt->bc_pa_lock);
237237

238238
rpcrdma_bc_free_rqst(r_xprt, rqst);
239239

240-
spin_lock_bh(&xprt->bc_pa_lock);
240+
spin_lock(&xprt->bc_pa_lock);
241241
}
242-
spin_unlock_bh(&xprt->bc_pa_lock);
242+
spin_unlock(&xprt->bc_pa_lock);
243243
}
244244

245245
/**
@@ -257,9 +257,9 @@ void xprt_rdma_bc_free_rqst(struct rpc_rqst *rqst)
257257
rpcrdma_recv_buffer_put(req->rl_reply);
258258
req->rl_reply = NULL;
259259

260-
spin_lock_bh(&xprt->bc_pa_lock);
260+
spin_lock(&xprt->bc_pa_lock);
261261
list_add_tail(&rqst->rq_bc_pa_list, &xprt->bc_pa_list);
262-
spin_unlock_bh(&xprt->bc_pa_lock);
262+
spin_unlock(&xprt->bc_pa_lock);
263263
}
264264

265265
/**

net/sunrpc/xprtrdma/fmr_ops.c

Lines changed: 60 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -49,46 +49,7 @@ fmr_is_supported(struct rpcrdma_ia *ia)
4949
return true;
5050
}
5151

52-
static int
53-
fmr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
54-
{
55-
static struct ib_fmr_attr fmr_attr = {
56-
.max_pages = RPCRDMA_MAX_FMR_SGES,
57-
.max_maps = 1,
58-
.page_shift = PAGE_SHIFT
59-
};
60-
61-
mr->fmr.fm_physaddrs = kcalloc(RPCRDMA_MAX_FMR_SGES,
62-
sizeof(u64), GFP_KERNEL);
63-
if (!mr->fmr.fm_physaddrs)
64-
goto out_free;
65-
66-
mr->mr_sg = kcalloc(RPCRDMA_MAX_FMR_SGES,
67-
sizeof(*mr->mr_sg), GFP_KERNEL);
68-
if (!mr->mr_sg)
69-
goto out_free;
70-
71-
sg_init_table(mr->mr_sg, RPCRDMA_MAX_FMR_SGES);
72-
73-
mr->fmr.fm_mr = ib_alloc_fmr(ia->ri_pd, RPCRDMA_FMR_ACCESS_FLAGS,
74-
&fmr_attr);
75-
if (IS_ERR(mr->fmr.fm_mr))
76-
goto out_fmr_err;
77-
78-
INIT_LIST_HEAD(&mr->mr_list);
79-
return 0;
80-
81-
out_fmr_err:
82-
dprintk("RPC: %s: ib_alloc_fmr returned %ld\n", __func__,
83-
PTR_ERR(mr->fmr.fm_mr));
84-
85-
out_free:
86-
kfree(mr->mr_sg);
87-
kfree(mr->fmr.fm_physaddrs);
88-
return -ENOMEM;
89-
}
90-
91-
static int
52+
static void
9253
__fmr_unmap(struct rpcrdma_mr *mr)
9354
{
9455
LIST_HEAD(l);
@@ -97,13 +58,16 @@ __fmr_unmap(struct rpcrdma_mr *mr)
9758
list_add(&mr->fmr.fm_mr->list, &l);
9859
rc = ib_unmap_fmr(&l);
9960
list_del(&mr->fmr.fm_mr->list);
100-
return rc;
61+
if (rc)
62+
pr_err("rpcrdma: final ib_unmap_fmr for %p failed %i\n",
63+
mr, rc);
10164
}
10265

66+
/* Release an MR.
67+
*/
10368
static void
10469
fmr_op_release_mr(struct rpcrdma_mr *mr)
10570
{
106-
LIST_HEAD(unmap_list);
10771
int rc;
10872

10973
kfree(mr->fmr.fm_physaddrs);
@@ -112,10 +76,7 @@ fmr_op_release_mr(struct rpcrdma_mr *mr)
11276
/* In case this one was left mapped, try to unmap it
11377
* to prevent dealloc_fmr from failing with EBUSY
11478
*/
115-
rc = __fmr_unmap(mr);
116-
if (rc)
117-
pr_err("rpcrdma: final ib_unmap_fmr for %p failed %i\n",
118-
mr, rc);
79+
__fmr_unmap(mr);
11980

12081
rc = ib_dealloc_fmr(mr->fmr.fm_mr);
12182
if (rc)
@@ -125,40 +86,68 @@ fmr_op_release_mr(struct rpcrdma_mr *mr)
12586
kfree(mr);
12687
}
12788

128-
/* Reset of a single FMR.
89+
/* MRs are dynamically allocated, so simply clean up and release the MR.
90+
* A replacement MR will subsequently be allocated on demand.
12991
*/
13092
static void
131-
fmr_op_recover_mr(struct rpcrdma_mr *mr)
93+
fmr_mr_recycle_worker(struct work_struct *work)
13294
{
95+
struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr, mr_recycle);
13396
struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
134-
int rc;
13597

136-
/* ORDER: invalidate first */
137-
rc = __fmr_unmap(mr);
138-
if (rc)
139-
goto out_release;
140-
141-
/* ORDER: then DMA unmap */
142-
rpcrdma_mr_unmap_and_put(mr);
98+
trace_xprtrdma_mr_recycle(mr);
14399

144-
r_xprt->rx_stats.mrs_recovered++;
145-
return;
146-
147-
out_release:
148-
pr_err("rpcrdma: FMR reset failed (%d), %p released\n", rc, mr);
149-
r_xprt->rx_stats.mrs_orphaned++;
150-
151-
trace_xprtrdma_dma_unmap(mr);
100+
trace_xprtrdma_mr_unmap(mr);
152101
ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
153102
mr->mr_sg, mr->mr_nents, mr->mr_dir);
154103

155104
spin_lock(&r_xprt->rx_buf.rb_mrlock);
156105
list_del(&mr->mr_all);
106+
r_xprt->rx_stats.mrs_recycled++;
157107
spin_unlock(&r_xprt->rx_buf.rb_mrlock);
158-
159108
fmr_op_release_mr(mr);
160109
}
161110

111+
static int
112+
fmr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr)
113+
{
114+
static struct ib_fmr_attr fmr_attr = {
115+
.max_pages = RPCRDMA_MAX_FMR_SGES,
116+
.max_maps = 1,
117+
.page_shift = PAGE_SHIFT
118+
};
119+
120+
mr->fmr.fm_physaddrs = kcalloc(RPCRDMA_MAX_FMR_SGES,
121+
sizeof(u64), GFP_KERNEL);
122+
if (!mr->fmr.fm_physaddrs)
123+
goto out_free;
124+
125+
mr->mr_sg = kcalloc(RPCRDMA_MAX_FMR_SGES,
126+
sizeof(*mr->mr_sg), GFP_KERNEL);
127+
if (!mr->mr_sg)
128+
goto out_free;
129+
130+
sg_init_table(mr->mr_sg, RPCRDMA_MAX_FMR_SGES);
131+
132+
mr->fmr.fm_mr = ib_alloc_fmr(ia->ri_pd, RPCRDMA_FMR_ACCESS_FLAGS,
133+
&fmr_attr);
134+
if (IS_ERR(mr->fmr.fm_mr))
135+
goto out_fmr_err;
136+
137+
INIT_LIST_HEAD(&mr->mr_list);
138+
INIT_WORK(&mr->mr_recycle, fmr_mr_recycle_worker);
139+
return 0;
140+
141+
out_fmr_err:
142+
dprintk("RPC: %s: ib_alloc_fmr returned %ld\n", __func__,
143+
PTR_ERR(mr->fmr.fm_mr));
144+
145+
out_free:
146+
kfree(mr->mr_sg);
147+
kfree(mr->fmr.fm_physaddrs);
148+
return -ENOMEM;
149+
}
150+
162151
/* On success, sets:
163152
* ep->rep_attr.cap.max_send_wr
164153
* ep->rep_attr.cap.max_recv_wr
@@ -187,6 +176,7 @@ fmr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
187176

188177
ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS /
189178
RPCRDMA_MAX_FMR_SGES);
179+
ia->ri_max_segs += 2; /* segments for head and tail buffers */
190180
return 0;
191181
}
192182

@@ -244,7 +234,7 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
244234
mr->mr_sg, i, mr->mr_dir);
245235
if (!mr->mr_nents)
246236
goto out_dmamap_err;
247-
trace_xprtrdma_dma_map(mr);
237+
trace_xprtrdma_mr_map(mr);
248238

249239
for (i = 0, dma_pages = mr->fmr.fm_physaddrs; i < mr->mr_nents; i++)
250240
dma_pages[i] = sg_dma_address(&mr->mr_sg[i]);
@@ -305,13 +295,13 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
305295
list_for_each_entry(mr, mrs, mr_list) {
306296
dprintk("RPC: %s: unmapping fmr %p\n",
307297
__func__, &mr->fmr);
308-
trace_xprtrdma_localinv(mr);
298+
trace_xprtrdma_mr_localinv(mr);
309299
list_add_tail(&mr->fmr.fm_mr->list, &unmap_list);
310300
}
311301
r_xprt->rx_stats.local_inv_needed++;
312302
rc = ib_unmap_fmr(&unmap_list);
313303
if (rc)
314-
goto out_reset;
304+
goto out_release;
315305

316306
/* ORDER: Now DMA unmap all of the req's MRs, and return
317307
* them to the free MW list.
@@ -324,21 +314,20 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mrs)
324314

325315
return;
326316

327-
out_reset:
317+
out_release:
328318
pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc);
329319

330320
while (!list_empty(mrs)) {
331321
mr = rpcrdma_mr_pop(mrs);
332322
list_del(&mr->fmr.fm_mr->list);
333-
fmr_op_recover_mr(mr);
323+
rpcrdma_mr_recycle(mr);
334324
}
335325
}
336326

337327
const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
338328
.ro_map = fmr_op_map,
339329
.ro_send = fmr_op_send,
340330
.ro_unmap_sync = fmr_op_unmap_sync,
341-
.ro_recover_mr = fmr_op_recover_mr,
342331
.ro_open = fmr_op_open,
343332
.ro_maxpages = fmr_op_maxpages,
344333
.ro_init_mr = fmr_op_init_mr,

0 commit comments

Comments
 (0)