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: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
e5523bd281
commit
e54524111f
@ -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 *);
|
|||||||
|
|
||||||
/* 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,26 +117,16 @@ 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,
|
||||||
u32 *page_offset,
|
u32 *page_offset,
|
||||||
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,15 +211,15 @@ 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,
|
||||||
u32 *page_offset,
|
u32 *page_offset,
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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;
|
||||||
&page_no, &page_offset,
|
ret = xprt->sc_reader(xprt, rqstp, head,
|
||||||
ntohl(ch->rc_target.rs_handle),
|
&page_no, &page_offset,
|
||||||
byte_count, rs_offset,
|
handle, byte_count,
|
||||||
((ch+1)->rc_discrim == 0) /* last */
|
rs_offset, 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)
|
|||||||
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user