From: Andi Kleen <ak@suse.de>
To: akpm@osdl.org, linux-kernel@vger.kernel.org
Cc: netfilter-devel@lists.netfilter.org
Subject: [PATCH] Fix small vmalloc per allocation limit
Date: Tue, 8 Feb 2005 11:33:46 +0100 [thread overview]
Message-ID: <20050208103345.GA9724@wotan.suse.de> (raw)
The vmap vmalloc rework in 2.5 had a unintended side effect.
vmalloc uses kmalloc now to allocate an array with a list of pages.
kmalloc has a 128K maximum. This limits the vmalloc maximum size
to 64MB on a 64bit system with 4K pages. That limit causes problems
with other subsystems, e.g. iptables relies on allocating large
vmallocs for its rule sets.
This is a bug IMHO - on 64bit platforms there shouldn't be
such a low limit on the vmalloc size. And even on 32bit it's too
small for custom kernels with enlarged vmalloc area.
Another problem is that this makes vmalloc unreliable. After the
system has been running for some time it is unlikely that kmalloc
will be able to allocate >order 2 pages due to memory fragmentation.
This patch takes the easy way out for fixing this by just allocating
this array with vmalloc when it is larger than a page.
While more complicated and intrusive solutions would be possible
they didn't use vmalloc recursively they didn't seem it worth
to handle this very infrequent case.
Please note that the vmalloc recursion is strictly bounded
because each nested allocation will generate a much smaller
stack frame. Also the kernel stack can handle even a few
recursion steps easily because vmalloc has only a small
stack frame.
Signed-off-by: Andi Kleen <ak@suse.de>
diff -u linux-2.6.11rc3/mm/vmalloc.c-o linux-2.6.11rc3/mm/vmalloc.c
--- linux-2.6.11rc3/mm/vmalloc.c-o 2005-02-04 09:13:51.000000000 +0100
+++ linux-2.6.11rc3/mm/vmalloc.c 2005-02-08 10:59:58.000000000 +0100
@@ -378,7 +378,10 @@
__free_page(area->pages[i]);
}
- kfree(area->pages);
+ if (area->nr_pages > PAGE_SIZE/sizeof(struct page *))
+ vfree(area->pages);
+ else
+ kfree(area->pages);
}
kfree(area);
@@ -482,7 +485,12 @@
array_size = (nr_pages * sizeof(struct page *));
area->nr_pages = nr_pages;
- area->pages = pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
+ /* Please note that the recursion is strictly bounded. */
+ if (array_size > PAGE_SIZE)
+ pages = __vmalloc(array_size, gfp_mask, PAGE_KERNEL);
+ else
+ pages = kmalloc(array_size, (gfp_mask & ~__GFP_HIGHMEM));
+ area->pages = pages;
if (!area->pages) {
remove_vm_area(area->addr);
kfree(area);
reply other threads:[~2005-02-08 10:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050208103345.GA9724@wotan.suse.de \
--to=ak@suse.de \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netfilter-devel@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®