aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-06-01 15:05:38 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-06-05 11:15:43 -0400
commit1dddda86c056ab4cf49e4206824a9de3e0c4159a (patch)
treefb1156af7d8940bcaa3d9b00a32d3603191b07b4 /net
parent0f41979164a52a1ca0f0a601f90000fc18e3a396 (diff)
SUNRPC: Clean up allocation and freeing of back channel requests
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/backchannel_rqst.c95
1 files changed, 55 insertions, 40 deletions
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
index 28504dfd3dad..1baa41099469 100644
--- a/net/sunrpc/backchannel_rqst.c
+++ b/net/sunrpc/backchannel_rqst.c
@@ -67,6 +67,55 @@ static void xprt_free_allocation(struct rpc_rqst *req)
67 kfree(req); 67 kfree(req);
68} 68}
69 69
70static int xprt_alloc_xdr_buf(struct xdr_buf *buf, gfp_t gfp_flags)
71{
72 struct page *page;
73 /* Preallocate one XDR receive buffer */
74 page = alloc_page(gfp_flags);
75 if (page == NULL)
76 return -ENOMEM;
77 buf->head[0].iov_base = page_address(page);
78 buf->head[0].iov_len = PAGE_SIZE;
79 buf->tail[0].iov_base = NULL;
80 buf->tail[0].iov_len = 0;
81 buf->page_len = 0;
82 buf->len = 0;
83 buf->buflen = PAGE_SIZE;
84 return 0;
85}
86
87static
88struct rpc_rqst *xprt_alloc_bc_req(struct rpc_xprt *xprt, gfp_t gfp_flags)
89{
90 struct rpc_rqst *req;
91
92 /* Pre-allocate one backchannel rpc_rqst */
93 req = kzalloc(sizeof(*req), gfp_flags);
94 if (req == NULL)
95 return NULL;
96
97 req->rq_xprt = xprt;
98 INIT_LIST_HEAD(&req->rq_list);
99 INIT_LIST_HEAD(&req->rq_bc_list);
100
101 /* Preallocate one XDR receive buffer */
102 if (xprt_alloc_xdr_buf(&req->rq_rcv_buf, gfp_flags) < 0) {
103 printk(KERN_ERR "Failed to create bc receive xbuf\n");
104 goto out_free;
105 }
106 req->rq_rcv_buf.len = PAGE_SIZE;
107
108 /* Preallocate one XDR send buffer */
109 if (xprt_alloc_xdr_buf(&req->rq_snd_buf, gfp_flags) < 0) {
110 printk(KERN_ERR "Failed to create bc snd xbuf\n");
111 goto out_free;
112 }
113 return req;
114out_free:
115 xprt_free_allocation(req);
116 return NULL;
117}
118
70/* 119/*
71 * Preallocate up to min_reqs structures and related buffers for use 120 * Preallocate up to min_reqs structures and related buffers for use
72 * by the backchannel. This function can be called multiple times 121 * by the backchannel. This function can be called multiple times
@@ -87,9 +136,7 @@ static void xprt_free_allocation(struct rpc_rqst *req)
87 */ 136 */
88int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) 137int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs)
89{ 138{
90 struct page *page_rcv = NULL, *page_snd = NULL; 139 struct rpc_rqst *req;
91 struct xdr_buf *xbufp = NULL;
92 struct rpc_rqst *req, *tmp;
93 struct list_head tmp_list; 140 struct list_head tmp_list;
94 int i; 141 int i;
95 142
@@ -106,7 +153,7 @@ int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs)
106 INIT_LIST_HEAD(&tmp_list); 153 INIT_LIST_HEAD(&tmp_list);
107 for (i = 0; i < min_reqs; i++) { 154 for (i = 0; i < min_reqs; i++) {
108 /* Pre-allocate one backchannel rpc_rqst */ 155 /* Pre-allocate one backchannel rpc_rqst */
109 req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL); 156 req = xprt_alloc_bc_req(xprt, GFP_KERNEL);
110 if (req == NULL) { 157 if (req == NULL) {
111 printk(KERN_ERR "Failed to create bc rpc_rqst\n"); 158 printk(KERN_ERR "Failed to create bc rpc_rqst\n");
112 goto out_free; 159 goto out_free;
@@ -115,41 +162,6 @@ int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs)
115 /* Add the allocated buffer to the tmp list */ 162 /* Add the allocated buffer to the tmp list */
116 dprintk("RPC: adding req= %p\n", req); 163 dprintk("RPC: adding req= %p\n", req);
117 list_add(&req->rq_bc_pa_list, &tmp_list); 164 list_add(&req->rq_bc_pa_list, &tmp_list);
118
119 req->rq_xprt = xprt;
120 INIT_LIST_HEAD(&req->rq_list);
121 INIT_LIST_HEAD(&req->rq_bc_list);
122
123 /* Preallocate one XDR receive buffer */
124 page_rcv = alloc_page(GFP_KERNEL);
125 if (page_rcv == NULL) {
126 printk(KERN_ERR "Failed to create bc receive xbuf\n");
127 goto out_free;
128 }
129 xbufp = &req->rq_rcv_buf;
130 xbufp->head[0].iov_base = page_address(page_rcv);
131 xbufp->head[0].iov_len = PAGE_SIZE;
132 xbufp->tail[0].iov_base = NULL;
133 xbufp->tail[0].iov_len = 0;
134 xbufp->page_len = 0;
135 xbufp->len = PAGE_SIZE;
136 xbufp->buflen = PAGE_SIZE;
137
138 /* Preallocate one XDR send buffer */
139 page_snd = alloc_page(GFP_KERNEL);
140 if (page_snd == NULL) {
141 printk(KERN_ERR "Failed to create bc snd xbuf\n");
142 goto out_free;
143 }
144
145 xbufp = &req->rq_snd_buf;
146 xbufp->head[0].iov_base = page_address(page_snd);
147 xbufp->head[0].iov_len = 0;
148 xbufp->tail[0].iov_base = NULL;
149 xbufp->tail[0].iov_len = 0;
150 xbufp->page_len = 0;
151 xbufp->len = 0;
152 xbufp->buflen = PAGE_SIZE;
153 } 165 }
154 166
155 /* 167 /*
@@ -167,7 +179,10 @@ out_free:
167 /* 179 /*
168 * Memory allocation failed, free the temporary list 180 * Memory allocation failed, free the temporary list
169 */ 181 */
170 list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) { 182 while (!list_empty(&tmp_list)) {
183 req = list_first_entry(&tmp_list,
184 struct rpc_rqst,
185 rq_bc_pa_list);
171 list_del(&req->rq_bc_pa_list); 186 list_del(&req->rq_bc_pa_list);
172 xprt_free_allocation(req); 187 xprt_free_allocation(req);
173 } 188 }