Messages in this thread | | | Date | Sat, 31 Mar 2012 20:27:46 +0800 | Subject | Re: [PATCH] hugetlb: fix race condition in hugetlb_fault() | From | Hillf Danton <> |
| |
On Sat, Mar 31, 2012 at 4:07 AM, Chris Metcalf <cmetcalf@tilera.com> wrote: > The race is as follows. Suppose a multi-threaded task forks a new > process, thus bumping up the ref count on all the pages. While the fork > is occurring (and thus we have marked all the PTEs as read-only), another > thread in the original process tries to write to a huge page, taking an > access violation from the write-protect and calling hugetlb_cow(). Now, > suppose the fork() fails. It will undo the COW and decrement the ref > count on the pages, so the ref count on the huge page drops back to 1. > Meanwhile hugetlb_cow() also decrements the ref count by one on the > original page, since the original address space doesn't need it any more, > having copied a new page to replace the original page. This leaves the > ref count at zero, and when we call unlock_page(), we panic. > > The solution is to take an extra reference to the page while we are > holding the lock on it. > > Cc: stable@kernel.org > Signed-off-by: Chris Metcalf <cmetcalf@tilera.com> > --- > mm/hugetlb.c | 8 ++++++-- > 1 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > index 4531be2..ab674fc 100644 > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -2703,8 +2703,10 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, > * so no worry about deadlock. > */ > page = pte_page(entry); > - if (page != pagecache_page) > + if (page != pagecache_page) { > + get_page(page); > lock_page(page); > + } > Perhaps, directly get page?
page = pte_page(entry); + get_page(page); if (page != pagecache_page) lock_page(page); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |