lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 3 Sep 2010 13:37:34 +0900 From: Naoya Horiguchi <n-horiguchi@...jp.nec.com> To: Andi Kleen <andi@...stfloor.org> Cc: Andrew Morton <akpm@...ux-foundation.org>, Christoph Lameter <cl@...ux-foundation.org>, Mel Gorman <mel@....ul.ie>, Wu Fengguang <fengguang.wu@...el.com>, "Jun'ichi Nomura" <j-nomura@...jp.nec.com>, linux-mm <linux-mm@...ck.org>, LKML <linux-kernel@...r.kernel.org> Subject: [PATCH 06/10] hugetlb: move refcounting in hugepage allocation inside hugetlb_lock Currently alloc_huge_page() raises page refcount outside hugetlb_lock. but it causes race when dequeue_hwpoison_huge_page() runs concurrently with alloc_huge_page(). To avoid it, this patch moves set_page_refcounted() in hugetlb_lock. Signed-off-by: Naoya Horiguchi <n-horiguchi@...jp.nec.com> Signed-off-by: Wu Fengguang <fengguang.wu@...el.com> --- mm/hugetlb.c | 35 +++++++++++++---------------------- 1 files changed, 13 insertions(+), 22 deletions(-) diff --git v2.6.36-rc2/mm/hugetlb.c v2.6.36-rc2/mm/hugetlb.c index 7cf9225..8ecae16 100644 --- v2.6.36-rc2/mm/hugetlb.c +++ v2.6.36-rc2/mm/hugetlb.c @@ -508,6 +508,7 @@ static struct page *dequeue_huge_page_node(struct hstate *h, int nid) return NULL; page = list_entry(h->hugepage_freelists[nid].next, struct page, lru); list_del(&page->lru); + set_page_refcounted(page); h->free_huge_pages--; h->free_huge_pages_node[nid]--; return page; @@ -867,12 +868,6 @@ static struct page *alloc_buddy_huge_page(struct hstate *h, int nid) spin_lock(&hugetlb_lock); if (page) { - /* - * This page is now managed by the hugetlb allocator and has - * no users -- drop the buddy allocator's reference. - */ - put_page_testzero(page); - VM_BUG_ON(page_count(page)); r_nid = page_to_nid(page); set_compound_page_dtor(page, free_huge_page); /* @@ -935,16 +930,13 @@ retry: spin_unlock(&hugetlb_lock); for (i = 0; i < needed; i++) { page = alloc_buddy_huge_page(h, NUMA_NO_NODE); - if (!page) { + if (!page) /* * We were not able to allocate enough pages to * satisfy the entire reservation so we free what * we've allocated so far. */ - spin_lock(&hugetlb_lock); - needed = 0; goto free; - } list_add(&page->lru, &surplus_list); } @@ -971,31 +963,31 @@ retry: needed += allocated; h->resv_huge_pages += delta; ret = 0; -free: + + spin_unlock(&hugetlb_lock); /* Free the needed pages to the hugetlb pool */ list_for_each_entry_safe(page, tmp, &surplus_list, lru) { if ((--needed) < 0) break; list_del(&page->lru); + /* + * This page is now managed by the hugetlb allocator and has + * no users -- drop the buddy allocator's reference. + */ + put_page_testzero(page); + VM_BUG_ON(page_count(page)); enqueue_huge_page(h, page); } /* Free unnecessary surplus pages to the buddy allocator */ +free: if (!list_empty(&surplus_list)) { - spin_unlock(&hugetlb_lock); list_for_each_entry_safe(page, tmp, &surplus_list, lru) { list_del(&page->lru); - /* - * The page has a reference count of zero already, so - * call free_huge_page directly instead of using - * put_page. This must be done with hugetlb_lock - * unlocked which is safe because free_huge_page takes - * hugetlb_lock before deciding how to free the page. - */ - free_huge_page(page); + put_page(page); } - spin_lock(&hugetlb_lock); } + spin_lock(&hugetlb_lock); return ret; } @@ -1122,7 +1114,6 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, } } - set_page_refcounted(page); set_page_private(page, (unsigned long) mapping); vma_commit_reservation(h, vma, addr); -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists