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:
parent
a5abf4e815
commit
5b180a9a64
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user