Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC: Abstract backchannel operations

xprt_{setup,destroy}_backchannel() won't be adequate for RPC/RMDA
bi-direction. In particular, receive buffers have to be pre-
registered and posted in order to receive incoming backchannel
requests.

Add a virtual function call to allow the insertion of appropriate
backchannel setup and destruction methods for each transport.

In addition, freeing a backchannel request is a little different
for RPC/RDMA. Introduce an rpc_xprt_op to handle the difference.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
Tested-By: Devesh Sharma <devesh.sharma@avagotech.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>

authored by

Chuck Lever and committed by
Anna Schumaker
42e5c3e2 a5b027e1

+37 -2
+5
include/linux/sunrpc/bc_xprt.h
··· 38 38 int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); 39 39 void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs); 40 40 41 + /* Socket backchannel transport methods */ 42 + int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs); 43 + void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs); 44 + void xprt_free_bc_rqst(struct rpc_rqst *req); 45 + 41 46 /* 42 47 * Determine if a shared backchannel is in use 43 48 */
+5
include/linux/sunrpc/xprt.h
··· 136 136 int (*enable_swap)(struct rpc_xprt *xprt); 137 137 void (*disable_swap)(struct rpc_xprt *xprt); 138 138 void (*inject_disconnect)(struct rpc_xprt *xprt); 139 + int (*bc_setup)(struct rpc_xprt *xprt, 140 + unsigned int min_reqs); 141 + void (*bc_free_rqst)(struct rpc_rqst *rqst); 142 + void (*bc_destroy)(struct rpc_xprt *xprt, 143 + unsigned int max_reqs); 139 144 }; 140 145 141 146 /*
+22 -2
net/sunrpc/backchannel_rqst.c
··· 138 138 */ 139 139 int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) 140 140 { 141 + if (!xprt->ops->bc_setup) 142 + return 0; 143 + return xprt->ops->bc_setup(xprt, min_reqs); 144 + } 145 + EXPORT_SYMBOL_GPL(xprt_setup_backchannel); 146 + 147 + int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs) 148 + { 141 149 struct rpc_rqst *req; 142 150 struct list_head tmp_list; 143 151 int i; ··· 200 192 dprintk("RPC: setup backchannel transport failed\n"); 201 193 return -ENOMEM; 202 194 } 203 - EXPORT_SYMBOL_GPL(xprt_setup_backchannel); 204 195 205 196 /** 206 197 * xprt_destroy_backchannel - Destroys the backchannel preallocated structures. ··· 211 204 * of reqs specified by the caller. 212 205 */ 213 206 void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs) 207 + { 208 + if (xprt->ops->bc_destroy) 209 + xprt->ops->bc_destroy(xprt, max_reqs); 210 + } 211 + EXPORT_SYMBOL_GPL(xprt_destroy_backchannel); 212 + 213 + void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs) 214 214 { 215 215 struct rpc_rqst *req = NULL, *tmp = NULL; 216 216 ··· 241 227 dprintk("RPC: backchannel list empty= %s\n", 242 228 list_empty(&xprt->bc_pa_list) ? "true" : "false"); 243 229 } 244 - EXPORT_SYMBOL_GPL(xprt_destroy_backchannel); 245 230 246 231 static struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt, __be32 xid) 247 232 { ··· 274 261 * associated with this rpc_task. 275 262 */ 276 263 void xprt_free_bc_request(struct rpc_rqst *req) 264 + { 265 + struct rpc_xprt *xprt = req->rq_xprt; 266 + 267 + xprt->ops->bc_free_rqst(req); 268 + } 269 + 270 + void xprt_free_bc_rqst(struct rpc_rqst *req) 277 271 { 278 272 struct rpc_xprt *xprt = req->rq_xprt; 279 273
+5
net/sunrpc/xprtsock.c
··· 2580 2580 .enable_swap = xs_enable_swap, 2581 2581 .disable_swap = xs_disable_swap, 2582 2582 .inject_disconnect = xs_inject_disconnect, 2583 + #ifdef CONFIG_SUNRPC_BACKCHANNEL 2584 + .bc_setup = xprt_setup_bc, 2585 + .bc_free_rqst = xprt_free_bc_rqst, 2586 + .bc_destroy = xprt_destroy_bc, 2587 + #endif 2583 2588 }; 2584 2589 2585 2590 /*