Commit b0e178a2 authored by Chuck Lever's avatar Chuck Lever Committed by Anna Schumaker

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: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarSagi Grimberg <sagig@mellanox.com>
Reviewed-by: default avatarDevesh Sharma <devesh.sharma@avagotech.com>
Tested-By: default avatarDevesh Sharma <devesh.sharma@avagotech.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 4220a072
...@@ -741,52 +741,27 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep) ...@@ -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 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep) ...@@ -883,8 +858,44 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep)
if (xprt->cwnd > cwnd) if (xprt->cwnd > cwnd)
xprt_release_rqst_cong(rqst->rq_task); xprt_release_rqst_cong(rqst->rq_task);
xprt_complete_rqst(rqst->rq_task, status);
spin_unlock(&xprt->transport_lock);
dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n", dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",
__func__, xprt, rqst, status); __func__, xprt, rqst, status);
xprt_complete_rqst(rqst->rq_task, 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); 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 @@ rpcrdma_recvcq_process_wc(struct ib_wc *wc, struct list_head *sched_list) ...@@ -225,7 +225,7 @@ rpcrdma_recvcq_process_wc(struct ib_wc *wc, struct list_head *sched_list)
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 { ...@@ -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
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment