Commit f96efd585b8d847181f81bf16721f96ded18d9fe

Authored by Joe Jin
Committed by Linus Torvalds
1 parent 2706a1b89b

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>

Showing 1 changed file with 11 additions and 4 deletions Side-by-side Diff

... ... @@ -101,13 +101,20 @@
101 101  
102 102 static int alloc_fresh_huge_page(void)
103 103 {
104   - static int nid = 0;
  104 + static int prev_nid;
105 105 struct page *page;
106   - page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
107   - HUGETLB_PAGE_ORDER);
108   - nid = next_node(nid, node_online_map);
  106 + static DEFINE_SPINLOCK(nid_lock);
  107 + int nid;
  108 +
  109 + spin_lock(&nid_lock);
  110 + nid = next_node(prev_nid, node_online_map);
109 111 if (nid == MAX_NUMNODES)
110 112 nid = first_node(node_online_map);
  113 + prev_nid = nid;
  114 + spin_unlock(&nid_lock);
  115 +
  116 + page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
  117 + HUGETLB_PAGE_ORDER);
111 118 if (page) {
112 119 set_compound_page_dtor(page, free_huge_page);
113 120 spin_lock(&hugetlb_lock);