]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mm: try to detect that page->ptl is in use
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Tue, 5 Nov 2013 06:06:59 +0000 (17:06 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 5 Nov 2013 06:40:20 +0000 (17:40 +1100)
prep_new_page() initialize page->private (and therefore page->ptl) with 0.
 Make sure nobody took it in use in between allocation of the page and
page table constructor.

It can happen if arch try to use slab for page table allocation: slab code
uses page->slab_cache and page->first_page (for tail pages), which share
storage with page->ptl.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Documentation/vm/split_page_table_lock
include/linux/mm.h

index e2f617b732ff339b62edf6755103e5c2a254f790..3c54f7dca2d4dbcbf7d5f3026054229f8a08bfd1 100644 (file)
@@ -53,6 +53,10 @@ There's no need in special enabling of PTE split page table lock:
 everything required is done by pgtable_page_ctor() and pgtable_page_dtor(),
 which must be called on PTE table allocation / freeing.
 
+Make sure the architecture doesn't use slab allocator for page table
+allacation: slab uses page->slab_cache and page->first_page for its pages.
+These fields share storage with page->ptl.
+
 PMD split lock only makes sense if you have more than two page table
 levels.
 
index d2af6a5da5e2385ad48570f18b1ffb5a58132c44..d0339741b6cee4be3b781ef15aaa994d520a60ee 100644 (file)
@@ -1346,6 +1346,15 @@ static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd)
 
 static inline bool ptlock_init(struct page *page)
 {
+       /*
+        * prep_new_page() initialize page->private (and therefore page->ptl)
+        * with 0. Make sure nobody took it in use in between.
+        *
+        * It can happen if arch try to use slab for page table allocation:
+        * slab code uses page->slab_cache and page->first_page (for tail
+        * pages), which share storage with page->ptl.
+        */
+       VM_BUG_ON(page->ptl);
        if (!ptlock_alloc(page))
                return false;
        spin_lock_init(ptlock_ptr(page));