Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 68ab3d8

Browse files
Masami Hiramatsutorvalds
authored andcommitted
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. [[email protected]: cleanup] Signed-off-by: Masami Hiramatsu <[email protected]> Cc: David Wilder <[email protected]> Reviewed-by: Tom Zanussi <[email protected]> Reviewed-by: Pekka Enberg <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 97a4feb commit 68ab3d8

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

kernel/relay.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,35 @@ static struct vm_operations_struct relay_file_mmap_ops = {
6565
.close = relay_file_mmap_close,
6666
};
6767

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+
6897
/**
6998
* relay_mmap_buf: - mmap channel buffer to process address space
7099
* @buf: relay channel buffer
@@ -109,7 +138,7 @@ static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
109138
*size = PAGE_ALIGN(*size);
110139
n_pages = *size >> PAGE_SHIFT;
111140

112-
buf->page_array = kcalloc(n_pages, sizeof(struct page *), GFP_KERNEL);
141+
buf->page_array = relay_alloc_page_array(n_pages);
113142
if (!buf->page_array)
114143
return NULL;
115144

@@ -130,7 +159,7 @@ static void *relay_alloc_buf(struct rchan_buf *buf, size_t *size)
130159
depopulate:
131160
for (j = 0; j < i; j++)
132161
__free_page(buf->page_array[j]);
133-
kfree(buf->page_array);
162+
relay_free_page_array(buf->page_array);
134163
return NULL;
135164
}
136165

@@ -189,7 +218,7 @@ static void relay_destroy_buf(struct rchan_buf *buf)
189218
vunmap(buf->start);
190219
for (i = 0; i < buf->page_count; i++)
191220
__free_page(buf->page_array[i]);
192-
kfree(buf->page_array);
221+
relay_free_page_array(buf->page_array);
193222
}
194223
chan->buf[buf->cpu] = NULL;
195224
kfree(buf->padding);

0 commit comments

Comments
 (0)