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

SUNRPC: Remove XDRBUF_SPARSE_PAGES flag in gss_proxy upcall

There's no need to defer allocation of pages for the receive buffer.

- This upcall is quite infrequent
- gssp_alloc_receive_pages() can allocate the pages with GFP_KERNEL,
unlike the transport
- gssp_alloc_receive_pages() knows exactly how many pages are needed

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Olga Kornievskaia <kolga@netapp.com>

+10 -6
+10 -5
net/sunrpc/auth_gss/gss_rpc_upcall.c
··· 200 200 201 201 static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg) 202 202 { 203 - int i; 203 + unsigned int i; 204 204 205 205 for (i = 0; i < arg->npages && arg->pages[i]; i++) 206 206 __free_page(arg->pages[i]); ··· 210 210 211 211 static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) 212 212 { 213 + unsigned int i; 214 + 213 215 arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); 214 216 arg->pages = kcalloc(arg->npages, sizeof(struct page *), GFP_KERNEL); 215 - /* 216 - * XXX: actual pages are allocated by xdr layer in 217 - * xdr_partial_copy_from_skb. 218 - */ 219 217 if (!arg->pages) 220 218 return -ENOMEM; 219 + for (i = 0; i < arg->npages; i++) { 220 + arg->pages[i] = alloc_page(GFP_KERNEL); 221 + if (!arg->pages[i]) { 222 + gssp_free_receive_pages(arg); 223 + return -ENOMEM; 224 + } 225 + } 221 226 return 0; 222 227 } 223 228
-1
net/sunrpc/auth_gss/gss_rpc_xdr.c
··· 771 771 xdr_inline_pages(&req->rq_rcv_buf, 772 772 PAGE_SIZE/2 /* pretty arbitrary */, 773 773 arg->pages, 0 /* page base */, arg->npages * PAGE_SIZE); 774 - req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES; 775 774 done: 776 775 if (err) 777 776 dprintk("RPC: gssx_enc_accept_sec_context: %d\n", err);