svcrdma: Add support to svc_rdma_send to handle chained WR

WR can be submitted as linked lists of WR. Update the svc_rdma_send
routine to handle WR chains. This will be used to submit a WR that
uses an FRMR with another WR that invalidates the FRMR.

Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
This commit is contained in:
Tom Tucker 2008-08-11 14:10:19 -05:00
parent a5abf4e815
commit 5b180a9a64

View File

@ -1235,17 +1235,23 @@ int svc_rdma_fastreg(struct svcxprt_rdma *xprt,
int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
{ {
struct ib_send_wr *bad_wr; struct ib_send_wr *bad_wr, *n_wr;
int wr_count;
int i;
int ret; int ret;
if (test_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags)) if (test_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags))
return -ENOTCONN; return -ENOTCONN;
BUG_ON(wr->send_flags != IB_SEND_SIGNALED); BUG_ON(wr->send_flags != IB_SEND_SIGNALED);
wr_count = 1;
for (n_wr = wr->next; n_wr; n_wr = n_wr->next)
wr_count++;
/* If the SQ is full, wait until an SQ entry is available */ /* If the SQ is full, wait until an SQ entry is available */
while (1) { while (1) {
spin_lock_bh(&xprt->sc_lock); spin_lock_bh(&xprt->sc_lock);
if (xprt->sc_sq_depth == atomic_read(&xprt->sc_sq_count)) { if (xprt->sc_sq_depth < atomic_read(&xprt->sc_sq_count) + wr_count) {
spin_unlock_bh(&xprt->sc_lock); spin_unlock_bh(&xprt->sc_lock);
atomic_inc(&rdma_stat_sq_starve); atomic_inc(&rdma_stat_sq_starve);
@ -1260,19 +1266,26 @@ int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
return 0; return 0;
continue; continue;
} }
/* Bumped used SQ WR count and post */ /* Take a transport ref for each WR posted */
svc_xprt_get(&xprt->sc_xprt); for (i = 0; i < wr_count; i++)
svc_xprt_get(&xprt->sc_xprt);
/* Bump used SQ WR count and post */
atomic_add(wr_count, &xprt->sc_sq_count);
ret = ib_post_send(xprt->sc_qp, wr, &bad_wr); ret = ib_post_send(xprt->sc_qp, wr, &bad_wr);
if (!ret) if (ret) {
atomic_inc(&xprt->sc_sq_count); set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
else { atomic_sub(wr_count, &xprt->sc_sq_count);
svc_xprt_put(&xprt->sc_xprt); for (i = 0; i < wr_count; i ++)
svc_xprt_put(&xprt->sc_xprt);
dprintk("svcrdma: failed to post SQ WR rc=%d, " dprintk("svcrdma: failed to post SQ WR rc=%d, "
"sc_sq_count=%d, sc_sq_depth=%d\n", "sc_sq_count=%d, sc_sq_depth=%d\n",
ret, atomic_read(&xprt->sc_sq_count), ret, atomic_read(&xprt->sc_sq_count),
xprt->sc_sq_depth); xprt->sc_sq_depth);
} }
spin_unlock_bh(&xprt->sc_lock); spin_unlock_bh(&xprt->sc_lock);
if (ret)
wake_up(&xprt->sc_send_wait);
break; break;
} }
return ret; return ret;