diff options
author | Peter Zijlstra <peterz@infradead.org> | 2013-11-14 17:31:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 19:32:20 -0500 |
commit | 539edb5846c740d78a8b6c2e43a99ca4323df68f (patch) | |
tree | dd03e1a7149f101f42311eac41e2857816cce36c | |
parent | 49076ec2ccaf68610aa03d96bced9a6694b93ca1 (diff) |
mm: properly separate the bloated ptl from the regular case
Use kernel/bounds.c to convert build-time spinlock_t size check into a
preprocessor symbol and apply that to properly separate the page::ptl
situation.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/mm.h | 24 | ||||
-rw-r--r-- | include/linux/mm_types.h | 9 | ||||
-rw-r--r-- | kernel/bounds.c | 2 | ||||
-rw-r--r-- | mm/memory.c | 11 |
4 files changed, 25 insertions, 21 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index d0339741b6ce..1cedd000cf29 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -1317,27 +1317,29 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a | |||
1317 | #endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */ | 1317 | #endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */ |
1318 | 1318 | ||
1319 | #if USE_SPLIT_PTE_PTLOCKS | 1319 | #if USE_SPLIT_PTE_PTLOCKS |
1320 | bool __ptlock_alloc(struct page *page); | 1320 | #if BLOATED_SPINLOCKS |
1321 | void __ptlock_free(struct page *page); | 1321 | extern bool ptlock_alloc(struct page *page); |
1322 | extern void ptlock_free(struct page *page); | ||
1323 | |||
1324 | static inline spinlock_t *ptlock_ptr(struct page *page) | ||
1325 | { | ||
1326 | return page->ptl; | ||
1327 | } | ||
1328 | #else /* BLOATED_SPINLOCKS */ | ||
1322 | static inline bool ptlock_alloc(struct page *page) | 1329 | static inline bool ptlock_alloc(struct page *page) |
1323 | { | 1330 | { |
1324 | if (sizeof(spinlock_t) > sizeof(page->ptl)) | ||
1325 | return __ptlock_alloc(page); | ||
1326 | return true; | 1331 | return true; |
1327 | } | 1332 | } |
1333 | |||
1328 | static inline void ptlock_free(struct page *page) | 1334 | static inline void ptlock_free(struct page *page) |
1329 | { | 1335 | { |
1330 | if (sizeof(spinlock_t) > sizeof(page->ptl)) | ||
1331 | __ptlock_free(page); | ||
1332 | } | 1336 | } |
1333 | 1337 | ||
1334 | static inline spinlock_t *ptlock_ptr(struct page *page) | 1338 | static inline spinlock_t *ptlock_ptr(struct page *page) |
1335 | { | 1339 | { |
1336 | if (sizeof(spinlock_t) > sizeof(page->ptl)) | 1340 | return &page->ptl; |
1337 | return (spinlock_t *) page->ptl; | ||
1338 | else | ||
1339 | return (spinlock_t *) &page->ptl; | ||
1340 | } | 1341 | } |
1342 | #endif /* BLOATED_SPINLOCKS */ | ||
1341 | 1343 | ||
1342 | static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd) | 1344 | static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd) |
1343 | { | 1345 | { |
@@ -1354,7 +1356,7 @@ static inline bool ptlock_init(struct page *page) | |||
1354 | * slab code uses page->slab_cache and page->first_page (for tail | 1356 | * slab code uses page->slab_cache and page->first_page (for tail |
1355 | * pages), which share storage with page->ptl. | 1357 | * pages), which share storage with page->ptl. |
1356 | */ | 1358 | */ |
1357 | VM_BUG_ON(page->ptl); | 1359 | VM_BUG_ON(*(unsigned long *)&page->ptl); |
1358 | if (!ptlock_alloc(page)) | 1360 | if (!ptlock_alloc(page)) |
1359 | return false; | 1361 | return false; |
1360 | spin_lock_init(ptlock_ptr(page)); | 1362 | spin_lock_init(ptlock_ptr(page)); |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 423da79877e6..10f5a7272b80 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -147,10 +147,11 @@ struct page { | |||
147 | * system if PG_buddy is set. | 147 | * system if PG_buddy is set. |
148 | */ | 148 | */ |
149 | #if USE_SPLIT_PTE_PTLOCKS | 149 | #if USE_SPLIT_PTE_PTLOCKS |
150 | unsigned long ptl; /* It's spinlock_t if it fits to long, | 150 | #if BLOATED_SPINLOCKS |
151 | * otherwise it's pointer to dynamicaly | 151 | spinlock_t *ptl; |
152 | * allocated spinlock_t. | 152 | #else |
153 | */ | 153 | spinlock_t ptl; |
154 | #endif | ||
154 | #endif | 155 | #endif |
155 | struct kmem_cache *slab_cache; /* SL[AU]B: Pointer to slab */ | 156 | struct kmem_cache *slab_cache; /* SL[AU]B: Pointer to slab */ |
156 | struct page *first_page; /* Compound tail pages */ | 157 | struct page *first_page; /* Compound tail pages */ |
diff --git a/kernel/bounds.c b/kernel/bounds.c index e8ca97b5c386..578782ef6ae1 100644 --- a/kernel/bounds.c +++ b/kernel/bounds.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kbuild.h> | 11 | #include <linux/kbuild.h> |
12 | #include <linux/page_cgroup.h> | 12 | #include <linux/page_cgroup.h> |
13 | #include <linux/log2.h> | 13 | #include <linux/log2.h> |
14 | #include <linux/spinlock.h> | ||
14 | 15 | ||
15 | void foo(void) | 16 | void foo(void) |
16 | { | 17 | { |
@@ -21,5 +22,6 @@ void foo(void) | |||
21 | #ifdef CONFIG_SMP | 22 | #ifdef CONFIG_SMP |
22 | DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS)); | 23 | DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS)); |
23 | #endif | 24 | #endif |
25 | DEFINE(BLOATED_SPINLOCKS, sizeof(spinlock_t) > sizeof(int)); | ||
24 | /* End of constants */ | 26 | /* End of constants */ |
25 | } | 27 | } |
diff --git a/mm/memory.c b/mm/memory.c index 24ffae2a530e..5d9025f3b3e1 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -4271,21 +4271,20 @@ void copy_user_huge_page(struct page *dst, struct page *src, | |||
4271 | } | 4271 | } |
4272 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ | 4272 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ |
4273 | 4273 | ||
4274 | #if USE_SPLIT_PTE_PTLOCKS | 4274 | #if USE_SPLIT_PTE_PTLOCKS && BLOATED_SPINLOCKS |
4275 | bool __ptlock_alloc(struct page *page) | 4275 | bool ptlock_alloc(struct page *page) |
4276 | { | 4276 | { |
4277 | spinlock_t *ptl; | 4277 | spinlock_t *ptl; |
4278 | 4278 | ||
4279 | ptl = kmalloc(sizeof(spinlock_t), GFP_KERNEL); | 4279 | ptl = kmalloc(sizeof(spinlock_t), GFP_KERNEL); |
4280 | if (!ptl) | 4280 | if (!ptl) |
4281 | return false; | 4281 | return false; |
4282 | page->ptl = (unsigned long)ptl; | 4282 | page->ptl = ptl; |
4283 | return true; | 4283 | return true; |
4284 | } | 4284 | } |
4285 | 4285 | ||
4286 | void __ptlock_free(struct page *page) | 4286 | void ptlock_free(struct page *page) |
4287 | { | 4287 | { |
4288 | if (sizeof(spinlock_t) > sizeof(page->ptl)) | 4288 | kfree(page->ptl); |
4289 | kfree((spinlock_t *)page->ptl); | ||
4290 | } | 4289 | } |
4291 | #endif | 4290 | #endif |