xprtrdma: Refactor reply handler error handling
Clean up: The error cases in rpcrdma_reply_handler() almost never execute. Ensure the compiler places them out of the hot path. No behavior change expected. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Reviewed-by: Devesh Sharma <devesh.sharma@avagotech.com> Tested-By: Devesh Sharma <devesh.sharma@avagotech.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
4220a07264
commit
b0e178a2d8
|
@ -741,52 +741,27 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep)
|
||||||
unsigned long cwnd;
|
unsigned long cwnd;
|
||||||
u32 credits;
|
u32 credits;
|
||||||
|
|
||||||
/* Check status. If bad, signal disconnect and return rep to pool */
|
dprintk("RPC: %s: incoming rep %p\n", __func__, rep);
|
||||||
if (rep->rr_len == ~0U) {
|
|
||||||
rpcrdma_recv_buffer_put(rep);
|
if (rep->rr_len == RPCRDMA_BAD_LEN)
|
||||||
if (r_xprt->rx_ep.rep_connected == 1) {
|
goto out_badstatus;
|
||||||
r_xprt->rx_ep.rep_connected = -EIO;
|
if (rep->rr_len < RPCRDMA_HDRLEN_MIN)
|
||||||
rpcrdma_conn_func(&r_xprt->rx_ep);
|
goto out_shortreply;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (rep->rr_len < RPCRDMA_HDRLEN_MIN) {
|
|
||||||
dprintk("RPC: %s: short/invalid reply\n", __func__);
|
|
||||||
goto repost;
|
|
||||||
}
|
|
||||||
headerp = rdmab_to_msg(rep->rr_rdmabuf);
|
headerp = rdmab_to_msg(rep->rr_rdmabuf);
|
||||||
if (headerp->rm_vers != rpcrdma_version) {
|
if (headerp->rm_vers != rpcrdma_version)
|
||||||
dprintk("RPC: %s: invalid version %d\n",
|
goto out_badversion;
|
||||||
__func__, be32_to_cpu(headerp->rm_vers));
|
|
||||||
goto repost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get XID and try for a match. */
|
/* Get XID and try for a match. */
|
||||||
spin_lock(&xprt->transport_lock);
|
spin_lock(&xprt->transport_lock);
|
||||||
rqst = xprt_lookup_rqst(xprt, headerp->rm_xid);
|
rqst = xprt_lookup_rqst(xprt, headerp->rm_xid);
|
||||||
if (rqst == NULL) {
|
if (!rqst)
|
||||||
spin_unlock(&xprt->transport_lock);
|
goto out_nomatch;
|
||||||
dprintk("RPC: %s: reply 0x%p failed "
|
|
||||||
"to match any request xid 0x%08x len %d\n",
|
|
||||||
__func__, rep, be32_to_cpu(headerp->rm_xid),
|
|
||||||
rep->rr_len);
|
|
||||||
repost:
|
|
||||||
r_xprt->rx_stats.bad_reply_count++;
|
|
||||||
if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, &r_xprt->rx_ep, rep))
|
|
||||||
rpcrdma_recv_buffer_put(rep);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get request object */
|
/* get request object */
|
||||||
req = rpcr_to_rdmar(rqst);
|
req = rpcr_to_rdmar(rqst);
|
||||||
if (req->rl_reply) {
|
if (req->rl_reply)
|
||||||
spin_unlock(&xprt->transport_lock);
|
goto out_duplicate;
|
||||||
dprintk("RPC: %s: duplicate reply 0x%p to RPC "
|
|
||||||
"request 0x%p: xid 0x%08x\n", __func__, rep, req,
|
|
||||||
be32_to_cpu(headerp->rm_xid));
|
|
||||||
goto repost;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintk("RPC: %s: reply 0x%p completes request 0x%p\n"
|
dprintk("RPC: %s: reply 0x%p completes request 0x%p\n"
|
||||||
" RPC request 0x%p xid 0x%08x\n",
|
" RPC request 0x%p xid 0x%08x\n",
|
||||||
|
@ -883,8 +858,44 @@ badheader:
|
||||||
if (xprt->cwnd > cwnd)
|
if (xprt->cwnd > cwnd)
|
||||||
xprt_release_rqst_cong(rqst->rq_task);
|
xprt_release_rqst_cong(rqst->rq_task);
|
||||||
|
|
||||||
dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",
|
|
||||||
__func__, xprt, rqst, status);
|
|
||||||
xprt_complete_rqst(rqst->rq_task, status);
|
xprt_complete_rqst(rqst->rq_task, status);
|
||||||
spin_unlock(&xprt->transport_lock);
|
spin_unlock(&xprt->transport_lock);
|
||||||
|
dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",
|
||||||
|
__func__, xprt, rqst, status);
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_badstatus:
|
||||||
|
rpcrdma_recv_buffer_put(rep);
|
||||||
|
if (r_xprt->rx_ep.rep_connected == 1) {
|
||||||
|
r_xprt->rx_ep.rep_connected = -EIO;
|
||||||
|
rpcrdma_conn_func(&r_xprt->rx_ep);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_shortreply:
|
||||||
|
dprintk("RPC: %s: short/invalid reply\n", __func__);
|
||||||
|
goto repost;
|
||||||
|
|
||||||
|
out_badversion:
|
||||||
|
dprintk("RPC: %s: invalid version %d\n",
|
||||||
|
__func__, be32_to_cpu(headerp->rm_vers));
|
||||||
|
goto repost;
|
||||||
|
|
||||||
|
out_nomatch:
|
||||||
|
spin_unlock(&xprt->transport_lock);
|
||||||
|
dprintk("RPC: %s: no match for incoming xid 0x%08x len %d\n",
|
||||||
|
__func__, be32_to_cpu(headerp->rm_xid),
|
||||||
|
rep->rr_len);
|
||||||
|
goto repost;
|
||||||
|
|
||||||
|
out_duplicate:
|
||||||
|
spin_unlock(&xprt->transport_lock);
|
||||||
|
dprintk("RPC: %s: "
|
||||||
|
"duplicate reply %p to RPC request %p: xid 0x%08x\n",
|
||||||
|
__func__, rep, req, be32_to_cpu(headerp->rm_xid));
|
||||||
|
|
||||||
|
repost:
|
||||||
|
r_xprt->rx_stats.bad_reply_count++;
|
||||||
|
if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, &r_xprt->rx_ep, rep))
|
||||||
|
rpcrdma_recv_buffer_put(rep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ out_fail:
|
||||||
if (wc->status != IB_WC_WR_FLUSH_ERR)
|
if (wc->status != IB_WC_WR_FLUSH_ERR)
|
||||||
pr_err("RPC: %s: rep %p: %s\n",
|
pr_err("RPC: %s: rep %p: %s\n",
|
||||||
__func__, rep, ib_wc_status_msg(wc->status));
|
__func__, rep, ib_wc_status_msg(wc->status));
|
||||||
rep->rr_len = ~0U;
|
rep->rr_len = RPCRDMA_BAD_LEN;
|
||||||
goto out_schedule;
|
goto out_schedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,8 @@ struct rpcrdma_rep {
|
||||||
struct rpcrdma_regbuf *rr_rdmabuf;
|
struct rpcrdma_regbuf *rr_rdmabuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RPCRDMA_BAD_LEN (~0U)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct rpcrdma_mw - external memory region metadata
|
* struct rpcrdma_mw - external memory region metadata
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue