Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+308 -357
+9 -9
include/trace/events/rpcrdma.h
··· 263 263 ); 264 264 265 265 #define DEFINE_MR_EVENT(name) \ 266 - DEFINE_EVENT(xprtrdma_mr, name, \ 266 + DEFINE_EVENT(xprtrdma_mr, xprtrdma_mr_##name, \ 267 267 TP_PROTO( \ 268 268 const struct rpcrdma_mr *mr \ 269 269 ), \ ··· 306 306 ** Connection events 307 307 **/ 308 308 309 - TRACE_EVENT(xprtrdma_conn_upcall, 309 + TRACE_EVENT(xprtrdma_cm_event, 310 310 TP_PROTO( 311 311 const struct rpcrdma_xprt *r_xprt, 312 312 struct rdma_cm_event *event ··· 377 377 DEFINE_RXPRT_EVENT(xprtrdma_reconnect); 378 378 DEFINE_RXPRT_EVENT(xprtrdma_inject_dsc); 379 379 380 - TRACE_EVENT(xprtrdma_qp_error, 380 + TRACE_EVENT(xprtrdma_qp_event, 381 381 TP_PROTO( 382 382 const struct rpcrdma_xprt *r_xprt, 383 383 const struct ib_event *event ··· 509 509 TP_STRUCT__entry( 510 510 __field(const void *, req) 511 511 __field(int, num_sge) 512 - __field(bool, signaled) 512 + __field(int, signaled) 513 513 __field(int, status) 514 514 ), 515 515 ··· 651 651 DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_li); 652 652 DEFINE_FRWR_DONE_EVENT(xprtrdma_wc_li_wake); 653 653 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); 659 659 660 660 /** 661 661 ** Reply events
+4 -10
net/sunrpc/xprt.c
··· 834 834 835 835 static void xprt_connect_status(struct rpc_task *task) 836 836 { 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: 842 839 dprintk("RPC: %5u xprt_connect_status: connection established\n", 843 840 task->tk_pid); 844 - return; 845 - } 846 - 847 - switch (task->tk_status) { 841 + break; 848 842 case -ECONNREFUSED: 849 843 case -ECONNRESET: 850 844 case -ECONNABORTED: ··· 855 861 default: 856 862 dprintk("RPC: %5u xprt_connect_status: error %d connecting to " 857 863 "server %s\n", task->tk_pid, -task->tk_status, 858 - xprt->servername); 864 + task->tk_rqstp->rq_xprt->servername); 859 865 task->tk_status = -EIO; 860 866 } 861 867 }
+8 -8
net/sunrpc/xprtrdma/backchannel.c
··· 53 53 rqst->rq_xprt = xprt; 54 54 INIT_LIST_HEAD(&rqst->rq_bc_list); 55 55 __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); 57 57 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); 59 59 60 60 size = r_xprt->rx_data.inline_rsize; 61 61 rb = rpcrdma_alloc_regbuf(size, DMA_TO_DEVICE, GFP_KERNEL); ··· 230 230 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); 231 231 struct rpc_rqst *rqst, *tmp; 232 232 233 - spin_lock_bh(&xprt->bc_pa_lock); 233 + spin_lock(&xprt->bc_pa_lock); 234 234 list_for_each_entry_safe(rqst, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { 235 235 list_del(&rqst->rq_bc_pa_list); 236 - spin_unlock_bh(&xprt->bc_pa_lock); 236 + spin_unlock(&xprt->bc_pa_lock); 237 237 238 238 rpcrdma_bc_free_rqst(r_xprt, rqst); 239 239 240 - spin_lock_bh(&xprt->bc_pa_lock); 240 + spin_lock(&xprt->bc_pa_lock); 241 241 } 242 - spin_unlock_bh(&xprt->bc_pa_lock); 242 + spin_unlock(&xprt->bc_pa_lock); 243 243 } 244 244 245 245 /** ··· 257 257 rpcrdma_recv_buffer_put(req->rl_reply); 258 258 req->rl_reply = NULL; 259 259 260 - spin_lock_bh(&xprt->bc_pa_lock); 260 + spin_lock(&xprt->bc_pa_lock); 261 261 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); 263 263 } 264 264 265 265 /**
+66 -77
net/sunrpc/xprtrdma/fmr_ops.c
··· 49 49 return true; 50 50 } 51 51 52 + static void 53 + __fmr_unmap(struct rpcrdma_mr *mr) 54 + { 55 + LIST_HEAD(l); 56 + int rc; 57 + 58 + list_add(&mr->fmr.fm_mr->list, &l); 59 + rc = ib_unmap_fmr(&l); 60 + list_del(&mr->fmr.fm_mr->list); 61 + if (rc) 62 + pr_err("rpcrdma: final ib_unmap_fmr for %p failed %i\n", 63 + mr, rc); 64 + } 65 + 66 + /* Release an MR. 67 + */ 68 + static void 69 + fmr_op_release_mr(struct rpcrdma_mr *mr) 70 + { 71 + int rc; 72 + 73 + kfree(mr->fmr.fm_physaddrs); 74 + kfree(mr->mr_sg); 75 + 76 + /* In case this one was left mapped, try to unmap it 77 + * to prevent dealloc_fmr from failing with EBUSY 78 + */ 79 + __fmr_unmap(mr); 80 + 81 + rc = ib_dealloc_fmr(mr->fmr.fm_mr); 82 + if (rc) 83 + pr_err("rpcrdma: final ib_dealloc_fmr for %p returned %i\n", 84 + mr, rc); 85 + 86 + kfree(mr); 87 + } 88 + 89 + /* MRs are dynamically allocated, so simply clean up and release the MR. 90 + * A replacement MR will subsequently be allocated on demand. 91 + */ 92 + static void 93 + fmr_mr_recycle_worker(struct work_struct *work) 94 + { 95 + struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr, mr_recycle); 96 + struct rpcrdma_xprt *r_xprt = mr->mr_xprt; 97 + 98 + trace_xprtrdma_mr_recycle(mr); 99 + 100 + trace_xprtrdma_mr_unmap(mr); 101 + ib_dma_unmap_sg(r_xprt->rx_ia.ri_device, 102 + mr->mr_sg, mr->mr_nents, mr->mr_dir); 103 + 104 + spin_lock(&r_xprt->rx_buf.rb_mrlock); 105 + list_del(&mr->mr_all); 106 + r_xprt->rx_stats.mrs_recycled++; 107 + spin_unlock(&r_xprt->rx_buf.rb_mrlock); 108 + fmr_op_release_mr(mr); 109 + } 110 + 52 111 static int 53 112 fmr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) 54 113 { ··· 135 76 goto out_fmr_err; 136 77 137 78 INIT_LIST_HEAD(&mr->mr_list); 79 + INIT_WORK(&mr->mr_recycle, fmr_mr_recycle_worker); 138 80 return 0; 139 81 140 82 out_fmr_err: ··· 146 86 kfree(mr->mr_sg); 147 87 kfree(mr->fmr.fm_physaddrs); 148 88 return -ENOMEM; 149 - } 150 - 151 - static int 152 - __fmr_unmap(struct rpcrdma_mr *mr) 153 - { 154 - LIST_HEAD(l); 155 - int rc; 156 - 157 - list_add(&mr->fmr.fm_mr->list, &l); 158 - rc = ib_unmap_fmr(&l); 159 - list_del(&mr->fmr.fm_mr->list); 160 - return rc; 161 - } 162 - 163 - static void 164 - fmr_op_release_mr(struct rpcrdma_mr *mr) 165 - { 166 - LIST_HEAD(unmap_list); 167 - int rc; 168 - 169 - kfree(mr->fmr.fm_physaddrs); 170 - kfree(mr->mr_sg); 171 - 172 - /* In case this one was left mapped, try to unmap it 173 - * to prevent dealloc_fmr from failing with EBUSY 174 - */ 175 - rc = __fmr_unmap(mr); 176 - if (rc) 177 - pr_err("rpcrdma: final ib_unmap_fmr for %p failed %i\n", 178 - mr, rc); 179 - 180 - rc = ib_dealloc_fmr(mr->fmr.fm_mr); 181 - if (rc) 182 - pr_err("rpcrdma: final ib_dealloc_fmr for %p returned %i\n", 183 - mr, rc); 184 - 185 - kfree(mr); 186 - } 187 - 188 - /* Reset of a single FMR. 189 - */ 190 - static void 191 - fmr_op_recover_mr(struct rpcrdma_mr *mr) 192 - { 193 - struct rpcrdma_xprt *r_xprt = mr->mr_xprt; 194 - int rc; 195 - 196 - /* ORDER: invalidate first */ 197 - rc = __fmr_unmap(mr); 198 - if (rc) 199 - goto out_release; 200 - 201 - /* ORDER: then DMA unmap */ 202 - rpcrdma_mr_unmap_and_put(mr); 203 - 204 - r_xprt->rx_stats.mrs_recovered++; 205 - return; 206 - 207 - out_release: 208 - pr_err("rpcrdma: FMR reset failed (%d), %p released\n", rc, mr); 209 - r_xprt->rx_stats.mrs_orphaned++; 210 - 211 - trace_xprtrdma_dma_unmap(mr); 212 - ib_dma_unmap_sg(r_xprt->rx_ia.ri_device, 213 - mr->mr_sg, mr->mr_nents, mr->mr_dir); 214 - 215 - spin_lock(&r_xprt->rx_buf.rb_mrlock); 216 - list_del(&mr->mr_all); 217 - spin_unlock(&r_xprt->rx_buf.rb_mrlock); 218 - 219 - fmr_op_release_mr(mr); 220 89 } 221 90 222 91 /* On success, sets: ··· 176 187 177 188 ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS / 178 189 RPCRDMA_MAX_FMR_SGES); 190 + ia->ri_max_segs += 2; /* segments for head and tail buffers */ 179 191 return 0; 180 192 } 181 193 ··· 234 244 mr->mr_sg, i, mr->mr_dir); 235 245 if (!mr->mr_nents) 236 246 goto out_dmamap_err; 237 - trace_xprtrdma_dma_map(mr); 247 + trace_xprtrdma_mr_map(mr); 238 248 239 249 for (i = 0, dma_pages = mr->fmr.fm_physaddrs; i < mr->mr_nents; i++) 240 250 dma_pages[i] = sg_dma_address(&mr->mr_sg[i]); ··· 295 305 list_for_each_entry(mr, mrs, mr_list) { 296 306 dprintk("RPC: %s: unmapping fmr %p\n", 297 307 __func__, &mr->fmr); 298 - trace_xprtrdma_localinv(mr); 308 + trace_xprtrdma_mr_localinv(mr); 299 309 list_add_tail(&mr->fmr.fm_mr->list, &unmap_list); 300 310 } 301 311 r_xprt->rx_stats.local_inv_needed++; 302 312 rc = ib_unmap_fmr(&unmap_list); 303 313 if (rc) 304 - goto out_reset; 314 + goto out_release; 305 315 306 316 /* ORDER: Now DMA unmap all of the req's MRs, and return 307 317 * them to the free MW list. ··· 314 324 315 325 return; 316 326 317 - out_reset: 327 + out_release: 318 328 pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc); 319 329 320 330 while (!list_empty(mrs)) { 321 331 mr = rpcrdma_mr_pop(mrs); 322 332 list_del(&mr->fmr.fm_mr->list); 323 - fmr_op_recover_mr(mr); 333 + rpcrdma_mr_recycle(mr); 324 334 } 325 335 } 326 336 ··· 328 338 .ro_map = fmr_op_map, 329 339 .ro_send = fmr_op_send, 330 340 .ro_unmap_sync = fmr_op_unmap_sync, 331 - .ro_recover_mr = fmr_op_recover_mr, 332 341 .ro_open = fmr_op_open, 333 342 .ro_maxpages = fmr_op_maxpages, 334 343 .ro_init_mr = fmr_op_init_mr,
+51 -86
net/sunrpc/xprtrdma/frwr_ops.c
··· 97 97 return false; 98 98 } 99 99 100 + static void 101 + frwr_op_release_mr(struct rpcrdma_mr *mr) 102 + { 103 + int rc; 104 + 105 + rc = ib_dereg_mr(mr->frwr.fr_mr); 106 + if (rc) 107 + pr_err("rpcrdma: final ib_dereg_mr for %p returned %i\n", 108 + mr, rc); 109 + kfree(mr->mr_sg); 110 + kfree(mr); 111 + } 112 + 113 + /* MRs are dynamically allocated, so simply clean up and release the MR. 114 + * A replacement MR will subsequently be allocated on demand. 115 + */ 116 + static void 117 + frwr_mr_recycle_worker(struct work_struct *work) 118 + { 119 + struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr, mr_recycle); 120 + enum rpcrdma_frwr_state state = mr->frwr.fr_state; 121 + struct rpcrdma_xprt *r_xprt = mr->mr_xprt; 122 + 123 + trace_xprtrdma_mr_recycle(mr); 124 + 125 + if (state != FRWR_FLUSHED_LI) { 126 + trace_xprtrdma_mr_unmap(mr); 127 + ib_dma_unmap_sg(r_xprt->rx_ia.ri_device, 128 + mr->mr_sg, mr->mr_nents, mr->mr_dir); 129 + } 130 + 131 + spin_lock(&r_xprt->rx_buf.rb_mrlock); 132 + list_del(&mr->mr_all); 133 + r_xprt->rx_stats.mrs_recycled++; 134 + spin_unlock(&r_xprt->rx_buf.rb_mrlock); 135 + frwr_op_release_mr(mr); 136 + } 137 + 100 138 static int 101 139 frwr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) 102 140 { ··· 151 113 goto out_list_err; 152 114 153 115 INIT_LIST_HEAD(&mr->mr_list); 116 + INIT_WORK(&mr->mr_recycle, frwr_mr_recycle_worker); 154 117 sg_init_table(mr->mr_sg, depth); 155 118 init_completion(&frwr->fr_linv_done); 156 119 return 0; ··· 168 129 __func__); 169 130 ib_dereg_mr(frwr->fr_mr); 170 131 return rc; 171 - } 172 - 173 - static void 174 - frwr_op_release_mr(struct rpcrdma_mr *mr) 175 - { 176 - int rc; 177 - 178 - rc = ib_dereg_mr(mr->frwr.fr_mr); 179 - if (rc) 180 - pr_err("rpcrdma: final ib_dereg_mr for %p returned %i\n", 181 - mr, rc); 182 - kfree(mr->mr_sg); 183 - kfree(mr); 184 - } 185 - 186 - static int 187 - __frwr_mr_reset(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) 188 - { 189 - struct rpcrdma_frwr *frwr = &mr->frwr; 190 - int rc; 191 - 192 - rc = ib_dereg_mr(frwr->fr_mr); 193 - if (rc) { 194 - pr_warn("rpcrdma: ib_dereg_mr status %d, frwr %p orphaned\n", 195 - rc, mr); 196 - return rc; 197 - } 198 - 199 - frwr->fr_mr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, 200 - ia->ri_max_frwr_depth); 201 - if (IS_ERR(frwr->fr_mr)) { 202 - pr_warn("rpcrdma: ib_alloc_mr status %ld, frwr %p orphaned\n", 203 - PTR_ERR(frwr->fr_mr), mr); 204 - return PTR_ERR(frwr->fr_mr); 205 - } 206 - 207 - dprintk("RPC: %s: recovered FRWR %p\n", __func__, frwr); 208 - frwr->fr_state = FRWR_IS_INVALID; 209 - return 0; 210 - } 211 - 212 - /* Reset of a single FRWR. Generate a fresh rkey by replacing the MR. 213 - */ 214 - static void 215 - frwr_op_recover_mr(struct rpcrdma_mr *mr) 216 - { 217 - enum rpcrdma_frwr_state state = mr->frwr.fr_state; 218 - struct rpcrdma_xprt *r_xprt = mr->mr_xprt; 219 - struct rpcrdma_ia *ia = &r_xprt->rx_ia; 220 - int rc; 221 - 222 - rc = __frwr_mr_reset(ia, mr); 223 - if (state != FRWR_FLUSHED_LI) { 224 - trace_xprtrdma_dma_unmap(mr); 225 - ib_dma_unmap_sg(ia->ri_device, 226 - mr->mr_sg, mr->mr_nents, mr->mr_dir); 227 - } 228 - if (rc) 229 - goto out_release; 230 - 231 - rpcrdma_mr_put(mr); 232 - r_xprt->rx_stats.mrs_recovered++; 233 - return; 234 - 235 - out_release: 236 - pr_err("rpcrdma: FRWR reset failed %d, %p released\n", rc, mr); 237 - r_xprt->rx_stats.mrs_orphaned++; 238 - 239 - spin_lock(&r_xprt->rx_buf.rb_mrlock); 240 - list_del(&mr->mr_all); 241 - spin_unlock(&r_xprt->rx_buf.rb_mrlock); 242 - 243 - frwr_op_release_mr(mr); 244 132 } 245 133 246 134 /* On success, sets: ··· 242 276 243 277 ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS / 244 278 ia->ri_max_frwr_depth); 279 + ia->ri_max_segs += 2; /* segments for head and tail buffers */ 245 280 return 0; 246 281 } 247 282 ··· 351 384 mr = NULL; 352 385 do { 353 386 if (mr) 354 - rpcrdma_mr_defer_recovery(mr); 387 + rpcrdma_mr_recycle(mr); 355 388 mr = rpcrdma_mr_get(r_xprt); 356 389 if (!mr) 357 390 return ERR_PTR(-EAGAIN); ··· 384 417 mr->mr_nents = ib_dma_map_sg(ia->ri_device, mr->mr_sg, i, mr->mr_dir); 385 418 if (!mr->mr_nents) 386 419 goto out_dmamap_err; 387 - trace_xprtrdma_dma_map(mr); 420 + trace_xprtrdma_mr_map(mr); 388 421 389 422 ibmr = frwr->fr_mr; 390 423 n = ib_map_mr_sg(ibmr, mr->mr_sg, mr->mr_nents, NULL, PAGE_SIZE); ··· 418 451 out_mapmr_err: 419 452 pr_err("rpcrdma: failed to map mr %p (%d/%d)\n", 420 453 frwr->fr_mr, n, mr->mr_nents); 421 - rpcrdma_mr_defer_recovery(mr); 454 + rpcrdma_mr_recycle(mr); 422 455 return ERR_PTR(-EIO); 423 456 } 424 457 ··· 466 499 list_for_each_entry(mr, mrs, mr_list) 467 500 if (mr->mr_handle == rep->rr_inv_rkey) { 468 501 list_del_init(&mr->mr_list); 469 - trace_xprtrdma_remoteinv(mr); 502 + trace_xprtrdma_mr_remoteinv(mr); 470 503 mr->frwr.fr_state = FRWR_IS_INVALID; 471 504 rpcrdma_mr_unmap_and_put(mr); 472 505 break; /* only one invalidated MR per RPC */ ··· 503 536 mr->frwr.fr_state = FRWR_IS_INVALID; 504 537 505 538 frwr = &mr->frwr; 506 - trace_xprtrdma_localinv(mr); 539 + trace_xprtrdma_mr_localinv(mr); 507 540 508 541 frwr->fr_cqe.done = frwr_wc_localinv; 509 542 last = &frwr->fr_invwr; ··· 537 570 if (bad_wr != first) 538 571 wait_for_completion(&frwr->fr_linv_done); 539 572 if (rc) 540 - goto reset_mrs; 573 + goto out_release; 541 574 542 575 /* ORDER: Now DMA unmap all of the MRs, and return 543 576 * them to the free MR list. ··· 549 582 } 550 583 return; 551 584 552 - reset_mrs: 585 + out_release: 553 586 pr_err("rpcrdma: FRWR invalidate ib_post_send returned %i\n", rc); 554 587 555 - /* Find and reset the MRs in the LOCAL_INV WRs that did not 588 + /* Unmap and release the MRs in the LOCAL_INV WRs that did not 556 589 * get posted. 557 590 */ 558 591 while (bad_wr) { 559 592 frwr = container_of(bad_wr, struct rpcrdma_frwr, 560 593 fr_invwr); 561 594 mr = container_of(frwr, struct rpcrdma_mr, frwr); 562 - 563 - __frwr_mr_reset(ia, mr); 564 - 565 595 bad_wr = bad_wr->next; 596 + 597 + list_del(&mr->mr_list); 598 + frwr_op_release_mr(mr); 566 599 } 567 - goto unmap; 568 600 } 569 601 570 602 const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = { ··· 571 605 .ro_send = frwr_op_send, 572 606 .ro_reminv = frwr_op_reminv, 573 607 .ro_unmap_sync = frwr_op_unmap_sync, 574 - .ro_recover_mr = frwr_op_recover_mr, 575 608 .ro_open = frwr_op_open, 576 609 .ro_maxpages = frwr_op_maxpages, 577 610 .ro_init_mr = frwr_op_init_mr,
+8 -12
net/sunrpc/xprtrdma/rpc_rdma.c
··· 71 71 size = RPCRDMA_HDRLEN_MIN; 72 72 73 73 /* Maximum Read list size */ 74 - maxsegs += 2; /* segment for head and tail buffers */ 75 74 size = maxsegs * rpcrdma_readchunk_maxsz * sizeof(__be32); 76 75 77 76 /* Minimal Read chunk size */ ··· 96 97 size = RPCRDMA_HDRLEN_MIN; 97 98 98 99 /* Maximum Write list size */ 99 - maxsegs += 2; /* segment for head and tail buffers */ 100 100 size = sizeof(__be32); /* segment count */ 101 101 size += maxsegs * rpcrdma_segment_maxsz * sizeof(__be32); 102 102 size += sizeof(__be32); /* list discriminator */ ··· 803 805 struct rpcrdma_mr *mr; 804 806 805 807 mr = rpcrdma_mr_pop(&req->rl_registered); 806 - rpcrdma_mr_defer_recovery(mr); 808 + rpcrdma_mr_recycle(mr); 807 809 } 808 810 809 811 /* This implementation supports the following combinations ··· 1214 1216 struct rpcrdma_xprt *r_xprt = rep->rr_rxprt; 1215 1217 struct rpc_xprt *xprt = &r_xprt->rx_xprt; 1216 1218 struct rpc_rqst *rqst = rep->rr_rqst; 1217 - unsigned long cwnd; 1218 1219 int status; 1219 1220 1220 1221 xprt->reestablish_timeout = 0; ··· 1236 1239 1237 1240 out: 1238 1241 spin_lock(&xprt->queue_lock); 1239 - cwnd = xprt->cwnd; 1240 - xprt->cwnd = r_xprt->rx_buf.rb_credits << RPC_CWNDSHIFT; 1241 - if (xprt->cwnd > cwnd) 1242 - xprt_release_rqst_cong(rqst->rq_task); 1243 - 1244 1242 xprt_complete_rqst(rqst->rq_task, status); 1245 1243 xprt_unpin_rqst(rqst); 1246 1244 spin_unlock(&xprt->queue_lock); ··· 1342 1350 if (!rqst) 1343 1351 goto out_norqst; 1344 1352 xprt_pin_rqst(rqst); 1353 + spin_unlock(&xprt->queue_lock); 1345 1354 1346 1355 if (credits == 0) 1347 1356 credits = 1; /* don't deadlock */ 1348 1357 else if (credits > buf->rb_max_requests) 1349 1358 credits = buf->rb_max_requests; 1350 - buf->rb_credits = credits; 1351 - 1352 - spin_unlock(&xprt->queue_lock); 1359 + if (buf->rb_credits != credits) { 1360 + spin_lock_bh(&xprt->transport_lock); 1361 + buf->rb_credits = credits; 1362 + xprt->cwnd = credits << RPC_CWNDSHIFT; 1363 + spin_unlock_bh(&xprt->transport_lock); 1364 + } 1353 1365 1354 1366 req = rpcr_to_rdmar(rqst); 1355 1367 req->rl_reply = rep;
+1
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
··· 242 242 xprt_rdma_bc_close(struct rpc_xprt *xprt) 243 243 { 244 244 dprintk("svcrdma: %s: xprt %p\n", __func__, xprt); 245 + xprt->cwnd = RPC_CWNDSHIFT; 245 246 } 246 247 247 248 static void
+52 -58
net/sunrpc/xprtrdma/transport.c
··· 225 225 } 226 226 } 227 227 228 - void 229 - rpcrdma_conn_func(struct rpcrdma_ep *ep) 230 - { 231 - schedule_delayed_work(&ep->rep_connect_worker, 0); 232 - } 233 - 234 - void 235 - rpcrdma_connect_worker(struct work_struct *work) 236 - { 237 - struct rpcrdma_ep *ep = 238 - container_of(work, struct rpcrdma_ep, rep_connect_worker.work); 239 - struct rpcrdma_xprt *r_xprt = 240 - container_of(ep, struct rpcrdma_xprt, rx_ep); 241 - struct rpc_xprt *xprt = &r_xprt->rx_xprt; 242 - 243 - spin_lock_bh(&xprt->transport_lock); 244 - if (ep->rep_connected > 0) { 245 - if (!xprt_test_and_set_connected(xprt)) 246 - xprt_wake_pending_tasks(xprt, 0); 247 - } else { 248 - if (xprt_test_and_clear_connected(xprt)) 249 - xprt_wake_pending_tasks(xprt, -ENOTCONN); 250 - } 251 - spin_unlock_bh(&xprt->transport_lock); 252 - } 253 - 228 + /** 229 + * xprt_rdma_connect_worker - establish connection in the background 230 + * @work: worker thread context 231 + * 232 + * Requester holds the xprt's send lock to prevent activity on this 233 + * transport while a fresh connection is being established. RPC tasks 234 + * sleep on the xprt's pending queue waiting for connect to complete. 235 + */ 254 236 static void 255 237 xprt_rdma_connect_worker(struct work_struct *work) 256 238 { 257 239 struct rpcrdma_xprt *r_xprt = container_of(work, struct rpcrdma_xprt, 258 240 rx_connect_worker.work); 259 241 struct rpc_xprt *xprt = &r_xprt->rx_xprt; 260 - int rc = 0; 261 - 262 - xprt_clear_connected(xprt); 242 + int rc; 263 243 264 244 rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia); 265 - if (rc) 266 - xprt_wake_pending_tasks(xprt, rc); 267 - 268 245 xprt_clear_connecting(xprt); 246 + if (r_xprt->rx_ep.rep_connected > 0) { 247 + if (!xprt_test_and_set_connected(xprt)) { 248 + xprt->stat.connect_count++; 249 + xprt->stat.connect_time += (long)jiffies - 250 + xprt->stat.connect_start; 251 + xprt_wake_pending_tasks(xprt, -EAGAIN); 252 + } 253 + } else { 254 + if (xprt_test_and_clear_connected(xprt)) 255 + xprt_wake_pending_tasks(xprt, rc); 256 + } 269 257 } 270 258 259 + /** 260 + * xprt_rdma_inject_disconnect - inject a connection fault 261 + * @xprt: transport context 262 + * 263 + * If @xprt is connected, disconnect it to simulate spurious connection 264 + * loss. 265 + */ 271 266 static void 272 267 xprt_rdma_inject_disconnect(struct rpc_xprt *xprt) 273 268 { 274 - struct rpcrdma_xprt *r_xprt = container_of(xprt, struct rpcrdma_xprt, 275 - rx_xprt); 269 + struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); 276 270 277 271 trace_xprtrdma_inject_dsc(r_xprt); 278 272 rdma_disconnect(r_xprt->rx_ia.ri_id); 279 273 } 280 274 281 - /* 282 - * xprt_rdma_destroy 275 + /** 276 + * xprt_rdma_destroy - Full tear down of transport 277 + * @xprt: doomed transport context 283 278 * 284 - * Destroy the xprt. 285 - * Free all memory associated with the object, including its own. 286 - * NOTE: none of the *destroy methods free memory for their top-level 287 - * objects, even though they may have allocated it (they do free 288 - * private memory). It's up to the caller to handle it. In this 289 - * case (RDMA transport), all structure memory is inlined with the 290 - * struct rpcrdma_xprt. 279 + * Caller guarantees there will be no more calls to us with 280 + * this @xprt. 291 281 */ 292 282 static void 293 283 xprt_rdma_destroy(struct rpc_xprt *xprt) ··· 287 297 trace_xprtrdma_destroy(r_xprt); 288 298 289 299 cancel_delayed_work_sync(&r_xprt->rx_connect_worker); 290 - 291 - xprt_clear_connected(xprt); 292 300 293 301 rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia); 294 302 rpcrdma_buffer_destroy(&r_xprt->rx_buf); ··· 430 442 } 431 443 432 444 /** 433 - * xprt_rdma_close - Close down RDMA connection 434 - * @xprt: generic transport to be closed 445 + * xprt_rdma_close - close a transport connection 446 + * @xprt: transport context 435 447 * 436 - * Called during transport shutdown reconnect, or device 437 - * removal. Caller holds the transport's write lock. 448 + * Called during transport shutdown, reconnect, or device removal. 449 + * Caller holds @xprt's send lock to prevent activity on this 450 + * transport while the connection is torn down. 438 451 */ 439 452 static void 440 453 xprt_rdma_close(struct rpc_xprt *xprt) ··· 457 468 xprt->reestablish_timeout = 0; 458 469 xprt_disconnect_done(xprt); 459 470 rpcrdma_ep_disconnect(ep, ia); 471 + 472 + /* Prepare @xprt for the next connection by reinitializing 473 + * its credit grant to one (see RFC 8166, Section 3.3.3). 474 + */ 475 + r_xprt->rx_buf.rb_credits = 1; 476 + xprt->cwnd = RPC_CWNDSHIFT; 460 477 } 461 478 462 479 /** ··· 514 519 xprt_force_disconnect(xprt); 515 520 } 516 521 522 + /** 523 + * xprt_rdma_connect - try to establish a transport connection 524 + * @xprt: transport state 525 + * @task: RPC scheduler context 526 + * 527 + */ 517 528 static void 518 529 xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task) 519 530 { ··· 639 638 * 0: Success; rq_buffer points to RPC buffer to use 640 639 * ENOMEM: Out of memory, call again later 641 640 * EIO: A permanent error occurred, do not retry 642 - * 643 - * The RDMA allocate/free functions need the task structure as a place 644 - * to hide the struct rpcrdma_req, which is necessary for the actual 645 - * send/recv sequence. 646 - * 647 - * xprt_rdma_allocate provides buffers that are already mapped for 648 - * DMA, and a local DMA lkey is provided for each. 649 641 */ 650 642 static int 651 643 xprt_rdma_allocate(struct rpc_task *task) ··· 762 768 0, /* need a local port? */ 763 769 xprt->stat.bind_count, 764 770 xprt->stat.connect_count, 765 - xprt->stat.connect_time, 771 + xprt->stat.connect_time / HZ, 766 772 idle_time, 767 773 xprt->stat.sends, 768 774 xprt->stat.recvs, ··· 782 788 r_xprt->rx_stats.bad_reply_count, 783 789 r_xprt->rx_stats.nomsg_call_count); 784 790 seq_printf(seq, "%lu %lu %lu %lu %lu %lu\n", 785 - r_xprt->rx_stats.mrs_recovered, 791 + r_xprt->rx_stats.mrs_recycled, 786 792 r_xprt->rx_stats.mrs_orphaned, 787 793 r_xprt->rx_stats.mrs_allocated, 788 794 r_xprt->rx_stats.local_inv_needed,
+92 -86
net/sunrpc/xprtrdma/verbs.c
··· 108 108 } 109 109 } 110 110 111 + /** 112 + * rpcrdma_disconnect_worker - Force a disconnect 113 + * @work: endpoint to be disconnected 114 + * 115 + * Provider callbacks can possibly run in an IRQ context. This function 116 + * is invoked in a worker thread to guarantee that disconnect wake-up 117 + * calls are always done in process context. 118 + */ 111 119 static void 112 - rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context) 120 + rpcrdma_disconnect_worker(struct work_struct *work) 121 + { 122 + struct rpcrdma_ep *ep = container_of(work, struct rpcrdma_ep, 123 + rep_disconnect_worker.work); 124 + struct rpcrdma_xprt *r_xprt = 125 + container_of(ep, struct rpcrdma_xprt, rx_ep); 126 + 127 + xprt_force_disconnect(&r_xprt->rx_xprt); 128 + } 129 + 130 + /** 131 + * rpcrdma_qp_event_handler - Handle one QP event (error notification) 132 + * @event: details of the event 133 + * @context: ep that owns QP where event occurred 134 + * 135 + * Called from the RDMA provider (device driver) possibly in an interrupt 136 + * context. 137 + */ 138 + static void 139 + rpcrdma_qp_event_handler(struct ib_event *event, void *context) 113 140 { 114 141 struct rpcrdma_ep *ep = context; 115 142 struct rpcrdma_xprt *r_xprt = container_of(ep, struct rpcrdma_xprt, 116 143 rx_ep); 117 144 118 - trace_xprtrdma_qp_error(r_xprt, event); 119 - pr_err("rpcrdma: %s on device %s ep %p\n", 120 - ib_event_msg(event->event), event->device->name, context); 145 + trace_xprtrdma_qp_event(r_xprt, event); 146 + pr_err("rpcrdma: %s on device %s connected to %s:%s\n", 147 + ib_event_msg(event->event), event->device->name, 148 + rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt)); 121 149 122 150 if (ep->rep_connected == 1) { 123 151 ep->rep_connected = -EIO; 124 - rpcrdma_conn_func(ep); 152 + schedule_delayed_work(&ep->rep_disconnect_worker, 0); 125 153 wake_up_all(&ep->rep_connect_wait); 126 154 } 127 155 } ··· 247 219 rpcrdma_set_max_header_sizes(r_xprt); 248 220 } 249 221 222 + /** 223 + * rpcrdma_cm_event_handler - Handle RDMA CM events 224 + * @id: rdma_cm_id on which an event has occurred 225 + * @event: details of the event 226 + * 227 + * Called with @id's mutex held. Returns 1 if caller should 228 + * destroy @id, otherwise 0. 229 + */ 250 230 static int 251 - rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) 231 + rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) 252 232 { 253 - struct rpcrdma_xprt *xprt = id->context; 254 - struct rpcrdma_ia *ia = &xprt->rx_ia; 255 - struct rpcrdma_ep *ep = &xprt->rx_ep; 256 - int connstate = 0; 233 + struct rpcrdma_xprt *r_xprt = id->context; 234 + struct rpcrdma_ia *ia = &r_xprt->rx_ia; 235 + struct rpcrdma_ep *ep = &r_xprt->rx_ep; 236 + struct rpc_xprt *xprt = &r_xprt->rx_xprt; 257 237 258 - trace_xprtrdma_conn_upcall(xprt, event); 238 + might_sleep(); 239 + 240 + trace_xprtrdma_cm_event(r_xprt, event); 259 241 switch (event->event) { 260 242 case RDMA_CM_EVENT_ADDR_RESOLVED: 261 243 case RDMA_CM_EVENT_ROUTE_RESOLVED: 262 244 ia->ri_async_rc = 0; 263 245 complete(&ia->ri_done); 264 - break; 246 + return 0; 265 247 case RDMA_CM_EVENT_ADDR_ERROR: 266 248 ia->ri_async_rc = -EPROTO; 267 249 complete(&ia->ri_done); 268 - break; 250 + return 0; 269 251 case RDMA_CM_EVENT_ROUTE_ERROR: 270 252 ia->ri_async_rc = -ENETUNREACH; 271 253 complete(&ia->ri_done); 272 - break; 254 + return 0; 273 255 case RDMA_CM_EVENT_DEVICE_REMOVAL: 274 256 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) 275 257 pr_info("rpcrdma: removing device %s for %s:%s\n", 276 258 ia->ri_device->name, 277 - rpcrdma_addrstr(xprt), rpcrdma_portstr(xprt)); 259 + rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt)); 278 260 #endif 279 261 set_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags); 280 262 ep->rep_connected = -ENODEV; 281 - xprt_force_disconnect(&xprt->rx_xprt); 263 + xprt_force_disconnect(xprt); 282 264 wait_for_completion(&ia->ri_remove_done); 283 265 284 266 ia->ri_id = NULL; ··· 296 258 /* Return 1 to ensure the core destroys the id. */ 297 259 return 1; 298 260 case RDMA_CM_EVENT_ESTABLISHED: 299 - ++xprt->rx_xprt.connect_cookie; 300 - connstate = 1; 301 - rpcrdma_update_connect_private(xprt, &event->param.conn); 302 - goto connected; 261 + ++xprt->connect_cookie; 262 + ep->rep_connected = 1; 263 + rpcrdma_update_connect_private(r_xprt, &event->param.conn); 264 + wake_up_all(&ep->rep_connect_wait); 265 + break; 303 266 case RDMA_CM_EVENT_CONNECT_ERROR: 304 - connstate = -ENOTCONN; 305 - goto connected; 267 + ep->rep_connected = -ENOTCONN; 268 + goto disconnected; 306 269 case RDMA_CM_EVENT_UNREACHABLE: 307 - connstate = -ENETUNREACH; 308 - goto connected; 270 + ep->rep_connected = -ENETUNREACH; 271 + goto disconnected; 309 272 case RDMA_CM_EVENT_REJECTED: 310 273 dprintk("rpcrdma: connection to %s:%s rejected: %s\n", 311 - rpcrdma_addrstr(xprt), rpcrdma_portstr(xprt), 274 + rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt), 312 275 rdma_reject_msg(id, event->status)); 313 - connstate = -ECONNREFUSED; 276 + ep->rep_connected = -ECONNREFUSED; 314 277 if (event->status == IB_CM_REJ_STALE_CONN) 315 - connstate = -EAGAIN; 316 - goto connected; 278 + ep->rep_connected = -EAGAIN; 279 + goto disconnected; 317 280 case RDMA_CM_EVENT_DISCONNECTED: 318 - ++xprt->rx_xprt.connect_cookie; 319 - connstate = -ECONNABORTED; 320 - connected: 321 - ep->rep_connected = connstate; 322 - rpcrdma_conn_func(ep); 281 + ++xprt->connect_cookie; 282 + ep->rep_connected = -ECONNABORTED; 283 + disconnected: 284 + xprt_force_disconnect(xprt); 323 285 wake_up_all(&ep->rep_connect_wait); 324 - /*FALLTHROUGH*/ 286 + break; 325 287 default: 326 - dprintk("RPC: %s: %s:%s on %s/%s (ep 0x%p): %s\n", 327 - __func__, 328 - rpcrdma_addrstr(xprt), rpcrdma_portstr(xprt), 329 - ia->ri_device->name, ia->ri_ops->ro_displayname, 330 - ep, rdma_event_msg(event->event)); 331 288 break; 332 289 } 333 290 291 + dprintk("RPC: %s: %s:%s on %s/%s: %s\n", __func__, 292 + rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt), 293 + ia->ri_device->name, ia->ri_ops->ro_displayname, 294 + rdma_event_msg(event->event)); 334 295 return 0; 335 296 } 336 297 ··· 345 308 init_completion(&ia->ri_done); 346 309 init_completion(&ia->ri_remove_done); 347 310 348 - id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_conn_upcall, 311 + id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_cm_event_handler, 349 312 xprt, RDMA_PS_TCP, IB_QPT_RC); 350 313 if (IS_ERR(id)) { 351 314 rc = PTR_ERR(id); ··· 556 519 if (rc) 557 520 return rc; 558 521 559 - ep->rep_attr.event_handler = rpcrdma_qp_async_error_upcall; 522 + ep->rep_attr.event_handler = rpcrdma_qp_event_handler; 560 523 ep->rep_attr.qp_context = ep; 561 524 ep->rep_attr.srq = NULL; 562 525 ep->rep_attr.cap.max_send_sge = max_sge; ··· 579 542 cdata->max_requests >> 2); 580 543 ep->rep_send_count = ep->rep_send_batch; 581 544 init_waitqueue_head(&ep->rep_connect_wait); 582 - INIT_DELAYED_WORK(&ep->rep_connect_worker, rpcrdma_connect_worker); 545 + INIT_DELAYED_WORK(&ep->rep_disconnect_worker, 546 + rpcrdma_disconnect_worker); 583 547 584 548 sendcq = ib_alloc_cq(ia->ri_device, NULL, 585 549 ep->rep_attr.cap.max_send_wr + 1, ··· 653 615 void 654 616 rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia) 655 617 { 656 - cancel_delayed_work_sync(&ep->rep_connect_worker); 618 + cancel_delayed_work_sync(&ep->rep_disconnect_worker); 657 619 658 620 if (ia->ri_id && ia->ri_id->qp) { 659 621 rpcrdma_ep_disconnect(ep, ia); ··· 766 728 { 767 729 struct rpcrdma_xprt *r_xprt = container_of(ia, struct rpcrdma_xprt, 768 730 rx_ia); 731 + struct rpc_xprt *xprt = &r_xprt->rx_xprt; 769 732 int rc; 770 733 771 734 retry: ··· 793 754 } 794 755 795 756 ep->rep_connected = 0; 757 + xprt_clear_connected(xprt); 758 + 796 759 rpcrdma_post_recvs(r_xprt, true); 797 760 798 761 rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma); ··· 918 877 sc->sc_xprt = r_xprt; 919 878 buf->rb_sc_ctxs[i] = sc; 920 879 } 921 - buf->rb_flags = 0; 922 880 923 881 return 0; 924 882 ··· 1018 978 } 1019 979 1020 980 static void 1021 - rpcrdma_mr_recovery_worker(struct work_struct *work) 1022 - { 1023 - struct rpcrdma_buffer *buf = container_of(work, struct rpcrdma_buffer, 1024 - rb_recovery_worker.work); 1025 - struct rpcrdma_mr *mr; 1026 - 1027 - spin_lock(&buf->rb_recovery_lock); 1028 - while (!list_empty(&buf->rb_stale_mrs)) { 1029 - mr = rpcrdma_mr_pop(&buf->rb_stale_mrs); 1030 - spin_unlock(&buf->rb_recovery_lock); 1031 - 1032 - trace_xprtrdma_recover_mr(mr); 1033 - mr->mr_xprt->rx_ia.ri_ops->ro_recover_mr(mr); 1034 - 1035 - spin_lock(&buf->rb_recovery_lock); 1036 - } 1037 - spin_unlock(&buf->rb_recovery_lock); 1038 - } 1039 - 1040 - void 1041 - rpcrdma_mr_defer_recovery(struct rpcrdma_mr *mr) 1042 - { 1043 - struct rpcrdma_xprt *r_xprt = mr->mr_xprt; 1044 - struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1045 - 1046 - spin_lock(&buf->rb_recovery_lock); 1047 - rpcrdma_mr_push(mr, &buf->rb_stale_mrs); 1048 - spin_unlock(&buf->rb_recovery_lock); 1049 - 1050 - schedule_delayed_work(&buf->rb_recovery_worker, 0); 1051 - } 1052 - 1053 - static void 1054 981 rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt) 1055 982 { 1056 983 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; ··· 1026 1019 LIST_HEAD(free); 1027 1020 LIST_HEAD(all); 1028 1021 1029 - for (count = 0; count < 3; count++) { 1022 + for (count = 0; count < ia->ri_max_segs; count++) { 1030 1023 struct rpcrdma_mr *mr; 1031 1024 int rc; 1032 1025 ··· 1145 1138 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 1146 1139 int i, rc; 1147 1140 1141 + buf->rb_flags = 0; 1148 1142 buf->rb_max_requests = r_xprt->rx_data.max_requests; 1149 1143 buf->rb_bc_srv_max_requests = 0; 1150 1144 spin_lock_init(&buf->rb_mrlock); 1151 1145 spin_lock_init(&buf->rb_lock); 1152 - spin_lock_init(&buf->rb_recovery_lock); 1153 1146 INIT_LIST_HEAD(&buf->rb_mrs); 1154 1147 INIT_LIST_HEAD(&buf->rb_all); 1155 - INIT_LIST_HEAD(&buf->rb_stale_mrs); 1156 1148 INIT_DELAYED_WORK(&buf->rb_refresh_worker, 1157 1149 rpcrdma_mr_refresh_worker); 1158 - INIT_DELAYED_WORK(&buf->rb_recovery_worker, 1159 - rpcrdma_mr_recovery_worker); 1160 1150 1161 1151 rpcrdma_mrs_create(r_xprt); 1162 1152 ··· 1237 1233 void 1238 1234 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) 1239 1235 { 1240 - cancel_delayed_work_sync(&buf->rb_recovery_worker); 1241 1236 cancel_delayed_work_sync(&buf->rb_refresh_worker); 1242 1237 1243 1238 rpcrdma_sendctxs_destroy(buf); ··· 1329 1326 { 1330 1327 struct rpcrdma_xprt *r_xprt = mr->mr_xprt; 1331 1328 1332 - trace_xprtrdma_dma_unmap(mr); 1329 + trace_xprtrdma_mr_unmap(mr); 1333 1330 ib_dma_unmap_sg(r_xprt->rx_ia.ri_device, 1334 1331 mr->mr_sg, mr->mr_nents, mr->mr_dir); 1335 1332 __rpcrdma_mr_put(&r_xprt->rx_buf, mr); ··· 1521 1518 struct ib_recv_wr *wr, *bad_wr; 1522 1519 int needed, count, rc; 1523 1520 1521 + rc = 0; 1522 + count = 0; 1524 1523 needed = buf->rb_credits + (buf->rb_bc_srv_max_requests << 1); 1525 1524 if (buf->rb_posted_receives > needed) 1526 - return; 1525 + goto out; 1527 1526 needed -= buf->rb_posted_receives; 1528 1527 1529 1528 count = 0; ··· 1561 1556 --needed; 1562 1557 } 1563 1558 if (!count) 1564 - return; 1559 + goto out; 1565 1560 1566 1561 rc = ib_post_recv(r_xprt->rx_ia.ri_id->qp, wr, 1567 1562 (const struct ib_recv_wr **)&bad_wr); ··· 1575 1570 } 1576 1571 } 1577 1572 buf->rb_posted_receives += count; 1573 + out: 1578 1574 trace_xprtrdma_post_recvs(r_xprt, count, rc); 1579 1575 }
+9 -9
net/sunrpc/xprtrdma/xprt_rdma.h
··· 101 101 wait_queue_head_t rep_connect_wait; 102 102 struct rpcrdma_connect_private rep_cm_private; 103 103 struct rdma_conn_param rep_remote_cma; 104 - struct delayed_work rep_connect_worker; 104 + struct delayed_work rep_disconnect_worker; 105 105 }; 106 106 107 107 /* Pre-allocate extra Work Requests for handling backward receives ··· 280 280 u32 mr_handle; 281 281 u32 mr_length; 282 282 u64 mr_offset; 283 + struct work_struct mr_recycle; 283 284 struct list_head mr_all; 284 285 }; 285 286 ··· 412 411 413 412 u32 rb_bc_max_requests; 414 413 415 - spinlock_t rb_recovery_lock; /* protect rb_stale_mrs */ 416 - struct list_head rb_stale_mrs; 417 - struct delayed_work rb_recovery_worker; 418 414 struct delayed_work rb_refresh_worker; 419 415 }; 420 416 #define rdmab_to_ia(b) (&container_of((b), struct rpcrdma_xprt, rx_buf)->rx_ia) ··· 450 452 unsigned long hardway_register_count; 451 453 unsigned long failed_marshal_count; 452 454 unsigned long bad_reply_count; 453 - unsigned long mrs_recovered; 455 + unsigned long mrs_recycled; 454 456 unsigned long mrs_orphaned; 455 457 unsigned long mrs_allocated; 456 458 unsigned long empty_sendctx_q; ··· 479 481 struct list_head *mrs); 480 482 void (*ro_unmap_sync)(struct rpcrdma_xprt *, 481 483 struct list_head *); 482 - void (*ro_recover_mr)(struct rpcrdma_mr *mr); 483 484 int (*ro_open)(struct rpcrdma_ia *, 484 485 struct rpcrdma_ep *, 485 486 struct rpcrdma_create_data_internal *); ··· 556 559 struct rpcrdma_create_data_internal *); 557 560 void rpcrdma_ep_destroy(struct rpcrdma_ep *, struct rpcrdma_ia *); 558 561 int rpcrdma_ep_connect(struct rpcrdma_ep *, struct rpcrdma_ia *); 559 - void rpcrdma_conn_func(struct rpcrdma_ep *ep); 560 562 void rpcrdma_ep_disconnect(struct rpcrdma_ep *, struct rpcrdma_ia *); 561 563 562 564 int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *, ··· 574 578 struct rpcrdma_mr *rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt); 575 579 void rpcrdma_mr_put(struct rpcrdma_mr *mr); 576 580 void rpcrdma_mr_unmap_and_put(struct rpcrdma_mr *mr); 577 - void rpcrdma_mr_defer_recovery(struct rpcrdma_mr *mr); 581 + 582 + static inline void 583 + rpcrdma_mr_recycle(struct rpcrdma_mr *mr) 584 + { 585 + schedule_work(&mr->mr_recycle); 586 + } 578 587 579 588 struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *); 580 589 void rpcrdma_buffer_put(struct rpcrdma_req *); ··· 653 652 extern unsigned int xprt_rdma_max_inline_read; 654 653 void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap); 655 654 void xprt_rdma_free_addresses(struct rpc_xprt *xprt); 656 - void rpcrdma_connect_worker(struct work_struct *work); 657 655 void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq); 658 656 int xprt_rdma_init(void); 659 657 void xprt_rdma_cleanup(void);
+8 -2
net/sunrpc/xprtsock.c
··· 1452 1452 clear_bit(XPRT_SOCK_CONNECTING, &transport->sock_state); 1453 1453 xprt_clear_connecting(xprt); 1454 1454 1455 + xprt->stat.connect_count++; 1456 + xprt->stat.connect_time += (long)jiffies - 1457 + xprt->stat.connect_start; 1455 1458 xprt_wake_pending_tasks(xprt, -EAGAIN); 1456 1459 } 1457 1460 spin_unlock(&xprt->transport_lock); ··· 1912 1909 case 0: 1913 1910 dprintk("RPC: xprt %p connected to %s\n", 1914 1911 xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); 1912 + xprt->stat.connect_count++; 1913 + xprt->stat.connect_time += (long)jiffies - 1914 + xprt->stat.connect_start; 1915 1915 xprt_set_connected(xprt); 1916 1916 case -ENOBUFS: 1917 1917 break; ··· 2415 2409 "%llu %llu %lu %llu %llu\n", 2416 2410 xprt->stat.bind_count, 2417 2411 xprt->stat.connect_count, 2418 - xprt->stat.connect_time, 2412 + xprt->stat.connect_time / HZ, 2419 2413 idle_time, 2420 2414 xprt->stat.sends, 2421 2415 xprt->stat.recvs, ··· 2470 2464 transport->srcport, 2471 2465 xprt->stat.bind_count, 2472 2466 xprt->stat.connect_count, 2473 - xprt->stat.connect_time, 2467 + xprt->stat.connect_time / HZ, 2474 2468 idle_time, 2475 2469 xprt->stat.sends, 2476 2470 xprt->stat.recvs,