xprtrdma: Add vector of ops for each memory registration strategy
Instead of employing switch() statements, let's use the typical Linux kernel idiom for handling behavioral variation: virtual functions. Start by defining a vector of operations for each supported memory registration mode, and by adding a source file for each mode. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Tested-by: Devesh Sharma <Devesh.Sharma@Emulex.Com> Tested-by: Meghana Cheripady <Meghana.Cheripady@Emulex.Com> Tested-by: Veeresh U. Kokatnur <veereshuk@chelsio.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
41f9702896
commit
a0ce85f595
|
@ -1,6 +1,7 @@
|
||||||
obj-$(CONFIG_SUNRPC_XPRT_RDMA_CLIENT) += xprtrdma.o
|
obj-$(CONFIG_SUNRPC_XPRT_RDMA_CLIENT) += xprtrdma.o
|
||||||
|
|
||||||
xprtrdma-y := transport.o rpc_rdma.o verbs.o
|
xprtrdma-y := transport.o rpc_rdma.o verbs.o \
|
||||||
|
fmr_ops.o frwr_ops.o physical_ops.o
|
||||||
|
|
||||||
obj-$(CONFIG_SUNRPC_XPRT_RDMA_SERVER) += svcrdma.o
|
obj-$(CONFIG_SUNRPC_XPRT_RDMA_SERVER) += svcrdma.o
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Oracle. All rights reserved.
|
||||||
|
* Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Lightweight memory registration using Fast Memory Regions (FMR).
|
||||||
|
* Referred to sometimes as MTHCAFMR mode.
|
||||||
|
*
|
||||||
|
* FMR uses synchronous memory registration and deregistration.
|
||||||
|
* FMR registration is known to be fast, but FMR deregistration
|
||||||
|
* can take tens of usecs to complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xprt_rdma.h"
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
|
||||||
|
.ro_displayname = "fmr",
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Oracle. All rights reserved.
|
||||||
|
* Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Lightweight memory registration using Fast Registration Work
|
||||||
|
* Requests (FRWR). Also referred to sometimes as FRMR mode.
|
||||||
|
*
|
||||||
|
* FRWR features ordered asynchronous registration and deregistration
|
||||||
|
* of arbitrarily sized memory regions. This is the fastest and safest
|
||||||
|
* but most complex memory registration mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xprt_rdma.h"
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
|
||||||
|
.ro_displayname = "frwr",
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Oracle. All rights reserved.
|
||||||
|
* Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* No-op chunk preparation. All client memory is pre-registered.
|
||||||
|
* Sometimes referred to as ALLPHYSICAL mode.
|
||||||
|
*
|
||||||
|
* Physical registration is simple because all client memory is
|
||||||
|
* pre-registered and never deregistered. This mode is good for
|
||||||
|
* adapter bring up, but is considered not safe: the server is
|
||||||
|
* trusted not to abuse its access to client memory not involved
|
||||||
|
* in RDMA I/O.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xprt_rdma.h"
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||||
|
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = {
|
||||||
|
.ro_displayname = "physical",
|
||||||
|
};
|
|
@ -492,10 +492,10 @@ connected:
|
||||||
int ird = attr->max_dest_rd_atomic;
|
int ird = attr->max_dest_rd_atomic;
|
||||||
int tird = ep->rep_remote_cma.responder_resources;
|
int tird = ep->rep_remote_cma.responder_resources;
|
||||||
|
|
||||||
pr_info("rpcrdma: connection to %pIS:%u on %s, memreg %d slots %d ird %d%s\n",
|
pr_info("rpcrdma: connection to %pIS:%u on %s, memreg '%s', %d credits, %d responders%s\n",
|
||||||
sap, rpc_get_port(sap),
|
sap, rpc_get_port(sap),
|
||||||
ia->ri_id->device->name,
|
ia->ri_id->device->name,
|
||||||
ia->ri_memreg_strategy,
|
ia->ri_ops->ro_displayname,
|
||||||
xprt->rx_buf.rb_max_requests,
|
xprt->rx_buf.rb_max_requests,
|
||||||
ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
|
ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
|
||||||
} else if (connstate < 0) {
|
} else if (connstate < 0) {
|
||||||
|
@ -650,13 +650,16 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
|
||||||
*/
|
*/
|
||||||
switch (memreg) {
|
switch (memreg) {
|
||||||
case RPCRDMA_FRMR:
|
case RPCRDMA_FRMR:
|
||||||
|
ia->ri_ops = &rpcrdma_frwr_memreg_ops;
|
||||||
break;
|
break;
|
||||||
case RPCRDMA_ALLPHYSICAL:
|
case RPCRDMA_ALLPHYSICAL:
|
||||||
|
ia->ri_ops = &rpcrdma_physical_memreg_ops;
|
||||||
mem_priv = IB_ACCESS_LOCAL_WRITE |
|
mem_priv = IB_ACCESS_LOCAL_WRITE |
|
||||||
IB_ACCESS_REMOTE_WRITE |
|
IB_ACCESS_REMOTE_WRITE |
|
||||||
IB_ACCESS_REMOTE_READ;
|
IB_ACCESS_REMOTE_READ;
|
||||||
goto register_setup;
|
goto register_setup;
|
||||||
case RPCRDMA_MTHCAFMR:
|
case RPCRDMA_MTHCAFMR:
|
||||||
|
ia->ri_ops = &rpcrdma_fmr_memreg_ops;
|
||||||
if (ia->ri_have_dma_lkey)
|
if (ia->ri_have_dma_lkey)
|
||||||
break;
|
break;
|
||||||
mem_priv = IB_ACCESS_LOCAL_WRITE;
|
mem_priv = IB_ACCESS_LOCAL_WRITE;
|
||||||
|
@ -676,8 +679,8 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out3;
|
goto out3;
|
||||||
}
|
}
|
||||||
dprintk("RPC: %s: memory registration strategy is %d\n",
|
dprintk("RPC: %s: memory registration strategy is '%s'\n",
|
||||||
__func__, memreg);
|
__func__, ia->ri_ops->ro_displayname);
|
||||||
|
|
||||||
/* Else will do memory reg/dereg for each chunk */
|
/* Else will do memory reg/dereg for each chunk */
|
||||||
ia->ri_memreg_strategy = memreg;
|
ia->ri_memreg_strategy = memreg;
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
* Interface Adapter -- one per transport instance
|
* Interface Adapter -- one per transport instance
|
||||||
*/
|
*/
|
||||||
struct rpcrdma_ia {
|
struct rpcrdma_ia {
|
||||||
|
const struct rpcrdma_memreg_ops *ri_ops;
|
||||||
rwlock_t ri_qplock;
|
rwlock_t ri_qplock;
|
||||||
struct rdma_cm_id *ri_id;
|
struct rdma_cm_id *ri_id;
|
||||||
struct ib_pd *ri_pd;
|
struct ib_pd *ri_pd;
|
||||||
|
@ -330,6 +331,17 @@ struct rpcrdma_stats {
|
||||||
unsigned long bad_reply_count;
|
unsigned long bad_reply_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per-registration mode operations
|
||||||
|
*/
|
||||||
|
struct rpcrdma_memreg_ops {
|
||||||
|
const char *ro_displayname;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops;
|
||||||
|
extern const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops;
|
||||||
|
extern const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RPCRDMA transport -- encapsulates the structures above for
|
* RPCRDMA transport -- encapsulates the structures above for
|
||||||
* integration with RPC.
|
* integration with RPC.
|
||||||
|
|
Loading…
Reference in New Issue