From 149a40180cc104f220d38b09465bb0f25723c97c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 27 Apr 2011 15:26:41 -0700 Subject: [PATCH] vfs: avoid large kmalloc()s for the fdtable Azurit reports large increases in system time after 2.6.36 when running Apache. It was bisected down to c3b11abedbc7329dca1 ("vfs: use kmalloc() to allocate fdmem if possible"). That patch caused the vfs to use kmalloc() for very large allocations and this is causing excessive work (and presumably excessive reclaim) within the page allocator. Fix it by falling back to vmalloc() earlier - when the allocation attempt would have been considered "costly" by reclaim. Reported-by: azurIt Tested-by: azurIt Acked-by: Changli Gao Cc: Americo Wang Cc: Jiri Slaby Acked-by: Eric Dumazet Cc: Mel Gorman Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/file.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/file.c b/fs/file.c index 0be344755c020..4c6992d8f3ba1 100644 --- a/fs/file.c +++ b/fs/file.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -39,14 +40,17 @@ int sysctl_nr_open_max = 1024 * 1024; /* raised later */ */ static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); -static inline void *alloc_fdmem(unsigned int size) +static void *alloc_fdmem(unsigned int size) { - void *data; - - data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); - if (data != NULL) - return data; - + /* + * Very large allocations can stress page reclaim, so fall back to + * vmalloc() if the allocation size will be considered "large" by the VM. + */ + if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { + void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); + if (data != NULL) + return data; + } return vmalloc(size); } -- 2.39.5