Commit f96efd58 authored by Joe Jin's avatar Joe Jin Committed by Linus Torvalds

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: default avatargurudas pai <gurudas.pai@oracle.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2706a1b8
...@@ -101,13 +101,20 @@ static void free_huge_page(struct page *page) ...@@ -101,13 +101,20 @@ static void free_huge_page(struct page *page)
static int alloc_fresh_huge_page(void) static int alloc_fresh_huge_page(void)
{ {
static int nid = 0; static int prev_nid;
struct page *page; struct page *page;
page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN, static DEFINE_SPINLOCK(nid_lock);
HUGETLB_PAGE_ORDER); int nid;
nid = next_node(nid, node_online_map);
spin_lock(&nid_lock);
nid = next_node(prev_nid, node_online_map);
if (nid == MAX_NUMNODES) if (nid == MAX_NUMNODES)
nid = first_node(node_online_map); 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) { if (page) {
set_compound_page_dtor(page, free_huge_page); set_compound_page_dtor(page, free_huge_page);
spin_lock(&hugetlb_lock); spin_lock(&hugetlb_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment