aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2013-11-14 17:31:51 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 19:32:20 -0500
commit49076ec2ccaf68610aa03d96bced9a6694b93ca1 (patch)
tree876564edb5cd164c7f9eaf39008f8f01fb164db6 /mm
parentf820e2805c7acb157a78438d07e47f4fc57fe679 (diff)
mm: dynamically allocate page->ptl if it cannot be embedded to struct page
If split page table lock is in use, we embed the lock into struct page of table's page. We have to disable split lock, if spinlock_t is too big be to be embedded, like when DEBUG_SPINLOCK or DEBUG_LOCK_ALLOC enabled. This patch add support for dynamic allocation of split page table lock if we can't embed it to struct page. page->ptl is unsigned long now and we use it as spinlock_t if sizeof(spinlock_t) <= sizeof(long), otherwise it's pointer to spinlock_t. The spinlock_t allocated in pgtable_page_ctor() for PTE table and in pgtable_pmd_page_ctor() for PMD table. All other helpers converted to support dynamically allocated page->ptl. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Reviewed-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/Kconfig2
-rw-r--r--mm/memory.c19
2 files changed, 19 insertions, 2 deletions
diff --git a/mm/Kconfig b/mm/Kconfig
index 7aa02def4666..de31af256207 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -218,8 +218,6 @@ config SPLIT_PTLOCK_CPUS
218 int 218 int
219 default "999999" if ARM && !CPU_CACHE_VIPT 219 default "999999" if ARM && !CPU_CACHE_VIPT
220 default "999999" if PARISC && !PA20 220 default "999999" if PARISC && !PA20
221 default "999999" if DEBUG_SPINLOCK || DEBUG_LOCK_ALLOC
222 default "999999" if !64BIT && GENERIC_LOCKBREAK
223 default "4" 221 default "4"
224 222
225config ARCH_ENABLE_SPLIT_PMD_PTLOCK 223config ARCH_ENABLE_SPLIT_PMD_PTLOCK
diff --git a/mm/memory.c b/mm/memory.c
index d05c6b10e926..24ffae2a530e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4270,3 +4270,22 @@ void copy_user_huge_page(struct page *dst, struct page *src,
4270 } 4270 }
4271} 4271}
4272#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ 4272#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
4273
4274#if USE_SPLIT_PTE_PTLOCKS
4275bool __ptlock_alloc(struct page *page)
4276{
4277 spinlock_t *ptl;
4278
4279 ptl = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
4280 if (!ptl)
4281 return false;
4282 page->ptl = (unsigned long)ptl;
4283 return true;
4284}
4285
4286void __ptlock_free(struct page *page)
4287{
4288 if (sizeof(spinlock_t) > sizeof(page->ptl))
4289 kfree((spinlock_t *)page->ptl);
4290}
4291#endif