hugetlb: fix race in alloc_fresh_huge_page()

That static `nid' index needs locking.  Without it we can end up calling
alloc_pages_node() with an illegal node ID and the kernel crashes.

Acked-by: gurudas pai <gurudas.pai@oracle.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Joe Jin 2007-07-15 23:38:12 -07:00 committed by Linus Torvalds
parent 2706a1b89b
commit f96efd585b
1 changed files with 11 additions and 4 deletions

View File

@ -101,13 +101,20 @@ static void free_huge_page(struct page *page)
static int alloc_fresh_huge_page(void)
{
static int nid = 0;
static int prev_nid;
struct page *page;
page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
HUGETLB_PAGE_ORDER);
nid = next_node(nid, node_online_map);
static DEFINE_SPINLOCK(nid_lock);
int nid;
spin_lock(&nid_lock);
nid = next_node(prev_nid, node_online_map);
if (nid == MAX_NUMNODES)
nid = first_node(node_online_map);
prev_nid = nid;
spin_unlock(&nid_lock);
page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
HUGETLB_PAGE_ORDER);
if (page) {
set_compound_page_dtor(page, free_huge_page);
spin_lock(&hugetlb_lock);