Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -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);