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

Ricardo Labiaga ricardo.labiaga at netapp.com
Wed Nov 28 21:59:04 EST 2007


For my own education, what happens if xs_tcp_data_ready() can not
allocate the back channel request and does not read the data off the
socket?  Will xs_tcp_data_ready() get called again because the data is
still there?

- ricardo

On Wed, 2007-11-28 at 16:54 +0200, Benny Halevy wrote:
> 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 {
>  					
>  
> +	if (xprt->bc_mempool && !xprt->bc_req) {
> +		xprt->bc_req = xprt_alloc_bc_request(xprt);
> +		if (!xprt->bc_req)
> +			goto out;
> +	}	 */
>  	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