diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2013-11-14 17:31:07 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 19:32:15 -0500 |
commit | e009bb30c8df8a52a9622b616b67436b6a03a0cd (patch) | |
tree | af36a8ea7ff8acb0bcc22130b28c3dd38cfa35d0 /include/linux/mm.h | |
parent | c4088ebdca64c9a2e34a38177d2249805ede1f4b (diff) |
mm: implement split page table lock for PMD level
The basic idea is the same as with PTE level: the lock is embedded into
struct page of table's page.
We can't use mm->pmd_huge_pte to store pgtables for THP, since we don't
take mm->page_table_lock anymore. Let's reuse page->lru of table's page
for that.
pgtable_pmd_page_ctor() returns true, if initialization is successful
and false otherwise. Current implementation never fails, but assumption
that constructor can fail will help to port it to -rt where spinlock_t
is rather huge and cannot be embedded into struct page -- dynamic
allocation is required.
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Tested-by: Alex Thorlton <athorlton@sgi.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "Eric W . Biederman" <ebiederm@xmission.com>
Cc: "Paul E . McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Dave Jones <davej@redhat.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Robin Holt <robinmholt@gmail.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Hugh Dickins <hughd@google.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 861cad53b744..255750d9b1be 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -1378,13 +1378,45 @@ static inline void pgtable_page_dtor(struct page *page) | |||
1378 | ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address))? \ | 1378 | ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd, address))? \ |
1379 | NULL: pte_offset_kernel(pmd, address)) | 1379 | NULL: pte_offset_kernel(pmd, address)) |
1380 | 1380 | ||
1381 | #if USE_SPLIT_PMD_PTLOCKS | ||
1382 | |||
1383 | static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) | ||
1384 | { | ||
1385 | return &virt_to_page(pmd)->ptl; | ||
1386 | } | ||
1387 | |||
1388 | static inline bool pgtable_pmd_page_ctor(struct page *page) | ||
1389 | { | ||
1390 | spin_lock_init(&page->ptl); | ||
1391 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
1392 | page->pmd_huge_pte = NULL; | ||
1393 | #endif | ||
1394 | return true; | ||
1395 | } | ||
1396 | |||
1397 | static inline void pgtable_pmd_page_dtor(struct page *page) | ||
1398 | { | ||
1399 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
1400 | VM_BUG_ON(page->pmd_huge_pte); | ||
1401 | #endif | ||
1402 | } | ||
1403 | |||
1404 | #define pmd_huge_pte(mm, pmd) (virt_to_page(pmd)->pmd_huge_pte) | ||
1405 | |||
1406 | #else | ||
1407 | |||
1381 | static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) | 1408 | static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) |
1382 | { | 1409 | { |
1383 | return &mm->page_table_lock; | 1410 | return &mm->page_table_lock; |
1384 | } | 1411 | } |
1385 | 1412 | ||
1413 | static inline bool pgtable_pmd_page_ctor(struct page *page) { return true; } | ||
1414 | static inline void pgtable_pmd_page_dtor(struct page *page) {} | ||
1415 | |||
1386 | #define pmd_huge_pte(mm, pmd) ((mm)->pmd_huge_pte) | 1416 | #define pmd_huge_pte(mm, pmd) ((mm)->pmd_huge_pte) |
1387 | 1417 | ||
1418 | #endif | ||
1419 | |||
1388 | static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd) | 1420 | static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd) |
1389 | { | 1421 | { |
1390 | spinlock_t *ptl = pmd_lockptr(mm, pmd); | 1422 | spinlock_t *ptl = pmd_lockptr(mm, pmd); |