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

relayfs: support larger relay buffer

Use vmalloc() and memset() instead of kcalloc() to allocate a page* array when
the array size is bigger than one page. This enables relayfs to support
bigger relay buffers than 64MB on 4k-page system, 512MB on 16k-page system.

[akpm@linux-foundation.org: cleanup]
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: David Wilder <dwilder@us.ibm.com>
Reviewed-by: Tom Zanussi <zanussi@comcast.net>
Reviewed-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Masami Hiramatsu and committed by
Linus Torvalds
68ab3d88 97a4feb4

+32 -3
+32 -3
kernel/relay.c
··· 65 65 .close = relay_file_mmap_close, 66 66 }; 67 67 68 + /* 69 + * allocate an array of pointers of struct page 70 + */ 71 + static struct page **relay_alloc_page_array(unsigned int n_pages) 72 + { 73 + struct page **array; 74 + size_t pa_size = n_pages * sizeof(struct page *); 75 + 76 + if (pa_size > PAGE_SIZE) { 77 + array = vmalloc(pa_size); 78 + if (array) 79 + memset(array, 0, pa_size); 80 + } else { 81 + array = kzalloc(pa_size, GFP_KERNEL); 82 + } 83 + return array; 84 + } 85 + 86 + /* 87 + * free an array of pointers of struct page 88 + */ 89 + static void relay_free_page_array(struct page **array) 90 + { 91 + if (is_vmalloc_addr(array)) 92 + vfree(array); 93 + else 94 + kfree(array); 95 + } 96 + 68 97 /** 69 98 * relay_mmap_buf: - mmap channel buffer to process address space 70 99 * @buf: relay channel buffer ··· 138 109 *size = PAGE_ALIGN(*size); 139 110 n_pages = *size >> PAGE_SHIFT; 140 111 141 - buf->page_array = kcalloc(n_pages, sizeof(struct page *), GFP_KERNEL); 112 + buf->page_array = relay_alloc_page_array(n_pages); 142 113 if (!buf->page_array) 143 114 return NULL; 144 115 ··· 159 130 depopulate: 160 131 for (j = 0; j < i; j++) 161 132 __free_page(buf->page_array[j]); 162 - kfree(buf->page_array); 133 + relay_free_page_array(buf->page_array); 163 134 return NULL; 164 135 } 165 136 ··· 218 189 vunmap(buf->start); 219 190 for (i = 0; i < buf->page_count; i++) 220 191 __free_page(buf->page_array[i]); 221 - kfree(buf->page_array); 192 + relay_free_page_array(buf->page_array); 222 193 } 223 194 chan->buf[buf->cpu] = NULL; 224 195 kfree(buf->padding);