[kernel] r17419 - in dists/lenny/linux-2.6/debian: . patches/bugfix/x86

Dann Frazier dannf at alioth.debian.org
Mon May 16 00:58:53 UTC 2011


Author: dannf
Date: Mon May 16 00:58:52 2011
New Revision: 17419

Log:
[x86] Flush TLB if PGD entry is changed in i386 PAE mode

Added:
   dists/lenny/linux-2.6/debian/patches/bugfix/x86/flush-tlb-if-pgd-entry-is-changed-in-pae-mode.patch
Modified:
   dists/lenny/linux-2.6/debian/changelog

Modified: dists/lenny/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny/linux-2.6/debian/changelog	Mon May 16 00:58:46 2011	(r17418)
+++ dists/lenny/linux-2.6/debian/changelog	Mon May 16 00:58:52 2011	(r17419)
@@ -28,6 +28,7 @@
     - libsas: fix runaway error handler problem
     - NFS: Fix "kernel BUG at fs/aio.c:554!"
     - md: fix regression with re-adding devices to arrays with no metadata
+    - [x86] Flush TLB if PGD entry is changed in i386 PAE mode
 
  -- Ben Hutchings <ben at decadent.org.uk>  Mon, 29 Nov 2010 02:01:24 +0000
 

Added: dists/lenny/linux-2.6/debian/patches/bugfix/x86/flush-tlb-if-pgd-entry-is-changed-in-pae-mode.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/bugfix/x86/flush-tlb-if-pgd-entry-is-changed-in-pae-mode.patch	Mon May 16 00:58:52 2011	(r17419)
@@ -0,0 +1,77 @@
+commit 89296f1f0b4ad37daa78859155708f1cbb568d15
+Author: Shaohua Li <shaohua.li at intel.com>
+Date:   Wed Mar 16 11:37:29 2011 +0800
+
+    x86: Flush TLB if PGD entry is changed in i386 PAE mode
+    
+    commit 4981d01eada5354d81c8929d5b2836829ba3df7b upstream.
+    
+    According to intel CPU manual, every time PGD entry is changed in i386 PAE
+    mode, we need do a full TLB flush. Current code follows this and there is
+    comment for this too in the code.
+    
+    But current code misses the multi-threaded case. A changed page table
+    might be used by several CPUs, every such CPU should flush TLB. Usually
+    this isn't a problem, because we prepopulate all PGD entries at process
+    fork. But when the process does munmap and follows new mmap, this issue
+    will be triggered.
+    
+    When it happens, some CPUs keep doing page faults:
+    
+      http://marc.info/?l=linux-kernel&m=129915020508238&w=2
+    
+    Reported-by: Yasunori Goto<y-goto at jp.fujitsu.com>
+    Tested-by: Yasunori Goto<y-goto at jp.fujitsu.com>
+    Reviewed-by: Rik van Riel <riel at redhat.com>
+    Signed-off-by: Shaohua Li<shaohua.li at intel.com>
+    Cc: Mallick Asit K <asit.k.mallick at intel.com>
+    Cc: Linus Torvalds <torvalds at linux-foundation.org>
+    Cc: Andrew Morton <akpm at linux-foundation.org>
+    Cc: linux-mm <linux-mm at kvack.org>
+    LKML-Reference: <1300246649.2337.95.camel at sli10-conroe>
+    Signed-off-by: Ingo Molnar <mingo at elte.hu>
+    Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+    [dannf: adjusted to Debian's 2.6.26]
+
+diff -urpN linux-source-2.6.26.orig/arch/x86/mm/pgtable.c linux-source-2.6.26/arch/x86/mm/pgtable.c
+--- linux-source-2.6.26.orig/arch/x86/mm/pgtable.c	2011-01-24 22:55:27.000000000 -0700
++++ linux-source-2.6.26/arch/x86/mm/pgtable.c	2011-05-15 17:52:48.497318444 -0600
+@@ -193,8 +193,7 @@ void pud_populate(struct mm_struct *mm,
+ 	 * section 8.1: in PAE mode we explicitly have to flush the
+ 	 * TLB via cr3 if the top-level pgd is changed...
+ 	 */
+-	if (mm == current->active_mm)
+-		write_cr3(read_cr3());
++	flush_tlb_mm(mm);
+ }
+ #else  /* !CONFIG_X86_PAE */
+ /* No need to prepopulate any pagetable entries in non-PAE modes. */
+diff -urpN linux-source-2.6.26.orig/include/asm-x86/pgtable-3level.h linux-source-2.6.26/include/asm-x86/pgtable-3level.h
+--- linux-source-2.6.26.orig/include/asm-x86/pgtable-3level.h	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/asm-x86/pgtable-3level.h	2011-05-15 17:52:48.497318444 -0600
+@@ -101,8 +101,6 @@ static inline void native_pmd_clear(pmd_
+ 
+ static inline void pud_clear(pud_t *pudp)
+ {
+-	unsigned long pgd;
+-
+ 	set_pud(pudp, __pud(0));
+ 
+ 	/*
+@@ -111,13 +109,10 @@ static inline void pud_clear(pud_t *pudp
+ 	 * section 8.1: in PAE mode we explicitly have to flush the
+ 	 * TLB via cr3 if the top-level pgd is changed...
+ 	 *
+-	 * Make sure the pud entry we're updating is within the
+-	 * current pgd to avoid unnecessary TLB flushes.
++	 * Currently all places where pud_clear() is called either have
++	 * flush_tlb_mm() followed or don't need TLB flush (x86_64 code or
++	 * pud_clear_bad()), so we don't need TLB flush here.
+ 	 */
+-	pgd = read_cr3();
+-	if (__pa(pudp) >= pgd && __pa(pudp) <
+-	    (pgd + sizeof(pgd_t)*PTRS_PER_PGD))
+-		write_cr3(pgd);
+ }
+ 
+ #define pud_page(pud) ((struct page *) __va(pud_val(pud) & PTE_MASK))



More information about the Kernel-svn-changes mailing list