Hi, I have a customer with a 4.12-based kernel who is experiencing memory exhaustion. There are over 100,000 rpc_rqst structures queue on sv_cb_list for handing by the NFSv4 callback, which is idle. The rpc_rqst.rq_xprt pointer points to freed memory. I notice that that server code calls svc_xprt_get() on the xprt before storing it in rq_xprt, but the client/backchannel code doesn't. I'm wondering if the following might be useful. I plan to explore the code a bit more tomorrow and if this still seems likely I get the customer to test this change, but I thought I would ask here as well incase someone more knowledgeable can give me any pointers. Thanks, NeilBrown diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 339e8c077c2d..c95ca39688b6 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -61,6 +61,7 @@ static void xprt_free_allocation(struct rpc_rqst *req) free_page((unsigned long)xbufp->head[0].iov_base); xbufp = &req->rq_snd_buf; free_page((unsigned long)xbufp->head[0].iov_base); + xprt_put(req->rq_xprt); kfree(req); } @@ -85,7 +86,7 @@ struct rpc_rqst *xprt_alloc_bc_req(struct rpc_xprt *xprt, gfp_t gfp_flags) if (req == NULL) return NULL; - req->rq_xprt = xprt; + req->rq_xprt = xprt_get(xprt); INIT_LIST_HEAD(&req->rq_bc_list); /* Preallocate one XDR receive buffer */
Attachment:
signature.asc
Description: PGP signature