Yet another PPC64 hugepage bugfix

From: David Gibson (david_at_gibson.dropbear.id.au)
Date: 04/06/04

  • Next message: Paul Jackson: "Re: [PATCH] mask ADT: new mask.h file [2/22]"
    Date:	Tue, 6 Apr 2004 15:25:38 +1000
    To: Andrew Morton <akpm@osdl.org>
    
    

    Andrew, please apply. Found this again while looking at hugepage
    extensions. Haven't actually had it bite yet - the race is small and
    the other bug will never be triggered in 32-bit processes, and the
    function is rarely called on 64-bit processes.

    This patch fixes two bugs in the (same part of the) PPC64 hugepage
    code. First the method we were using to free stale PTE pages was not
    safe with some recent changes (race condition). BenH has fixed this
    to work in the new way. Second, we were not checking for a valid PGD
    entry before dereferencing the PMD page when scanning for stale PTE
    page pointers.

    ===== arch/ppc64/mm/hugetlbpage.c 1.14 vs edited =====
    Index: working-2.6/arch/ppc64/mm/hugetlbpage.c
    ===================================================================
    --- working-2.6.orig/arch/ppc64/mm/hugetlbpage.c 2004-04-05 17:45:53.000000000 +1000
    +++ working-2.6/arch/ppc64/mm/hugetlbpage.c 2004-04-06 15:09:29.383726856 +1000
    @@ -247,6 +247,7 @@
     {
             struct vm_area_struct *vma;
             unsigned long addr;
    + struct mmu_gather *tlb;
     
             if (mm->context.low_hpages)
                     return 0; /* The window is already open */
    @@ -262,32 +263,39 @@
     
             /* Clean up any leftover PTE pages in the region */
             spin_lock(&mm->page_table_lock);
    + tlb = tlb_gather_mmu(mm, 0);
             for (addr = TASK_HPAGE_BASE_32; addr < TASK_HPAGE_END_32;
                  addr += PMD_SIZE) {
                     pgd_t *pgd = pgd_offset(mm, addr);
    - pmd_t *pmd = pmd_offset(pgd, addr);
    -
    - if (! pmd_none(*pmd)) {
    - struct page *page = pmd_page(*pmd);
    - pte_t *pte = (pte_t *)pmd_page_kernel(*pmd);
    - int i;
    -
    - /* No VMAs, so there should be no PTEs, check
    - * just in case. */
    - for (i = 0; i < PTRS_PER_PTE; i++) {
    - BUG_ON(! pte_none(*pte));
    - pte++;
    - }
    + pmd_t *pmd;
    + struct page *page;
    + pte_t *pte;
    + int i;
     
    + if (pgd_none(*pgd))
    + continue;
    + pmd = pmd_offset(pgd, addr);
    + if (!pmd || pmd_none(*pmd))
    + continue;
    + if (pmd_bad(*pmd)) {
    + pmd_ERROR(*pmd);
                             pmd_clear(pmd);
    - pgtable_remove_rmap(page);
    - pte_free(page);
    + continue;
                     }
    + pte = (pte_t *)pmd_page_kernel(*pmd);
    + /* No VMAs, so there should be no PTEs, check just in case. */
    + for (i = 0; i < PTRS_PER_PTE; i++) {
    + BUG_ON(!pte_none(*pte));
    + pte++;
    + }
    + page = pmd_page(*pmd);
    + pmd_clear(pmd);
    + pgtable_remove_rmap(page);
    + pte_free_tlb(tlb, page);
             }
    + tlb_finish_mmu(tlb, TASK_HPAGE_BASE_32, TASK_HPAGE_END_32);
             spin_unlock(&mm->page_table_lock);
     
    - /* FIXME: do we need to scan for PTEs too? */
    -
             mm->context.low_hpages = 1;
     
             /* the context change must make it to memory before the slbia,

    -- 
    David Gibson			| For every complex problem there is a
    david AT gibson.dropbear.id.au	| solution which is simple, neat and
    				| wrong.
    http://www.ozlabs.org/people/dgibson
    -
    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/
    

  • Next message: Paul Jackson: "Re: [PATCH] mask ADT: new mask.h file [2/22]"

    Relevant Pages

    • Re: [PATCH]CPU hotplug breaks wake_up_new_task
      ... the bug. ... The simple fix for this race is: ... 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/ ...
      (Linux-Kernel)
    • Re: kernel bug: futex_wait hang
      ... The primary suspect is a deadlock, race of some kind or other bug ... that a program bug can only show up with one of the threading libraries ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: tickle nmi watchdog whilst doing serial writes.
      ... > NMI watchdog decides the box is dead so this is kind of weird. ... There is a bug somewhere that makes it sometimes expire faster. ... I found only one bug so far - touch_nmi_watchdog has a race ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Re: Interesting race condition...
      ... > On a loaded system the bug did not occur, which certainly indicates a race ... Should someone file a bug report via 'bashbug'? ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • Warp Rogue 0.5.2 released
      ... The "Never jams" attribute was removed from the Ork guns. ... A bug that allowed shooting through closed doors was fixed. ... A bug that allowed recruiting race leaders was fixed. ... The character generation screens were rearranged. ...
      (rec.games.roguelike.announce)