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

svcrdma: Fix retry loop in svc_rdma_send()

Don't call ib_post_send() at all if the transport is already
shutting down.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

+17 -11
+17 -11
net/sunrpc/xprtrdma/svc_rdma_sendto.c
··· 320 320 * that these values remain available after the ib_post_send() call. 321 321 * In some error flow cases, svc_rdma_wc_send() releases @ctxt. 322 322 * 323 - * Returns zero if the Send WR was posted successfully. Otherwise, a 324 - * negative errno is returned. 323 + * Return values: 324 + * %0: @ctxt's WR chain was posted successfully 325 + * %-ENOTCONN: The connection was lost 325 326 */ 326 327 int svc_rdma_send(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *ctxt) 327 328 { ··· 339 338 DMA_TO_DEVICE); 340 339 341 340 /* If the SQ is full, wait until an SQ entry is available */ 342 - while (1) { 341 + while (!test_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags)) { 343 342 if ((atomic_dec_return(&rdma->sc_sq_avail) < 0)) { 344 343 svc_rdma_wake_send_waiters(rdma, 1); 344 + 345 + /* When the transport is torn down, assume 346 + * ib_drain_sq() will trigger enough Send 347 + * completions to wake us. The XPT_CLOSE test 348 + * above should then cause the while loop to 349 + * exit. 350 + */ 345 351 percpu_counter_inc(&svcrdma_stat_sq_starve); 346 352 trace_svcrdma_sq_full(rdma, &cid); 347 353 wait_event(rdma->sc_send_wait, 348 354 atomic_read(&rdma->sc_sq_avail) > 0); 349 - if (test_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags)) 350 - return -ENOTCONN; 351 355 trace_svcrdma_sq_retry(rdma, &cid); 352 356 continue; 353 357 } 354 358 355 359 trace_svcrdma_post_send(ctxt); 356 360 ret = ib_post_send(rdma->sc_qp, wr, NULL); 357 - if (ret) 361 + if (ret) { 362 + trace_svcrdma_sq_post_err(rdma, &cid, ret); 363 + svc_xprt_deferred_close(&rdma->sc_xprt); 364 + svc_rdma_wake_send_waiters(rdma, 1); 358 365 break; 366 + } 359 367 return 0; 360 368 } 361 - 362 - trace_svcrdma_sq_post_err(rdma, &cid, ret); 363 - svc_xprt_deferred_close(&rdma->sc_xprt); 364 - svc_rdma_wake_send_waiters(rdma, 1); 365 - return ret; 369 + return -ENOTCONN; 366 370 } 367 371 368 372 /**