aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMichal Hocko2017-05-08 17:57:15 -0500
committerLinus Torvalds2017-05-08 19:15:12 -0500
commit6c5ab6511f718c3fb19bcc3f78a90b0e0b601675 (patch)
tree6f3f4eb344c0e10e966b63192bda55f91b68f80c /mm
parent1f5307b1e094bfffa83c65c40ac6e3415c108780 (diff)
downloadkernel-6c5ab6511f718c3fb19bcc3f78a90b0e0b601675.tar.gz
kernel-6c5ab6511f718c3fb19bcc3f78a90b0e0b601675.tar.xz
kernel-6c5ab6511f718c3fb19bcc3f78a90b0e0b601675.zip
mm: support __GFP_REPEAT in kvmalloc_node for >32kB
vhost code uses __GFP_REPEAT when allocating vhost_virtqueue resp. vhost_vsock because it would really like to prefer kmalloc to the vmalloc fallback - see 23cc5a991c7a ("vhost-net: extend device allocation to vmalloc") for more context. Michael Tsirkin has also noted: "__GFP_REPEAT overhead is during allocation time. Using vmalloc means all accesses are slowed down. Allocation is not on data path, accesses are." The similar applies to other vhost_kvzalloc users. Let's teach kvmalloc_node to handle __GFP_REPEAT properly. There are two things to be careful about. First we should prevent from the OOM killer and so have to involve __GFP_NORETRY by default and secondly override __GFP_REPEAT for !costly order requests as the __GFP_REPEAT is ignored for !costly orders. Supporting __GFP_REPEAT like semantic for !costly request is possible it would require changes in the page allocator. This is out of scope of this patch. This patch shouldn't introduce any functional change. Link: http://lkml.kernel.org/r/20170306103032.2540-3-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Michael S. Tsirkin <mst@redhat.com> Cc: David Miller <davem@davemloft.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/util.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/mm/util.c b/mm/util.c
index 10a14a0ac3c2..f4e590b2c0da 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -339,7 +339,9 @@ EXPORT_SYMBOL(vm_mmap);
339 * Uses kmalloc to get the memory but if the allocation fails then falls back 339 * Uses kmalloc to get the memory but if the allocation fails then falls back
340 * to the vmalloc allocator. Use kvfree for freeing the memory. 340 * to the vmalloc allocator. Use kvfree for freeing the memory.
341 * 341 *
342 * Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported 342 * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT
343 * is supported only for large (>32kB) allocations, and it should be used only if
344 * kmalloc is preferable to the vmalloc fallback, due to visible performance drawbacks.
343 * 345 *
344 * Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people. 346 * Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people.
345 */ 347 */
@@ -358,8 +360,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
358 * Make sure that larger requests are not too disruptive - no OOM 360 * Make sure that larger requests are not too disruptive - no OOM
359 * killer and no allocation failure warnings as we have a fallback 361 * killer and no allocation failure warnings as we have a fallback
360 */ 362 */
361 if (size > PAGE_SIZE) 363 if (size > PAGE_SIZE) {
362 kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; 364 kmalloc_flags |= __GFP_NOWARN;
365
366 /*
367 * We have to override __GFP_REPEAT by __GFP_NORETRY for !costly
368 * requests because there is no other way to tell the allocator
369 * that we want to fail rather than retry endlessly.
370 */
371 if (!(kmalloc_flags & __GFP_REPEAT) ||
372 (size <= PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER))
373 kmalloc_flags |= __GFP_NORETRY;
374 }
363 375
364 ret = kmalloc_node(size, kmalloc_flags, node); 376 ret = kmalloc_node(size, kmalloc_flags, node);
365 377