Commit e5452411 authored by Chuck Lever's avatar Chuck Lever Committed by J. Bruce Fields

svcrdma: Plant reader function in struct svcxprt_rdma

The RDMA reader function doesn't change once an svcxprt_rdma is
instantiated. Instead of checking sc_devcap during every incoming
RPC, set the reader function once when the connection is accepted.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent e5523bd2
...@@ -150,6 +150,10 @@ struct svcxprt_rdma { ...@@ -150,6 +150,10 @@ struct svcxprt_rdma {
struct ib_cq *sc_rq_cq; struct ib_cq *sc_rq_cq;
struct ib_cq *sc_sq_cq; struct ib_cq *sc_sq_cq;
struct ib_mr *sc_phys_mr; /* MR for server memory */ struct ib_mr *sc_phys_mr; /* MR for server memory */
int (*sc_reader)(struct svcxprt_rdma *,
struct svc_rqst *,
struct svc_rdma_op_ctxt *,
int *, u32 *, u32, u32, u64, bool);
u32 sc_dev_caps; /* distilled device caps */ u32 sc_dev_caps; /* distilled device caps */
u32 sc_dma_lkey; /* local dma key */ u32 sc_dma_lkey; /* local dma key */
unsigned int sc_frmr_pg_list_len; unsigned int sc_frmr_pg_list_len;
...@@ -195,6 +199,12 @@ extern int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *); ...@@ -195,6 +199,12 @@ extern int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *);
/* svc_rdma_recvfrom.c */ /* svc_rdma_recvfrom.c */
extern int svc_rdma_recvfrom(struct svc_rqst *); extern int svc_rdma_recvfrom(struct svc_rqst *);
extern int rdma_read_chunk_lcl(struct svcxprt_rdma *, struct svc_rqst *,
struct svc_rdma_op_ctxt *, int *, u32 *,
u32, u32, u64, bool);
extern int rdma_read_chunk_frmr(struct svcxprt_rdma *, struct svc_rqst *,
struct svc_rdma_op_ctxt *, int *, u32 *,
u32, u32, u64, bool);
/* svc_rdma_sendto.c */ /* svc_rdma_sendto.c */
extern int svc_rdma_sendto(struct svc_rqst *); extern int svc_rdma_sendto(struct svc_rqst *);
......
...@@ -117,18 +117,8 @@ static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) ...@@ -117,18 +117,8 @@ static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count)
return min_t(int, sge_count, xprt->sc_max_sge); return min_t(int, sge_count, xprt->sc_max_sge);
} }
typedef int (*rdma_reader_fn)(struct svcxprt_rdma *xprt,
struct svc_rqst *rqstp,
struct svc_rdma_op_ctxt *head,
int *page_no,
u32 *page_offset,
u32 rs_handle,
u32 rs_length,
u64 rs_offset,
int last);
/* Issue an RDMA_READ using the local lkey to map the data sink */ /* Issue an RDMA_READ using the local lkey to map the data sink */
static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
struct svc_rqst *rqstp, struct svc_rqst *rqstp,
struct svc_rdma_op_ctxt *head, struct svc_rdma_op_ctxt *head,
int *page_no, int *page_no,
...@@ -136,7 +126,7 @@ static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, ...@@ -136,7 +126,7 @@ static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
u32 rs_handle, u32 rs_handle,
u32 rs_length, u32 rs_length,
u64 rs_offset, u64 rs_offset,
int last) bool last)
{ {
struct ib_send_wr read_wr; struct ib_send_wr read_wr;
int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT; int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT;
...@@ -221,7 +211,7 @@ static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, ...@@ -221,7 +211,7 @@ static int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
} }
/* Issue an RDMA_READ using an FRMR to map the data sink */ /* Issue an RDMA_READ using an FRMR to map the data sink */
static int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt, int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
struct svc_rqst *rqstp, struct svc_rqst *rqstp,
struct svc_rdma_op_ctxt *head, struct svc_rdma_op_ctxt *head,
int *page_no, int *page_no,
...@@ -229,7 +219,7 @@ static int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt, ...@@ -229,7 +219,7 @@ static int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt,
u32 rs_handle, u32 rs_handle,
u32 rs_length, u32 rs_length,
u64 rs_offset, u64 rs_offset,
int last) bool last)
{ {
struct ib_send_wr read_wr; struct ib_send_wr read_wr;
struct ib_send_wr inv_wr; struct ib_send_wr inv_wr;
...@@ -374,9 +364,9 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt, ...@@ -374,9 +364,9 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt,
{ {
int page_no, ret; int page_no, ret;
struct rpcrdma_read_chunk *ch; struct rpcrdma_read_chunk *ch;
u32 page_offset, byte_count; u32 handle, page_offset, byte_count;
u64 rs_offset; u64 rs_offset;
rdma_reader_fn reader; bool last;
/* If no read list is present, return 0 */ /* If no read list is present, return 0 */
ch = svc_rdma_get_read_chunk(rmsgp); ch = svc_rdma_get_read_chunk(rmsgp);
...@@ -399,27 +389,20 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt, ...@@ -399,27 +389,20 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt,
head->arg.len = rqstp->rq_arg.len; head->arg.len = rqstp->rq_arg.len;
head->arg.buflen = rqstp->rq_arg.buflen; head->arg.buflen = rqstp->rq_arg.buflen;
/* Use FRMR if supported */
if (xprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG)
reader = rdma_read_chunk_frmr;
else
reader = rdma_read_chunk_lcl;
page_no = 0; page_offset = 0; page_no = 0; page_offset = 0;
for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
ch->rc_discrim != 0; ch++) { ch->rc_discrim != 0; ch++) {
handle = be32_to_cpu(ch->rc_target.rs_handle);
byte_count = be32_to_cpu(ch->rc_target.rs_length);
xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset, xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset,
&rs_offset); &rs_offset);
byte_count = ntohl(ch->rc_target.rs_length);
while (byte_count > 0) { while (byte_count > 0) {
ret = reader(xprt, rqstp, head, last = (ch + 1)->rc_discrim == xdr_zero;
ret = xprt->sc_reader(xprt, rqstp, head,
&page_no, &page_offset, &page_no, &page_offset,
ntohl(ch->rc_target.rs_handle), handle, byte_count,
byte_count, rs_offset, rs_offset, last);
((ch+1)->rc_discrim == 0) /* last */
);
if (ret < 0) if (ret < 0)
goto err; goto err;
byte_count -= ret; byte_count -= ret;
......
...@@ -974,10 +974,12 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) ...@@ -974,10 +974,12 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
* NB: iWARP requires remote write access for the data sink * NB: iWARP requires remote write access for the data sink
* of an RDMA_READ. IB does not. * of an RDMA_READ. IB does not.
*/ */
newxprt->sc_reader = rdma_read_chunk_lcl;
if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
newxprt->sc_frmr_pg_list_len = newxprt->sc_frmr_pg_list_len =
devattr.max_fast_reg_page_list_len; devattr.max_fast_reg_page_list_len;
newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG; newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG;
newxprt->sc_reader = rdma_read_chunk_frmr;
} }
/* /*
......
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