[pnfs] [PATCH] preallocate a backchannel request in xs_tcp_data_ready

Benny Halevy bhalevy at panasas.com
Wed Nov 28 09:54:27 EST 2007


this way allocation in xs_tcp_read_request cannot fail
and callback ops won't get dropped but rather be blocked
in the socket queue when there's memory pressure on the client

Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---

This proposal is completely untested...

 include/linux/sunrpc/xprt.h |    1 +
 net/sunrpc/xprtsock.c       |   22 ++++++++++------------
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index c6f2ae6..6022e2a 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -179,6 +179,7 @@ struct rpc_xprt {
 						 */
 	struct kmem_cache *	bc_slab;	/* The slab for the callback request mempool */
 	mempool_t *		bc_mempool;	/* The mempool where callbacks allocate rpc_rqst structs from */
+	struct rpc_rqst *	bc_req;		/* a preallocated back channel request */
 #endif
 	struct list_head	recv;
 
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3247521..c2ae90f 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -977,21 +977,13 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_rea
 		}
 	} else {
 		/* RPC_CALL */
-		if (xprt->bc_mempool) {
-			req = xprt_alloc_bc_request(xprt);
-			req->rq_xid = transport->tcp_xid;
-		} else {
+		if (!xprt->bc_mempool) {
 			dprintk("RPC:       Unexpected callback dropped\n");
 			goto error;
 		}
-		if (req == NULL) {
-			/*
-			 * Drop the callback.
-			 * XXX Should we instead terminate the connection?
- 			 */
-			dprintk("RPC:       Couldn't get rpc_rqst for the callback! Dropping callback...\n");
-			goto error;
-		}
+		req = xprt->bc_req;
+		xprt->bc_req = NULL;
+		BUG_ON(req != NULL);
 	}
 
 	rcvbuf = &req->rq_private_buf;
@@ -1150,6 +1142,12 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
 	if (xprt->shutdown)
 		goto out;
 
+	if (xprt->bc_mempool && !xprt->bc_req) {
+		xprt->bc_req = xprt_alloc_bc_request(xprt);
+		if (!xprt->bc_req)
+			goto out;
+	}
+
 	/* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
 	rd_desc.arg.data = xprt;
 	rd_desc.count = 65536;
--
1.5.3.3




More information about the pNFS mailing list