]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/hugetlb.c
r8169: PHY power-on fix
[linux-2.6-omap-h63xx.git] / mm / hugetlb.c
index c4a573b857bdaf692cd4ecdc635525a028cfe423..d7ca59d66c5929194da1b9c0197d924aba2106cd 100644 (file)
@@ -78,16 +78,14 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
        for (z = zonelist->zones; *z; z++) {
                nid = zone_to_nid(*z);
                if (cpuset_zone_allowed_softwall(*z, htlb_alloc_mask) &&
-                   !list_empty(&hugepage_freelists[nid]))
+                   !list_empty(&hugepage_freelists[nid])) {
+                       page = list_entry(hugepage_freelists[nid].next,
+                                         struct page, lru);
+                       list_del(&page->lru);
+                       free_huge_pages--;
+                       free_huge_pages_node[nid]--;
                        break;
-       }
-
-       if (*z) {
-               page = list_entry(hugepage_freelists[nid].next,
-                                 struct page, lru);
-               list_del(&page->lru);
-               free_huge_pages--;
-               free_huge_pages_node[nid]--;
+               }
        }
        return page;
 }
@@ -107,15 +105,19 @@ static int alloc_fresh_huge_page(void)
 {
        static int prev_nid;
        struct page *page;
-       static DEFINE_SPINLOCK(nid_lock);
        int nid;
 
-       spin_lock(&nid_lock);
+       /*
+        * Copy static prev_nid to local nid, work on that, then copy it
+        * back to prev_nid afterwards: otherwise there's a window in which
+        * a racer might pass invalid nid MAX_NUMNODES to alloc_pages_node.
+        * But we don't need to use a spin_lock here: it really doesn't
+        * matter if occasionally a racer chooses the same nid as we do.
+        */
        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, htlb_alloc_mask|__GFP_COMP|__GFP_NOWARN,
                                        HUGETLB_PAGE_ORDER);
@@ -207,7 +209,7 @@ static void update_and_free_page(struct page *page)
                                1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
                                1 << PG_private | 1<< PG_writeback);
        }
-       page[1].lru.next = NULL;
+       set_compound_page_dtor(page, NULL);
        set_page_refcounted(page);
        __free_pages(page, HUGETLB_PAGE_ORDER);
 }