diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2015-03-30 14:34:21 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2015-03-31 09:52:52 -0400 |
commit | a0ce85f595c22d28bf03c3fae8545b3077b7be1b (patch) | |
tree | 0b814731f9c21bbb38013c1c0ce48acf4fab1d7f | |
parent | 41f97028969e4c88efa5fcf58bc6125210413a6d (diff) |
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>
-rw-r--r-- | net/sunrpc/xprtrdma/Makefile | 3 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/fmr_ops.c | 22 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/frwr_ops.c | 22 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/physical_ops.c | 24 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 11 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 12 |
6 files changed, 89 insertions, 5 deletions
diff --git a/net/sunrpc/xprtrdma/Makefile b/net/sunrpc/xprtrdma/Makefile index da5136fd5694..579f72bbcf4b 100644 --- a/net/sunrpc/xprtrdma/Makefile +++ b/net/sunrpc/xprtrdma/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-$(CONFIG_SUNRPC_XPRT_RDMA_CLIENT) += xprtrdma.o | 1 | obj-$(CONFIG_SUNRPC_XPRT_RDMA_CLIENT) += xprtrdma.o |
2 | 2 | ||
3 | xprtrdma-y := transport.o rpc_rdma.o verbs.o | 3 | xprtrdma-y := transport.o rpc_rdma.o verbs.o \ |
4 | fmr_ops.o frwr_ops.o physical_ops.o | ||
4 | 5 | ||
5 | obj-$(CONFIG_SUNRPC_XPRT_RDMA_SERVER) += svcrdma.o | 6 | obj-$(CONFIG_SUNRPC_XPRT_RDMA_SERVER) += svcrdma.o |
6 | 7 | ||
diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c new file mode 100644 index 000000000000..ffb7d9358480 --- /dev/null +++ b/net/sunrpc/xprtrdma/fmr_ops.c | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Oracle. All rights reserved. | ||
3 | * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | /* Lightweight memory registration using Fast Memory Regions (FMR). | ||
7 | * Referred to sometimes as MTHCAFMR mode. | ||
8 | * | ||
9 | * FMR uses synchronous memory registration and deregistration. | ||
10 | * FMR registration is known to be fast, but FMR deregistration | ||
11 | * can take tens of usecs to complete. | ||
12 | */ | ||
13 | |||
14 | #include "xprt_rdma.h" | ||
15 | |||
16 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | ||
17 | # define RPCDBG_FACILITY RPCDBG_TRANS | ||
18 | #endif | ||
19 | |||
20 | const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = { | ||
21 | .ro_displayname = "fmr", | ||
22 | }; | ||
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c new file mode 100644 index 000000000000..79173f98e09a --- /dev/null +++ b/net/sunrpc/xprtrdma/frwr_ops.c | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Oracle. All rights reserved. | ||
3 | * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | /* Lightweight memory registration using Fast Registration Work | ||
7 | * Requests (FRWR). Also referred to sometimes as FRMR mode. | ||
8 | * | ||
9 | * FRWR features ordered asynchronous registration and deregistration | ||
10 | * of arbitrarily sized memory regions. This is the fastest and safest | ||
11 | * but most complex memory registration mode. | ||
12 | */ | ||
13 | |||
14 | #include "xprt_rdma.h" | ||
15 | |||
16 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | ||
17 | # define RPCDBG_FACILITY RPCDBG_TRANS | ||
18 | #endif | ||
19 | |||
20 | const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = { | ||
21 | .ro_displayname = "frwr", | ||
22 | }; | ||
diff --git a/net/sunrpc/xprtrdma/physical_ops.c b/net/sunrpc/xprtrdma/physical_ops.c new file mode 100644 index 000000000000..b0922accabcf --- /dev/null +++ b/net/sunrpc/xprtrdma/physical_ops.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Oracle. All rights reserved. | ||
3 | * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | /* No-op chunk preparation. All client memory is pre-registered. | ||
7 | * Sometimes referred to as ALLPHYSICAL mode. | ||
8 | * | ||
9 | * Physical registration is simple because all client memory is | ||
10 | * pre-registered and never deregistered. This mode is good for | ||
11 | * adapter bring up, but is considered not safe: the server is | ||
12 | * trusted not to abuse its access to client memory not involved | ||
13 | * in RDMA I/O. | ||
14 | */ | ||
15 | |||
16 | #include "xprt_rdma.h" | ||
17 | |||
18 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | ||
19 | # define RPCDBG_FACILITY RPCDBG_TRANS | ||
20 | #endif | ||
21 | |||
22 | const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = { | ||
23 | .ro_displayname = "physical", | ||
24 | }; | ||
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 99752b5b7354..c3319e12551c 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -492,10 +492,10 @@ connected: | |||
492 | int ird = attr->max_dest_rd_atomic; | 492 | int ird = attr->max_dest_rd_atomic; |
493 | int tird = ep->rep_remote_cma.responder_resources; | 493 | int tird = ep->rep_remote_cma.responder_resources; |
494 | 494 | ||
495 | pr_info("rpcrdma: connection to %pIS:%u on %s, memreg %d slots %d ird %d%s\n", | 495 | pr_info("rpcrdma: connection to %pIS:%u on %s, memreg '%s', %d credits, %d responders%s\n", |
496 | sap, rpc_get_port(sap), | 496 | sap, rpc_get_port(sap), |
497 | ia->ri_id->device->name, | 497 | ia->ri_id->device->name, |
498 | ia->ri_memreg_strategy, | 498 | ia->ri_ops->ro_displayname, |
499 | xprt->rx_buf.rb_max_requests, | 499 | xprt->rx_buf.rb_max_requests, |
500 | ird, ird < 4 && ird < tird / 2 ? " (low!)" : ""); | 500 | ird, ird < 4 && ird < tird / 2 ? " (low!)" : ""); |
501 | } else if (connstate < 0) { | 501 | } else if (connstate < 0) { |
@@ -650,13 +650,16 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg) | |||
650 | */ | 650 | */ |
651 | switch (memreg) { | 651 | switch (memreg) { |
652 | case RPCRDMA_FRMR: | 652 | case RPCRDMA_FRMR: |
653 | ia->ri_ops = &rpcrdma_frwr_memreg_ops; | ||
653 | break; | 654 | break; |
654 | case RPCRDMA_ALLPHYSICAL: | 655 | case RPCRDMA_ALLPHYSICAL: |
656 | ia->ri_ops = &rpcrdma_physical_memreg_ops; | ||
655 | mem_priv = IB_ACCESS_LOCAL_WRITE | | 657 | mem_priv = IB_ACCESS_LOCAL_WRITE | |
656 | IB_ACCESS_REMOTE_WRITE | | 658 | IB_ACCESS_REMOTE_WRITE | |
657 | IB_ACCESS_REMOTE_READ; | 659 | IB_ACCESS_REMOTE_READ; |
658 | goto register_setup; | 660 | goto register_setup; |
659 | case RPCRDMA_MTHCAFMR: | 661 | case RPCRDMA_MTHCAFMR: |
662 | ia->ri_ops = &rpcrdma_fmr_memreg_ops; | ||
660 | if (ia->ri_have_dma_lkey) | 663 | if (ia->ri_have_dma_lkey) |
661 | break; | 664 | break; |
662 | mem_priv = IB_ACCESS_LOCAL_WRITE; | 665 | mem_priv = IB_ACCESS_LOCAL_WRITE; |
@@ -676,8 +679,8 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg) | |||
676 | rc = -ENOMEM; | 679 | rc = -ENOMEM; |
677 | goto out3; | 680 | goto out3; |
678 | } | 681 | } |
679 | dprintk("RPC: %s: memory registration strategy is %d\n", | 682 | dprintk("RPC: %s: memory registration strategy is '%s'\n", |
680 | __func__, memreg); | 683 | __func__, ia->ri_ops->ro_displayname); |
681 | 684 | ||
682 | /* Else will do memory reg/dereg for each chunk */ | 685 | /* Else will do memory reg/dereg for each chunk */ |
683 | ia->ri_memreg_strategy = memreg; | 686 | ia->ri_memreg_strategy = memreg; |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index c8afd83e8b75..ef3cf4aeecd6 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -60,6 +60,7 @@ | |||
60 | * Interface Adapter -- one per transport instance | 60 | * Interface Adapter -- one per transport instance |
61 | */ | 61 | */ |
62 | struct rpcrdma_ia { | 62 | struct rpcrdma_ia { |
63 | const struct rpcrdma_memreg_ops *ri_ops; | ||
63 | rwlock_t ri_qplock; | 64 | rwlock_t ri_qplock; |
64 | struct rdma_cm_id *ri_id; | 65 | struct rdma_cm_id *ri_id; |
65 | struct ib_pd *ri_pd; | 66 | struct ib_pd *ri_pd; |
@@ -331,6 +332,17 @@ struct rpcrdma_stats { | |||
331 | }; | 332 | }; |
332 | 333 | ||
333 | /* | 334 | /* |
335 | * Per-registration mode operations | ||
336 | */ | ||
337 | struct rpcrdma_memreg_ops { | ||
338 | const char *ro_displayname; | ||
339 | }; | ||
340 | |||
341 | extern const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops; | ||
342 | extern const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops; | ||
343 | extern const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops; | ||
344 | |||
345 | /* | ||
334 | * RPCRDMA transport -- encapsulates the structures above for | 346 | * RPCRDMA transport -- encapsulates the structures above for |
335 | * integration with RPC. | 347 | * integration with RPC. |
336 | * | 348 | * |