diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 21:46:22 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 21:46:22 -0500 |
| commit | 73da9e1a9f310a449eeb9bf5735a9cd475fef5e2 (patch) | |
| tree | 82cd78255b0a480340a8427e7ba5586df8280ac4 | |
| parent | b2fe5fa68642860e7de76167c3111623aa0d5de1 (diff) | |
| parent | 3f56a2f8030071cf86520ef4fc3045ba6856e610 (diff) | |
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton:
- misc fixes
- ocfs2 updates
- most of MM
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (118 commits)
mm: remove PG_highmem description
tools, vm: new option to specify kpageflags file
mm/swap.c: make functions and their kernel-doc agree
mm, memory_hotplug: fix memmap initialization
mm: correct comments regarding do_fault_around()
mm: numa: do not trap faults on shared data section pages.
hugetlb, mbind: fall back to default policy if vma is NULL
hugetlb, mempolicy: fix the mbind hugetlb migration
mm, hugetlb: further simplify hugetlb allocation API
mm, hugetlb: get rid of surplus page accounting tricks
mm, hugetlb: do not rely on overcommit limit during migration
mm, hugetlb: integrate giga hugetlb more naturally to the allocation path
mm, hugetlb: unify core page allocation accounting and initialization
mm/memcontrol.c: try harder to decrease [memory,memsw].limit_in_bytes
mm/memcontrol.c: make local symbol static
mm/hmm: fix uninitialized use of 'entry' in hmm_vma_walk_pmd()
include/linux/mmzone.h: fix explanation of lower bits in the SPARSEMEM mem_map pointer
mm/compaction.c: fix comment for try_to_compact_pages()
mm/page_ext.c: make page_ext_init a noop when CONFIG_PAGE_EXTENSION but nothing uses it
zsmalloc: use U suffix for negative literals being shifted
...
118 files changed, 2607 insertions, 1863 deletions
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 5025ff9307e6..ff234d229cbb 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
| @@ -30,7 +30,6 @@ Currently, these files are in /proc/sys/vm: | |||
| 30 | - dirty_writeback_centisecs | 30 | - dirty_writeback_centisecs |
| 31 | - drop_caches | 31 | - drop_caches |
| 32 | - extfrag_threshold | 32 | - extfrag_threshold |
| 33 | - hugepages_treat_as_movable | ||
| 34 | - hugetlb_shm_group | 33 | - hugetlb_shm_group |
| 35 | - laptop_mode | 34 | - laptop_mode |
| 36 | - legacy_va_layout | 35 | - legacy_va_layout |
| @@ -261,30 +260,6 @@ any throttling. | |||
| 261 | 260 | ||
| 262 | ============================================================== | 261 | ============================================================== |
| 263 | 262 | ||
| 264 | hugepages_treat_as_movable | ||
| 265 | |||
| 266 | This parameter controls whether we can allocate hugepages from ZONE_MOVABLE | ||
| 267 | or not. If set to non-zero, hugepages can be allocated from ZONE_MOVABLE. | ||
| 268 | ZONE_MOVABLE is created when kernel boot parameter kernelcore= is specified, | ||
| 269 | so this parameter has no effect if used without kernelcore=. | ||
| 270 | |||
| 271 | Hugepage migration is now available in some situations which depend on the | ||
| 272 | architecture and/or the hugepage size. If a hugepage supports migration, | ||
| 273 | allocation from ZONE_MOVABLE is always enabled for the hugepage regardless | ||
| 274 | of the value of this parameter. | ||
| 275 | IOW, this parameter affects only non-migratable hugepages. | ||
| 276 | |||
| 277 | Assuming that hugepages are not migratable in your system, one usecase of | ||
| 278 | this parameter is that users can make hugepage pool more extensible by | ||
| 279 | enabling the allocation from ZONE_MOVABLE. This is because on ZONE_MOVABLE | ||
| 280 | page reclaim/migration/compaction work more and you can get contiguous | ||
| 281 | memory more likely. Note that using ZONE_MOVABLE for non-migratable | ||
| 282 | hugepages can do harm to other features like memory hotremove (because | ||
| 283 | memory hotremove expects that memory blocks on ZONE_MOVABLE are always | ||
| 284 | removable,) so it's a trade-off responsible for the users. | ||
| 285 | |||
| 286 | ============================================================== | ||
| 287 | |||
| 288 | hugetlb_shm_group | 263 | hugetlb_shm_group |
| 289 | 264 | ||
| 290 | hugetlb_shm_group contains group id that is allowed to create SysV | 265 | hugetlb_shm_group contains group id that is allowed to create SysV |
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index 59cbc803aad6..faf077d50d42 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt | |||
| @@ -20,19 +20,20 @@ options. | |||
| 20 | 20 | ||
| 21 | The /proc/meminfo file provides information about the total number of | 21 | The /proc/meminfo file provides information about the total number of |
| 22 | persistent hugetlb pages in the kernel's huge page pool. It also displays | 22 | persistent hugetlb pages in the kernel's huge page pool. It also displays |
| 23 | information about the number of free, reserved and surplus huge pages and the | 23 | default huge page size and information about the number of free, reserved |
| 24 | default huge page size. The huge page size is needed for generating the | 24 | and surplus huge pages in the pool of huge pages of default size. |
| 25 | proper alignment and size of the arguments to system calls that map huge page | 25 | The huge page size is needed for generating the proper alignment and |
| 26 | regions. | 26 | size of the arguments to system calls that map huge page regions. |
| 27 | 27 | ||
| 28 | The output of "cat /proc/meminfo" will include lines like: | 28 | The output of "cat /proc/meminfo" will include lines like: |
| 29 | 29 | ||
| 30 | ..... | 30 | ..... |
| 31 | HugePages_Total: vvv | 31 | HugePages_Total: uuu |
| 32 | HugePages_Free: www | 32 | HugePages_Free: vvv |
| 33 | HugePages_Rsvd: xxx | 33 | HugePages_Rsvd: www |
| 34 | HugePages_Surp: yyy | 34 | HugePages_Surp: xxx |
| 35 | Hugepagesize: zzz kB | 35 | Hugepagesize: yyy kB |
| 36 | Hugetlb: zzz kB | ||
| 36 | 37 | ||
| 37 | where: | 38 | where: |
| 38 | HugePages_Total is the size of the pool of huge pages. | 39 | HugePages_Total is the size of the pool of huge pages. |
| @@ -47,6 +48,14 @@ HugePages_Surp is short for "surplus," and is the number of huge pages in | |||
| 47 | the pool above the value in /proc/sys/vm/nr_hugepages. The | 48 | the pool above the value in /proc/sys/vm/nr_hugepages. The |
| 48 | maximum number of surplus huge pages is controlled by | 49 | maximum number of surplus huge pages is controlled by |
| 49 | /proc/sys/vm/nr_overcommit_hugepages. | 50 | /proc/sys/vm/nr_overcommit_hugepages. |
| 51 | Hugepagesize is the default hugepage size (in Kb). | ||
| 52 | Hugetlb is the total amount of memory (in kB), consumed by huge | ||
| 53 | pages of all sizes. | ||
| 54 | If huge pages of different sizes are in use, this number | ||
| 55 | will exceed HugePages_Total * Hugepagesize. To get more | ||
| 56 | detailed information, please, refer to | ||
| 57 | /sys/kernel/mm/hugepages (described below). | ||
| 58 | |||
| 50 | 59 | ||
| 51 | /proc/filesystems should also show a filesystem of type "hugetlbfs" configured | 60 | /proc/filesystems should also show a filesystem of type "hugetlbfs" configured |
| 52 | in the kernel. | 61 | in the kernel. |
diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h index b18fcb606908..dc8ee011882f 100644 --- a/arch/arc/include/asm/hugepage.h +++ b/arch/arc/include/asm/hugepage.h | |||
| @@ -74,4 +74,7 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); | |||
| 74 | extern void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, | 74 | extern void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, |
| 75 | unsigned long end); | 75 | unsigned long end); |
| 76 | 76 | ||
| 77 | /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/ | ||
| 78 | #define pmdp_establish generic_pmdp_establish | ||
| 79 | |||
| 77 | #endif | 80 | #endif |
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 1a7a17b2a1ba..2a4836087358 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h | |||
| @@ -249,6 +249,9 @@ PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF); | |||
| 249 | #define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) | 249 | #define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) |
| 250 | #define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot) | 250 | #define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot) |
| 251 | 251 | ||
| 252 | /* No hardware dirty/accessed bits -- generic_pmdp_establish() fits */ | ||
| 253 | #define pmdp_establish generic_pmdp_establish | ||
| 254 | |||
| 252 | /* represent a notpresent pmd by faulting entry, this is used by pmdp_invalidate */ | 255 | /* represent a notpresent pmd by faulting entry, this is used by pmdp_invalidate */ |
| 253 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | 256 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) |
| 254 | { | 257 | { |
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 89167c43ebb5..094374c82db0 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
| @@ -706,6 +706,13 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, | |||
| 706 | { | 706 | { |
| 707 | ptep_set_wrprotect(mm, address, (pte_t *)pmdp); | 707 | ptep_set_wrprotect(mm, address, (pte_t *)pmdp); |
| 708 | } | 708 | } |
| 709 | |||
| 710 | #define pmdp_establish pmdp_establish | ||
| 711 | static inline pmd_t pmdp_establish(struct vm_area_struct *vma, | ||
| 712 | unsigned long address, pmd_t *pmdp, pmd_t pmd) | ||
| 713 | { | ||
| 714 | return __pmd(xchg_relaxed(&pmd_val(*pmdp), pmd_val(pmd))); | ||
| 715 | } | ||
| 709 | #endif | 716 | #endif |
| 710 | 717 | ||
| 711 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 718 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index b88a8dd14933..a6f300a208bd 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c | |||
| @@ -115,14 +115,6 @@ static void set_eit_vector_entries(void) | |||
| 115 | _flush_cache_copyback_all(); | 115 | _flush_cache_copyback_all(); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | void abort(void) | ||
| 119 | { | ||
| 120 | BUG(); | ||
| 121 | |||
| 122 | /* if that doesn't kill us, halt */ | ||
| 123 | panic("Oops failed to kill thread"); | ||
| 124 | } | ||
| 125 | |||
| 126 | void __init trap_init(void) | 118 | void __init trap_init(void) |
| 127 | { | 119 | { |
| 128 | set_eit_vector_entries(); | 120 | set_eit_vector_entries(); |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 1a508a74d48d..129e0328367f 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
| @@ -534,6 +534,9 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, | |||
| 534 | 534 | ||
| 535 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 535 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 536 | 536 | ||
| 537 | /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/ | ||
| 538 | #define pmdp_establish generic_pmdp_establish | ||
| 539 | |||
| 537 | #define has_transparent_hugepage has_transparent_hugepage | 540 | #define has_transparent_hugepage has_transparent_hugepage |
| 538 | extern int has_transparent_hugepage(void); | 541 | extern int has_transparent_hugepage(void); |
| 539 | 542 | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e92432ae9737..73fcf592ee91 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
| @@ -151,7 +151,6 @@ config PPC | |||
| 151 | select ARCH_MIGHT_HAVE_PC_PARPORT | 151 | select ARCH_MIGHT_HAVE_PC_PARPORT |
| 152 | select ARCH_MIGHT_HAVE_PC_SERIO | 152 | select ARCH_MIGHT_HAVE_PC_SERIO |
| 153 | select ARCH_SUPPORTS_ATOMIC_RMW | 153 | select ARCH_SUPPORTS_ATOMIC_RMW |
| 154 | select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT | ||
| 155 | select ARCH_USE_BUILTIN_BSWAP | 154 | select ARCH_USE_BUILTIN_BSWAP |
| 156 | select ARCH_USE_CMPXCHG_LOCKREF if PPC64 | 155 | select ARCH_USE_CMPXCHG_LOCKREF if PPC64 |
| 157 | select ARCH_WANT_IPC_PARSE_VERSION | 156 | select ARCH_WANT_IPC_PARSE_VERSION |
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 197ced1eaaa0..2d9df40446f6 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h | |||
| @@ -101,8 +101,6 @@ extern pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, | |||
| 101 | extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 101 | extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
| 102 | pgtable_t pgtable); | 102 | pgtable_t pgtable); |
| 103 | extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); | 103 | extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); |
| 104 | extern void hash__pmdp_huge_split_prepare(struct vm_area_struct *vma, | ||
| 105 | unsigned long address, pmd_t *pmdp); | ||
| 106 | extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, | 104 | extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, |
| 107 | unsigned long addr, pmd_t *pmdp); | 105 | unsigned long addr, pmd_t *pmdp); |
| 108 | extern int hash__has_transparent_hugepage(void); | 106 | extern int hash__has_transparent_hugepage(void); |
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 8d40cf03cb67..cb46d1034f33 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h | |||
| @@ -203,8 +203,6 @@ extern pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, | |||
| 203 | extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 203 | extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
| 204 | pgtable_t pgtable); | 204 | pgtable_t pgtable); |
| 205 | extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); | 205 | extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); |
| 206 | extern void hash__pmdp_huge_split_prepare(struct vm_area_struct *vma, | ||
| 207 | unsigned long address, pmd_t *pmdp); | ||
| 208 | extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, | 206 | extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, |
| 209 | unsigned long addr, pmd_t *pmdp); | 207 | unsigned long addr, pmd_t *pmdp); |
| 210 | extern int hash__has_transparent_hugepage(void); | 208 | extern int hash__has_transparent_hugepage(void); |
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 44697817ccc6..6ca1208cedcb 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h | |||
| @@ -1137,17 +1137,8 @@ static inline pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, | |||
| 1137 | } | 1137 | } |
| 1138 | 1138 | ||
| 1139 | #define __HAVE_ARCH_PMDP_INVALIDATE | 1139 | #define __HAVE_ARCH_PMDP_INVALIDATE |
| 1140 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 1140 | extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
| 1141 | pmd_t *pmdp); | 1141 | pmd_t *pmdp); |
| 1142 | |||
| 1143 | #define __HAVE_ARCH_PMDP_HUGE_SPLIT_PREPARE | ||
| 1144 | static inline void pmdp_huge_split_prepare(struct vm_area_struct *vma, | ||
| 1145 | unsigned long address, pmd_t *pmdp) | ||
| 1146 | { | ||
| 1147 | if (radix_enabled()) | ||
| 1148 | return radix__pmdp_huge_split_prepare(vma, address, pmdp); | ||
| 1149 | return hash__pmdp_huge_split_prepare(vma, address, pmdp); | ||
| 1150 | } | ||
| 1151 | 1142 | ||
| 1152 | #define pmd_move_must_withdraw pmd_move_must_withdraw | 1143 | #define pmd_move_must_withdraw pmd_move_must_withdraw |
| 1153 | struct spinlock; | 1144 | struct spinlock; |
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index 19c44e1495ae..365010f66570 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h | |||
| @@ -269,12 +269,6 @@ static inline pmd_t radix__pmd_mkhuge(pmd_t pmd) | |||
| 269 | return __pmd(pmd_val(pmd) | _PAGE_PTE | R_PAGE_LARGE); | 269 | return __pmd(pmd_val(pmd) | _PAGE_PTE | R_PAGE_LARGE); |
| 270 | return __pmd(pmd_val(pmd) | _PAGE_PTE); | 270 | return __pmd(pmd_val(pmd) | _PAGE_PTE); |
| 271 | } | 271 | } |
| 272 | static inline void radix__pmdp_huge_split_prepare(struct vm_area_struct *vma, | ||
| 273 | unsigned long address, pmd_t *pmdp) | ||
| 274 | { | ||
| 275 | /* Nothing to do for radix. */ | ||
| 276 | return; | ||
| 277 | } | ||
| 278 | 272 | ||
| 279 | extern unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, | 273 | extern unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, |
| 280 | pmd_t *pmdp, unsigned long clr, | 274 | pmd_t *pmdp, unsigned long clr, |
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c index 3b65917785a5..422e80253a33 100644 --- a/arch/powerpc/mm/pgtable-book3s64.c +++ b/arch/powerpc/mm/pgtable-book3s64.c | |||
| @@ -90,16 +90,19 @@ void serialize_against_pte_lookup(struct mm_struct *mm) | |||
| 90 | * We use this to invalidate a pmdp entry before switching from a | 90 | * We use this to invalidate a pmdp entry before switching from a |
| 91 | * hugepte to regular pmd entry. | 91 | * hugepte to regular pmd entry. |
| 92 | */ | 92 | */ |
| 93 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 93 | pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
| 94 | pmd_t *pmdp) | 94 | pmd_t *pmdp) |
| 95 | { | 95 | { |
| 96 | pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0); | 96 | unsigned long old_pmd; |
| 97 | |||
| 98 | old_pmd = pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0); | ||
| 97 | flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | 99 | flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE); |
| 98 | /* | 100 | /* |
| 99 | * This ensures that generic code that rely on IRQ disabling | 101 | * This ensures that generic code that rely on IRQ disabling |
| 100 | * to prevent a parallel THP split work as expected. | 102 | * to prevent a parallel THP split work as expected. |
| 101 | */ | 103 | */ |
| 102 | serialize_against_pte_lookup(vma->vm_mm); | 104 | serialize_against_pte_lookup(vma->vm_mm); |
| 105 | return __pmd(old_pmd); | ||
| 103 | } | 106 | } |
| 104 | 107 | ||
| 105 | static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) | 108 | static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) |
diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c index ec277913e01b..469808e77e58 100644 --- a/arch/powerpc/mm/pgtable-hash64.c +++ b/arch/powerpc/mm/pgtable-hash64.c | |||
| @@ -296,28 +296,6 @@ pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) | |||
| 296 | return pgtable; | 296 | return pgtable; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | void hash__pmdp_huge_split_prepare(struct vm_area_struct *vma, | ||
| 300 | unsigned long address, pmd_t *pmdp) | ||
| 301 | { | ||
| 302 | VM_BUG_ON(address & ~HPAGE_PMD_MASK); | ||
| 303 | VM_BUG_ON(REGION_ID(address) != USER_REGION_ID); | ||
| 304 | VM_BUG_ON(pmd_devmap(*pmdp)); | ||
| 305 | |||
| 306 | /* | ||
| 307 | * We can't mark the pmd none here, because that will cause a race | ||
| 308 | * against exit_mmap. We need to continue mark pmd TRANS HUGE, while | ||
| 309 | * we spilt, but at the same time we wan't rest of the ppc64 code | ||
| 310 | * not to insert hash pte on this, because we will be modifying | ||
| 311 | * the deposited pgtable in the caller of this function. Hence | ||
| 312 | * clear the _PAGE_USER so that we move the fault handling to | ||
| 313 | * higher level function and that will serialize against ptl. | ||
| 314 | * We need to flush existing hash pte entries here even though, | ||
| 315 | * the translation is still valid, because we will withdraw | ||
| 316 | * pgtable_t after this. | ||
| 317 | */ | ||
| 318 | pmd_hugepage_update(vma->vm_mm, address, pmdp, 0, _PAGE_PRIVILEGED); | ||
| 319 | } | ||
| 320 | |||
| 321 | /* | 299 | /* |
| 322 | * A linux hugepage PMD was changed and the corresponding hash table entries | 300 | * A linux hugepage PMD was changed and the corresponding hash table entries |
| 323 | * neesd to be flushed. | 301 | * neesd to be flushed. |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 9376637229c9..0105ce28e246 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -108,7 +108,6 @@ config S390 | |||
| 108 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE | 108 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE |
| 109 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION | 109 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION |
| 110 | select ARCH_SUPPORTS_ATOMIC_RMW | 110 | select ARCH_SUPPORTS_ATOMIC_RMW |
| 111 | select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT | ||
| 112 | select ARCH_SUPPORTS_NUMA_BALANCING | 111 | select ARCH_SUPPORTS_NUMA_BALANCING |
| 113 | select ARCH_USE_BUILTIN_BSWAP | 112 | select ARCH_USE_BUILTIN_BSWAP |
| 114 | select ARCH_USE_CMPXCHG_LOCKREF | 113 | select ARCH_USE_CMPXCHG_LOCKREF |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 0a6b0286c32e..2d24d33bf188 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -1505,12 +1505,12 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, | |||
| 1505 | } | 1505 | } |
| 1506 | 1506 | ||
| 1507 | #define __HAVE_ARCH_PMDP_INVALIDATE | 1507 | #define __HAVE_ARCH_PMDP_INVALIDATE |
| 1508 | static inline void pmdp_invalidate(struct vm_area_struct *vma, | 1508 | static inline pmd_t pmdp_invalidate(struct vm_area_struct *vma, |
| 1509 | unsigned long addr, pmd_t *pmdp) | 1509 | unsigned long addr, pmd_t *pmdp) |
| 1510 | { | 1510 | { |
| 1511 | pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); | 1511 | pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); |
| 1512 | 1512 | ||
| 1513 | pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); | 1513 | return pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); |
| 1514 | } | 1514 | } |
| 1515 | 1515 | ||
| 1516 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT | 1516 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 9937c5ff94a9..339920fdf9ed 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
| @@ -1010,7 +1010,7 @@ void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, | |||
| 1010 | pmd_t *pmd); | 1010 | pmd_t *pmd); |
| 1011 | 1011 | ||
| 1012 | #define __HAVE_ARCH_PMDP_INVALIDATE | 1012 | #define __HAVE_ARCH_PMDP_INVALIDATE |
| 1013 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 1013 | extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
| 1014 | pmd_t *pmdp); | 1014 | pmd_t *pmdp); |
| 1015 | 1015 | ||
| 1016 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 1016 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index 4ae86bc0d35c..847ddffbf38a 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
| @@ -219,17 +219,28 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
| 219 | } | 219 | } |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static inline pmd_t pmdp_establish(struct vm_area_struct *vma, | ||
| 223 | unsigned long address, pmd_t *pmdp, pmd_t pmd) | ||
| 224 | { | ||
| 225 | pmd_t old; | ||
| 226 | |||
| 227 | do { | ||
| 228 | old = *pmdp; | ||
| 229 | } while (cmpxchg64(&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd); | ||
| 230 | |||
| 231 | return old; | ||
| 232 | } | ||
| 233 | |||
| 222 | /* | 234 | /* |
| 223 | * This routine is only called when splitting a THP | 235 | * This routine is only called when splitting a THP |
| 224 | */ | 236 | */ |
| 225 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 237 | pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
| 226 | pmd_t *pmdp) | 238 | pmd_t *pmdp) |
| 227 | { | 239 | { |
| 228 | pmd_t entry = *pmdp; | 240 | pmd_t old, entry; |
| 229 | |||
| 230 | pmd_val(entry) &= ~_PAGE_VALID; | ||
| 231 | 241 | ||
| 232 | set_pmd_at(vma->vm_mm, address, pmdp, entry); | 242 | entry = __pmd(pmd_val(*pmdp) & ~_PAGE_VALID); |
| 243 | old = pmdp_establish(vma, address, pmdp, entry); | ||
| 233 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | 244 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); |
| 234 | 245 | ||
| 235 | /* | 246 | /* |
| @@ -240,6 +251,8 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | |||
| 240 | if ((pmd_val(entry) & _PAGE_PMD_HUGE) && | 251 | if ((pmd_val(entry) & _PAGE_PMD_HUGE) && |
| 241 | !is_huge_zero_page(pmd_page(entry))) | 252 | !is_huge_zero_page(pmd_page(entry))) |
| 242 | (vma->vm_mm)->context.thp_pte_count--; | 253 | (vma->vm_mm)->context.thp_pte_count--; |
| 254 | |||
| 255 | return old; | ||
| 243 | } | 256 | } |
| 244 | 257 | ||
| 245 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 258 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index fcd3b4d24eea..d416fd9fdb3b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -69,7 +69,6 @@ config X86 | |||
| 69 | select ARCH_MIGHT_HAVE_PC_PARPORT | 69 | select ARCH_MIGHT_HAVE_PC_PARPORT |
| 70 | select ARCH_MIGHT_HAVE_PC_SERIO | 70 | select ARCH_MIGHT_HAVE_PC_SERIO |
| 71 | select ARCH_SUPPORTS_ATOMIC_RMW | 71 | select ARCH_SUPPORTS_ATOMIC_RMW |
| 72 | select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT | ||
| 73 | select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 | 72 | select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 |
| 74 | select ARCH_USE_BUILTIN_BSWAP | 73 | select ARCH_USE_BUILTIN_BSWAP |
| 75 | select ARCH_USE_QUEUED_RWLOCKS | 74 | select ARCH_USE_QUEUED_RWLOCKS |
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index bc4af5453802..f24df59c40b2 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
| @@ -158,7 +158,6 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep) | |||
| 158 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) | 158 | #define native_ptep_get_and_clear(xp) native_local_ptep_get_and_clear(xp) |
| 159 | #endif | 159 | #endif |
| 160 | 160 | ||
| 161 | #ifdef CONFIG_SMP | ||
| 162 | union split_pmd { | 161 | union split_pmd { |
| 163 | struct { | 162 | struct { |
| 164 | u32 pmd_low; | 163 | u32 pmd_low; |
| @@ -166,6 +165,8 @@ union split_pmd { | |||
| 166 | }; | 165 | }; |
| 167 | pmd_t pmd; | 166 | pmd_t pmd; |
| 168 | }; | 167 | }; |
| 168 | |||
| 169 | #ifdef CONFIG_SMP | ||
| 169 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) | 170 | static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) |
| 170 | { | 171 | { |
| 171 | union split_pmd res, *orig = (union split_pmd *)pmdp; | 172 | union split_pmd res, *orig = (union split_pmd *)pmdp; |
| @@ -181,6 +182,40 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) | |||
| 181 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) | 182 | #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp) |
| 182 | #endif | 183 | #endif |
| 183 | 184 | ||
| 185 | #ifndef pmdp_establish | ||
| 186 | #define pmdp_establish pmdp_establish | ||
| 187 | static inline pmd_t pmdp_establish(struct vm_area_struct *vma, | ||
| 188 | unsigned long address, pmd_t *pmdp, pmd_t pmd) | ||
| 189 | { | ||
| 190 | pmd_t old; | ||
| 191 | |||
| 192 | /* | ||
| 193 | * If pmd has present bit cleared we can get away without expensive | ||
| 194 | * cmpxchg64: we can update pmdp half-by-half without racing with | ||
| 195 | * anybody. | ||
| 196 | */ | ||
| 197 | if (!(pmd_val(pmd) & _PAGE_PRESENT)) { | ||
| 198 | union split_pmd old, new, *ptr; | ||
| 199 | |||
| 200 | ptr = (union split_pmd *)pmdp; | ||
| 201 | |||
| 202 | new.pmd = pmd; | ||
| 203 | |||
| 204 | /* xchg acts as a barrier before setting of the high bits */ | ||
| 205 | old.pmd_low = xchg(&ptr->pmd_low, new.pmd_low); | ||
| 206 | old.pmd_high = ptr->pmd_high; | ||
| 207 | ptr->pmd_high = new.pmd_high; | ||
| 208 | return old.pmd; | ||
| 209 | } | ||
| 210 | |||
| 211 | do { | ||
| 212 | old = *pmdp; | ||
| 213 | } while (cmpxchg64(&pmdp->pmd, old.pmd, pmd.pmd) != old.pmd); | ||
| 214 | |||
| 215 | return old; | ||
| 216 | } | ||
| 217 | #endif | ||
| 218 | |||
| 184 | #ifdef CONFIG_SMP | 219 | #ifdef CONFIG_SMP |
| 185 | union split_pud { | 220 | union split_pud { |
| 186 | struct { | 221 | struct { |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index e42b8943cb1a..63c2552b6b65 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
| @@ -1109,6 +1109,21 @@ static inline int pud_write(pud_t pud) | |||
| 1109 | return pud_flags(pud) & _PAGE_RW; | 1109 | return pud_flags(pud) & _PAGE_RW; |
| 1110 | } | 1110 | } |
| 1111 | 1111 | ||
| 1112 | #ifndef pmdp_establish | ||
| 1113 | #define pmdp_establish pmdp_establish | ||
| 1114 | static inline pmd_t pmdp_establish(struct vm_area_struct *vma, | ||
| 1115 | unsigned long address, pmd_t *pmdp, pmd_t pmd) | ||
| 1116 | { | ||
| 1117 | if (IS_ENABLED(CONFIG_SMP)) { | ||
| 1118 | return xchg(pmdp, pmd); | ||
| 1119 | } else { | ||
| 1120 | pmd_t old = *pmdp; | ||
| 1121 | *pmdp = pmd; | ||
| 1122 | return old; | ||
| 1123 | } | ||
| 1124 | } | ||
| 1125 | #endif | ||
| 1126 | |||
| 1112 | /* | 1127 | /* |
| 1113 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); | 1128 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); |
| 1114 | * | 1129 | * |
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index e7b3ce123da6..70aceefe14d5 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c | |||
| @@ -77,6 +77,7 @@ static void do_remove(struct mmu_rb_handler *handler, | |||
| 77 | static void handle_remove(struct work_struct *work); | 77 | static void handle_remove(struct work_struct *work); |
| 78 | 78 | ||
| 79 | static const struct mmu_notifier_ops mn_opts = { | 79 | static const struct mmu_notifier_ops mn_opts = { |
| 80 | .flags = MMU_INVALIDATE_DOES_NOT_BLOCK, | ||
| 80 | .invalidate_range_start = mmu_notifier_range_start, | 81 | .invalidate_range_start = mmu_notifier_range_start, |
| 81 | }; | 82 | }; |
| 82 | 83 | ||
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c index 7d94e1d39e5e..df72493a0f13 100644 --- a/drivers/iommu/amd_iommu_v2.c +++ b/drivers/iommu/amd_iommu_v2.c | |||
| @@ -427,6 +427,7 @@ static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm) | |||
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | static const struct mmu_notifier_ops iommu_mn = { | 429 | static const struct mmu_notifier_ops iommu_mn = { |
| 430 | .flags = MMU_INVALIDATE_DOES_NOT_BLOCK, | ||
| 430 | .release = mn_release, | 431 | .release = mn_release, |
| 431 | .clear_flush_young = mn_clear_flush_young, | 432 | .clear_flush_young = mn_clear_flush_young, |
| 432 | .invalidate_range = mn_invalidate_range, | 433 | .invalidate_range = mn_invalidate_range, |
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index ed1cf7c5a43b..0a826eb7fe48 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c | |||
| @@ -276,6 +276,7 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm) | |||
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | static const struct mmu_notifier_ops intel_mmuops = { | 278 | static const struct mmu_notifier_ops intel_mmuops = { |
| 279 | .flags = MMU_INVALIDATE_DOES_NOT_BLOCK, | ||
| 279 | .release = intel_mm_release, | 280 | .release = intel_mm_release, |
| 280 | .change_pte = intel_change_pte, | 281 | .change_pte = intel_change_pte, |
| 281 | .invalidate_range = intel_invalidate_range, | 282 | .invalidate_range = intel_invalidate_range, |
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c index 9918eda0e05f..a3454eb56fbf 100644 --- a/drivers/misc/sgi-gru/grutlbpurge.c +++ b/drivers/misc/sgi-gru/grutlbpurge.c | |||
| @@ -258,6 +258,7 @@ static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm) | |||
| 258 | 258 | ||
| 259 | 259 | ||
| 260 | static const struct mmu_notifier_ops gru_mmuops = { | 260 | static const struct mmu_notifier_ops gru_mmuops = { |
| 261 | .flags = MMU_INVALIDATE_DOES_NOT_BLOCK, | ||
| 261 | .invalidate_range_start = gru_invalidate_range_start, | 262 | .invalidate_range_start = gru_invalidate_range_start, |
| 262 | .invalidate_range_end = gru_invalidate_range_end, | 263 | .invalidate_range_end = gru_invalidate_range_end, |
| 263 | .release = gru_release, | 264 | .release = gru_release, |
| @@ -44,6 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | /* The 'colour' (ie low bits) within a PMD of a page offset. */ | 45 | /* The 'colour' (ie low bits) within a PMD of a page offset. */ |
| 46 | #define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) | 46 | #define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) |
| 47 | #define PG_PMD_NR (PMD_SIZE >> PAGE_SHIFT) | ||
| 47 | 48 | ||
| 48 | static wait_queue_head_t wait_table[DAX_WAIT_TABLE_ENTRIES]; | 49 | static wait_queue_head_t wait_table[DAX_WAIT_TABLE_ENTRIES]; |
| 49 | 50 | ||
| @@ -375,8 +376,8 @@ restart: | |||
| 375 | * unmapped. | 376 | * unmapped. |
| 376 | */ | 377 | */ |
| 377 | if (pmd_downgrade && dax_is_zero_entry(entry)) | 378 | if (pmd_downgrade && dax_is_zero_entry(entry)) |
| 378 | unmap_mapping_range(mapping, | 379 | unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR, |
| 379 | (index << PAGE_SHIFT) & PMD_MASK, PMD_SIZE, 0); | 380 | PG_PMD_NR, false); |
| 380 | 381 | ||
| 381 | err = radix_tree_preload( | 382 | err = radix_tree_preload( |
| 382 | mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM); | 383 | mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM); |
| @@ -538,12 +539,10 @@ static void *dax_insert_mapping_entry(struct address_space *mapping, | |||
| 538 | if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_ZERO_PAGE)) { | 539 | if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_ZERO_PAGE)) { |
| 539 | /* we are replacing a zero page with block mapping */ | 540 | /* we are replacing a zero page with block mapping */ |
| 540 | if (dax_is_pmd_entry(entry)) | 541 | if (dax_is_pmd_entry(entry)) |
| 541 | unmap_mapping_range(mapping, | 542 | unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR, |
| 542 | (vmf->pgoff << PAGE_SHIFT) & PMD_MASK, | 543 | PG_PMD_NR, false); |
| 543 | PMD_SIZE, 0); | ||
| 544 | else /* pte entry */ | 544 | else /* pte entry */ |
| 545 | unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT, | 545 | unmap_mapping_pages(mapping, vmf->pgoff, 1, false); |
| 546 | PAGE_SIZE, 0); | ||
| 547 | } | 546 | } |
| 548 | 547 | ||
| 549 | spin_lock_irq(&mapping->tree_lock); | 548 | spin_lock_irq(&mapping->tree_lock); |
| @@ -636,8 +635,8 @@ static void dax_mapping_entry_mkclean(struct address_space *mapping, | |||
| 636 | pmd = pmd_mkclean(pmd); | 635 | pmd = pmd_mkclean(pmd); |
| 637 | set_pmd_at(vma->vm_mm, address, pmdp, pmd); | 636 | set_pmd_at(vma->vm_mm, address, pmdp, pmd); |
| 638 | unlock_pmd: | 637 | unlock_pmd: |
| 639 | spin_unlock(ptl); | ||
| 640 | #endif | 638 | #endif |
| 639 | spin_unlock(ptl); | ||
| 641 | } else { | 640 | } else { |
| 642 | if (pfn != pte_pfn(*ptep)) | 641 | if (pfn != pte_pfn(*ptep)) |
| 643 | goto unlock_pte; | 642 | goto unlock_pte; |
| @@ -1269,12 +1268,6 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, | |||
| 1269 | } | 1268 | } |
| 1270 | 1269 | ||
| 1271 | #ifdef CONFIG_FS_DAX_PMD | 1270 | #ifdef CONFIG_FS_DAX_PMD |
| 1272 | /* | ||
| 1273 | * The 'colour' (ie low bits) within a PMD of a page offset. This comes up | ||
| 1274 | * more often than one might expect in the below functions. | ||
| 1275 | */ | ||
| 1276 | #define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1) | ||
| 1277 | |||
| 1278 | static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, | 1271 | static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, |
| 1279 | void *entry) | 1272 | void *entry) |
| 1280 | { | 1273 | { |
diff --git a/fs/fcntl.c b/fs/fcntl.c index c7b9e0948107..e95fa0a352ea 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
| @@ -418,7 +418,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | |||
| 418 | break; | 418 | break; |
| 419 | case F_ADD_SEALS: | 419 | case F_ADD_SEALS: |
| 420 | case F_GET_SEALS: | 420 | case F_GET_SEALS: |
| 421 | err = shmem_fcntl(filp, cmd, arg); | 421 | err = memfd_fcntl(filp, cmd, arg); |
| 422 | break; | 422 | break; |
| 423 | case F_GET_RW_HINT: | 423 | case F_GET_RW_HINT: |
| 424 | case F_SET_RW_HINT: | 424 | case F_SET_RW_HINT: |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8a85f3f53446..8fe1b0aa2896 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
| @@ -55,16 +55,6 @@ struct hugetlbfs_config { | |||
| 55 | umode_t mode; | 55 | umode_t mode; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | struct hugetlbfs_inode_info { | ||
| 59 | struct shared_policy policy; | ||
| 60 | struct inode vfs_inode; | ||
| 61 | }; | ||
| 62 | |||
| 63 | static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode) | ||
| 64 | { | ||
| 65 | return container_of(inode, struct hugetlbfs_inode_info, vfs_inode); | ||
| 66 | } | ||
| 67 | |||
| 68 | int sysctl_hugetlb_shm_group; | 58 | int sysctl_hugetlb_shm_group; |
| 69 | 59 | ||
| 70 | enum { | 60 | enum { |
| @@ -520,8 +510,16 @@ static long hugetlbfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
| 520 | 510 | ||
| 521 | if (hole_end > hole_start) { | 511 | if (hole_end > hole_start) { |
| 522 | struct address_space *mapping = inode->i_mapping; | 512 | struct address_space *mapping = inode->i_mapping; |
| 513 | struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); | ||
| 523 | 514 | ||
| 524 | inode_lock(inode); | 515 | inode_lock(inode); |
| 516 | |||
| 517 | /* protected by i_mutex */ | ||
| 518 | if (info->seals & F_SEAL_WRITE) { | ||
| 519 | inode_unlock(inode); | ||
| 520 | return -EPERM; | ||
| 521 | } | ||
| 522 | |||
| 525 | i_mmap_lock_write(mapping); | 523 | i_mmap_lock_write(mapping); |
| 526 | if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root)) | 524 | if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root)) |
| 527 | hugetlb_vmdelete_list(&mapping->i_mmap, | 525 | hugetlb_vmdelete_list(&mapping->i_mmap, |
| @@ -539,6 +537,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, | |||
| 539 | loff_t len) | 537 | loff_t len) |
| 540 | { | 538 | { |
| 541 | struct inode *inode = file_inode(file); | 539 | struct inode *inode = file_inode(file); |
| 540 | struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); | ||
| 542 | struct address_space *mapping = inode->i_mapping; | 541 | struct address_space *mapping = inode->i_mapping; |
| 543 | struct hstate *h = hstate_inode(inode); | 542 | struct hstate *h = hstate_inode(inode); |
| 544 | struct vm_area_struct pseudo_vma; | 543 | struct vm_area_struct pseudo_vma; |
| @@ -570,6 +569,11 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, | |||
| 570 | if (error) | 569 | if (error) |
| 571 | goto out; | 570 | goto out; |
| 572 | 571 | ||
| 572 | if ((info->seals & F_SEAL_GROW) && offset + len > inode->i_size) { | ||
| 573 | error = -EPERM; | ||
| 574 | goto out; | ||
| 575 | } | ||
| 576 | |||
| 573 | /* | 577 | /* |
| 574 | * Initialize a pseudo vma as this is required by the huge page | 578 | * Initialize a pseudo vma as this is required by the huge page |
| 575 | * allocation routines. If NUMA is configured, use page index | 579 | * allocation routines. If NUMA is configured, use page index |
| @@ -660,6 +664,7 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 660 | struct hstate *h = hstate_inode(inode); | 664 | struct hstate *h = hstate_inode(inode); |
| 661 | int error; | 665 | int error; |
| 662 | unsigned int ia_valid = attr->ia_valid; | 666 | unsigned int ia_valid = attr->ia_valid; |
| 667 | struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); | ||
| 663 | 668 | ||
| 664 | BUG_ON(!inode); | 669 | BUG_ON(!inode); |
| 665 | 670 | ||
| @@ -668,9 +673,16 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 668 | return error; | 673 | return error; |
| 669 | 674 | ||
| 670 | if (ia_valid & ATTR_SIZE) { | 675 | if (ia_valid & ATTR_SIZE) { |
| 671 | if (attr->ia_size & ~huge_page_mask(h)) | 676 | loff_t oldsize = inode->i_size; |
| 677 | loff_t newsize = attr->ia_size; | ||
| 678 | |||
| 679 | if (newsize & ~huge_page_mask(h)) | ||
| 672 | return -EINVAL; | 680 | return -EINVAL; |
| 673 | error = hugetlb_vmtruncate(inode, attr->ia_size); | 681 | /* protected by i_mutex */ |
| 682 | if ((newsize < oldsize && (info->seals & F_SEAL_SHRINK)) || | ||
| 683 | (newsize > oldsize && (info->seals & F_SEAL_GROW))) | ||
| 684 | return -EPERM; | ||
| 685 | error = hugetlb_vmtruncate(inode, newsize); | ||
| 674 | if (error) | 686 | if (error) |
| 675 | return error; | 687 | return error; |
| 676 | } | 688 | } |
| @@ -722,6 +734,8 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, | |||
| 722 | 734 | ||
| 723 | inode = new_inode(sb); | 735 | inode = new_inode(sb); |
| 724 | if (inode) { | 736 | if (inode) { |
| 737 | struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode); | ||
| 738 | |||
| 725 | inode->i_ino = get_next_ino(); | 739 | inode->i_ino = get_next_ino(); |
| 726 | inode_init_owner(inode, dir, mode); | 740 | inode_init_owner(inode, dir, mode); |
| 727 | lockdep_set_class(&inode->i_mapping->i_mmap_rwsem, | 741 | lockdep_set_class(&inode->i_mapping->i_mmap_rwsem, |
| @@ -729,6 +743,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, | |||
| 729 | inode->i_mapping->a_ops = &hugetlbfs_aops; | 743 | inode->i_mapping->a_ops = &hugetlbfs_aops; |
| 730 | inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); | 744 | inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); |
| 731 | inode->i_mapping->private_data = resv_map; | 745 | inode->i_mapping->private_data = resv_map; |
| 746 | info->seals = F_SEAL_SEAL; | ||
| 732 | switch (mode & S_IFMT) { | 747 | switch (mode & S_IFMT) { |
| 733 | default: | 748 | default: |
| 734 | init_special_inode(inode, mode, dev); | 749 | init_special_inode(inode, mode, dev); |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 40b5cc97f7b0..917fadca8a7b 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
| @@ -311,7 +311,9 @@ struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type) | |||
| 311 | if (had_lock < 0) | 311 | if (had_lock < 0) |
| 312 | return ERR_PTR(had_lock); | 312 | return ERR_PTR(had_lock); |
| 313 | 313 | ||
| 314 | down_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
| 314 | acl = ocfs2_get_acl_nolock(inode, type, di_bh); | 315 | acl = ocfs2_get_acl_nolock(inode, type, di_bh); |
| 316 | up_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
| 315 | 317 | ||
| 316 | ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock); | 318 | ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock); |
| 317 | brelse(di_bh); | 319 | brelse(di_bh); |
| @@ -330,7 +332,9 @@ int ocfs2_acl_chmod(struct inode *inode, struct buffer_head *bh) | |||
| 330 | if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) | 332 | if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) |
| 331 | return 0; | 333 | return 0; |
| 332 | 334 | ||
| 335 | down_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
| 333 | acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, bh); | 336 | acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, bh); |
| 337 | up_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
| 334 | if (IS_ERR(acl) || !acl) | 338 | if (IS_ERR(acl) || !acl) |
| 335 | return PTR_ERR(acl); | 339 | return PTR_ERR(acl); |
| 336 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); | 340 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); |
| @@ -361,8 +365,10 @@ int ocfs2_init_acl(handle_t *handle, | |||
| 361 | 365 | ||
| 362 | if (!S_ISLNK(inode->i_mode)) { | 366 | if (!S_ISLNK(inode->i_mode)) { |
| 363 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { | 367 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { |
| 368 | down_read(&OCFS2_I(dir)->ip_xattr_sem); | ||
| 364 | acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT, | 369 | acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT, |
| 365 | dir_bh); | 370 | dir_bh); |
| 371 | up_read(&OCFS2_I(dir)->ip_xattr_sem); | ||
| 366 | if (IS_ERR(acl)) | 372 | if (IS_ERR(acl)) |
| 367 | return PTR_ERR(acl); | 373 | return PTR_ERR(acl); |
| 368 | } | 374 | } |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index ab5105f9767e..9a876bb07cac 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -165,6 +165,13 @@ static int ocfs2_dinode_insert_check(struct ocfs2_extent_tree *et, | |||
| 165 | struct ocfs2_extent_rec *rec); | 165 | struct ocfs2_extent_rec *rec); |
| 166 | static int ocfs2_dinode_sanity_check(struct ocfs2_extent_tree *et); | 166 | static int ocfs2_dinode_sanity_check(struct ocfs2_extent_tree *et); |
| 167 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et); | 167 | static void ocfs2_dinode_fill_root_el(struct ocfs2_extent_tree *et); |
| 168 | |||
| 169 | static int ocfs2_reuse_blk_from_dealloc(handle_t *handle, | ||
| 170 | struct ocfs2_extent_tree *et, | ||
| 171 | struct buffer_head **new_eb_bh, | ||
| 172 | int blk_wanted, int *blk_given); | ||
| 173 | static int ocfs2_is_dealloc_empty(struct ocfs2_extent_tree *et); | ||
| 174 | |||
| 168 | static const struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { | 175 | static const struct ocfs2_extent_tree_operations ocfs2_dinode_et_ops = { |
| 169 | .eo_set_last_eb_blk = ocfs2_dinode_set_last_eb_blk, | 176 | .eo_set_last_eb_blk = ocfs2_dinode_set_last_eb_blk, |
| 170 | .eo_get_last_eb_blk = ocfs2_dinode_get_last_eb_blk, | 177 | .eo_get_last_eb_blk = ocfs2_dinode_get_last_eb_blk, |
| @@ -448,6 +455,7 @@ static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et, | |||
| 448 | if (!obj) | 455 | if (!obj) |
| 449 | obj = (void *)bh->b_data; | 456 | obj = (void *)bh->b_data; |
| 450 | et->et_object = obj; | 457 | et->et_object = obj; |
| 458 | et->et_dealloc = NULL; | ||
| 451 | 459 | ||
| 452 | et->et_ops->eo_fill_root_el(et); | 460 | et->et_ops->eo_fill_root_el(et); |
| 453 | if (!et->et_ops->eo_fill_max_leaf_clusters) | 461 | if (!et->et_ops->eo_fill_max_leaf_clusters) |
| @@ -1158,7 +1166,7 @@ static int ocfs2_add_branch(handle_t *handle, | |||
| 1158 | struct buffer_head **last_eb_bh, | 1166 | struct buffer_head **last_eb_bh, |
| 1159 | struct ocfs2_alloc_context *meta_ac) | 1167 | struct ocfs2_alloc_context *meta_ac) |
| 1160 | { | 1168 | { |
| 1161 | int status, new_blocks, i; | 1169 | int status, new_blocks, i, block_given = 0; |
| 1162 | u64 next_blkno, new_last_eb_blk; | 1170 | u64 next_blkno, new_last_eb_blk; |
| 1163 | struct buffer_head *bh; | 1171 | struct buffer_head *bh; |
| 1164 | struct buffer_head **new_eb_bhs = NULL; | 1172 | struct buffer_head **new_eb_bhs = NULL; |
| @@ -1213,11 +1221,31 @@ static int ocfs2_add_branch(handle_t *handle, | |||
| 1213 | goto bail; | 1221 | goto bail; |
| 1214 | } | 1222 | } |
| 1215 | 1223 | ||
| 1216 | status = ocfs2_create_new_meta_bhs(handle, et, new_blocks, | 1224 | /* Firstyly, try to reuse dealloc since we have already estimated how |
| 1217 | meta_ac, new_eb_bhs); | 1225 | * many extent blocks we may use. |
| 1218 | if (status < 0) { | 1226 | */ |
| 1219 | mlog_errno(status); | 1227 | if (!ocfs2_is_dealloc_empty(et)) { |
| 1220 | goto bail; | 1228 | status = ocfs2_reuse_blk_from_dealloc(handle, et, |
| 1229 | new_eb_bhs, new_blocks, | ||
| 1230 | &block_given); | ||
| 1231 | if (status < 0) { | ||
| 1232 | mlog_errno(status); | ||
| 1233 | goto bail; | ||
| 1234 | } | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | BUG_ON(block_given > new_blocks); | ||
| 1238 | |||
| 1239 | if (block_given < new_blocks) { | ||
| 1240 | BUG_ON(!meta_ac); | ||
| 1241 | status = ocfs2_create_new_meta_bhs(handle, et, | ||
| 1242 | new_blocks - block_given, | ||
| 1243 | meta_ac, | ||
| 1244 | &new_eb_bhs[block_given]); | ||
| 1245 | if (status < 0) { | ||
| 1246 | mlog_errno(status); | ||
| 1247 | goto bail; | ||
| 1248 | } | ||
| 1221 | } | 1249 | } |
| 1222 | 1250 | ||
| 1223 | /* Note: new_eb_bhs[new_blocks - 1] is the guy which will be | 1251 | /* Note: new_eb_bhs[new_blocks - 1] is the guy which will be |
| @@ -1340,15 +1368,25 @@ static int ocfs2_shift_tree_depth(handle_t *handle, | |||
| 1340 | struct ocfs2_alloc_context *meta_ac, | 1368 | struct ocfs2_alloc_context *meta_ac, |
| 1341 | struct buffer_head **ret_new_eb_bh) | 1369 | struct buffer_head **ret_new_eb_bh) |
| 1342 | { | 1370 | { |
| 1343 | int status, i; | 1371 | int status, i, block_given = 0; |
| 1344 | u32 new_clusters; | 1372 | u32 new_clusters; |
| 1345 | struct buffer_head *new_eb_bh = NULL; | 1373 | struct buffer_head *new_eb_bh = NULL; |
| 1346 | struct ocfs2_extent_block *eb; | 1374 | struct ocfs2_extent_block *eb; |
| 1347 | struct ocfs2_extent_list *root_el; | 1375 | struct ocfs2_extent_list *root_el; |
| 1348 | struct ocfs2_extent_list *eb_el; | 1376 | struct ocfs2_extent_list *eb_el; |
| 1349 | 1377 | ||
| 1350 | status = ocfs2_create_new_meta_bhs(handle, et, 1, meta_ac, | 1378 | if (!ocfs2_is_dealloc_empty(et)) { |
| 1351 | &new_eb_bh); | 1379 | status = ocfs2_reuse_blk_from_dealloc(handle, et, |
| 1380 | &new_eb_bh, 1, | ||
| 1381 | &block_given); | ||
| 1382 | } else if (meta_ac) { | ||
| 1383 | status = ocfs2_create_new_meta_bhs(handle, et, 1, meta_ac, | ||
| 1384 | &new_eb_bh); | ||
| 1385 | |||
| 1386 | } else { | ||
| 1387 | BUG(); | ||
| 1388 | } | ||
| 1389 | |||
| 1352 | if (status < 0) { | 1390 | if (status < 0) { |
| 1353 | mlog_errno(status); | 1391 | mlog_errno(status); |
| 1354 | goto bail; | 1392 | goto bail; |
| @@ -1511,7 +1549,7 @@ static int ocfs2_grow_tree(handle_t *handle, struct ocfs2_extent_tree *et, | |||
| 1511 | int depth = le16_to_cpu(el->l_tree_depth); | 1549 | int depth = le16_to_cpu(el->l_tree_depth); |
| 1512 | struct buffer_head *bh = NULL; | 1550 | struct buffer_head *bh = NULL; |
| 1513 | 1551 | ||
| 1514 | BUG_ON(meta_ac == NULL); | 1552 | BUG_ON(meta_ac == NULL && ocfs2_is_dealloc_empty(et)); |
| 1515 | 1553 | ||
| 1516 | shift = ocfs2_find_branch_target(et, &bh); | 1554 | shift = ocfs2_find_branch_target(et, &bh); |
| 1517 | if (shift < 0) { | 1555 | if (shift < 0) { |
| @@ -2598,11 +2636,8 @@ static void ocfs2_unlink_subtree(handle_t *handle, | |||
| 2598 | int i; | 2636 | int i; |
| 2599 | struct buffer_head *root_bh = left_path->p_node[subtree_index].bh; | 2637 | struct buffer_head *root_bh = left_path->p_node[subtree_index].bh; |
| 2600 | struct ocfs2_extent_list *root_el = left_path->p_node[subtree_index].el; | 2638 | struct ocfs2_extent_list *root_el = left_path->p_node[subtree_index].el; |
| 2601 | struct ocfs2_extent_list *el; | ||
| 2602 | struct ocfs2_extent_block *eb; | 2639 | struct ocfs2_extent_block *eb; |
| 2603 | 2640 | ||
| 2604 | el = path_leaf_el(left_path); | ||
| 2605 | |||
| 2606 | eb = (struct ocfs2_extent_block *)right_path->p_node[subtree_index + 1].bh->b_data; | 2641 | eb = (struct ocfs2_extent_block *)right_path->p_node[subtree_index + 1].bh->b_data; |
| 2607 | 2642 | ||
| 2608 | for(i = 1; i < le16_to_cpu(root_el->l_next_free_rec); i++) | 2643 | for(i = 1; i < le16_to_cpu(root_el->l_next_free_rec); i++) |
| @@ -3938,7 +3973,7 @@ static void ocfs2_adjust_rightmost_records(handle_t *handle, | |||
| 3938 | struct ocfs2_path *path, | 3973 | struct ocfs2_path *path, |
| 3939 | struct ocfs2_extent_rec *insert_rec) | 3974 | struct ocfs2_extent_rec *insert_rec) |
| 3940 | { | 3975 | { |
| 3941 | int ret, i, next_free; | 3976 | int i, next_free; |
| 3942 | struct buffer_head *bh; | 3977 | struct buffer_head *bh; |
| 3943 | struct ocfs2_extent_list *el; | 3978 | struct ocfs2_extent_list *el; |
| 3944 | struct ocfs2_extent_rec *rec; | 3979 | struct ocfs2_extent_rec *rec; |
| @@ -3955,7 +3990,6 @@ static void ocfs2_adjust_rightmost_records(handle_t *handle, | |||
| 3955 | ocfs2_error(ocfs2_metadata_cache_get_super(et->et_ci), | 3990 | ocfs2_error(ocfs2_metadata_cache_get_super(et->et_ci), |
| 3956 | "Owner %llu has a bad extent list\n", | 3991 | "Owner %llu has a bad extent list\n", |
| 3957 | (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci)); | 3992 | (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci)); |
| 3958 | ret = -EIO; | ||
| 3959 | return; | 3993 | return; |
| 3960 | } | 3994 | } |
| 3961 | 3995 | ||
| @@ -5057,7 +5091,6 @@ int ocfs2_split_extent(handle_t *handle, | |||
| 5057 | struct buffer_head *last_eb_bh = NULL; | 5091 | struct buffer_head *last_eb_bh = NULL; |
| 5058 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; | 5092 | struct ocfs2_extent_rec *rec = &el->l_recs[split_index]; |
| 5059 | struct ocfs2_merge_ctxt ctxt; | 5093 | struct ocfs2_merge_ctxt ctxt; |
| 5060 | struct ocfs2_extent_list *rightmost_el; | ||
| 5061 | 5094 | ||
| 5062 | if (le32_to_cpu(rec->e_cpos) > le32_to_cpu(split_rec->e_cpos) || | 5095 | if (le32_to_cpu(rec->e_cpos) > le32_to_cpu(split_rec->e_cpos) || |
| 5063 | ((le32_to_cpu(rec->e_cpos) + le16_to_cpu(rec->e_leaf_clusters)) < | 5096 | ((le32_to_cpu(rec->e_cpos) + le16_to_cpu(rec->e_leaf_clusters)) < |
| @@ -5093,9 +5126,7 @@ int ocfs2_split_extent(handle_t *handle, | |||
| 5093 | } | 5126 | } |
| 5094 | 5127 | ||
| 5095 | eb = (struct ocfs2_extent_block *) last_eb_bh->b_data; | 5128 | eb = (struct ocfs2_extent_block *) last_eb_bh->b_data; |
| 5096 | rightmost_el = &eb->h_list; | 5129 | } |
| 5097 | } else | ||
| 5098 | rightmost_el = path_root_el(path); | ||
| 5099 | 5130 | ||
| 5100 | if (rec->e_cpos == split_rec->e_cpos && | 5131 | if (rec->e_cpos == split_rec->e_cpos && |
| 5101 | rec->e_leaf_clusters == split_rec->e_leaf_clusters) | 5132 | rec->e_leaf_clusters == split_rec->e_leaf_clusters) |
| @@ -6585,6 +6616,154 @@ ocfs2_find_per_slot_free_list(int type, | |||
| 6585 | return fl; | 6616 | return fl; |
| 6586 | } | 6617 | } |
| 6587 | 6618 | ||
| 6619 | static struct ocfs2_per_slot_free_list * | ||
| 6620 | ocfs2_find_preferred_free_list(int type, | ||
| 6621 | int preferred_slot, | ||
| 6622 | int *real_slot, | ||
| 6623 | struct ocfs2_cached_dealloc_ctxt *ctxt) | ||
| 6624 | { | ||
| 6625 | struct ocfs2_per_slot_free_list *fl = ctxt->c_first_suballocator; | ||
| 6626 | |||
| 6627 | while (fl) { | ||
| 6628 | if (fl->f_inode_type == type && fl->f_slot == preferred_slot) { | ||
| 6629 | *real_slot = fl->f_slot; | ||
| 6630 | return fl; | ||
| 6631 | } | ||
| 6632 | |||
| 6633 | fl = fl->f_next_suballocator; | ||
| 6634 | } | ||
| 6635 | |||
| 6636 | /* If we can't find any free list matching preferred slot, just use | ||
| 6637 | * the first one. | ||
| 6638 | */ | ||
| 6639 | fl = ctxt->c_first_suballocator; | ||
| 6640 | *real_slot = fl->f_slot; | ||
| 6641 | |||
| 6642 | return fl; | ||
| 6643 | } | ||
| 6644 | |||
| 6645 | /* Return Value 1 indicates empty */ | ||
| 6646 | static int ocfs2_is_dealloc_empty(struct ocfs2_extent_tree *et) | ||
| 6647 | { | ||
| 6648 | struct ocfs2_per_slot_free_list *fl = NULL; | ||
| 6649 | |||
| 6650 | if (!et->et_dealloc) | ||
| 6651 | return 1; | ||
| 6652 | |||
| 6653 | fl = et->et_dealloc->c_first_suballocator; | ||
| 6654 | if (!fl) | ||
| 6655 | return 1; | ||
| 6656 | |||
| 6657 | if (!fl->f_first) | ||
| 6658 | return 1; | ||
| 6659 | |||
| 6660 | return 0; | ||
| 6661 | } | ||
| 6662 | |||
| 6663 | /* If extent was deleted from tree due to extent rotation and merging, and | ||
| 6664 | * no metadata is reserved ahead of time. Try to reuse some extents | ||
| 6665 | * just deleted. This is only used to reuse extent blocks. | ||
| 6666 | * It is supposed to find enough extent blocks in dealloc if our estimation | ||
| 6667 | * on metadata is accurate. | ||
| 6668 | */ | ||
| 6669 | static int ocfs2_reuse_blk_from_dealloc(handle_t *handle, | ||
| 6670 | struct ocfs2_extent_tree *et, | ||
| 6671 | struct buffer_head **new_eb_bh, | ||
| 6672 | int blk_wanted, int *blk_given) | ||
| 6673 | { | ||
| 6674 | int i, status = 0, real_slot; | ||
| 6675 | struct ocfs2_cached_dealloc_ctxt *dealloc; | ||
| 6676 | struct ocfs2_per_slot_free_list *fl; | ||
| 6677 | struct ocfs2_cached_block_free *bf; | ||
| 6678 | struct ocfs2_extent_block *eb; | ||
| 6679 | struct ocfs2_super *osb = | ||
| 6680 | OCFS2_SB(ocfs2_metadata_cache_get_super(et->et_ci)); | ||
| 6681 | |||
| 6682 | *blk_given = 0; | ||
| 6683 | |||
| 6684 | /* If extent tree doesn't have a dealloc, this is not faulty. Just | ||
| 6685 | * tell upper caller dealloc can't provide any block and it should | ||
| 6686 | * ask for alloc to claim more space. | ||
| 6687 | */ | ||
| 6688 | dealloc = et->et_dealloc; | ||
| 6689 | if (!dealloc) | ||
| 6690 | goto bail; | ||
| 6691 | |||
| 6692 | for (i = 0; i < blk_wanted; i++) { | ||
| 6693 | /* Prefer to use local slot */ | ||
| 6694 | fl = ocfs2_find_preferred_free_list(EXTENT_ALLOC_SYSTEM_INODE, | ||
| 6695 | osb->slot_num, &real_slot, | ||
| 6696 | dealloc); | ||
| 6697 | /* If no more block can be reused, we should claim more | ||
| 6698 | * from alloc. Just return here normally. | ||
| 6699 | */ | ||
| 6700 | if (!fl) { | ||
| 6701 | status = 0; | ||
| 6702 | break; | ||
| 6703 | } | ||
| 6704 | |||
| 6705 | bf = fl->f_first; | ||
| 6706 | fl->f_first = bf->free_next; | ||
| 6707 | |||
| 6708 | new_eb_bh[i] = sb_getblk(osb->sb, bf->free_blk); | ||
| 6709 | if (new_eb_bh[i] == NULL) { | ||
| 6710 | status = -ENOMEM; | ||
| 6711 | mlog_errno(status); | ||
| 6712 | goto bail; | ||
| 6713 | } | ||
| 6714 | |||
| 6715 | mlog(0, "Reusing block(%llu) from " | ||
| 6716 | "dealloc(local slot:%d, real slot:%d)\n", | ||
| 6717 | bf->free_blk, osb->slot_num, real_slot); | ||
| 6718 | |||
| 6719 | ocfs2_set_new_buffer_uptodate(et->et_ci, new_eb_bh[i]); | ||
| 6720 | |||
| 6721 | status = ocfs2_journal_access_eb(handle, et->et_ci, | ||
| 6722 | new_eb_bh[i], | ||
| 6723 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
| 6724 | if (status < 0) { | ||
| 6725 | mlog_errno(status); | ||
| 6726 | goto bail; | ||
| 6727 | } | ||
| 6728 | |||
| 6729 | memset(new_eb_bh[i]->b_data, 0, osb->sb->s_blocksize); | ||
| 6730 | eb = (struct ocfs2_extent_block *) new_eb_bh[i]->b_data; | ||
| 6731 | |||
| 6732 | /* We can't guarantee that buffer head is still cached, so | ||
| 6733 | * polutlate the extent block again. | ||
| 6734 | */ | ||
| 6735 | strcpy(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE); | ||
| 6736 | eb->h_blkno = cpu_to_le64(bf->free_blk); | ||
| 6737 | eb->h_fs_generation = cpu_to_le32(osb->fs_generation); | ||
| 6738 | eb->h_suballoc_slot = cpu_to_le16(real_slot); | ||
| 6739 | eb->h_suballoc_loc = cpu_to_le64(bf->free_bg); | ||
| 6740 | eb->h_suballoc_bit = cpu_to_le16(bf->free_bit); | ||
| 6741 | eb->h_list.l_count = | ||
| 6742 | cpu_to_le16(ocfs2_extent_recs_per_eb(osb->sb)); | ||
| 6743 | |||
| 6744 | /* We'll also be dirtied by the caller, so | ||
| 6745 | * this isn't absolutely necessary. | ||
| 6746 | */ | ||
| 6747 | ocfs2_journal_dirty(handle, new_eb_bh[i]); | ||
| 6748 | |||
| 6749 | if (!fl->f_first) { | ||
| 6750 | dealloc->c_first_suballocator = fl->f_next_suballocator; | ||
| 6751 | kfree(fl); | ||
| 6752 | } | ||
| 6753 | kfree(bf); | ||
| 6754 | } | ||
| 6755 | |||
| 6756 | *blk_given = i; | ||
| 6757 | |||
| 6758 | bail: | ||
| 6759 | if (unlikely(status < 0)) { | ||
| 6760 | for (i = 0; i < blk_wanted; i++) | ||
| 6761 | brelse(new_eb_bh[i]); | ||
| 6762 | } | ||
| 6763 | |||
| 6764 | return status; | ||
| 6765 | } | ||
| 6766 | |||
| 6588 | int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, | 6767 | int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, |
| 6589 | int type, int slot, u64 suballoc, | 6768 | int type, int slot, u64 suballoc, |
| 6590 | u64 blkno, unsigned int bit) | 6769 | u64 blkno, unsigned int bit) |
| @@ -7382,6 +7561,7 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
| 7382 | struct buffer_head *gd_bh = NULL; | 7561 | struct buffer_head *gd_bh = NULL; |
| 7383 | struct ocfs2_dinode *main_bm; | 7562 | struct ocfs2_dinode *main_bm; |
| 7384 | struct ocfs2_group_desc *gd = NULL; | 7563 | struct ocfs2_group_desc *gd = NULL; |
| 7564 | struct ocfs2_trim_fs_info info, *pinfo = NULL; | ||
| 7385 | 7565 | ||
| 7386 | start = range->start >> osb->s_clustersize_bits; | 7566 | start = range->start >> osb->s_clustersize_bits; |
| 7387 | len = range->len >> osb->s_clustersize_bits; | 7567 | len = range->len >> osb->s_clustersize_bits; |
| @@ -7419,6 +7599,42 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
| 7419 | 7599 | ||
| 7420 | trace_ocfs2_trim_fs(start, len, minlen); | 7600 | trace_ocfs2_trim_fs(start, len, minlen); |
| 7421 | 7601 | ||
| 7602 | ocfs2_trim_fs_lock_res_init(osb); | ||
| 7603 | ret = ocfs2_trim_fs_lock(osb, NULL, 1); | ||
| 7604 | if (ret < 0) { | ||
| 7605 | if (ret != -EAGAIN) { | ||
| 7606 | mlog_errno(ret); | ||
| 7607 | ocfs2_trim_fs_lock_res_uninit(osb); | ||
| 7608 | goto out_unlock; | ||
| 7609 | } | ||
| 7610 | |||
| 7611 | mlog(ML_NOTICE, "Wait for trim on device (%s) to " | ||
| 7612 | "finish, which is running from another node.\n", | ||
| 7613 | osb->dev_str); | ||
| 7614 | ret = ocfs2_trim_fs_lock(osb, &info, 0); | ||
| 7615 | if (ret < 0) { | ||
| 7616 | mlog_errno(ret); | ||
| 7617 | ocfs2_trim_fs_lock_res_uninit(osb); | ||
| 7618 | goto out_unlock; | ||
| 7619 | } | ||
| 7620 | |||
| 7621 | if (info.tf_valid && info.tf_success && | ||
| 7622 | info.tf_start == start && info.tf_len == len && | ||
| 7623 | info.tf_minlen == minlen) { | ||
| 7624 | /* Avoid sending duplicated trim to a shared device */ | ||
| 7625 | mlog(ML_NOTICE, "The same trim on device (%s) was " | ||
| 7626 | "just done from node (%u), return.\n", | ||
| 7627 | osb->dev_str, info.tf_nodenum); | ||
| 7628 | range->len = info.tf_trimlen; | ||
| 7629 | goto out_trimunlock; | ||
| 7630 | } | ||
| 7631 | } | ||
| 7632 | |||
| 7633 | info.tf_nodenum = osb->node_num; | ||
| 7634 | info.tf_start = start; | ||
| 7635 | info.tf_len = len; | ||
| 7636 | info.tf_minlen = minlen; | ||
| 7637 | |||
| 7422 | /* Determine first and last group to examine based on start and len */ | 7638 | /* Determine first and last group to examine based on start and len */ |
| 7423 | first_group = ocfs2_which_cluster_group(main_bm_inode, start); | 7639 | first_group = ocfs2_which_cluster_group(main_bm_inode, start); |
| 7424 | if (first_group == osb->first_cluster_group_blkno) | 7640 | if (first_group == osb->first_cluster_group_blkno) |
| @@ -7463,6 +7679,13 @@ int ocfs2_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
| 7463 | group += ocfs2_clusters_to_blocks(sb, osb->bitmap_cpg); | 7679 | group += ocfs2_clusters_to_blocks(sb, osb->bitmap_cpg); |
| 7464 | } | 7680 | } |
| 7465 | range->len = trimmed * sb->s_blocksize; | 7681 | range->len = trimmed * sb->s_blocksize; |
| 7682 | |||
| 7683 | info.tf_trimlen = range->len; | ||
| 7684 | info.tf_success = (ret ? 0 : 1); | ||
| 7685 | pinfo = &info; | ||
| 7686 | out_trimunlock: | ||
| 7687 | ocfs2_trim_fs_unlock(osb, pinfo); | ||
| 7688 | ocfs2_trim_fs_lock_res_uninit(osb); | ||
| 7466 | out_unlock: | 7689 | out_unlock: |
| 7467 | ocfs2_inode_unlock(main_bm_inode, 0); | 7690 | ocfs2_inode_unlock(main_bm_inode, 0); |
| 7468 | brelse(main_bm_bh); | 7691 | brelse(main_bm_bh); |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 27b75cf32cfa..250bcacdf9e9 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
| @@ -61,6 +61,7 @@ struct ocfs2_extent_tree { | |||
| 61 | ocfs2_journal_access_func et_root_journal_access; | 61 | ocfs2_journal_access_func et_root_journal_access; |
| 62 | void *et_object; | 62 | void *et_object; |
| 63 | unsigned int et_max_leaf_clusters; | 63 | unsigned int et_max_leaf_clusters; |
| 64 | struct ocfs2_cached_dealloc_ctxt *et_dealloc; | ||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | /* | 67 | /* |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index d1516327b787..e8e205bf2e41 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -797,6 +797,7 @@ struct ocfs2_write_ctxt { | |||
| 797 | struct ocfs2_cached_dealloc_ctxt w_dealloc; | 797 | struct ocfs2_cached_dealloc_ctxt w_dealloc; |
| 798 | 798 | ||
| 799 | struct list_head w_unwritten_list; | 799 | struct list_head w_unwritten_list; |
| 800 | unsigned int w_unwritten_count; | ||
| 800 | }; | 801 | }; |
| 801 | 802 | ||
| 802 | void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages) | 803 | void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages) |
| @@ -1386,6 +1387,7 @@ retry: | |||
| 1386 | desc->c_clear_unwritten = 0; | 1387 | desc->c_clear_unwritten = 0; |
| 1387 | list_add_tail(&new->ue_ip_node, &oi->ip_unwritten_list); | 1388 | list_add_tail(&new->ue_ip_node, &oi->ip_unwritten_list); |
| 1388 | list_add_tail(&new->ue_node, &wc->w_unwritten_list); | 1389 | list_add_tail(&new->ue_node, &wc->w_unwritten_list); |
| 1390 | wc->w_unwritten_count++; | ||
| 1389 | new = NULL; | 1391 | new = NULL; |
| 1390 | unlock: | 1392 | unlock: |
| 1391 | spin_unlock(&oi->ip_lock); | 1393 | spin_unlock(&oi->ip_lock); |
| @@ -2256,7 +2258,7 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, | |||
| 2256 | ue->ue_phys = desc->c_phys; | 2258 | ue->ue_phys = desc->c_phys; |
| 2257 | 2259 | ||
| 2258 | list_splice_tail_init(&wc->w_unwritten_list, &dwc->dw_zero_list); | 2260 | list_splice_tail_init(&wc->w_unwritten_list, &dwc->dw_zero_list); |
| 2259 | dwc->dw_zero_count++; | 2261 | dwc->dw_zero_count += wc->w_unwritten_count; |
| 2260 | } | 2262 | } |
| 2261 | 2263 | ||
| 2262 | ret = ocfs2_write_end_nolock(inode->i_mapping, pos, len, len, wc); | 2264 | ret = ocfs2_write_end_nolock(inode->i_mapping, pos, len, len, wc); |
| @@ -2330,6 +2332,12 @@ static int ocfs2_dio_end_io_write(struct inode *inode, | |||
| 2330 | 2332 | ||
| 2331 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); | 2333 | ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh); |
| 2332 | 2334 | ||
| 2335 | /* Attach dealloc with extent tree in case that we may reuse extents | ||
| 2336 | * which are already unlinked from current extent tree due to extent | ||
| 2337 | * rotation and merging. | ||
| 2338 | */ | ||
| 2339 | et.et_dealloc = &dealloc; | ||
| 2340 | |||
| 2333 | ret = ocfs2_lock_allocators(inode, &et, 0, dwc->dw_zero_count*2, | 2341 | ret = ocfs2_lock_allocators(inode, &et, 0, dwc->dw_zero_count*2, |
| 2334 | &data_ac, &meta_ac); | 2342 | &data_ac, &meta_ac); |
| 2335 | if (ret) { | 2343 | if (ret) { |
diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index 62e8ec619b4c..af2e7473956e 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c | |||
| @@ -314,12 +314,13 @@ void o2quo_conn_err(u8 node) | |||
| 314 | node, qs->qs_connected); | 314 | node, qs->qs_connected); |
| 315 | 315 | ||
| 316 | clear_bit(node, qs->qs_conn_bm); | 316 | clear_bit(node, qs->qs_conn_bm); |
| 317 | |||
| 318 | if (test_bit(node, qs->qs_hb_bm)) | ||
| 319 | o2quo_set_hold(qs, node); | ||
| 317 | } | 320 | } |
| 318 | 321 | ||
| 319 | mlog(0, "node %u, %d total\n", node, qs->qs_connected); | 322 | mlog(0, "node %u, %d total\n", node, qs->qs_connected); |
| 320 | 323 | ||
| 321 | if (test_bit(node, qs->qs_hb_bm)) | ||
| 322 | o2quo_set_hold(qs, node); | ||
| 323 | 324 | ||
| 324 | spin_unlock(&qs->qs_lock); | 325 | spin_unlock(&qs->qs_lock); |
| 325 | } | 326 | } |
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index b95e7df5b76a..0276f7f8d5e6 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h | |||
| @@ -196,7 +196,7 @@ struct o2net_msg_handler { | |||
| 196 | u32 nh_msg_type; | 196 | u32 nh_msg_type; |
| 197 | u32 nh_key; | 197 | u32 nh_key; |
| 198 | o2net_msg_handler_func *nh_func; | 198 | o2net_msg_handler_func *nh_func; |
| 199 | o2net_msg_handler_func *nh_func_data; | 199 | void *nh_func_data; |
| 200 | o2net_post_msg_handler_func | 200 | o2net_post_msg_handler_func |
| 201 | *nh_post_func; | 201 | *nh_post_func; |
| 202 | struct kref nh_kref; | 202 | struct kref nh_kref; |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 32f9c72dff17..b7520e20a770 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
| @@ -1958,7 +1958,7 @@ int ocfs2_readdir(struct file *file, struct dir_context *ctx) | |||
| 1958 | 1958 | ||
| 1959 | trace_ocfs2_readdir((unsigned long long)OCFS2_I(inode)->ip_blkno); | 1959 | trace_ocfs2_readdir((unsigned long long)OCFS2_I(inode)->ip_blkno); |
| 1960 | 1960 | ||
| 1961 | error = ocfs2_inode_lock_atime(inode, file->f_path.mnt, &lock_level); | 1961 | error = ocfs2_inode_lock_atime(inode, file->f_path.mnt, &lock_level, 1); |
| 1962 | if (lock_level && error >= 0) { | 1962 | if (lock_level && error >= 0) { |
| 1963 | /* We release EX lock which used to update atime | 1963 | /* We release EX lock which used to update atime |
| 1964 | * and get PR lock again to reduce contention | 1964 | * and get PR lock again to reduce contention |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 9c3e0f13ca87..a7df226f9449 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -1122,13 +1122,6 @@ recheck: | |||
| 1122 | /* sleep if we haven't finished voting yet */ | 1122 | /* sleep if we haven't finished voting yet */ |
| 1123 | if (sleep) { | 1123 | if (sleep) { |
| 1124 | unsigned long timeo = msecs_to_jiffies(DLM_MASTERY_TIMEOUT_MS); | 1124 | unsigned long timeo = msecs_to_jiffies(DLM_MASTERY_TIMEOUT_MS); |
| 1125 | |||
| 1126 | /* | ||
| 1127 | if (kref_read(&mle->mle_refs) < 2) | ||
| 1128 | mlog(ML_ERROR, "mle (%p) refs=%d, name=%.*s\n", mle, | ||
| 1129 | kref_read(&mle->mle_refs), | ||
| 1130 | res->lockname.len, res->lockname.name); | ||
| 1131 | */ | ||
| 1132 | atomic_set(&mle->woken, 0); | 1125 | atomic_set(&mle->woken, 0); |
| 1133 | (void)wait_event_timeout(mle->wq, | 1126 | (void)wait_event_timeout(mle->wq, |
| 1134 | (atomic_read(&mle->woken) == 1), | 1127 | (atomic_read(&mle->woken) == 1), |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 4689940a953c..9479f99c2145 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
| @@ -259,6 +259,10 @@ static struct ocfs2_lock_res_ops ocfs2_nfs_sync_lops = { | |||
| 259 | .flags = 0, | 259 | .flags = 0, |
| 260 | }; | 260 | }; |
| 261 | 261 | ||
| 262 | static struct ocfs2_lock_res_ops ocfs2_trim_fs_lops = { | ||
| 263 | .flags = LOCK_TYPE_REQUIRES_REFRESH|LOCK_TYPE_USES_LVB, | ||
| 264 | }; | ||
| 265 | |||
| 262 | static struct ocfs2_lock_res_ops ocfs2_orphan_scan_lops = { | 266 | static struct ocfs2_lock_res_ops ocfs2_orphan_scan_lops = { |
| 263 | .flags = LOCK_TYPE_REQUIRES_REFRESH|LOCK_TYPE_USES_LVB, | 267 | .flags = LOCK_TYPE_REQUIRES_REFRESH|LOCK_TYPE_USES_LVB, |
| 264 | }; | 268 | }; |
| @@ -676,6 +680,24 @@ static void ocfs2_nfs_sync_lock_res_init(struct ocfs2_lock_res *res, | |||
| 676 | &ocfs2_nfs_sync_lops, osb); | 680 | &ocfs2_nfs_sync_lops, osb); |
| 677 | } | 681 | } |
| 678 | 682 | ||
| 683 | void ocfs2_trim_fs_lock_res_init(struct ocfs2_super *osb) | ||
| 684 | { | ||
| 685 | struct ocfs2_lock_res *lockres = &osb->osb_trim_fs_lockres; | ||
| 686 | |||
| 687 | ocfs2_lock_res_init_once(lockres); | ||
| 688 | ocfs2_build_lock_name(OCFS2_LOCK_TYPE_TRIM_FS, 0, 0, lockres->l_name); | ||
| 689 | ocfs2_lock_res_init_common(osb, lockres, OCFS2_LOCK_TYPE_TRIM_FS, | ||
| 690 | &ocfs2_trim_fs_lops, osb); | ||
| 691 | } | ||
| 692 | |||
| 693 | void ocfs2_trim_fs_lock_res_uninit(struct ocfs2_super *osb) | ||
| 694 | { | ||
| 695 | struct ocfs2_lock_res *lockres = &osb->osb_trim_fs_lockres; | ||
| 696 | |||
| 697 | ocfs2_simple_drop_lockres(osb, lockres); | ||
| 698 | ocfs2_lock_res_free(lockres); | ||
| 699 | } | ||
| 700 | |||
| 679 | static void ocfs2_orphan_scan_lock_res_init(struct ocfs2_lock_res *res, | 701 | static void ocfs2_orphan_scan_lock_res_init(struct ocfs2_lock_res *res, |
| 680 | struct ocfs2_super *osb) | 702 | struct ocfs2_super *osb) |
| 681 | { | 703 | { |
| @@ -1742,6 +1764,27 @@ int ocfs2_rw_lock(struct inode *inode, int write) | |||
| 1742 | return status; | 1764 | return status; |
| 1743 | } | 1765 | } |
| 1744 | 1766 | ||
| 1767 | int ocfs2_try_rw_lock(struct inode *inode, int write) | ||
| 1768 | { | ||
| 1769 | int status, level; | ||
| 1770 | struct ocfs2_lock_res *lockres; | ||
| 1771 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 1772 | |||
| 1773 | mlog(0, "inode %llu try to take %s RW lock\n", | ||
| 1774 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
| 1775 | write ? "EXMODE" : "PRMODE"); | ||
| 1776 | |||
| 1777 | if (ocfs2_mount_local(osb)) | ||
| 1778 | return 0; | ||
| 1779 | |||
| 1780 | lockres = &OCFS2_I(inode)->ip_rw_lockres; | ||
| 1781 | |||
| 1782 | level = write ? DLM_LOCK_EX : DLM_LOCK_PR; | ||
| 1783 | |||
| 1784 | status = ocfs2_cluster_lock(osb, lockres, level, DLM_LKF_NOQUEUE, 0); | ||
| 1785 | return status; | ||
| 1786 | } | ||
| 1787 | |||
| 1745 | void ocfs2_rw_unlock(struct inode *inode, int write) | 1788 | void ocfs2_rw_unlock(struct inode *inode, int write) |
| 1746 | { | 1789 | { |
| 1747 | int level = write ? DLM_LOCK_EX : DLM_LOCK_PR; | 1790 | int level = write ? DLM_LOCK_EX : DLM_LOCK_PR; |
| @@ -2486,6 +2529,15 @@ int ocfs2_inode_lock_with_page(struct inode *inode, | |||
| 2486 | ret = ocfs2_inode_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK); | 2529 | ret = ocfs2_inode_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK); |
| 2487 | if (ret == -EAGAIN) { | 2530 | if (ret == -EAGAIN) { |
| 2488 | unlock_page(page); | 2531 | unlock_page(page); |
| 2532 | /* | ||
| 2533 | * If we can't get inode lock immediately, we should not return | ||
| 2534 | * directly here, since this will lead to a softlockup problem. | ||
| 2535 | * The method is to get a blocking lock and immediately unlock | ||
| 2536 | * before returning, this can avoid CPU resource waste due to | ||
| 2537 | * lots of retries, and benefits fairness in getting lock. | ||
| 2538 | */ | ||
| 2539 | if (ocfs2_inode_lock(inode, ret_bh, ex) == 0) | ||
| 2540 | ocfs2_inode_unlock(inode, ex); | ||
| 2489 | ret = AOP_TRUNCATED_PAGE; | 2541 | ret = AOP_TRUNCATED_PAGE; |
| 2490 | } | 2542 | } |
| 2491 | 2543 | ||
| @@ -2494,13 +2546,18 @@ int ocfs2_inode_lock_with_page(struct inode *inode, | |||
| 2494 | 2546 | ||
| 2495 | int ocfs2_inode_lock_atime(struct inode *inode, | 2547 | int ocfs2_inode_lock_atime(struct inode *inode, |
| 2496 | struct vfsmount *vfsmnt, | 2548 | struct vfsmount *vfsmnt, |
| 2497 | int *level) | 2549 | int *level, int wait) |
| 2498 | { | 2550 | { |
| 2499 | int ret; | 2551 | int ret; |
| 2500 | 2552 | ||
| 2501 | ret = ocfs2_inode_lock(inode, NULL, 0); | 2553 | if (wait) |
| 2554 | ret = ocfs2_inode_lock(inode, NULL, 0); | ||
| 2555 | else | ||
| 2556 | ret = ocfs2_try_inode_lock(inode, NULL, 0); | ||
| 2557 | |||
| 2502 | if (ret < 0) { | 2558 | if (ret < 0) { |
| 2503 | mlog_errno(ret); | 2559 | if (ret != -EAGAIN) |
| 2560 | mlog_errno(ret); | ||
| 2504 | return ret; | 2561 | return ret; |
| 2505 | } | 2562 | } |
| 2506 | 2563 | ||
| @@ -2512,9 +2569,14 @@ int ocfs2_inode_lock_atime(struct inode *inode, | |||
| 2512 | struct buffer_head *bh = NULL; | 2569 | struct buffer_head *bh = NULL; |
| 2513 | 2570 | ||
| 2514 | ocfs2_inode_unlock(inode, 0); | 2571 | ocfs2_inode_unlock(inode, 0); |
| 2515 | ret = ocfs2_inode_lock(inode, &bh, 1); | 2572 | if (wait) |
| 2573 | ret = ocfs2_inode_lock(inode, &bh, 1); | ||
| 2574 | else | ||
| 2575 | ret = ocfs2_try_inode_lock(inode, &bh, 1); | ||
| 2576 | |||
| 2516 | if (ret < 0) { | 2577 | if (ret < 0) { |
| 2517 | mlog_errno(ret); | 2578 | if (ret != -EAGAIN) |
| 2579 | mlog_errno(ret); | ||
| 2518 | return ret; | 2580 | return ret; |
| 2519 | } | 2581 | } |
| 2520 | *level = 1; | 2582 | *level = 1; |
| @@ -2745,6 +2807,70 @@ void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex) | |||
| 2745 | ex ? LKM_EXMODE : LKM_PRMODE); | 2807 | ex ? LKM_EXMODE : LKM_PRMODE); |
| 2746 | } | 2808 | } |
| 2747 | 2809 | ||
| 2810 | int ocfs2_trim_fs_lock(struct ocfs2_super *osb, | ||
| 2811 | struct ocfs2_trim_fs_info *info, int trylock) | ||
| 2812 | { | ||
| 2813 | int status; | ||
| 2814 | struct ocfs2_trim_fs_lvb *lvb; | ||
| 2815 | struct ocfs2_lock_res *lockres = &osb->osb_trim_fs_lockres; | ||
| 2816 | |||
| 2817 | if (info) | ||
| 2818 | info->tf_valid = 0; | ||
| 2819 | |||
| 2820 | if (ocfs2_is_hard_readonly(osb)) | ||
| 2821 | return -EROFS; | ||
| 2822 | |||
| 2823 | if (ocfs2_mount_local(osb)) | ||
| 2824 | return 0; | ||
| 2825 | |||
| 2826 | status = ocfs2_cluster_lock(osb, lockres, DLM_LOCK_EX, | ||
| 2827 | trylock ? DLM_LKF_NOQUEUE : 0, 0); | ||
| 2828 | if (status < 0) { | ||
| 2829 | if (status != -EAGAIN) | ||
| 2830 | mlog_errno(status); | ||
| 2831 | return status; | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | if (info) { | ||
| 2835 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | ||
| 2836 | if (ocfs2_dlm_lvb_valid(&lockres->l_lksb) && | ||
| 2837 | lvb->lvb_version == OCFS2_TRIMFS_LVB_VERSION) { | ||
| 2838 | info->tf_valid = 1; | ||
| 2839 | info->tf_success = lvb->lvb_success; | ||
| 2840 | info->tf_nodenum = be32_to_cpu(lvb->lvb_nodenum); | ||
| 2841 | info->tf_start = be64_to_cpu(lvb->lvb_start); | ||
| 2842 | info->tf_len = be64_to_cpu(lvb->lvb_len); | ||
| 2843 | info->tf_minlen = be64_to_cpu(lvb->lvb_minlen); | ||
| 2844 | info->tf_trimlen = be64_to_cpu(lvb->lvb_trimlen); | ||
| 2845 | } | ||
| 2846 | } | ||
| 2847 | |||
| 2848 | return status; | ||
| 2849 | } | ||
| 2850 | |||
| 2851 | void ocfs2_trim_fs_unlock(struct ocfs2_super *osb, | ||
| 2852 | struct ocfs2_trim_fs_info *info) | ||
| 2853 | { | ||
| 2854 | struct ocfs2_trim_fs_lvb *lvb; | ||
| 2855 | struct ocfs2_lock_res *lockres = &osb->osb_trim_fs_lockres; | ||
| 2856 | |||
| 2857 | if (ocfs2_mount_local(osb)) | ||
| 2858 | return; | ||
| 2859 | |||
| 2860 | if (info) { | ||
| 2861 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | ||
| 2862 | lvb->lvb_version = OCFS2_TRIMFS_LVB_VERSION; | ||
| 2863 | lvb->lvb_success = info->tf_success; | ||
| 2864 | lvb->lvb_nodenum = cpu_to_be32(info->tf_nodenum); | ||
| 2865 | lvb->lvb_start = cpu_to_be64(info->tf_start); | ||
| 2866 | lvb->lvb_len = cpu_to_be64(info->tf_len); | ||
| 2867 | lvb->lvb_minlen = cpu_to_be64(info->tf_minlen); | ||
| 2868 | lvb->lvb_trimlen = cpu_to_be64(info->tf_trimlen); | ||
| 2869 | } | ||
| 2870 | |||
| 2871 | ocfs2_cluster_unlock(osb, lockres, DLM_LOCK_EX); | ||
| 2872 | } | ||
| 2873 | |||
| 2748 | int ocfs2_dentry_lock(struct dentry *dentry, int ex) | 2874 | int ocfs2_dentry_lock(struct dentry *dentry, int ex) |
| 2749 | { | 2875 | { |
| 2750 | int ret; | 2876 | int ret; |
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index a7fc18ba0dc1..256e0a9067b8 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
| @@ -70,6 +70,29 @@ struct ocfs2_orphan_scan_lvb { | |||
| 70 | __be32 lvb_os_seqno; | 70 | __be32 lvb_os_seqno; |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | #define OCFS2_TRIMFS_LVB_VERSION 1 | ||
| 74 | |||
| 75 | struct ocfs2_trim_fs_lvb { | ||
| 76 | __u8 lvb_version; | ||
| 77 | __u8 lvb_success; | ||
| 78 | __u8 lvb_reserved[2]; | ||
| 79 | __be32 lvb_nodenum; | ||
| 80 | __be64 lvb_start; | ||
| 81 | __be64 lvb_len; | ||
| 82 | __be64 lvb_minlen; | ||
| 83 | __be64 lvb_trimlen; | ||
| 84 | }; | ||
| 85 | |||
| 86 | struct ocfs2_trim_fs_info { | ||
| 87 | u8 tf_valid; /* lvb is valid, or not */ | ||
| 88 | u8 tf_success; /* trim is successful, or not */ | ||
| 89 | u32 tf_nodenum; /* osb node number */ | ||
| 90 | u64 tf_start; /* trim start offset in clusters */ | ||
| 91 | u64 tf_len; /* trim end offset in clusters */ | ||
| 92 | u64 tf_minlen; /* trim minimum contiguous free clusters */ | ||
| 93 | u64 tf_trimlen; /* trimmed length in bytes */ | ||
| 94 | }; | ||
| 95 | |||
| 73 | struct ocfs2_lock_holder { | 96 | struct ocfs2_lock_holder { |
| 74 | struct list_head oh_list; | 97 | struct list_head oh_list; |
| 75 | struct pid *oh_owner_pid; | 98 | struct pid *oh_owner_pid; |
| @@ -116,13 +139,14 @@ void ocfs2_lock_res_free(struct ocfs2_lock_res *res); | |||
| 116 | int ocfs2_create_new_inode_locks(struct inode *inode); | 139 | int ocfs2_create_new_inode_locks(struct inode *inode); |
| 117 | int ocfs2_drop_inode_locks(struct inode *inode); | 140 | int ocfs2_drop_inode_locks(struct inode *inode); |
| 118 | int ocfs2_rw_lock(struct inode *inode, int write); | 141 | int ocfs2_rw_lock(struct inode *inode, int write); |
| 142 | int ocfs2_try_rw_lock(struct inode *inode, int write); | ||
| 119 | void ocfs2_rw_unlock(struct inode *inode, int write); | 143 | void ocfs2_rw_unlock(struct inode *inode, int write); |
| 120 | int ocfs2_open_lock(struct inode *inode); | 144 | int ocfs2_open_lock(struct inode *inode); |
| 121 | int ocfs2_try_open_lock(struct inode *inode, int write); | 145 | int ocfs2_try_open_lock(struct inode *inode, int write); |
| 122 | void ocfs2_open_unlock(struct inode *inode); | 146 | void ocfs2_open_unlock(struct inode *inode); |
| 123 | int ocfs2_inode_lock_atime(struct inode *inode, | 147 | int ocfs2_inode_lock_atime(struct inode *inode, |
| 124 | struct vfsmount *vfsmnt, | 148 | struct vfsmount *vfsmnt, |
| 125 | int *level); | 149 | int *level, int wait); |
| 126 | int ocfs2_inode_lock_full_nested(struct inode *inode, | 150 | int ocfs2_inode_lock_full_nested(struct inode *inode, |
| 127 | struct buffer_head **ret_bh, | 151 | struct buffer_head **ret_bh, |
| 128 | int ex, | 152 | int ex, |
| @@ -140,6 +164,9 @@ int ocfs2_inode_lock_with_page(struct inode *inode, | |||
| 140 | /* 99% of the time we don't want to supply any additional flags -- | 164 | /* 99% of the time we don't want to supply any additional flags -- |
| 141 | * those are for very specific cases only. */ | 165 | * those are for very specific cases only. */ |
| 142 | #define ocfs2_inode_lock(i, b, e) ocfs2_inode_lock_full_nested(i, b, e, 0, OI_LS_NORMAL) | 166 | #define ocfs2_inode_lock(i, b, e) ocfs2_inode_lock_full_nested(i, b, e, 0, OI_LS_NORMAL) |
| 167 | #define ocfs2_try_inode_lock(i, b, e)\ | ||
| 168 | ocfs2_inode_lock_full_nested(i, b, e, OCFS2_META_LOCK_NOQUEUE,\ | ||
| 169 | OI_LS_NORMAL) | ||
| 143 | void ocfs2_inode_unlock(struct inode *inode, | 170 | void ocfs2_inode_unlock(struct inode *inode, |
| 144 | int ex); | 171 | int ex); |
| 145 | int ocfs2_super_lock(struct ocfs2_super *osb, | 172 | int ocfs2_super_lock(struct ocfs2_super *osb, |
| @@ -153,6 +180,12 @@ int ocfs2_rename_lock(struct ocfs2_super *osb); | |||
| 153 | void ocfs2_rename_unlock(struct ocfs2_super *osb); | 180 | void ocfs2_rename_unlock(struct ocfs2_super *osb); |
| 154 | int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex); | 181 | int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex); |
| 155 | void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex); | 182 | void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex); |
| 183 | void ocfs2_trim_fs_lock_res_init(struct ocfs2_super *osb); | ||
| 184 | void ocfs2_trim_fs_lock_res_uninit(struct ocfs2_super *osb); | ||
| 185 | int ocfs2_trim_fs_lock(struct ocfs2_super *osb, | ||
| 186 | struct ocfs2_trim_fs_info *info, int trylock); | ||
| 187 | void ocfs2_trim_fs_unlock(struct ocfs2_super *osb, | ||
| 188 | struct ocfs2_trim_fs_info *info); | ||
| 156 | int ocfs2_dentry_lock(struct dentry *dentry, int ex); | 189 | int ocfs2_dentry_lock(struct dentry *dentry, int ex); |
| 157 | void ocfs2_dentry_unlock(struct dentry *dentry, int ex); | 190 | void ocfs2_dentry_unlock(struct dentry *dentry, int ex); |
| 158 | int ocfs2_file_lock(struct file *file, int ex, int trylock); | 191 | int ocfs2_file_lock(struct file *file, int ex, int trylock); |
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index e4719e0a3f99..06cb96462bf9 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "inode.h" | 38 | #include "inode.h" |
| 39 | #include "super.h" | 39 | #include "super.h" |
| 40 | #include "symlink.h" | 40 | #include "symlink.h" |
| 41 | #include "aops.h" | ||
| 41 | #include "ocfs2_trace.h" | 42 | #include "ocfs2_trace.h" |
| 42 | 43 | ||
| 43 | #include "buffer_head_io.h" | 44 | #include "buffer_head_io.h" |
| @@ -832,6 +833,50 @@ out: | |||
| 832 | return ret; | 833 | return ret; |
| 833 | } | 834 | } |
| 834 | 835 | ||
| 836 | /* Is IO overwriting allocated blocks? */ | ||
| 837 | int ocfs2_overwrite_io(struct inode *inode, struct buffer_head *di_bh, | ||
| 838 | u64 map_start, u64 map_len) | ||
| 839 | { | ||
| 840 | int ret = 0, is_last; | ||
| 841 | u32 mapping_end, cpos; | ||
| 842 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 843 | struct ocfs2_extent_rec rec; | ||
| 844 | |||
| 845 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { | ||
| 846 | if (ocfs2_size_fits_inline_data(di_bh, map_start + map_len)) | ||
| 847 | return ret; | ||
| 848 | else | ||
| 849 | return -EAGAIN; | ||
| 850 | } | ||
| 851 | |||
| 852 | cpos = map_start >> osb->s_clustersize_bits; | ||
| 853 | mapping_end = ocfs2_clusters_for_bytes(inode->i_sb, | ||
| 854 | map_start + map_len); | ||
| 855 | is_last = 0; | ||
| 856 | while (cpos < mapping_end && !is_last) { | ||
| 857 | ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos, | ||
| 858 | NULL, &rec, &is_last); | ||
| 859 | if (ret) { | ||
| 860 | mlog_errno(ret); | ||
| 861 | goto out; | ||
| 862 | } | ||
| 863 | |||
| 864 | if (rec.e_blkno == 0ULL) | ||
| 865 | break; | ||
| 866 | |||
| 867 | if (rec.e_flags & OCFS2_EXT_REFCOUNTED) | ||
| 868 | break; | ||
| 869 | |||
| 870 | cpos = le32_to_cpu(rec.e_cpos) + | ||
| 871 | le16_to_cpu(rec.e_leaf_clusters); | ||
| 872 | } | ||
| 873 | |||
| 874 | if (cpos < mapping_end) | ||
| 875 | ret = -EAGAIN; | ||
| 876 | out: | ||
| 877 | return ret; | ||
| 878 | } | ||
| 879 | |||
| 835 | int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int whence) | 880 | int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int whence) |
| 836 | { | 881 | { |
| 837 | struct inode *inode = file->f_mapping->host; | 882 | struct inode *inode = file->f_mapping->host; |
diff --git a/fs/ocfs2/extent_map.h b/fs/ocfs2/extent_map.h index 67ea57d2fd59..1057586ec19f 100644 --- a/fs/ocfs2/extent_map.h +++ b/fs/ocfs2/extent_map.h | |||
| @@ -53,6 +53,9 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno, | |||
| 53 | int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 53 | int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 54 | u64 map_start, u64 map_len); | 54 | u64 map_start, u64 map_len); |
| 55 | 55 | ||
| 56 | int ocfs2_overwrite_io(struct inode *inode, struct buffer_head *di_bh, | ||
| 57 | u64 map_start, u64 map_len); | ||
| 58 | |||
| 56 | int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin); | 59 | int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin); |
| 57 | 60 | ||
| 58 | int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster, | 61 | int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster, |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index a1d051055472..5d1784a365a3 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -140,6 +140,8 @@ static int ocfs2_file_open(struct inode *inode, struct file *file) | |||
| 140 | spin_unlock(&oi->ip_lock); | 140 | spin_unlock(&oi->ip_lock); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | file->f_mode |= FMODE_NOWAIT; | ||
| 144 | |||
| 143 | leave: | 145 | leave: |
| 144 | return status; | 146 | return status; |
| 145 | } | 147 | } |
| @@ -2132,12 +2134,12 @@ out: | |||
| 2132 | } | 2134 | } |
| 2133 | 2135 | ||
| 2134 | static int ocfs2_prepare_inode_for_write(struct file *file, | 2136 | static int ocfs2_prepare_inode_for_write(struct file *file, |
| 2135 | loff_t pos, | 2137 | loff_t pos, size_t count, int wait) |
| 2136 | size_t count) | ||
| 2137 | { | 2138 | { |
| 2138 | int ret = 0, meta_level = 0; | 2139 | int ret = 0, meta_level = 0, overwrite_io = 0; |
| 2139 | struct dentry *dentry = file->f_path.dentry; | 2140 | struct dentry *dentry = file->f_path.dentry; |
| 2140 | struct inode *inode = d_inode(dentry); | 2141 | struct inode *inode = d_inode(dentry); |
| 2142 | struct buffer_head *di_bh = NULL; | ||
| 2141 | loff_t end; | 2143 | loff_t end; |
| 2142 | 2144 | ||
| 2143 | /* | 2145 | /* |
| @@ -2145,13 +2147,40 @@ static int ocfs2_prepare_inode_for_write(struct file *file, | |||
| 2145 | * if we need to make modifications here. | 2147 | * if we need to make modifications here. |
| 2146 | */ | 2148 | */ |
| 2147 | for(;;) { | 2149 | for(;;) { |
| 2148 | ret = ocfs2_inode_lock(inode, NULL, meta_level); | 2150 | if (wait) |
| 2151 | ret = ocfs2_inode_lock(inode, NULL, meta_level); | ||
| 2152 | else | ||
| 2153 | ret = ocfs2_try_inode_lock(inode, | ||
| 2154 | overwrite_io ? NULL : &di_bh, meta_level); | ||
| 2149 | if (ret < 0) { | 2155 | if (ret < 0) { |
| 2150 | meta_level = -1; | 2156 | meta_level = -1; |
| 2151 | mlog_errno(ret); | 2157 | if (ret != -EAGAIN) |
| 2158 | mlog_errno(ret); | ||
| 2152 | goto out; | 2159 | goto out; |
| 2153 | } | 2160 | } |
| 2154 | 2161 | ||
| 2162 | /* | ||
| 2163 | * Check if IO will overwrite allocated blocks in case | ||
| 2164 | * IOCB_NOWAIT flag is set. | ||
| 2165 | */ | ||
| 2166 | if (!wait && !overwrite_io) { | ||
| 2167 | overwrite_io = 1; | ||
| 2168 | if (!down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem)) { | ||
| 2169 | ret = -EAGAIN; | ||
| 2170 | goto out_unlock; | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | ret = ocfs2_overwrite_io(inode, di_bh, pos, count); | ||
| 2174 | brelse(di_bh); | ||
| 2175 | di_bh = NULL; | ||
| 2176 | up_read(&OCFS2_I(inode)->ip_alloc_sem); | ||
| 2177 | if (ret < 0) { | ||
| 2178 | if (ret != -EAGAIN) | ||
| 2179 | mlog_errno(ret); | ||
| 2180 | goto out_unlock; | ||
| 2181 | } | ||
| 2182 | } | ||
| 2183 | |||
| 2155 | /* Clear suid / sgid if necessary. We do this here | 2184 | /* Clear suid / sgid if necessary. We do this here |
| 2156 | * instead of later in the write path because | 2185 | * instead of later in the write path because |
| 2157 | * remove_suid() calls ->setattr without any hint that | 2186 | * remove_suid() calls ->setattr without any hint that |
| @@ -2199,7 +2228,9 @@ static int ocfs2_prepare_inode_for_write(struct file *file, | |||
| 2199 | 2228 | ||
| 2200 | out_unlock: | 2229 | out_unlock: |
| 2201 | trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno, | 2230 | trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno, |
| 2202 | pos, count); | 2231 | pos, count, wait); |
| 2232 | |||
| 2233 | brelse(di_bh); | ||
| 2203 | 2234 | ||
| 2204 | if (meta_level >= 0) | 2235 | if (meta_level >= 0) |
| 2205 | ocfs2_inode_unlock(inode, meta_level); | 2236 | ocfs2_inode_unlock(inode, meta_level); |
| @@ -2211,7 +2242,7 @@ out: | |||
| 2211 | static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | 2242 | static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, |
| 2212 | struct iov_iter *from) | 2243 | struct iov_iter *from) |
| 2213 | { | 2244 | { |
| 2214 | int direct_io, rw_level; | 2245 | int rw_level; |
| 2215 | ssize_t written = 0; | 2246 | ssize_t written = 0; |
| 2216 | ssize_t ret; | 2247 | ssize_t ret; |
| 2217 | size_t count = iov_iter_count(from); | 2248 | size_t count = iov_iter_count(from); |
| @@ -2223,6 +2254,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
| 2223 | void *saved_ki_complete = NULL; | 2254 | void *saved_ki_complete = NULL; |
| 2224 | int append_write = ((iocb->ki_pos + count) >= | 2255 | int append_write = ((iocb->ki_pos + count) >= |
| 2225 | i_size_read(inode) ? 1 : 0); | 2256 | i_size_read(inode) ? 1 : 0); |
| 2257 | int direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0; | ||
| 2258 | int nowait = iocb->ki_flags & IOCB_NOWAIT ? 1 : 0; | ||
| 2226 | 2259 | ||
| 2227 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, | 2260 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, |
| 2228 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 2261 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
| @@ -2230,12 +2263,17 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
| 2230 | file->f_path.dentry->d_name.name, | 2263 | file->f_path.dentry->d_name.name, |
| 2231 | (unsigned int)from->nr_segs); /* GRRRRR */ | 2264 | (unsigned int)from->nr_segs); /* GRRRRR */ |
| 2232 | 2265 | ||
| 2266 | if (!direct_io && nowait) | ||
| 2267 | return -EOPNOTSUPP; | ||
| 2268 | |||
| 2233 | if (count == 0) | 2269 | if (count == 0) |
| 2234 | return 0; | 2270 | return 0; |
| 2235 | 2271 | ||
| 2236 | direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0; | 2272 | if (nowait) { |
| 2237 | 2273 | if (!inode_trylock(inode)) | |
| 2238 | inode_lock(inode); | 2274 | return -EAGAIN; |
| 2275 | } else | ||
| 2276 | inode_lock(inode); | ||
| 2239 | 2277 | ||
| 2240 | /* | 2278 | /* |
| 2241 | * Concurrent O_DIRECT writes are allowed with | 2279 | * Concurrent O_DIRECT writes are allowed with |
| @@ -2244,9 +2282,13 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
| 2244 | */ | 2282 | */ |
| 2245 | rw_level = (!direct_io || full_coherency || append_write); | 2283 | rw_level = (!direct_io || full_coherency || append_write); |
| 2246 | 2284 | ||
| 2247 | ret = ocfs2_rw_lock(inode, rw_level); | 2285 | if (nowait) |
| 2286 | ret = ocfs2_try_rw_lock(inode, rw_level); | ||
| 2287 | else | ||
| 2288 | ret = ocfs2_rw_lock(inode, rw_level); | ||
| 2248 | if (ret < 0) { | 2289 | if (ret < 0) { |
| 2249 | mlog_errno(ret); | 2290 | if (ret != -EAGAIN) |
| 2291 | mlog_errno(ret); | ||
| 2250 | goto out_mutex; | 2292 | goto out_mutex; |
| 2251 | } | 2293 | } |
| 2252 | 2294 | ||
| @@ -2260,9 +2302,13 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
| 2260 | * other nodes to drop their caches. Buffered I/O | 2302 | * other nodes to drop their caches. Buffered I/O |
| 2261 | * already does this in write_begin(). | 2303 | * already does this in write_begin(). |
| 2262 | */ | 2304 | */ |
| 2263 | ret = ocfs2_inode_lock(inode, NULL, 1); | 2305 | if (nowait) |
| 2306 | ret = ocfs2_try_inode_lock(inode, NULL, 1); | ||
| 2307 | else | ||
| 2308 | ret = ocfs2_inode_lock(inode, NULL, 1); | ||
| 2264 | if (ret < 0) { | 2309 | if (ret < 0) { |
| 2265 | mlog_errno(ret); | 2310 | if (ret != -EAGAIN) |
| 2311 | mlog_errno(ret); | ||
| 2266 | goto out; | 2312 | goto out; |
| 2267 | } | 2313 | } |
| 2268 | 2314 | ||
| @@ -2277,9 +2323,10 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
| 2277 | } | 2323 | } |
| 2278 | count = ret; | 2324 | count = ret; |
| 2279 | 2325 | ||
| 2280 | ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count); | 2326 | ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, !nowait); |
| 2281 | if (ret < 0) { | 2327 | if (ret < 0) { |
| 2282 | mlog_errno(ret); | 2328 | if (ret != -EAGAIN) |
| 2329 | mlog_errno(ret); | ||
| 2283 | goto out; | 2330 | goto out; |
| 2284 | } | 2331 | } |
| 2285 | 2332 | ||
| @@ -2355,6 +2402,8 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, | |||
| 2355 | int ret = 0, rw_level = -1, lock_level = 0; | 2402 | int ret = 0, rw_level = -1, lock_level = 0; |
| 2356 | struct file *filp = iocb->ki_filp; | 2403 | struct file *filp = iocb->ki_filp; |
| 2357 | struct inode *inode = file_inode(filp); | 2404 | struct inode *inode = file_inode(filp); |
| 2405 | int direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0; | ||
| 2406 | int nowait = iocb->ki_flags & IOCB_NOWAIT ? 1 : 0; | ||
| 2358 | 2407 | ||
| 2359 | trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry, | 2408 | trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry, |
| 2360 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 2409 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
| @@ -2369,14 +2418,22 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, | |||
| 2369 | goto bail; | 2418 | goto bail; |
| 2370 | } | 2419 | } |
| 2371 | 2420 | ||
| 2421 | if (!direct_io && nowait) | ||
| 2422 | return -EOPNOTSUPP; | ||
| 2423 | |||
| 2372 | /* | 2424 | /* |
| 2373 | * buffered reads protect themselves in ->readpage(). O_DIRECT reads | 2425 | * buffered reads protect themselves in ->readpage(). O_DIRECT reads |
| 2374 | * need locks to protect pending reads from racing with truncate. | 2426 | * need locks to protect pending reads from racing with truncate. |
| 2375 | */ | 2427 | */ |
| 2376 | if (iocb->ki_flags & IOCB_DIRECT) { | 2428 | if (direct_io) { |
| 2377 | ret = ocfs2_rw_lock(inode, 0); | 2429 | if (nowait) |
| 2430 | ret = ocfs2_try_rw_lock(inode, 0); | ||
| 2431 | else | ||
| 2432 | ret = ocfs2_rw_lock(inode, 0); | ||
| 2433 | |||
| 2378 | if (ret < 0) { | 2434 | if (ret < 0) { |
| 2379 | mlog_errno(ret); | 2435 | if (ret != -EAGAIN) |
| 2436 | mlog_errno(ret); | ||
| 2380 | goto bail; | 2437 | goto bail; |
| 2381 | } | 2438 | } |
| 2382 | rw_level = 0; | 2439 | rw_level = 0; |
| @@ -2393,9 +2450,11 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, | |||
| 2393 | * like i_size. This allows the checks down below | 2450 | * like i_size. This allows the checks down below |
| 2394 | * generic_file_aio_read() a chance of actually working. | 2451 | * generic_file_aio_read() a chance of actually working. |
| 2395 | */ | 2452 | */ |
| 2396 | ret = ocfs2_inode_lock_atime(inode, filp->f_path.mnt, &lock_level); | 2453 | ret = ocfs2_inode_lock_atime(inode, filp->f_path.mnt, &lock_level, |
| 2454 | !nowait); | ||
| 2397 | if (ret < 0) { | 2455 | if (ret < 0) { |
| 2398 | mlog_errno(ret); | 2456 | if (ret != -EAGAIN) |
| 2457 | mlog_errno(ret); | ||
| 2399 | goto bail; | 2458 | goto bail; |
| 2400 | } | 2459 | } |
| 2401 | ocfs2_inode_unlock(inode, lock_level); | 2460 | ocfs2_inode_unlock(inode, lock_level); |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 36304434eacf..e5dcea6cee5f 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
| @@ -666,23 +666,24 @@ static int __ocfs2_journal_access(handle_t *handle, | |||
| 666 | /* we can safely remove this assertion after testing. */ | 666 | /* we can safely remove this assertion after testing. */ |
| 667 | if (!buffer_uptodate(bh)) { | 667 | if (!buffer_uptodate(bh)) { |
| 668 | mlog(ML_ERROR, "giving me a buffer that's not uptodate!\n"); | 668 | mlog(ML_ERROR, "giving me a buffer that's not uptodate!\n"); |
| 669 | mlog(ML_ERROR, "b_blocknr=%llu\n", | 669 | mlog(ML_ERROR, "b_blocknr=%llu, b_state=0x%lx\n", |
| 670 | (unsigned long long)bh->b_blocknr); | 670 | (unsigned long long)bh->b_blocknr, bh->b_state); |
| 671 | 671 | ||
| 672 | lock_buffer(bh); | 672 | lock_buffer(bh); |
| 673 | /* | 673 | /* |
| 674 | * A previous attempt to write this buffer head failed. | 674 | * A previous transaction with a couple of buffer heads fail |
| 675 | * Nothing we can do but to retry the write and hope for | 675 | * to checkpoint, so all the bhs are marked as BH_Write_EIO. |
| 676 | * the best. | 676 | * For current transaction, the bh is just among those error |
| 677 | * bhs which previous transaction handle. We can't just clear | ||
| 678 | * its BH_Write_EIO and reuse directly, since other bhs are | ||
| 679 | * not written to disk yet and that will cause metadata | ||
| 680 | * inconsistency. So we should set fs read-only to avoid | ||
| 681 | * further damage. | ||
| 677 | */ | 682 | */ |
| 678 | if (buffer_write_io_error(bh) && !buffer_uptodate(bh)) { | 683 | if (buffer_write_io_error(bh) && !buffer_uptodate(bh)) { |
| 679 | clear_buffer_write_io_error(bh); | ||
| 680 | set_buffer_uptodate(bh); | ||
| 681 | } | ||
| 682 | |||
| 683 | if (!buffer_uptodate(bh)) { | ||
| 684 | unlock_buffer(bh); | 684 | unlock_buffer(bh); |
| 685 | return -EIO; | 685 | return ocfs2_error(osb->sb, "A previous attempt to " |
| 686 | "write this buffer head failed\n"); | ||
| 686 | } | 687 | } |
| 687 | unlock_buffer(bh); | 688 | unlock_buffer(bh); |
| 688 | } | 689 | } |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index 098f5c712569..fb9a20e3d608 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
| @@ -184,7 +184,7 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 184 | int ret = 0, lock_level = 0; | 184 | int ret = 0, lock_level = 0; |
| 185 | 185 | ||
| 186 | ret = ocfs2_inode_lock_atime(file_inode(file), | 186 | ret = ocfs2_inode_lock_atime(file_inode(file), |
| 187 | file->f_path.mnt, &lock_level); | 187 | file->f_path.mnt, &lock_level, 1); |
| 188 | if (ret < 0) { | 188 | if (ret < 0) { |
| 189 | mlog_errno(ret); | 189 | mlog_errno(ret); |
| 190 | goto out; | 190 | goto out; |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 9a50f222ac97..6867eef2e06b 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
| @@ -404,6 +404,7 @@ struct ocfs2_super | |||
| 404 | struct ocfs2_lock_res osb_super_lockres; | 404 | struct ocfs2_lock_res osb_super_lockres; |
| 405 | struct ocfs2_lock_res osb_rename_lockres; | 405 | struct ocfs2_lock_res osb_rename_lockres; |
| 406 | struct ocfs2_lock_res osb_nfs_sync_lockres; | 406 | struct ocfs2_lock_res osb_nfs_sync_lockres; |
| 407 | struct ocfs2_lock_res osb_trim_fs_lockres; | ||
| 407 | struct ocfs2_dlm_debug *osb_dlm_debug; | 408 | struct ocfs2_dlm_debug *osb_dlm_debug; |
| 408 | 409 | ||
| 409 | struct dentry *osb_debug_root; | 410 | struct dentry *osb_debug_root; |
diff --git a/fs/ocfs2/ocfs2_lockid.h b/fs/ocfs2/ocfs2_lockid.h index d277aabf5dfb..7051b994c776 100644 --- a/fs/ocfs2/ocfs2_lockid.h +++ b/fs/ocfs2/ocfs2_lockid.h | |||
| @@ -50,6 +50,7 @@ enum ocfs2_lock_type { | |||
| 50 | OCFS2_LOCK_TYPE_NFS_SYNC, | 50 | OCFS2_LOCK_TYPE_NFS_SYNC, |
| 51 | OCFS2_LOCK_TYPE_ORPHAN_SCAN, | 51 | OCFS2_LOCK_TYPE_ORPHAN_SCAN, |
| 52 | OCFS2_LOCK_TYPE_REFCOUNT, | 52 | OCFS2_LOCK_TYPE_REFCOUNT, |
| 53 | OCFS2_LOCK_TYPE_TRIM_FS, | ||
| 53 | OCFS2_NUM_LOCK_TYPES | 54 | OCFS2_NUM_LOCK_TYPES |
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| @@ -93,6 +94,9 @@ static inline char ocfs2_lock_type_char(enum ocfs2_lock_type type) | |||
| 93 | case OCFS2_LOCK_TYPE_REFCOUNT: | 94 | case OCFS2_LOCK_TYPE_REFCOUNT: |
| 94 | c = 'T'; | 95 | c = 'T'; |
| 95 | break; | 96 | break; |
| 97 | case OCFS2_LOCK_TYPE_TRIM_FS: | ||
| 98 | c = 'I'; | ||
| 99 | break; | ||
| 96 | default: | 100 | default: |
| 97 | c = '\0'; | 101 | c = '\0'; |
| 98 | } | 102 | } |
| @@ -115,6 +119,7 @@ static char *ocfs2_lock_type_strings[] = { | |||
| 115 | [OCFS2_LOCK_TYPE_NFS_SYNC] = "NFSSync", | 119 | [OCFS2_LOCK_TYPE_NFS_SYNC] = "NFSSync", |
| 116 | [OCFS2_LOCK_TYPE_ORPHAN_SCAN] = "OrphanScan", | 120 | [OCFS2_LOCK_TYPE_ORPHAN_SCAN] = "OrphanScan", |
| 117 | [OCFS2_LOCK_TYPE_REFCOUNT] = "Refcount", | 121 | [OCFS2_LOCK_TYPE_REFCOUNT] = "Refcount", |
| 122 | [OCFS2_LOCK_TYPE_TRIM_FS] = "TrimFs", | ||
| 118 | }; | 123 | }; |
| 119 | 124 | ||
| 120 | static inline const char *ocfs2_lock_type_string(enum ocfs2_lock_type type) | 125 | static inline const char *ocfs2_lock_type_string(enum ocfs2_lock_type type) |
diff --git a/fs/ocfs2/ocfs2_trace.h b/fs/ocfs2/ocfs2_trace.h index a0b5d00ef0a9..e2a11aaece10 100644 --- a/fs/ocfs2/ocfs2_trace.h +++ b/fs/ocfs2/ocfs2_trace.h | |||
| @@ -1449,20 +1449,22 @@ DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_remove_inode_range); | |||
| 1449 | 1449 | ||
| 1450 | TRACE_EVENT(ocfs2_prepare_inode_for_write, | 1450 | TRACE_EVENT(ocfs2_prepare_inode_for_write, |
| 1451 | TP_PROTO(unsigned long long ino, unsigned long long saved_pos, | 1451 | TP_PROTO(unsigned long long ino, unsigned long long saved_pos, |
| 1452 | unsigned long count), | 1452 | unsigned long count, int wait), |
| 1453 | TP_ARGS(ino, saved_pos, count), | 1453 | TP_ARGS(ino, saved_pos, count, wait), |
| 1454 | TP_STRUCT__entry( | 1454 | TP_STRUCT__entry( |
| 1455 | __field(unsigned long long, ino) | 1455 | __field(unsigned long long, ino) |
| 1456 | __field(unsigned long long, saved_pos) | 1456 | __field(unsigned long long, saved_pos) |
| 1457 | __field(unsigned long, count) | 1457 | __field(unsigned long, count) |
| 1458 | __field(int, wait) | ||
| 1458 | ), | 1459 | ), |
| 1459 | TP_fast_assign( | 1460 | TP_fast_assign( |
| 1460 | __entry->ino = ino; | 1461 | __entry->ino = ino; |
| 1461 | __entry->saved_pos = saved_pos; | 1462 | __entry->saved_pos = saved_pos; |
| 1462 | __entry->count = count; | 1463 | __entry->count = count; |
| 1464 | __entry->wait = wait; | ||
| 1463 | ), | 1465 | ), |
| 1464 | TP_printk("%llu %llu %lu", __entry->ino, | 1466 | TP_printk("%llu %llu %lu %d", __entry->ino, |
| 1465 | __entry->saved_pos, __entry->count) | 1467 | __entry->saved_pos, __entry->count, __entry->wait) |
| 1466 | ); | 1468 | ); |
| 1467 | 1469 | ||
| 1468 | DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret); | 1470 | DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret); |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 9f0b95abc09f..d8f5f6ce99dc 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
| @@ -2438,6 +2438,8 @@ static int ocfs2_block_group_clear_bits(handle_t *handle, | |||
| 2438 | } | 2438 | } |
| 2439 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); | 2439 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); |
| 2440 | if (le16_to_cpu(bg->bg_free_bits_count) > le16_to_cpu(bg->bg_bits)) { | 2440 | if (le16_to_cpu(bg->bg_free_bits_count) > le16_to_cpu(bg->bg_bits)) { |
| 2441 | if (undo_fn) | ||
| 2442 | jbd_unlock_bh_state(group_bh); | ||
| 2441 | return ocfs2_error(alloc_inode->i_sb, "Group descriptor # %llu has bit count %u but claims %u are freed. num_bits %d\n", | 2443 | return ocfs2_error(alloc_inode->i_sb, "Group descriptor # %llu has bit count %u but claims %u are freed. num_bits %d\n", |
| 2442 | (unsigned long long)le64_to_cpu(bg->bg_blkno), | 2444 | (unsigned long long)le64_to_cpu(bg->bg_blkno), |
| 2443 | le16_to_cpu(bg->bg_bits), | 2445 | le16_to_cpu(bg->bg_bits), |
| @@ -2563,16 +2565,16 @@ static int _ocfs2_free_clusters(handle_t *handle, | |||
| 2563 | int status; | 2565 | int status; |
| 2564 | u16 bg_start_bit; | 2566 | u16 bg_start_bit; |
| 2565 | u64 bg_blkno; | 2567 | u64 bg_blkno; |
| 2566 | struct ocfs2_dinode *fe; | ||
| 2567 | 2568 | ||
| 2568 | /* You can't ever have a contiguous set of clusters | 2569 | /* You can't ever have a contiguous set of clusters |
| 2569 | * bigger than a block group bitmap so we never have to worry | 2570 | * bigger than a block group bitmap so we never have to worry |
| 2570 | * about looping on them. | 2571 | * about looping on them. |
| 2571 | * This is expensive. We can safely remove once this stuff has | 2572 | * This is expensive. We can safely remove once this stuff has |
| 2572 | * gotten tested really well. */ | 2573 | * gotten tested really well. */ |
| 2573 | BUG_ON(start_blk != ocfs2_clusters_to_blocks(bitmap_inode->i_sb, ocfs2_blocks_to_clusters(bitmap_inode->i_sb, start_blk))); | 2574 | BUG_ON(start_blk != ocfs2_clusters_to_blocks(bitmap_inode->i_sb, |
| 2575 | ocfs2_blocks_to_clusters(bitmap_inode->i_sb, | ||
| 2576 | start_blk))); | ||
| 2574 | 2577 | ||
| 2575 | fe = (struct ocfs2_dinode *) bitmap_bh->b_data; | ||
| 2576 | 2578 | ||
| 2577 | ocfs2_block_to_cluster_group(bitmap_inode, start_blk, &bg_blkno, | 2579 | ocfs2_block_to_cluster_group(bitmap_inode, start_blk, &bg_blkno, |
| 2578 | &bg_start_bit); | 2580 | &bg_start_bit); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 80efa5699fb0..ffa4952d432b 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -474,9 +474,8 @@ static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb) | |||
| 474 | new = ocfs2_get_system_file_inode(osb, i, osb->slot_num); | 474 | new = ocfs2_get_system_file_inode(osb, i, osb->slot_num); |
| 475 | if (!new) { | 475 | if (!new) { |
| 476 | ocfs2_release_system_inodes(osb); | 476 | ocfs2_release_system_inodes(osb); |
| 477 | status = -EINVAL; | 477 | status = ocfs2_is_soft_readonly(osb) ? -EROFS : -EINVAL; |
| 478 | mlog_errno(status); | 478 | mlog_errno(status); |
| 479 | /* FIXME: Should ERROR_RO_FS */ | ||
| 480 | mlog(ML_ERROR, "Unable to load system inode %d, " | 479 | mlog(ML_ERROR, "Unable to load system inode %d, " |
| 481 | "possibly corrupt fs?", i); | 480 | "possibly corrupt fs?", i); |
| 482 | goto bail; | 481 | goto bail; |
| @@ -505,7 +504,7 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb) | |||
| 505 | new = ocfs2_get_system_file_inode(osb, i, osb->slot_num); | 504 | new = ocfs2_get_system_file_inode(osb, i, osb->slot_num); |
| 506 | if (!new) { | 505 | if (!new) { |
| 507 | ocfs2_release_system_inodes(osb); | 506 | ocfs2_release_system_inodes(osb); |
| 508 | status = -EINVAL; | 507 | status = ocfs2_is_soft_readonly(osb) ? -EROFS : -EINVAL; |
| 509 | mlog(ML_ERROR, "status=%d, sysfile=%d, slot=%d\n", | 508 | mlog(ML_ERROR, "status=%d, sysfile=%d, slot=%d\n", |
| 510 | status, i, osb->slot_num); | 509 | status, i, osb->slot_num); |
| 511 | goto bail; | 510 | goto bail; |
| @@ -1208,14 +1207,15 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1208 | read_super_error: | 1207 | read_super_error: |
| 1209 | brelse(bh); | 1208 | brelse(bh); |
| 1210 | 1209 | ||
| 1210 | if (status) | ||
| 1211 | mlog_errno(status); | ||
| 1212 | |||
| 1211 | if (osb) { | 1213 | if (osb) { |
| 1212 | atomic_set(&osb->vol_state, VOLUME_DISABLED); | 1214 | atomic_set(&osb->vol_state, VOLUME_DISABLED); |
| 1213 | wake_up(&osb->osb_mount_event); | 1215 | wake_up(&osb->osb_mount_event); |
| 1214 | ocfs2_dismount_volume(sb, 1); | 1216 | ocfs2_dismount_volume(sb, 1); |
| 1215 | } | 1217 | } |
| 1216 | 1218 | ||
| 1217 | if (status) | ||
| 1218 | mlog_errno(status); | ||
| 1219 | return status; | 1219 | return status; |
| 1220 | } | 1220 | } |
| 1221 | 1221 | ||
| @@ -1843,6 +1843,9 @@ static int ocfs2_mount_volume(struct super_block *sb) | |||
| 1843 | status = ocfs2_dlm_init(osb); | 1843 | status = ocfs2_dlm_init(osb); |
| 1844 | if (status < 0) { | 1844 | if (status < 0) { |
| 1845 | mlog_errno(status); | 1845 | mlog_errno(status); |
| 1846 | if (status == -EBADR && ocfs2_userspace_stack(osb)) | ||
| 1847 | mlog(ML_ERROR, "couldn't mount because cluster name on" | ||
| 1848 | " disk does not match the running cluster name.\n"); | ||
| 1846 | goto leave; | 1849 | goto leave; |
| 1847 | } | 1850 | } |
| 1848 | 1851 | ||
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index c5898c59d411..c261c1dfd374 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -638,14 +638,17 @@ int ocfs2_calc_xattr_init(struct inode *dir, | |||
| 638 | si->value_len); | 638 | si->value_len); |
| 639 | 639 | ||
| 640 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { | 640 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { |
| 641 | down_read(&OCFS2_I(dir)->ip_xattr_sem); | ||
| 641 | acl_len = ocfs2_xattr_get_nolock(dir, dir_bh, | 642 | acl_len = ocfs2_xattr_get_nolock(dir, dir_bh, |
| 642 | OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT, | 643 | OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT, |
| 643 | "", NULL, 0); | 644 | "", NULL, 0); |
| 645 | up_read(&OCFS2_I(dir)->ip_xattr_sem); | ||
| 644 | if (acl_len > 0) { | 646 | if (acl_len > 0) { |
| 645 | a_size = ocfs2_xattr_entry_real_size(0, acl_len); | 647 | a_size = ocfs2_xattr_entry_real_size(0, acl_len); |
| 646 | if (S_ISDIR(mode)) | 648 | if (S_ISDIR(mode)) |
| 647 | a_size <<= 1; | 649 | a_size <<= 1; |
| 648 | } else if (acl_len != 0 && acl_len != -ENODATA) { | 650 | } else if (acl_len != 0 && acl_len != -ENODATA) { |
| 651 | ret = acl_len; | ||
| 649 | mlog_errno(ret); | 652 | mlog_errno(ret); |
| 650 | return ret; | 653 | return ret; |
| 651 | } | 654 | } |
| @@ -6415,7 +6418,7 @@ static int ocfs2_reflink_xattr_header(handle_t *handle, | |||
| 6415 | * and then insert the extents one by one. | 6418 | * and then insert the extents one by one. |
| 6416 | */ | 6419 | */ |
| 6417 | if (xv->xr_list.l_tree_depth) { | 6420 | if (xv->xr_list.l_tree_depth) { |
| 6418 | memcpy(new_xv, &def_xv, sizeof(def_xv)); | 6421 | memcpy(new_xv, &def_xv, OCFS2_XATTR_ROOT_SIZE); |
| 6419 | vb->vb_xv = new_xv; | 6422 | vb->vb_xv = new_xv; |
| 6420 | vb->vb_bh = value_bh; | 6423 | vb->vb_bh = value_bh; |
| 6421 | ocfs2_init_xattr_value_extent_tree(&data_et, | 6424 | ocfs2_init_xattr_value_extent_tree(&data_et, |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 339e4c1c044d..ec6d2983a5cb 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
| @@ -47,8 +47,11 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) | |||
| 47 | if (hiwater_rss < mm->hiwater_rss) | 47 | if (hiwater_rss < mm->hiwater_rss) |
| 48 | hiwater_rss = mm->hiwater_rss; | 48 | hiwater_rss = mm->hiwater_rss; |
| 49 | 49 | ||
| 50 | text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; | 50 | /* split executable areas between text and lib */ |
| 51 | lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; | 51 | text = PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK); |
| 52 | text = min(text, mm->exec_vm << PAGE_SHIFT); | ||
| 53 | lib = (mm->exec_vm << PAGE_SHIFT) - text; | ||
| 54 | |||
| 52 | swap = get_mm_counter(mm, MM_SWAPENTS); | 55 | swap = get_mm_counter(mm, MM_SWAPENTS); |
| 53 | seq_printf(m, | 56 | seq_printf(m, |
| 54 | "VmPeak:\t%8lu kB\n" | 57 | "VmPeak:\t%8lu kB\n" |
| @@ -76,7 +79,9 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) | |||
| 76 | file << (PAGE_SHIFT-10), | 79 | file << (PAGE_SHIFT-10), |
| 77 | shmem << (PAGE_SHIFT-10), | 80 | shmem << (PAGE_SHIFT-10), |
| 78 | mm->data_vm << (PAGE_SHIFT-10), | 81 | mm->data_vm << (PAGE_SHIFT-10), |
| 79 | mm->stack_vm << (PAGE_SHIFT-10), text, lib, | 82 | mm->stack_vm << (PAGE_SHIFT-10), |
| 83 | text >> 10, | ||
| 84 | lib >> 10, | ||
| 80 | mm_pgtables_bytes(mm) >> 10, | 85 | mm_pgtables_bytes(mm) >> 10, |
| 81 | swap << (PAGE_SHIFT-10)); | 86 | swap << (PAGE_SHIFT-10)); |
| 82 | hugetlb_report_usage(m, mm); | 87 | hugetlb_report_usage(m, mm); |
| @@ -977,14 +982,14 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma, | |||
| 977 | static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, | 982 | static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, |
| 978 | unsigned long addr, pmd_t *pmdp) | 983 | unsigned long addr, pmd_t *pmdp) |
| 979 | { | 984 | { |
| 980 | pmd_t pmd = *pmdp; | 985 | pmd_t old, pmd = *pmdp; |
| 981 | 986 | ||
| 982 | if (pmd_present(pmd)) { | 987 | if (pmd_present(pmd)) { |
| 983 | /* See comment in change_huge_pmd() */ | 988 | /* See comment in change_huge_pmd() */ |
| 984 | pmdp_invalidate(vma, addr, pmdp); | 989 | old = pmdp_invalidate(vma, addr, pmdp); |
| 985 | if (pmd_dirty(*pmdp)) | 990 | if (pmd_dirty(old)) |
| 986 | pmd = pmd_mkdirty(pmd); | 991 | pmd = pmd_mkdirty(pmd); |
| 987 | if (pmd_young(*pmdp)) | 992 | if (pmd_young(old)) |
| 988 | pmd = pmd_mkyoung(pmd); | 993 | pmd = pmd_mkyoung(pmd); |
| 989 | 994 | ||
| 990 | pmd = pmd_wrprotect(pmd); | 995 | pmd = pmd_wrprotect(pmd); |
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 743eaa646898..87a13a7c8270 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c | |||
| @@ -294,10 +294,13 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx, | |||
| 294 | * pmd_trans_unstable) of the pmd. | 294 | * pmd_trans_unstable) of the pmd. |
| 295 | */ | 295 | */ |
| 296 | _pmd = READ_ONCE(*pmd); | 296 | _pmd = READ_ONCE(*pmd); |
| 297 | if (!pmd_present(_pmd)) | 297 | if (pmd_none(_pmd)) |
| 298 | goto out; | 298 | goto out; |
| 299 | 299 | ||
| 300 | ret = false; | 300 | ret = false; |
| 301 | if (!pmd_present(_pmd)) | ||
| 302 | goto out; | ||
| 303 | |||
| 301 | if (pmd_trans_huge(_pmd)) | 304 | if (pmd_trans_huge(_pmd)) |
| 302 | goto out; | 305 | goto out; |
| 303 | 306 | ||
| @@ -985,24 +988,14 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *ctx, | |||
| 985 | struct uffd_msg *msg) | 988 | struct uffd_msg *msg) |
| 986 | { | 989 | { |
| 987 | int fd; | 990 | int fd; |
| 988 | struct file *file; | ||
| 989 | unsigned int flags = new->flags & UFFD_SHARED_FCNTL_FLAGS; | ||
| 990 | 991 | ||
| 991 | fd = get_unused_fd_flags(flags); | 992 | fd = anon_inode_getfd("[userfaultfd]", &userfaultfd_fops, new, |
| 993 | O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS)); | ||
| 992 | if (fd < 0) | 994 | if (fd < 0) |
| 993 | return fd; | 995 | return fd; |
| 994 | 996 | ||
| 995 | file = anon_inode_getfile("[userfaultfd]", &userfaultfd_fops, new, | ||
| 996 | O_RDWR | flags); | ||
| 997 | if (IS_ERR(file)) { | ||
| 998 | put_unused_fd(fd); | ||
| 999 | return PTR_ERR(file); | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | fd_install(fd, file); | ||
| 1003 | msg->arg.reserved.reserved1 = 0; | 997 | msg->arg.reserved.reserved1 = 0; |
| 1004 | msg->arg.fork.ufd = fd; | 998 | msg->arg.fork.ufd = fd; |
| 1005 | |||
| 1006 | return 0; | 999 | return 0; |
| 1007 | } | 1000 | } |
| 1008 | 1001 | ||
| @@ -1884,24 +1877,10 @@ static void init_once_userfaultfd_ctx(void *mem) | |||
| 1884 | seqcount_init(&ctx->refile_seq); | 1877 | seqcount_init(&ctx->refile_seq); |
| 1885 | } | 1878 | } |
| 1886 | 1879 | ||
| 1887 | /** | 1880 | SYSCALL_DEFINE1(userfaultfd, int, flags) |
| 1888 | * userfaultfd_file_create - Creates a userfaultfd file pointer. | ||
| 1889 | * @flags: Flags for the userfaultfd file. | ||
| 1890 | * | ||
| 1891 | * This function creates a userfaultfd file pointer, w/out installing | ||
| 1892 | * it into the fd table. This is useful when the userfaultfd file is | ||
| 1893 | * used during the initialization of data structures that require | ||
| 1894 | * extra setup after the userfaultfd creation. So the userfaultfd | ||
| 1895 | * creation is split into the file pointer creation phase, and the | ||
| 1896 | * file descriptor installation phase. In this way races with | ||
| 1897 | * userspace closing the newly installed file descriptor can be | ||
| 1898 | * avoided. Returns a userfaultfd file pointer, or a proper error | ||
| 1899 | * pointer. | ||
| 1900 | */ | ||
| 1901 | static struct file *userfaultfd_file_create(int flags) | ||
| 1902 | { | 1881 | { |
| 1903 | struct file *file; | ||
| 1904 | struct userfaultfd_ctx *ctx; | 1882 | struct userfaultfd_ctx *ctx; |
| 1883 | int fd; | ||
| 1905 | 1884 | ||
| 1906 | BUG_ON(!current->mm); | 1885 | BUG_ON(!current->mm); |
| 1907 | 1886 | ||
| @@ -1909,14 +1888,12 @@ static struct file *userfaultfd_file_create(int flags) | |||
| 1909 | BUILD_BUG_ON(UFFD_CLOEXEC != O_CLOEXEC); | 1888 | BUILD_BUG_ON(UFFD_CLOEXEC != O_CLOEXEC); |
| 1910 | BUILD_BUG_ON(UFFD_NONBLOCK != O_NONBLOCK); | 1889 | BUILD_BUG_ON(UFFD_NONBLOCK != O_NONBLOCK); |
| 1911 | 1890 | ||
| 1912 | file = ERR_PTR(-EINVAL); | ||
| 1913 | if (flags & ~UFFD_SHARED_FCNTL_FLAGS) | 1891 | if (flags & ~UFFD_SHARED_FCNTL_FLAGS) |
| 1914 | goto out; | 1892 | return -EINVAL; |
| 1915 | 1893 | ||
| 1916 | file = ERR_PTR(-ENOMEM); | ||
| 1917 | ctx = kmem_cache_alloc(userfaultfd_ctx_cachep, GFP_KERNEL); | 1894 | ctx = kmem_cache_alloc(userfaultfd_ctx_cachep, GFP_KERNEL); |
| 1918 | if (!ctx) | 1895 | if (!ctx) |
| 1919 | goto out; | 1896 | return -ENOMEM; |
| 1920 | 1897 | ||
| 1921 | atomic_set(&ctx->refcount, 1); | 1898 | atomic_set(&ctx->refcount, 1); |
| 1922 | ctx->flags = flags; | 1899 | ctx->flags = flags; |
| @@ -1927,39 +1904,13 @@ static struct file *userfaultfd_file_create(int flags) | |||
| 1927 | /* prevent the mm struct to be freed */ | 1904 | /* prevent the mm struct to be freed */ |
| 1928 | mmgrab(ctx->mm); | 1905 | mmgrab(ctx->mm); |
| 1929 | 1906 | ||
| 1930 | file = anon_inode_getfile("[userfaultfd]", &userfaultfd_fops, ctx, | 1907 | fd = anon_inode_getfd("[userfaultfd]", &userfaultfd_fops, ctx, |
| 1931 | O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS)); | 1908 | O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS)); |
| 1932 | if (IS_ERR(file)) { | 1909 | if (fd < 0) { |
| 1933 | mmdrop(ctx->mm); | 1910 | mmdrop(ctx->mm); |
| 1934 | kmem_cache_free(userfaultfd_ctx_cachep, ctx); | 1911 | kmem_cache_free(userfaultfd_ctx_cachep, ctx); |
| 1935 | } | 1912 | } |
| 1936 | out: | ||
| 1937 | return file; | ||
| 1938 | } | ||
| 1939 | |||
| 1940 | SYSCALL_DEFINE1(userfaultfd, int, flags) | ||
| 1941 | { | ||
| 1942 | int fd, error; | ||
| 1943 | struct file *file; | ||
| 1944 | |||
| 1945 | error = get_unused_fd_flags(flags & UFFD_SHARED_FCNTL_FLAGS); | ||
| 1946 | if (error < 0) | ||
| 1947 | return error; | ||
| 1948 | fd = error; | ||
| 1949 | |||
| 1950 | file = userfaultfd_file_create(flags); | ||
| 1951 | if (IS_ERR(file)) { | ||
| 1952 | error = PTR_ERR(file); | ||
| 1953 | goto err_put_unused_fd; | ||
| 1954 | } | ||
| 1955 | fd_install(fd, file); | ||
| 1956 | |||
| 1957 | return fd; | 1913 | return fd; |
| 1958 | |||
| 1959 | err_put_unused_fd: | ||
| 1960 | put_unused_fd(fd); | ||
| 1961 | |||
| 1962 | return error; | ||
| 1963 | } | 1914 | } |
| 1964 | 1915 | ||
| 1965 | static int __init userfaultfd_init(void) | 1916 | static int __init userfaultfd_init(void) |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 868e68561f91..2cfa3075d148 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
| @@ -309,19 +309,26 @@ extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | |||
| 309 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); | 309 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); |
| 310 | #endif | 310 | #endif |
| 311 | 311 | ||
| 312 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE | 312 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 313 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 313 | /* |
| 314 | pmd_t *pmdp); | 314 | * This is an implementation of pmdp_establish() that is only suitable for an |
| 315 | #endif | 315 | * architecture that doesn't have hardware dirty/accessed bits. In this case we |
| 316 | 316 | * can't race with CPU which sets these bits and non-atomic aproach is fine. | |
| 317 | #ifndef __HAVE_ARCH_PMDP_HUGE_SPLIT_PREPARE | 317 | */ |
| 318 | static inline void pmdp_huge_split_prepare(struct vm_area_struct *vma, | 318 | static inline pmd_t generic_pmdp_establish(struct vm_area_struct *vma, |
| 319 | unsigned long address, pmd_t *pmdp) | 319 | unsigned long address, pmd_t *pmdp, pmd_t pmd) |
| 320 | { | 320 | { |
| 321 | 321 | pmd_t old_pmd = *pmdp; | |
| 322 | set_pmd_at(vma->vm_mm, address, pmdp, pmd); | ||
| 323 | return old_pmd; | ||
| 322 | } | 324 | } |
| 323 | #endif | 325 | #endif |
| 324 | 326 | ||
| 327 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE | ||
| 328 | extern pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
| 329 | pmd_t *pmdp); | ||
| 330 | #endif | ||
| 331 | |||
| 325 | #ifndef __HAVE_ARCH_PTE_SAME | 332 | #ifndef __HAVE_ARCH_PTE_SAME |
| 326 | static inline int pte_same(pte_t pte_a, pte_t pte_b) | 333 | static inline int pte_same(pte_t pte_a, pte_t pte_b) |
| 327 | { | 334 | { |
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 82a25880714a..36fa6a2a82e3 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
| @@ -119,6 +119,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, | |||
| 119 | long freed); | 119 | long freed); |
| 120 | bool isolate_huge_page(struct page *page, struct list_head *list); | 120 | bool isolate_huge_page(struct page *page, struct list_head *list); |
| 121 | void putback_active_hugepage(struct page *page); | 121 | void putback_active_hugepage(struct page *page); |
| 122 | void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason); | ||
| 122 | void free_huge_page(struct page *page); | 123 | void free_huge_page(struct page *page); |
| 123 | void hugetlb_fix_reserve_counts(struct inode *inode); | 124 | void hugetlb_fix_reserve_counts(struct inode *inode); |
| 124 | extern struct mutex *hugetlb_fault_mutex_table; | 125 | extern struct mutex *hugetlb_fault_mutex_table; |
| @@ -129,7 +130,6 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, | |||
| 129 | 130 | ||
| 130 | pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud); | 131 | pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud); |
| 131 | 132 | ||
| 132 | extern int hugepages_treat_as_movable; | ||
| 133 | extern int sysctl_hugetlb_shm_group; | 133 | extern int sysctl_hugetlb_shm_group; |
| 134 | extern struct list_head huge_boot_pages; | 134 | extern struct list_head huge_boot_pages; |
| 135 | 135 | ||
| @@ -158,6 +158,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, | |||
| 158 | unsigned long address, unsigned long end, pgprot_t newprot); | 158 | unsigned long address, unsigned long end, pgprot_t newprot); |
| 159 | 159 | ||
| 160 | bool is_hugetlb_entry_migration(pte_t pte); | 160 | bool is_hugetlb_entry_migration(pte_t pte); |
| 161 | |||
| 161 | #else /* !CONFIG_HUGETLB_PAGE */ | 162 | #else /* !CONFIG_HUGETLB_PAGE */ |
| 162 | 163 | ||
| 163 | static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) | 164 | static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) |
| @@ -198,6 +199,7 @@ static inline bool isolate_huge_page(struct page *page, struct list_head *list) | |||
| 198 | return false; | 199 | return false; |
| 199 | } | 200 | } |
| 200 | #define putback_active_hugepage(p) do {} while (0) | 201 | #define putback_active_hugepage(p) do {} while (0) |
| 202 | #define move_hugetlb_state(old, new, reason) do {} while (0) | ||
| 201 | 203 | ||
| 202 | static inline unsigned long hugetlb_change_protection(struct vm_area_struct *vma, | 204 | static inline unsigned long hugetlb_change_protection(struct vm_area_struct *vma, |
| 203 | unsigned long address, unsigned long end, pgprot_t newprot) | 205 | unsigned long address, unsigned long end, pgprot_t newprot) |
| @@ -271,6 +273,17 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) | |||
| 271 | return sb->s_fs_info; | 273 | return sb->s_fs_info; |
| 272 | } | 274 | } |
| 273 | 275 | ||
| 276 | struct hugetlbfs_inode_info { | ||
| 277 | struct shared_policy policy; | ||
| 278 | struct inode vfs_inode; | ||
| 279 | unsigned int seals; | ||
| 280 | }; | ||
| 281 | |||
| 282 | static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode) | ||
| 283 | { | ||
| 284 | return container_of(inode, struct hugetlbfs_inode_info, vfs_inode); | ||
| 285 | } | ||
| 286 | |||
| 274 | extern const struct file_operations hugetlbfs_file_operations; | 287 | extern const struct file_operations hugetlbfs_file_operations; |
| 275 | extern const struct vm_operations_struct hugetlb_vm_ops; | 288 | extern const struct vm_operations_struct hugetlb_vm_ops; |
| 276 | struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, | 289 | struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, |
| @@ -343,10 +356,10 @@ struct huge_bootmem_page { | |||
| 343 | struct page *alloc_huge_page(struct vm_area_struct *vma, | 356 | struct page *alloc_huge_page(struct vm_area_struct *vma, |
| 344 | unsigned long addr, int avoid_reserve); | 357 | unsigned long addr, int avoid_reserve); |
| 345 | struct page *alloc_huge_page_node(struct hstate *h, int nid); | 358 | struct page *alloc_huge_page_node(struct hstate *h, int nid); |
| 346 | struct page *alloc_huge_page_noerr(struct vm_area_struct *vma, | ||
| 347 | unsigned long addr, int avoid_reserve); | ||
| 348 | struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid, | 359 | struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid, |
| 349 | nodemask_t *nmask); | 360 | nodemask_t *nmask); |
| 361 | struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma, | ||
| 362 | unsigned long address); | ||
| 350 | int huge_add_to_page_cache(struct page *page, struct address_space *mapping, | 363 | int huge_add_to_page_cache(struct page *page, struct address_space *mapping, |
| 351 | pgoff_t idx); | 364 | pgoff_t idx); |
| 352 | 365 | ||
| @@ -524,7 +537,7 @@ struct hstate {}; | |||
| 524 | #define alloc_huge_page(v, a, r) NULL | 537 | #define alloc_huge_page(v, a, r) NULL |
| 525 | #define alloc_huge_page_node(h, nid) NULL | 538 | #define alloc_huge_page_node(h, nid) NULL |
| 526 | #define alloc_huge_page_nodemask(h, preferred_nid, nmask) NULL | 539 | #define alloc_huge_page_nodemask(h, preferred_nid, nmask) NULL |
| 527 | #define alloc_huge_page_noerr(v, a, r) NULL | 540 | #define alloc_huge_page_vma(h, vma, address) NULL |
| 528 | #define alloc_bootmem_huge_page(h) NULL | 541 | #define alloc_bootmem_huge_page(h) NULL |
| 529 | #define hstate_file(f) NULL | 542 | #define hstate_file(f) NULL |
| 530 | #define hstate_sizelog(s) NULL | 543 | #define hstate_sizelog(s) NULL |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 69966c461d1c..882046863581 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
| @@ -108,7 +108,10 @@ struct lruvec_stat { | |||
| 108 | */ | 108 | */ |
| 109 | struct mem_cgroup_per_node { | 109 | struct mem_cgroup_per_node { |
| 110 | struct lruvec lruvec; | 110 | struct lruvec lruvec; |
| 111 | struct lruvec_stat __percpu *lruvec_stat; | 111 | |
| 112 | struct lruvec_stat __percpu *lruvec_stat_cpu; | ||
| 113 | atomic_long_t lruvec_stat[NR_VM_NODE_STAT_ITEMS]; | ||
| 114 | |||
| 112 | unsigned long lru_zone_size[MAX_NR_ZONES][NR_LRU_LISTS]; | 115 | unsigned long lru_zone_size[MAX_NR_ZONES][NR_LRU_LISTS]; |
| 113 | 116 | ||
| 114 | struct mem_cgroup_reclaim_iter iter[DEF_PRIORITY + 1]; | 117 | struct mem_cgroup_reclaim_iter iter[DEF_PRIORITY + 1]; |
| @@ -227,10 +230,10 @@ struct mem_cgroup { | |||
| 227 | spinlock_t move_lock; | 230 | spinlock_t move_lock; |
| 228 | struct task_struct *move_lock_task; | 231 | struct task_struct *move_lock_task; |
| 229 | unsigned long move_lock_flags; | 232 | unsigned long move_lock_flags; |
| 230 | /* | 233 | |
| 231 | * percpu counter. | 234 | struct mem_cgroup_stat_cpu __percpu *stat_cpu; |
| 232 | */ | 235 | atomic_long_t stat[MEMCG_NR_STAT]; |
| 233 | struct mem_cgroup_stat_cpu __percpu *stat; | 236 | atomic_long_t events[MEMCG_NR_EVENTS]; |
| 234 | 237 | ||
| 235 | unsigned long socket_pressure; | 238 | unsigned long socket_pressure; |
| 236 | 239 | ||
| @@ -265,6 +268,12 @@ struct mem_cgroup { | |||
| 265 | /* WARNING: nodeinfo must be the last member here */ | 268 | /* WARNING: nodeinfo must be the last member here */ |
| 266 | }; | 269 | }; |
| 267 | 270 | ||
| 271 | /* | ||
| 272 | * size of first charge trial. "32" comes from vmscan.c's magic value. | ||
| 273 | * TODO: maybe necessary to use big numbers in big irons. | ||
| 274 | */ | ||
| 275 | #define MEMCG_CHARGE_BATCH 32U | ||
| 276 | |||
| 268 | extern struct mem_cgroup *root_mem_cgroup; | 277 | extern struct mem_cgroup *root_mem_cgroup; |
| 269 | 278 | ||
| 270 | static inline bool mem_cgroup_disabled(void) | 279 | static inline bool mem_cgroup_disabled(void) |
| @@ -272,13 +281,6 @@ static inline bool mem_cgroup_disabled(void) | |||
| 272 | return !cgroup_subsys_enabled(memory_cgrp_subsys); | 281 | return !cgroup_subsys_enabled(memory_cgrp_subsys); |
| 273 | } | 282 | } |
| 274 | 283 | ||
| 275 | static inline void mem_cgroup_event(struct mem_cgroup *memcg, | ||
| 276 | enum memcg_event_item event) | ||
| 277 | { | ||
| 278 | this_cpu_inc(memcg->stat->events[event]); | ||
| 279 | cgroup_file_notify(&memcg->events_file); | ||
| 280 | } | ||
| 281 | |||
| 282 | bool mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg); | 284 | bool mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg); |
| 283 | 285 | ||
| 284 | int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm, | 286 | int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm, |
| @@ -492,32 +494,38 @@ void unlock_page_memcg(struct page *page); | |||
| 492 | static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, | 494 | static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, |
| 493 | int idx) | 495 | int idx) |
| 494 | { | 496 | { |
| 495 | long val = 0; | 497 | long x = atomic_long_read(&memcg->stat[idx]); |
| 496 | int cpu; | 498 | #ifdef CONFIG_SMP |
| 497 | 499 | if (x < 0) | |
| 498 | for_each_possible_cpu(cpu) | 500 | x = 0; |
| 499 | val += per_cpu(memcg->stat->count[idx], cpu); | 501 | #endif |
| 500 | 502 | return x; | |
| 501 | if (val < 0) | ||
| 502 | val = 0; | ||
| 503 | |||
| 504 | return val; | ||
| 505 | } | 503 | } |
| 506 | 504 | ||
| 507 | /* idx can be of type enum memcg_stat_item or node_stat_item */ | 505 | /* idx can be of type enum memcg_stat_item or node_stat_item */ |
| 508 | static inline void __mod_memcg_state(struct mem_cgroup *memcg, | 506 | static inline void __mod_memcg_state(struct mem_cgroup *memcg, |
| 509 | int idx, int val) | 507 | int idx, int val) |
| 510 | { | 508 | { |
| 511 | if (!mem_cgroup_disabled()) | 509 | long x; |
| 512 | __this_cpu_add(memcg->stat->count[idx], val); | 510 | |
| 511 | if (mem_cgroup_disabled()) | ||
| 512 | return; | ||
| 513 | |||
| 514 | x = val + __this_cpu_read(memcg->stat_cpu->count[idx]); | ||
| 515 | if (unlikely(abs(x) > MEMCG_CHARGE_BATCH)) { | ||
| 516 | atomic_long_add(x, &memcg->stat[idx]); | ||
| 517 | x = 0; | ||
| 518 | } | ||
| 519 | __this_cpu_write(memcg->stat_cpu->count[idx], x); | ||
| 513 | } | 520 | } |
| 514 | 521 | ||
| 515 | /* idx can be of type enum memcg_stat_item or node_stat_item */ | 522 | /* idx can be of type enum memcg_stat_item or node_stat_item */ |
| 516 | static inline void mod_memcg_state(struct mem_cgroup *memcg, | 523 | static inline void mod_memcg_state(struct mem_cgroup *memcg, |
| 517 | int idx, int val) | 524 | int idx, int val) |
| 518 | { | 525 | { |
| 519 | if (!mem_cgroup_disabled()) | 526 | preempt_disable(); |
| 520 | this_cpu_add(memcg->stat->count[idx], val); | 527 | __mod_memcg_state(memcg, idx, val); |
| 528 | preempt_enable(); | ||
| 521 | } | 529 | } |
| 522 | 530 | ||
| 523 | /** | 531 | /** |
| @@ -555,87 +563,108 @@ static inline unsigned long lruvec_page_state(struct lruvec *lruvec, | |||
| 555 | enum node_stat_item idx) | 563 | enum node_stat_item idx) |
| 556 | { | 564 | { |
| 557 | struct mem_cgroup_per_node *pn; | 565 | struct mem_cgroup_per_node *pn; |
| 558 | long val = 0; | 566 | long x; |
| 559 | int cpu; | ||
| 560 | 567 | ||
| 561 | if (mem_cgroup_disabled()) | 568 | if (mem_cgroup_disabled()) |
| 562 | return node_page_state(lruvec_pgdat(lruvec), idx); | 569 | return node_page_state(lruvec_pgdat(lruvec), idx); |
| 563 | 570 | ||
| 564 | pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); | 571 | pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); |
| 565 | for_each_possible_cpu(cpu) | 572 | x = atomic_long_read(&pn->lruvec_stat[idx]); |
| 566 | val += per_cpu(pn->lruvec_stat->count[idx], cpu); | 573 | #ifdef CONFIG_SMP |
| 567 | 574 | if (x < 0) | |
| 568 | if (val < 0) | 575 | x = 0; |
| 569 | val = 0; | 576 | #endif |
| 570 | 577 | return x; | |
| 571 | return val; | ||
| 572 | } | 578 | } |
| 573 | 579 | ||
| 574 | static inline void __mod_lruvec_state(struct lruvec *lruvec, | 580 | static inline void __mod_lruvec_state(struct lruvec *lruvec, |
| 575 | enum node_stat_item idx, int val) | 581 | enum node_stat_item idx, int val) |
| 576 | { | 582 | { |
| 577 | struct mem_cgroup_per_node *pn; | 583 | struct mem_cgroup_per_node *pn; |
| 584 | long x; | ||
| 578 | 585 | ||
| 586 | /* Update node */ | ||
| 579 | __mod_node_page_state(lruvec_pgdat(lruvec), idx, val); | 587 | __mod_node_page_state(lruvec_pgdat(lruvec), idx, val); |
| 588 | |||
| 580 | if (mem_cgroup_disabled()) | 589 | if (mem_cgroup_disabled()) |
| 581 | return; | 590 | return; |
| 591 | |||
| 582 | pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); | 592 | pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); |
| 593 | |||
| 594 | /* Update memcg */ | ||
| 583 | __mod_memcg_state(pn->memcg, idx, val); | 595 | __mod_memcg_state(pn->memcg, idx, val); |
| 584 | __this_cpu_add(pn->lruvec_stat->count[idx], val); | 596 | |
| 597 | /* Update lruvec */ | ||
| 598 | x = val + __this_cpu_read(pn->lruvec_stat_cpu->count[idx]); | ||
| 599 | if (unlikely(abs(x) > MEMCG_CHARGE_BATCH)) { | ||
| 600 | atomic_long_add(x, &pn->lruvec_stat[idx]); | ||
| 601 | x = 0; | ||
| 602 | } | ||
| 603 | __this_cpu_write(pn->lruvec_stat_cpu->count[idx], x); | ||
| 585 | } | 604 | } |
| 586 | 605 | ||
| 587 | static inline void mod_lruvec_state(struct lruvec *lruvec, | 606 | static inline void mod_lruvec_state(struct lruvec *lruvec, |
| 588 | enum node_stat_item idx, int val) | 607 | enum node_stat_item idx, int val) |
| 589 | { | 608 | { |
| 590 | struct mem_cgroup_per_node *pn; | 609 | preempt_disable(); |
| 591 | 610 | __mod_lruvec_state(lruvec, idx, val); | |
| 592 | mod_node_page_state(lruvec_pgdat(lruvec), idx, val); | 611 | preempt_enable(); |
| 593 | if (mem_cgroup_disabled()) | ||
| 594 | return; | ||
| 595 | pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec); | ||
| 596 | mod_memcg_state(pn->memcg, idx, val); | ||
| 597 | this_cpu_add(pn->lruvec_stat->count[idx], val); | ||
| 598 | } | 612 | } |
| 599 | 613 | ||
| 600 | static inline void __mod_lruvec_page_state(struct page *page, | 614 | static inline void __mod_lruvec_page_state(struct page *page, |
| 601 | enum node_stat_item idx, int val) | 615 | enum node_stat_item idx, int val) |
| 602 | { | 616 | { |
| 603 | struct mem_cgroup_per_node *pn; | 617 | pg_data_t *pgdat = page_pgdat(page); |
| 618 | struct lruvec *lruvec; | ||
| 604 | 619 | ||
| 605 | __mod_node_page_state(page_pgdat(page), idx, val); | 620 | /* Untracked pages have no memcg, no lruvec. Update only the node */ |
| 606 | if (mem_cgroup_disabled() || !page->mem_cgroup) | 621 | if (!page->mem_cgroup) { |
| 622 | __mod_node_page_state(pgdat, idx, val); | ||
| 607 | return; | 623 | return; |
| 608 | __mod_memcg_state(page->mem_cgroup, idx, val); | 624 | } |
| 609 | pn = page->mem_cgroup->nodeinfo[page_to_nid(page)]; | 625 | |
| 610 | __this_cpu_add(pn->lruvec_stat->count[idx], val); | 626 | lruvec = mem_cgroup_lruvec(pgdat, page->mem_cgroup); |
| 627 | __mod_lruvec_state(lruvec, idx, val); | ||
| 611 | } | 628 | } |
| 612 | 629 | ||
| 613 | static inline void mod_lruvec_page_state(struct page *page, | 630 | static inline void mod_lruvec_page_state(struct page *page, |
| 614 | enum node_stat_item idx, int val) | 631 | enum node_stat_item idx, int val) |
| 615 | { | 632 | { |
| 616 | struct mem_cgroup_per_node *pn; | 633 | preempt_disable(); |
| 617 | 634 | __mod_lruvec_page_state(page, idx, val); | |
| 618 | mod_node_page_state(page_pgdat(page), idx, val); | 635 | preempt_enable(); |
| 619 | if (mem_cgroup_disabled() || !page->mem_cgroup) | ||
| 620 | return; | ||
| 621 | mod_memcg_state(page->mem_cgroup, idx, val); | ||
| 622 | pn = page->mem_cgroup->nodeinfo[page_to_nid(page)]; | ||
| 623 | this_cpu_add(pn->lruvec_stat->count[idx], val); | ||
| 624 | } | 636 | } |
| 625 | 637 | ||
| 626 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, | 638 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, |
| 627 | gfp_t gfp_mask, | 639 | gfp_t gfp_mask, |
| 628 | unsigned long *total_scanned); | 640 | unsigned long *total_scanned); |
| 629 | 641 | ||
| 642 | /* idx can be of type enum memcg_event_item or vm_event_item */ | ||
| 643 | static inline void __count_memcg_events(struct mem_cgroup *memcg, | ||
| 644 | int idx, unsigned long count) | ||
| 645 | { | ||
| 646 | unsigned long x; | ||
| 647 | |||
| 648 | if (mem_cgroup_disabled()) | ||
| 649 | return; | ||
| 650 | |||
| 651 | x = count + __this_cpu_read(memcg->stat_cpu->events[idx]); | ||
| 652 | if (unlikely(x > MEMCG_CHARGE_BATCH)) { | ||
| 653 | atomic_long_add(x, &memcg->events[idx]); | ||
| 654 | x = 0; | ||
| 655 | } | ||
| 656 | __this_cpu_write(memcg->stat_cpu->events[idx], x); | ||
| 657 | } | ||
| 658 | |||
| 630 | static inline void count_memcg_events(struct mem_cgroup *memcg, | 659 | static inline void count_memcg_events(struct mem_cgroup *memcg, |
| 631 | enum vm_event_item idx, | 660 | int idx, unsigned long count) |
| 632 | unsigned long count) | ||
| 633 | { | 661 | { |
| 634 | if (!mem_cgroup_disabled()) | 662 | preempt_disable(); |
| 635 | this_cpu_add(memcg->stat->events[idx], count); | 663 | __count_memcg_events(memcg, idx, count); |
| 664 | preempt_enable(); | ||
| 636 | } | 665 | } |
| 637 | 666 | ||
| 638 | /* idx can be of type enum memcg_stat_item or node_stat_item */ | 667 | /* idx can be of type enum memcg_event_item or vm_event_item */ |
| 639 | static inline void count_memcg_page_event(struct page *page, | 668 | static inline void count_memcg_page_event(struct page *page, |
| 640 | int idx) | 669 | int idx) |
| 641 | { | 670 | { |
| @@ -654,12 +683,20 @@ static inline void count_memcg_event_mm(struct mm_struct *mm, | |||
| 654 | rcu_read_lock(); | 683 | rcu_read_lock(); |
| 655 | memcg = mem_cgroup_from_task(rcu_dereference(mm->owner)); | 684 | memcg = mem_cgroup_from_task(rcu_dereference(mm->owner)); |
| 656 | if (likely(memcg)) { | 685 | if (likely(memcg)) { |
| 657 | this_cpu_inc(memcg->stat->events[idx]); | 686 | count_memcg_events(memcg, idx, 1); |
| 658 | if (idx == OOM_KILL) | 687 | if (idx == OOM_KILL) |
| 659 | cgroup_file_notify(&memcg->events_file); | 688 | cgroup_file_notify(&memcg->events_file); |
| 660 | } | 689 | } |
| 661 | rcu_read_unlock(); | 690 | rcu_read_unlock(); |
| 662 | } | 691 | } |
| 692 | |||
| 693 | static inline void mem_cgroup_event(struct mem_cgroup *memcg, | ||
| 694 | enum memcg_event_item event) | ||
| 695 | { | ||
| 696 | count_memcg_events(memcg, event, 1); | ||
| 697 | cgroup_file_notify(&memcg->events_file); | ||
| 698 | } | ||
| 699 | |||
| 663 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 700 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 664 | void mem_cgroup_split_huge_fixup(struct page *head); | 701 | void mem_cgroup_split_huge_fixup(struct page *head); |
| 665 | #endif | 702 | #endif |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 7fc92384977e..173d2484f6e3 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -1312,8 +1312,6 @@ void free_pgd_range(struct mmu_gather *tlb, unsigned long addr, | |||
| 1312 | unsigned long end, unsigned long floor, unsigned long ceiling); | 1312 | unsigned long end, unsigned long floor, unsigned long ceiling); |
| 1313 | int copy_page_range(struct mm_struct *dst, struct mm_struct *src, | 1313 | int copy_page_range(struct mm_struct *dst, struct mm_struct *src, |
| 1314 | struct vm_area_struct *vma); | 1314 | struct vm_area_struct *vma); |
| 1315 | void unmap_mapping_range(struct address_space *mapping, | ||
| 1316 | loff_t const holebegin, loff_t const holelen, int even_cows); | ||
| 1317 | int follow_pte_pmd(struct mm_struct *mm, unsigned long address, | 1315 | int follow_pte_pmd(struct mm_struct *mm, unsigned long address, |
| 1318 | unsigned long *start, unsigned long *end, | 1316 | unsigned long *start, unsigned long *end, |
| 1319 | pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); | 1317 | pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); |
| @@ -1324,12 +1322,6 @@ int follow_phys(struct vm_area_struct *vma, unsigned long address, | |||
| 1324 | int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, | 1322 | int generic_access_phys(struct vm_area_struct *vma, unsigned long addr, |
| 1325 | void *buf, int len, int write); | 1323 | void *buf, int len, int write); |
| 1326 | 1324 | ||
| 1327 | static inline void unmap_shared_mapping_range(struct address_space *mapping, | ||
| 1328 | loff_t const holebegin, loff_t const holelen) | ||
| 1329 | { | ||
| 1330 | unmap_mapping_range(mapping, holebegin, holelen, 0); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | extern void truncate_pagecache(struct inode *inode, loff_t new); | 1325 | extern void truncate_pagecache(struct inode *inode, loff_t new); |
| 1334 | extern void truncate_setsize(struct inode *inode, loff_t newsize); | 1326 | extern void truncate_setsize(struct inode *inode, loff_t newsize); |
| 1335 | void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to); | 1327 | void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to); |
| @@ -1344,6 +1336,10 @@ extern int handle_mm_fault(struct vm_area_struct *vma, unsigned long address, | |||
| 1344 | extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, | 1336 | extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, |
| 1345 | unsigned long address, unsigned int fault_flags, | 1337 | unsigned long address, unsigned int fault_flags, |
| 1346 | bool *unlocked); | 1338 | bool *unlocked); |
| 1339 | void unmap_mapping_pages(struct address_space *mapping, | ||
| 1340 | pgoff_t start, pgoff_t nr, bool even_cows); | ||
| 1341 | void unmap_mapping_range(struct address_space *mapping, | ||
| 1342 | loff_t const holebegin, loff_t const holelen, int even_cows); | ||
| 1347 | #else | 1343 | #else |
| 1348 | static inline int handle_mm_fault(struct vm_area_struct *vma, | 1344 | static inline int handle_mm_fault(struct vm_area_struct *vma, |
| 1349 | unsigned long address, unsigned int flags) | 1345 | unsigned long address, unsigned int flags) |
| @@ -1360,10 +1356,20 @@ static inline int fixup_user_fault(struct task_struct *tsk, | |||
| 1360 | BUG(); | 1356 | BUG(); |
| 1361 | return -EFAULT; | 1357 | return -EFAULT; |
| 1362 | } | 1358 | } |
| 1359 | static inline void unmap_mapping_pages(struct address_space *mapping, | ||
| 1360 | pgoff_t start, pgoff_t nr, bool even_cows) { } | ||
| 1361 | static inline void unmap_mapping_range(struct address_space *mapping, | ||
| 1362 | loff_t const holebegin, loff_t const holelen, int even_cows) { } | ||
| 1363 | #endif | 1363 | #endif |
| 1364 | 1364 | ||
| 1365 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, | 1365 | static inline void unmap_shared_mapping_range(struct address_space *mapping, |
| 1366 | unsigned int gup_flags); | 1366 | loff_t const holebegin, loff_t const holelen) |
| 1367 | { | ||
| 1368 | unmap_mapping_range(mapping, holebegin, holelen, 0); | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, | ||
| 1372 | void *buf, int len, unsigned int gup_flags); | ||
| 1367 | extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, | 1373 | extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, |
| 1368 | void *buf, int len, unsigned int gup_flags); | 1374 | void *buf, int len, unsigned int gup_flags); |
| 1369 | extern int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, | 1375 | extern int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index cfd0ac4e5e0e..fd1af6b9591d 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
| @@ -31,28 +31,56 @@ struct hmm; | |||
| 31 | * it to keep track of whatever it is we are using the page for at the | 31 | * it to keep track of whatever it is we are using the page for at the |
| 32 | * moment. Note that we have no way to track which tasks are using | 32 | * moment. Note that we have no way to track which tasks are using |
| 33 | * a page, though if it is a pagecache page, rmap structures can tell us | 33 | * a page, though if it is a pagecache page, rmap structures can tell us |
| 34 | * who is mapping it. | 34 | * who is mapping it. If you allocate the page using alloc_pages(), you |
| 35 | * can use some of the space in struct page for your own purposes. | ||
| 35 | * | 36 | * |
| 36 | * The objects in struct page are organized in double word blocks in | 37 | * Pages that were once in the page cache may be found under the RCU lock |
| 37 | * order to allows us to use atomic double word operations on portions | 38 | * even after they have been recycled to a different purpose. The page |
| 38 | * of struct page. That is currently only used by slub but the arrangement | 39 | * cache reads and writes some of the fields in struct page to pin the |
| 39 | * allows the use of atomic double word operations on the flags/mapping | 40 | * page before checking that it's still in the page cache. It is vital |
| 40 | * and lru list pointers also. | 41 | * that all users of struct page: |
| 42 | * 1. Use the first word as PageFlags. | ||
| 43 | * 2. Clear or preserve bit 0 of page->compound_head. It is used as | ||
| 44 | * PageTail for compound pages, and the page cache must not see false | ||
| 45 | * positives. Some users put a pointer here (guaranteed to be at least | ||
| 46 | * 4-byte aligned), other users avoid using the field altogether. | ||
| 47 | * 3. page->_refcount must either not be used, or must be used in such a | ||
| 48 | * way that other CPUs temporarily incrementing and then decrementing the | ||
| 49 | * refcount does not cause problems. On receiving the page from | ||
| 50 | * alloc_pages(), the refcount will be positive. | ||
| 51 | * 4. Either preserve page->_mapcount or restore it to -1 before freeing it. | ||
| 52 | * | ||
| 53 | * If you allocate pages of order > 0, you can use the fields in the struct | ||
| 54 | * page associated with each page, but bear in mind that the pages may have | ||
| 55 | * been inserted individually into the page cache, so you must use the above | ||
| 56 | * four fields in a compatible way for each struct page. | ||
| 57 | * | ||
| 58 | * SLUB uses cmpxchg_double() to atomically update its freelist and | ||
| 59 | * counters. That requires that freelist & counters be adjacent and | ||
| 60 | * double-word aligned. We align all struct pages to double-word | ||
| 61 | * boundaries, and ensure that 'freelist' is aligned within the | ||
| 62 | * struct. | ||
| 41 | */ | 63 | */ |
| 64 | #ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE | ||
| 65 | #define _struct_page_alignment __aligned(2 * sizeof(unsigned long)) | ||
| 66 | #if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) | ||
| 67 | #define _slub_counter_t unsigned long | ||
| 68 | #else | ||
| 69 | #define _slub_counter_t unsigned int | ||
| 70 | #endif | ||
| 71 | #else /* !CONFIG_HAVE_ALIGNED_STRUCT_PAGE */ | ||
| 72 | #define _struct_page_alignment | ||
| 73 | #define _slub_counter_t unsigned int | ||
| 74 | #endif /* !CONFIG_HAVE_ALIGNED_STRUCT_PAGE */ | ||
| 75 | |||
| 42 | struct page { | 76 | struct page { |
| 43 | /* First double word block */ | 77 | /* First double word block */ |
| 44 | unsigned long flags; /* Atomic flags, some possibly | 78 | unsigned long flags; /* Atomic flags, some possibly |
| 45 | * updated asynchronously */ | 79 | * updated asynchronously */ |
| 46 | union { | 80 | union { |
| 47 | struct address_space *mapping; /* If low bit clear, points to | 81 | /* See page-flags.h for the definition of PAGE_MAPPING_FLAGS */ |
| 48 | * inode address_space, or NULL. | 82 | struct address_space *mapping; |
| 49 | * If page mapped as anonymous | 83 | |
| 50 | * memory, low bit is set, and | ||
| 51 | * it points to anon_vma object | ||
| 52 | * or KSM private structure. See | ||
| 53 | * PAGE_MAPPING_ANON and | ||
| 54 | * PAGE_MAPPING_KSM. | ||
| 55 | */ | ||
| 56 | void *s_mem; /* slab first object */ | 84 | void *s_mem; /* slab first object */ |
| 57 | atomic_t compound_mapcount; /* first tail page */ | 85 | atomic_t compound_mapcount; /* first tail page */ |
| 58 | /* page_deferred_list().next -- second tail page */ | 86 | /* page_deferred_list().next -- second tail page */ |
| @@ -66,40 +94,27 @@ struct page { | |||
| 66 | }; | 94 | }; |
| 67 | 95 | ||
| 68 | union { | 96 | union { |
| 69 | #if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) && \ | 97 | _slub_counter_t counters; |
| 70 | defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE) | 98 | unsigned int active; /* SLAB */ |
| 71 | /* Used for cmpxchg_double in slub */ | 99 | struct { /* SLUB */ |
| 72 | unsigned long counters; | 100 | unsigned inuse:16; |
| 73 | #else | 101 | unsigned objects:15; |
| 74 | /* | 102 | unsigned frozen:1; |
| 75 | * Keep _refcount separate from slub cmpxchg_double data. | 103 | }; |
| 76 | * As the rest of the double word is protected by slab_lock | 104 | int units; /* SLOB */ |
| 77 | * but _refcount is not. | 105 | |
| 78 | */ | 106 | struct { /* Page cache */ |
| 79 | unsigned counters; | 107 | /* |
| 80 | #endif | 108 | * Count of ptes mapped in mms, to show when |
| 81 | struct { | 109 | * page is mapped & limit reverse map searches. |
| 110 | * | ||
| 111 | * Extra information about page type may be | ||
| 112 | * stored here for pages that are never mapped, | ||
| 113 | * in which case the value MUST BE <= -2. | ||
| 114 | * See page-flags.h for more details. | ||
| 115 | */ | ||
| 116 | atomic_t _mapcount; | ||
| 82 | 117 | ||
| 83 | union { | ||
| 84 | /* | ||
| 85 | * Count of ptes mapped in mms, to show when | ||
| 86 | * page is mapped & limit reverse map searches. | ||
| 87 | * | ||
| 88 | * Extra information about page type may be | ||
| 89 | * stored here for pages that are never mapped, | ||
| 90 | * in which case the value MUST BE <= -2. | ||
| 91 | * See page-flags.h for more details. | ||
| 92 | */ | ||
| 93 | atomic_t _mapcount; | ||
| 94 | |||
| 95 | unsigned int active; /* SLAB */ | ||
| 96 | struct { /* SLUB */ | ||
| 97 | unsigned inuse:16; | ||
| 98 | unsigned objects:15; | ||
| 99 | unsigned frozen:1; | ||
| 100 | }; | ||
| 101 | int units; /* SLOB */ | ||
| 102 | }; | ||
| 103 | /* | 118 | /* |
| 104 | * Usage count, *USE WRAPPER FUNCTION* when manual | 119 | * Usage count, *USE WRAPPER FUNCTION* when manual |
| 105 | * accounting. See page_ref.h | 120 | * accounting. See page_ref.h |
| @@ -109,8 +124,6 @@ struct page { | |||
| 109 | }; | 124 | }; |
| 110 | 125 | ||
| 111 | /* | 126 | /* |
| 112 | * Third double word block | ||
| 113 | * | ||
| 114 | * WARNING: bit 0 of the first word encode PageTail(). That means | 127 | * WARNING: bit 0 of the first word encode PageTail(). That means |
| 115 | * the rest users of the storage space MUST NOT use the bit to | 128 | * the rest users of the storage space MUST NOT use the bit to |
| 116 | * avoid collision and false-positive PageTail(). | 129 | * avoid collision and false-positive PageTail(). |
| @@ -145,19 +158,9 @@ struct page { | |||
| 145 | unsigned long compound_head; /* If bit zero is set */ | 158 | unsigned long compound_head; /* If bit zero is set */ |
| 146 | 159 | ||
| 147 | /* First tail page only */ | 160 | /* First tail page only */ |
| 148 | #ifdef CONFIG_64BIT | 161 | unsigned char compound_dtor; |
| 149 | /* | 162 | unsigned char compound_order; |
| 150 | * On 64 bit system we have enough space in struct page | 163 | /* two/six bytes available here */ |
| 151 | * to encode compound_dtor and compound_order with | ||
| 152 | * unsigned int. It can help compiler generate better or | ||
| 153 | * smaller code on some archtectures. | ||
| 154 | */ | ||
| 155 | unsigned int compound_dtor; | ||
| 156 | unsigned int compound_order; | ||
| 157 | #else | ||
| 158 | unsigned short int compound_dtor; | ||
| 159 | unsigned short int compound_order; | ||
| 160 | #endif | ||
| 161 | }; | 164 | }; |
| 162 | 165 | ||
| 163 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && USE_SPLIT_PMD_PTLOCKS | 166 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && USE_SPLIT_PMD_PTLOCKS |
| @@ -171,15 +174,14 @@ struct page { | |||
| 171 | #endif | 174 | #endif |
| 172 | }; | 175 | }; |
| 173 | 176 | ||
| 174 | /* Remainder is not double word aligned */ | ||
| 175 | union { | 177 | union { |
| 176 | unsigned long private; /* Mapping-private opaque data: | 178 | /* |
| 177 | * usually used for buffer_heads | 179 | * Mapping-private opaque data: |
| 178 | * if PagePrivate set; used for | 180 | * Usually used for buffer_heads if PagePrivate |
| 179 | * swp_entry_t if PageSwapCache; | 181 | * Used for swp_entry_t if PageSwapCache |
| 180 | * indicates order in the buddy | 182 | * Indicates order in the buddy system if PageBuddy |
| 181 | * system if PG_buddy is set. | 183 | */ |
| 182 | */ | 184 | unsigned long private; |
| 183 | #if USE_SPLIT_PTE_PTLOCKS | 185 | #if USE_SPLIT_PTE_PTLOCKS |
| 184 | #if ALLOC_SPLIT_PTLOCKS | 186 | #if ALLOC_SPLIT_PTLOCKS |
| 185 | spinlock_t *ptl; | 187 | spinlock_t *ptl; |
| @@ -212,15 +214,7 @@ struct page { | |||
| 212 | #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS | 214 | #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS |
| 213 | int _last_cpupid; | 215 | int _last_cpupid; |
| 214 | #endif | 216 | #endif |
| 215 | } | 217 | } _struct_page_alignment; |
| 216 | /* | ||
| 217 | * The struct page can be forced to be double word aligned so that atomic ops | ||
| 218 | * on double words work. The SLUB allocator can make use of such a feature. | ||
| 219 | */ | ||
| 220 | #ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE | ||
| 221 | __aligned(2 * sizeof(unsigned long)) | ||
| 222 | #endif | ||
| 223 | ; | ||
| 224 | 218 | ||
| 225 | #define PAGE_FRAG_CACHE_MAX_SIZE __ALIGN_MASK(32768, ~PAGE_MASK) | 219 | #define PAGE_FRAG_CACHE_MAX_SIZE __ALIGN_MASK(32768, ~PAGE_MASK) |
| 226 | #define PAGE_FRAG_CACHE_MAX_ORDER get_order(PAGE_FRAG_CACHE_MAX_SIZE) | 220 | #define PAGE_FRAG_CACHE_MAX_ORDER get_order(PAGE_FRAG_CACHE_MAX_SIZE) |
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index b25dc9db19fc..2d07a1ed5a31 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #ifndef _LINUX_MMU_NOTIFIER_H | 2 | #ifndef _LINUX_MMU_NOTIFIER_H |
| 3 | #define _LINUX_MMU_NOTIFIER_H | 3 | #define _LINUX_MMU_NOTIFIER_H |
| 4 | 4 | ||
| 5 | #include <linux/types.h> | ||
| 5 | #include <linux/list.h> | 6 | #include <linux/list.h> |
| 6 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
| 7 | #include <linux/mm_types.h> | 8 | #include <linux/mm_types.h> |
| @@ -10,6 +11,9 @@ | |||
| 10 | struct mmu_notifier; | 11 | struct mmu_notifier; |
| 11 | struct mmu_notifier_ops; | 12 | struct mmu_notifier_ops; |
| 12 | 13 | ||
| 14 | /* mmu_notifier_ops flags */ | ||
| 15 | #define MMU_INVALIDATE_DOES_NOT_BLOCK (0x01) | ||
| 16 | |||
| 13 | #ifdef CONFIG_MMU_NOTIFIER | 17 | #ifdef CONFIG_MMU_NOTIFIER |
| 14 | 18 | ||
| 15 | /* | 19 | /* |
| @@ -27,6 +31,15 @@ struct mmu_notifier_mm { | |||
| 27 | 31 | ||
| 28 | struct mmu_notifier_ops { | 32 | struct mmu_notifier_ops { |
| 29 | /* | 33 | /* |
| 34 | * Flags to specify behavior of callbacks for this MMU notifier. | ||
| 35 | * Used to determine which context an operation may be called. | ||
| 36 | * | ||
| 37 | * MMU_INVALIDATE_DOES_NOT_BLOCK: invalidate_range_* callbacks do not | ||
| 38 | * block | ||
| 39 | */ | ||
| 40 | int flags; | ||
| 41 | |||
| 42 | /* | ||
| 30 | * Called either by mmu_notifier_unregister or when the mm is | 43 | * Called either by mmu_notifier_unregister or when the mm is |
| 31 | * being destroyed by exit_mmap, always before all pages are | 44 | * being destroyed by exit_mmap, always before all pages are |
| 32 | * freed. This can run concurrently with other mmu notifier | 45 | * freed. This can run concurrently with other mmu notifier |
| @@ -137,6 +150,10 @@ struct mmu_notifier_ops { | |||
| 137 | * page. Pages will no longer be referenced by the linux | 150 | * page. Pages will no longer be referenced by the linux |
| 138 | * address space but may still be referenced by sptes until | 151 | * address space but may still be referenced by sptes until |
| 139 | * the last refcount is dropped. | 152 | * the last refcount is dropped. |
| 153 | * | ||
| 154 | * If both of these callbacks cannot block, and invalidate_range | ||
| 155 | * cannot block, mmu_notifier_ops.flags should have | ||
| 156 | * MMU_INVALIDATE_DOES_NOT_BLOCK set. | ||
| 140 | */ | 157 | */ |
| 141 | void (*invalidate_range_start)(struct mmu_notifier *mn, | 158 | void (*invalidate_range_start)(struct mmu_notifier *mn, |
| 142 | struct mm_struct *mm, | 159 | struct mm_struct *mm, |
| @@ -159,12 +176,13 @@ struct mmu_notifier_ops { | |||
| 159 | * external TLB range needs to be flushed. For more in depth | 176 | * external TLB range needs to be flushed. For more in depth |
| 160 | * discussion on this see Documentation/vm/mmu_notifier.txt | 177 | * discussion on this see Documentation/vm/mmu_notifier.txt |
| 161 | * | 178 | * |
| 162 | * The invalidate_range() function is called under the ptl | ||
| 163 | * spin-lock and not allowed to sleep. | ||
| 164 | * | ||
| 165 | * Note that this function might be called with just a sub-range | 179 | * Note that this function might be called with just a sub-range |
| 166 | * of what was passed to invalidate_range_start()/end(), if | 180 | * of what was passed to invalidate_range_start()/end(), if |
| 167 | * called between those functions. | 181 | * called between those functions. |
| 182 | * | ||
| 183 | * If this callback cannot block, and invalidate_range_{start,end} | ||
| 184 | * cannot block, mmu_notifier_ops.flags should have | ||
| 185 | * MMU_INVALIDATE_DOES_NOT_BLOCK set. | ||
| 168 | */ | 186 | */ |
| 169 | void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm, | 187 | void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm, |
| 170 | unsigned long start, unsigned long end); | 188 | unsigned long start, unsigned long end); |
| @@ -218,6 +236,7 @@ extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, | |||
| 218 | bool only_end); | 236 | bool only_end); |
| 219 | extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, | 237 | extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, |
| 220 | unsigned long start, unsigned long end); | 238 | unsigned long start, unsigned long end); |
| 239 | extern bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm); | ||
| 221 | 240 | ||
| 222 | static inline void mmu_notifier_release(struct mm_struct *mm) | 241 | static inline void mmu_notifier_release(struct mm_struct *mm) |
| 223 | { | 242 | { |
| @@ -457,6 +476,11 @@ static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, | |||
| 457 | { | 476 | { |
| 458 | } | 477 | } |
| 459 | 478 | ||
| 479 | static inline bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm) | ||
| 480 | { | ||
| 481 | return false; | ||
| 482 | } | ||
| 483 | |||
| 460 | static inline void mmu_notifier_mm_init(struct mm_struct *mm) | 484 | static inline void mmu_notifier_mm_init(struct mm_struct *mm) |
| 461 | { | 485 | { |
| 462 | } | 486 | } |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 67f2e3c38939..7522a6987595 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
| @@ -1166,8 +1166,16 @@ extern unsigned long usemap_size(void); | |||
| 1166 | 1166 | ||
| 1167 | /* | 1167 | /* |
| 1168 | * We use the lower bits of the mem_map pointer to store | 1168 | * We use the lower bits of the mem_map pointer to store |
| 1169 | * a little bit of information. There should be at least | 1169 | * a little bit of information. The pointer is calculated |
| 1170 | * 3 bits here due to 32-bit alignment. | 1170 | * as mem_map - section_nr_to_pfn(pnum). The result is |
| 1171 | * aligned to the minimum alignment of the two values: | ||
| 1172 | * 1. All mem_map arrays are page-aligned. | ||
| 1173 | * 2. section_nr_to_pfn() always clears PFN_SECTION_SHIFT | ||
| 1174 | * lowest bits. PFN_SECTION_SHIFT is arch-specific | ||
| 1175 | * (equal SECTION_SIZE_BITS - PAGE_SHIFT), and the | ||
| 1176 | * worst combination is powerpc with 256k pages, | ||
| 1177 | * which results in PFN_SECTION_SHIFT equal 6. | ||
| 1178 | * To sum it up, at least 6 bits are available. | ||
| 1171 | */ | 1179 | */ |
| 1172 | #define SECTION_MARKED_PRESENT (1UL<<0) | 1180 | #define SECTION_MARKED_PRESENT (1UL<<0) |
| 1173 | #define SECTION_HAS_MEM_MAP (1UL<<1) | 1181 | #define SECTION_HAS_MEM_MAP (1UL<<1) |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 3ec44e27aa9d..50c2b8786831 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
| @@ -46,11 +46,6 @@ | |||
| 46 | * guarantees that this bit is cleared for a page when it first is entered into | 46 | * guarantees that this bit is cleared for a page when it first is entered into |
| 47 | * the page cache. | 47 | * the page cache. |
| 48 | * | 48 | * |
| 49 | * PG_highmem pages are not permanently mapped into the kernel virtual address | ||
| 50 | * space, they need to be kmapped separately for doing IO on the pages. The | ||
| 51 | * struct page (these bits with information) are always mapped into kernel | ||
| 52 | * address space... | ||
| 53 | * | ||
| 54 | * PG_hwpoison indicates that a page got corrupted in hardware and contains | 49 | * PG_hwpoison indicates that a page got corrupted in hardware and contains |
| 55 | * data with incorrect ECC bits that triggered a machine check. Accessing is | 50 | * data with incorrect ECC bits that triggered a machine check. Accessing is |
| 56 | * not safe since it may cause another machine check. Don't touch! | 51 | * not safe since it may cause another machine check. Don't touch! |
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 5fb6580f7f23..6dc456ac6136 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h | |||
| @@ -9,14 +9,14 @@ | |||
| 9 | #ifndef _LINUX_PAGEVEC_H | 9 | #ifndef _LINUX_PAGEVEC_H |
| 10 | #define _LINUX_PAGEVEC_H | 10 | #define _LINUX_PAGEVEC_H |
| 11 | 11 | ||
| 12 | /* 14 pointers + two long's align the pagevec structure to a power of two */ | 12 | /* 15 pointers + header align the pagevec structure to a power of two */ |
| 13 | #define PAGEVEC_SIZE 14 | 13 | #define PAGEVEC_SIZE 15 |
| 14 | 14 | ||
| 15 | struct page; | 15 | struct page; |
| 16 | struct address_space; | 16 | struct address_space; |
| 17 | 17 | ||
| 18 | struct pagevec { | 18 | struct pagevec { |
| 19 | unsigned long nr; | 19 | unsigned char nr; |
| 20 | bool percpu_pvec_drained; | 20 | bool percpu_pvec_drained; |
| 21 | struct page *pages[PAGEVEC_SIZE]; | 21 | struct page *pages[PAGEVEC_SIZE]; |
| 22 | }; | 22 | }; |
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 3d49b91b674d..bd422561a75e 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | /* | 11 | /* |
| 12 | * Routines for handling mm_structs | 12 | * Routines for handling mm_structs |
| 13 | */ | 13 | */ |
| 14 | extern struct mm_struct * mm_alloc(void); | 14 | extern struct mm_struct *mm_alloc(void); |
| 15 | 15 | ||
| 16 | /** | 16 | /** |
| 17 | * mmgrab() - Pin a &struct mm_struct. | 17 | * mmgrab() - Pin a &struct mm_struct. |
| @@ -35,27 +35,7 @@ static inline void mmgrab(struct mm_struct *mm) | |||
| 35 | atomic_inc(&mm->mm_count); | 35 | atomic_inc(&mm->mm_count); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | /* mmdrop drops the mm and the page tables */ | 38 | extern void mmdrop(struct mm_struct *mm); |
| 39 | extern void __mmdrop(struct mm_struct *); | ||
| 40 | static inline void mmdrop(struct mm_struct *mm) | ||
| 41 | { | ||
| 42 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | ||
| 43 | __mmdrop(mm); | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline void mmdrop_async_fn(struct work_struct *work) | ||
| 47 | { | ||
| 48 | struct mm_struct *mm = container_of(work, struct mm_struct, async_put_work); | ||
| 49 | __mmdrop(mm); | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void mmdrop_async(struct mm_struct *mm) | ||
| 53 | { | ||
| 54 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) { | ||
| 55 | INIT_WORK(&mm->async_put_work, mmdrop_async_fn); | ||
| 56 | schedule_work(&mm->async_put_work); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | 39 | ||
| 60 | /** | 40 | /** |
| 61 | * mmget() - Pin the address space associated with a &struct mm_struct. | 41 | * mmget() - Pin the address space associated with a &struct mm_struct. |
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 06b295bec00d..73b5e655a76e 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h | |||
| @@ -112,13 +112,11 @@ extern void shmem_uncharge(struct inode *inode, long pages); | |||
| 112 | 112 | ||
| 113 | #ifdef CONFIG_TMPFS | 113 | #ifdef CONFIG_TMPFS |
| 114 | 114 | ||
| 115 | extern int shmem_add_seals(struct file *file, unsigned int seals); | 115 | extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned long arg); |
| 116 | extern int shmem_get_seals(struct file *file); | ||
| 117 | extern long shmem_fcntl(struct file *file, unsigned int cmd, unsigned long arg); | ||
| 118 | 116 | ||
| 119 | #else | 117 | #else |
| 120 | 118 | ||
| 121 | static inline long shmem_fcntl(struct file *f, unsigned int c, unsigned long a) | 119 | static inline long memfd_fcntl(struct file *f, unsigned int c, unsigned long a) |
| 122 | { | 120 | { |
| 123 | return -EINVAL; | 121 | return -EINVAL; |
| 124 | } | 122 | } |
diff --git a/include/linux/swap.h b/include/linux/swap.h index c2b8128799c1..7b6a59f722a3 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
| @@ -332,7 +332,6 @@ extern void mark_page_accessed(struct page *); | |||
| 332 | extern void lru_add_drain(void); | 332 | extern void lru_add_drain(void); |
| 333 | extern void lru_add_drain_cpu(int cpu); | 333 | extern void lru_add_drain_cpu(int cpu); |
| 334 | extern void lru_add_drain_all(void); | 334 | extern void lru_add_drain_all(void); |
| 335 | extern void lru_add_drain_all_cpuslocked(void); | ||
| 336 | extern void rotate_reclaimable_page(struct page *page); | 335 | extern void rotate_reclaimable_page(struct page *page); |
| 337 | extern void deactivate_file_page(struct page *page); | 336 | extern void deactivate_file_page(struct page *page); |
| 338 | extern void mark_page_lazyfree(struct page *page); | 337 | extern void mark_page_lazyfree(struct page *page); |
| @@ -345,7 +344,6 @@ extern void lru_cache_add_active_or_unevictable(struct page *page, | |||
| 345 | 344 | ||
| 346 | /* linux/mm/vmscan.c */ | 345 | /* linux/mm/vmscan.c */ |
| 347 | extern unsigned long zone_reclaimable_pages(struct zone *zone); | 346 | extern unsigned long zone_reclaimable_pages(struct zone *zone); |
| 348 | extern unsigned long pgdat_reclaimable_pages(struct pglist_data *pgdat); | ||
| 349 | extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, | 347 | extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, |
| 350 | gfp_t gfp_mask, nodemask_t *mask); | 348 | gfp_t gfp_mask, nodemask_t *mask); |
| 351 | extern int __isolate_lru_page(struct page *page, isolate_mode_t mode); | 349 | extern int __isolate_lru_page(struct page *page, isolate_mode_t mode); |
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 1779c9817b39..a4c2317d8b9f 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h | |||
| @@ -216,23 +216,6 @@ static inline unsigned long zone_page_state_snapshot(struct zone *zone, | |||
| 216 | return x; | 216 | return x; |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | static inline unsigned long node_page_state_snapshot(pg_data_t *pgdat, | ||
| 220 | enum node_stat_item item) | ||
| 221 | { | ||
| 222 | long x = atomic_long_read(&pgdat->vm_stat[item]); | ||
| 223 | |||
| 224 | #ifdef CONFIG_SMP | ||
| 225 | int cpu; | ||
| 226 | for_each_online_cpu(cpu) | ||
| 227 | x += per_cpu_ptr(pgdat->per_cpu_nodestats, cpu)->vm_node_stat_diff[item]; | ||
| 228 | |||
| 229 | if (x < 0) | ||
| 230 | x = 0; | ||
| 231 | #endif | ||
| 232 | return x; | ||
| 233 | } | ||
| 234 | |||
| 235 | |||
| 236 | #ifdef CONFIG_NUMA | 219 | #ifdef CONFIG_NUMA |
| 237 | extern void __inc_numa_state(struct zone *zone, enum numa_stat_item item); | 220 | extern void __inc_numa_state(struct zone *zone, enum numa_stat_item item); |
| 238 | extern unsigned long sum_zone_node_page_state(int node, | 221 | extern unsigned long sum_zone_node_page_state(int node, |
diff --git a/include/linux/zpool.h b/include/linux/zpool.h index 004ba807df96..7238865e75b0 100644 --- a/include/linux/zpool.h +++ b/include/linux/zpool.h | |||
| @@ -108,4 +108,6 @@ void zpool_register_driver(struct zpool_driver *driver); | |||
| 108 | 108 | ||
| 109 | int zpool_unregister_driver(struct zpool_driver *driver); | 109 | int zpool_unregister_driver(struct zpool_driver *driver); |
| 110 | 110 | ||
| 111 | bool zpool_evictable(struct zpool *pool); | ||
| 112 | |||
| 111 | #endif | 113 | #endif |
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index d70b53e65f43..e0b8b9173e1c 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h | |||
| @@ -192,12 +192,12 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_re | |||
| 192 | 192 | ||
| 193 | TRACE_EVENT(mm_shrink_slab_start, | 193 | TRACE_EVENT(mm_shrink_slab_start, |
| 194 | TP_PROTO(struct shrinker *shr, struct shrink_control *sc, | 194 | TP_PROTO(struct shrinker *shr, struct shrink_control *sc, |
| 195 | long nr_objects_to_shrink, unsigned long pgs_scanned, | 195 | long nr_objects_to_shrink, unsigned long cache_items, |
| 196 | unsigned long lru_pgs, unsigned long cache_items, | 196 | unsigned long long delta, unsigned long total_scan, |
| 197 | unsigned long long delta, unsigned long total_scan), | 197 | int priority), |
| 198 | 198 | ||
| 199 | TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, | 199 | TP_ARGS(shr, sc, nr_objects_to_shrink, cache_items, delta, total_scan, |
| 200 | cache_items, delta, total_scan), | 200 | priority), |
| 201 | 201 | ||
| 202 | TP_STRUCT__entry( | 202 | TP_STRUCT__entry( |
| 203 | __field(struct shrinker *, shr) | 203 | __field(struct shrinker *, shr) |
| @@ -205,11 +205,10 @@ TRACE_EVENT(mm_shrink_slab_start, | |||
| 205 | __field(int, nid) | 205 | __field(int, nid) |
| 206 | __field(long, nr_objects_to_shrink) | 206 | __field(long, nr_objects_to_shrink) |
| 207 | __field(gfp_t, gfp_flags) | 207 | __field(gfp_t, gfp_flags) |
| 208 | __field(unsigned long, pgs_scanned) | ||
| 209 | __field(unsigned long, lru_pgs) | ||
| 210 | __field(unsigned long, cache_items) | 208 | __field(unsigned long, cache_items) |
| 211 | __field(unsigned long long, delta) | 209 | __field(unsigned long long, delta) |
| 212 | __field(unsigned long, total_scan) | 210 | __field(unsigned long, total_scan) |
| 211 | __field(int, priority) | ||
| 213 | ), | 212 | ), |
| 214 | 213 | ||
| 215 | TP_fast_assign( | 214 | TP_fast_assign( |
| @@ -218,24 +217,22 @@ TRACE_EVENT(mm_shrink_slab_start, | |||
| 218 | __entry->nid = sc->nid; | 217 | __entry->nid = sc->nid; |
| 219 | __entry->nr_objects_to_shrink = nr_objects_to_shrink; | 218 | __entry->nr_objects_to_shrink = nr_objects_to_shrink; |
| 220 | __entry->gfp_flags = sc->gfp_mask; | 219 | __entry->gfp_flags = sc->gfp_mask; |
| 221 | __entry->pgs_scanned = pgs_scanned; | ||
| 222 | __entry->lru_pgs = lru_pgs; | ||
| 223 | __entry->cache_items = cache_items; | 220 | __entry->cache_items = cache_items; |
| 224 | __entry->delta = delta; | 221 | __entry->delta = delta; |
| 225 | __entry->total_scan = total_scan; | 222 | __entry->total_scan = total_scan; |
| 223 | __entry->priority = priority; | ||
| 226 | ), | 224 | ), |
| 227 | 225 | ||
| 228 | TP_printk("%pF %p: nid: %d objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", | 226 | TP_printk("%pF %p: nid: %d objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d", |
| 229 | __entry->shrink, | 227 | __entry->shrink, |
| 230 | __entry->shr, | 228 | __entry->shr, |
| 231 | __entry->nid, | 229 | __entry->nid, |
| 232 | __entry->nr_objects_to_shrink, | 230 | __entry->nr_objects_to_shrink, |
| 233 | show_gfp_flags(__entry->gfp_flags), | 231 | show_gfp_flags(__entry->gfp_flags), |
| 234 | __entry->pgs_scanned, | ||
| 235 | __entry->lru_pgs, | ||
| 236 | __entry->cache_items, | 232 | __entry->cache_items, |
| 237 | __entry->delta, | 233 | __entry->delta, |
| 238 | __entry->total_scan) | 234 | __entry->total_scan, |
| 235 | __entry->priority) | ||
| 239 | ); | 236 | ); |
| 240 | 237 | ||
| 241 | TRACE_EVENT(mm_shrink_slab_end, | 238 | TRACE_EVENT(mm_shrink_slab_end, |
diff --git a/kernel/fork.c b/kernel/fork.c index 2295fc69717f..5e6cf0dd031c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -77,6 +77,7 @@ | |||
| 77 | #include <linux/blkdev.h> | 77 | #include <linux/blkdev.h> |
| 78 | #include <linux/fs_struct.h> | 78 | #include <linux/fs_struct.h> |
| 79 | #include <linux/magic.h> | 79 | #include <linux/magic.h> |
| 80 | #include <linux/sched/mm.h> | ||
| 80 | #include <linux/perf_event.h> | 81 | #include <linux/perf_event.h> |
| 81 | #include <linux/posix-timers.h> | 82 | #include <linux/posix-timers.h> |
| 82 | #include <linux/user-return-notifier.h> | 83 | #include <linux/user-return-notifier.h> |
| @@ -390,6 +391,241 @@ void free_task(struct task_struct *tsk) | |||
| 390 | } | 391 | } |
| 391 | EXPORT_SYMBOL(free_task); | 392 | EXPORT_SYMBOL(free_task); |
| 392 | 393 | ||
| 394 | #ifdef CONFIG_MMU | ||
| 395 | static __latent_entropy int dup_mmap(struct mm_struct *mm, | ||
| 396 | struct mm_struct *oldmm) | ||
| 397 | { | ||
| 398 | struct vm_area_struct *mpnt, *tmp, *prev, **pprev; | ||
| 399 | struct rb_node **rb_link, *rb_parent; | ||
| 400 | int retval; | ||
| 401 | unsigned long charge; | ||
| 402 | LIST_HEAD(uf); | ||
| 403 | |||
| 404 | uprobe_start_dup_mmap(); | ||
| 405 | if (down_write_killable(&oldmm->mmap_sem)) { | ||
| 406 | retval = -EINTR; | ||
| 407 | goto fail_uprobe_end; | ||
| 408 | } | ||
| 409 | flush_cache_dup_mm(oldmm); | ||
| 410 | uprobe_dup_mmap(oldmm, mm); | ||
| 411 | /* | ||
| 412 | * Not linked in yet - no deadlock potential: | ||
| 413 | */ | ||
| 414 | down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); | ||
| 415 | |||
| 416 | /* No ordering required: file already has been exposed. */ | ||
| 417 | RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); | ||
| 418 | |||
| 419 | mm->total_vm = oldmm->total_vm; | ||
| 420 | mm->data_vm = oldmm->data_vm; | ||
| 421 | mm->exec_vm = oldmm->exec_vm; | ||
| 422 | mm->stack_vm = oldmm->stack_vm; | ||
| 423 | |||
| 424 | rb_link = &mm->mm_rb.rb_node; | ||
| 425 | rb_parent = NULL; | ||
| 426 | pprev = &mm->mmap; | ||
| 427 | retval = ksm_fork(mm, oldmm); | ||
| 428 | if (retval) | ||
| 429 | goto out; | ||
| 430 | retval = khugepaged_fork(mm, oldmm); | ||
| 431 | if (retval) | ||
| 432 | goto out; | ||
| 433 | |||
| 434 | prev = NULL; | ||
| 435 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { | ||
| 436 | struct file *file; | ||
| 437 | |||
| 438 | if (mpnt->vm_flags & VM_DONTCOPY) { | ||
| 439 | vm_stat_account(mm, mpnt->vm_flags, -vma_pages(mpnt)); | ||
| 440 | continue; | ||
| 441 | } | ||
| 442 | charge = 0; | ||
| 443 | if (mpnt->vm_flags & VM_ACCOUNT) { | ||
| 444 | unsigned long len = vma_pages(mpnt); | ||
| 445 | |||
| 446 | if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ | ||
| 447 | goto fail_nomem; | ||
| 448 | charge = len; | ||
| 449 | } | ||
| 450 | tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); | ||
| 451 | if (!tmp) | ||
| 452 | goto fail_nomem; | ||
| 453 | *tmp = *mpnt; | ||
| 454 | INIT_LIST_HEAD(&tmp->anon_vma_chain); | ||
| 455 | retval = vma_dup_policy(mpnt, tmp); | ||
| 456 | if (retval) | ||
| 457 | goto fail_nomem_policy; | ||
| 458 | tmp->vm_mm = mm; | ||
| 459 | retval = dup_userfaultfd(tmp, &uf); | ||
| 460 | if (retval) | ||
| 461 | goto fail_nomem_anon_vma_fork; | ||
| 462 | if (tmp->vm_flags & VM_WIPEONFORK) { | ||
| 463 | /* VM_WIPEONFORK gets a clean slate in the child. */ | ||
| 464 | tmp->anon_vma = NULL; | ||
| 465 | if (anon_vma_prepare(tmp)) | ||
| 466 | goto fail_nomem_anon_vma_fork; | ||
| 467 | } else if (anon_vma_fork(tmp, mpnt)) | ||
| 468 | goto fail_nomem_anon_vma_fork; | ||
| 469 | tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT); | ||
| 470 | tmp->vm_next = tmp->vm_prev = NULL; | ||
| 471 | file = tmp->vm_file; | ||
| 472 | if (file) { | ||
| 473 | struct inode *inode = file_inode(file); | ||
| 474 | struct address_space *mapping = file->f_mapping; | ||
| 475 | |||
| 476 | get_file(file); | ||
| 477 | if (tmp->vm_flags & VM_DENYWRITE) | ||
| 478 | atomic_dec(&inode->i_writecount); | ||
| 479 | i_mmap_lock_write(mapping); | ||
| 480 | if (tmp->vm_flags & VM_SHARED) | ||
| 481 | atomic_inc(&mapping->i_mmap_writable); | ||
| 482 | flush_dcache_mmap_lock(mapping); | ||
| 483 | /* insert tmp into the share list, just after mpnt */ | ||
| 484 | vma_interval_tree_insert_after(tmp, mpnt, | ||
| 485 | &mapping->i_mmap); | ||
| 486 | flush_dcache_mmap_unlock(mapping); | ||
| 487 | i_mmap_unlock_write(mapping); | ||
| 488 | } | ||
| 489 | |||
| 490 | /* | ||
| 491 | * Clear hugetlb-related page reserves for children. This only | ||
| 492 | * affects MAP_PRIVATE mappings. Faults generated by the child | ||
| 493 | * are not guaranteed to succeed, even if read-only | ||
| 494 | */ | ||
| 495 | if (is_vm_hugetlb_page(tmp)) | ||
| 496 | reset_vma_resv_huge_pages(tmp); | ||
| 497 | |||
| 498 | /* | ||
| 499 | * Link in the new vma and copy the page table entries. | ||
| 500 | */ | ||
| 501 | *pprev = tmp; | ||
| 502 | pprev = &tmp->vm_next; | ||
| 503 | tmp->vm_prev = prev; | ||
| 504 | prev = tmp; | ||
| 505 | |||
| 506 | __vma_link_rb(mm, tmp, rb_link, rb_parent); | ||
| 507 | rb_link = &tmp->vm_rb.rb_right; | ||
| 508 | rb_parent = &tmp->vm_rb; | ||
| 509 | |||
| 510 | mm->map_count++; | ||
| 511 | if (!(tmp->vm_flags & VM_WIPEONFORK)) | ||
| 512 | retval = copy_page_range(mm, oldmm, mpnt); | ||
| 513 | |||
| 514 | if (tmp->vm_ops && tmp->vm_ops->open) | ||
| 515 | tmp->vm_ops->open(tmp); | ||
| 516 | |||
| 517 | if (retval) | ||
| 518 | goto out; | ||
| 519 | } | ||
| 520 | /* a new mm has just been created */ | ||
| 521 | arch_dup_mmap(oldmm, mm); | ||
| 522 | retval = 0; | ||
| 523 | out: | ||
| 524 | up_write(&mm->mmap_sem); | ||
| 525 | flush_tlb_mm(oldmm); | ||
| 526 | up_write(&oldmm->mmap_sem); | ||
| 527 | dup_userfaultfd_complete(&uf); | ||
| 528 | fail_uprobe_end: | ||
| 529 | uprobe_end_dup_mmap(); | ||
| 530 | return retval; | ||
| 531 | fail_nomem_anon_vma_fork: | ||
| 532 | mpol_put(vma_policy(tmp)); | ||
| 533 | fail_nomem_policy: | ||
| 534 | kmem_cache_free(vm_area_cachep, tmp); | ||
| 535 | fail_nomem: | ||
| 536 | retval = -ENOMEM; | ||
| 537 | vm_unacct_memory(charge); | ||
| 538 | goto out; | ||
| 539 | } | ||
| 540 | |||
| 541 | static inline int mm_alloc_pgd(struct mm_struct *mm) | ||
| 542 | { | ||
| 543 | mm->pgd = pgd_alloc(mm); | ||
| 544 | if (unlikely(!mm->pgd)) | ||
| 545 | return -ENOMEM; | ||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 549 | static inline void mm_free_pgd(struct mm_struct *mm) | ||
| 550 | { | ||
| 551 | pgd_free(mm, mm->pgd); | ||
| 552 | } | ||
| 553 | #else | ||
| 554 | static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | ||
| 555 | { | ||
| 556 | down_write(&oldmm->mmap_sem); | ||
| 557 | RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); | ||
| 558 | up_write(&oldmm->mmap_sem); | ||
| 559 | return 0; | ||
| 560 | } | ||
| 561 | #define mm_alloc_pgd(mm) (0) | ||
| 562 | #define mm_free_pgd(mm) | ||
| 563 | #endif /* CONFIG_MMU */ | ||
| 564 | |||
| 565 | static void check_mm(struct mm_struct *mm) | ||
| 566 | { | ||
| 567 | int i; | ||
| 568 | |||
| 569 | for (i = 0; i < NR_MM_COUNTERS; i++) { | ||
| 570 | long x = atomic_long_read(&mm->rss_stat.count[i]); | ||
| 571 | |||
| 572 | if (unlikely(x)) | ||
| 573 | printk(KERN_ALERT "BUG: Bad rss-counter state " | ||
| 574 | "mm:%p idx:%d val:%ld\n", mm, i, x); | ||
| 575 | } | ||
| 576 | |||
| 577 | if (mm_pgtables_bytes(mm)) | ||
| 578 | pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n", | ||
| 579 | mm_pgtables_bytes(mm)); | ||
| 580 | |||
| 581 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS | ||
| 582 | VM_BUG_ON_MM(mm->pmd_huge_pte, mm); | ||
| 583 | #endif | ||
| 584 | } | ||
| 585 | |||
| 586 | #define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) | ||
| 587 | #define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) | ||
| 588 | |||
| 589 | /* | ||
| 590 | * Called when the last reference to the mm | ||
| 591 | * is dropped: either by a lazy thread or by | ||
| 592 | * mmput. Free the page directory and the mm. | ||
| 593 | */ | ||
| 594 | static void __mmdrop(struct mm_struct *mm) | ||
| 595 | { | ||
| 596 | BUG_ON(mm == &init_mm); | ||
| 597 | mm_free_pgd(mm); | ||
| 598 | destroy_context(mm); | ||
| 599 | hmm_mm_destroy(mm); | ||
| 600 | mmu_notifier_mm_destroy(mm); | ||
| 601 | check_mm(mm); | ||
| 602 | put_user_ns(mm->user_ns); | ||
| 603 | free_mm(mm); | ||
| 604 | } | ||
| 605 | |||
| 606 | void mmdrop(struct mm_struct *mm) | ||
| 607 | { | ||
| 608 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | ||
| 609 | __mmdrop(mm); | ||
| 610 | } | ||
| 611 | EXPORT_SYMBOL_GPL(mmdrop); | ||
| 612 | |||
| 613 | static void mmdrop_async_fn(struct work_struct *work) | ||
| 614 | { | ||
| 615 | struct mm_struct *mm; | ||
| 616 | |||
| 617 | mm = container_of(work, struct mm_struct, async_put_work); | ||
| 618 | __mmdrop(mm); | ||
| 619 | } | ||
| 620 | |||
| 621 | static void mmdrop_async(struct mm_struct *mm) | ||
| 622 | { | ||
| 623 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) { | ||
| 624 | INIT_WORK(&mm->async_put_work, mmdrop_async_fn); | ||
| 625 | schedule_work(&mm->async_put_work); | ||
| 626 | } | ||
| 627 | } | ||
| 628 | |||
| 393 | static inline void free_signal_struct(struct signal_struct *sig) | 629 | static inline void free_signal_struct(struct signal_struct *sig) |
| 394 | { | 630 | { |
| 395 | taskstats_tgid_free(sig); | 631 | taskstats_tgid_free(sig); |
| @@ -594,181 +830,8 @@ free_tsk: | |||
| 594 | return NULL; | 830 | return NULL; |
| 595 | } | 831 | } |
| 596 | 832 | ||
| 597 | #ifdef CONFIG_MMU | ||
| 598 | static __latent_entropy int dup_mmap(struct mm_struct *mm, | ||
| 599 | struct mm_struct *oldmm) | ||
| 600 | { | ||
| 601 | struct vm_area_struct *mpnt, *tmp, *prev, **pprev; | ||
| 602 | struct rb_node **rb_link, *rb_parent; | ||
| 603 | int retval; | ||
| 604 | unsigned long charge; | ||
| 605 | LIST_HEAD(uf); | ||
| 606 | |||
| 607 | uprobe_start_dup_mmap(); | ||
| 608 | if (down_write_killable(&oldmm->mmap_sem)) { | ||
| 609 | retval = -EINTR; | ||
| 610 | goto fail_uprobe_end; | ||
| 611 | } | ||
| 612 | flush_cache_dup_mm(oldmm); | ||
| 613 | uprobe_dup_mmap(oldmm, mm); | ||
| 614 | /* | ||
| 615 | * Not linked in yet - no deadlock potential: | ||
| 616 | */ | ||
| 617 | down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING); | ||
| 618 | |||
| 619 | /* No ordering required: file already has been exposed. */ | ||
| 620 | RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); | ||
| 621 | |||
| 622 | mm->total_vm = oldmm->total_vm; | ||
| 623 | mm->data_vm = oldmm->data_vm; | ||
| 624 | mm->exec_vm = oldmm->exec_vm; | ||
| 625 | mm->stack_vm = oldmm->stack_vm; | ||
| 626 | |||
| 627 | rb_link = &mm->mm_rb.rb_node; | ||
| 628 | rb_parent = NULL; | ||
| 629 | pprev = &mm->mmap; | ||
| 630 | retval = ksm_fork(mm, oldmm); | ||
| 631 | if (retval) | ||
| 632 | goto out; | ||
| 633 | retval = khugepaged_fork(mm, oldmm); | ||
| 634 | if (retval) | ||
| 635 | goto out; | ||
| 636 | |||
| 637 | prev = NULL; | ||
| 638 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { | ||
| 639 | struct file *file; | ||
| 640 | |||
| 641 | if (mpnt->vm_flags & VM_DONTCOPY) { | ||
| 642 | vm_stat_account(mm, mpnt->vm_flags, -vma_pages(mpnt)); | ||
| 643 | continue; | ||
| 644 | } | ||
| 645 | charge = 0; | ||
| 646 | if (mpnt->vm_flags & VM_ACCOUNT) { | ||
| 647 | unsigned long len = vma_pages(mpnt); | ||
| 648 | |||
| 649 | if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ | ||
| 650 | goto fail_nomem; | ||
| 651 | charge = len; | ||
| 652 | } | ||
| 653 | tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); | ||
| 654 | if (!tmp) | ||
| 655 | goto fail_nomem; | ||
| 656 | *tmp = *mpnt; | ||
| 657 | INIT_LIST_HEAD(&tmp->anon_vma_chain); | ||
| 658 | retval = vma_dup_policy(mpnt, tmp); | ||
| 659 | if (retval) | ||
| 660 | goto fail_nomem_policy; | ||
| 661 | tmp->vm_mm = mm; | ||
| 662 | retval = dup_userfaultfd(tmp, &uf); | ||
| 663 | if (retval) | ||
| 664 | goto fail_nomem_anon_vma_fork; | ||
| 665 | if (tmp->vm_flags & VM_WIPEONFORK) { | ||
| 666 | /* VM_WIPEONFORK gets a clean slate in the child. */ | ||
| 667 | tmp->anon_vma = NULL; | ||
| 668 | if (anon_vma_prepare(tmp)) | ||
| 669 | goto fail_nomem_anon_vma_fork; | ||
| 670 | } else if (anon_vma_fork(tmp, mpnt)) | ||
| 671 | goto fail_nomem_anon_vma_fork; | ||
| 672 | tmp->vm_flags &= ~(VM_LOCKED | VM_LOCKONFAULT); | ||
| 673 | tmp->vm_next = tmp->vm_prev = NULL; | ||
| 674 | file = tmp->vm_file; | ||
| 675 | if (file) { | ||
| 676 | struct inode *inode = file_inode(file); | ||
| 677 | struct address_space *mapping = file->f_mapping; | ||
| 678 | |||
| 679 | get_file(file); | ||
| 680 | if (tmp->vm_flags & VM_DENYWRITE) | ||
| 681 | atomic_dec(&inode->i_writecount); | ||
| 682 | i_mmap_lock_write(mapping); | ||
| 683 | if (tmp->vm_flags & VM_SHARED) | ||
| 684 | atomic_inc(&mapping->i_mmap_writable); | ||
| 685 | flush_dcache_mmap_lock(mapping); | ||
| 686 | /* insert tmp into the share list, just after mpnt */ | ||
| 687 | vma_interval_tree_insert_after(tmp, mpnt, | ||
| 688 | &mapping->i_mmap); | ||
| 689 | flush_dcache_mmap_unlock(mapping); | ||
| 690 | i_mmap_unlock_write(mapping); | ||
| 691 | } | ||
| 692 | |||
| 693 | /* | ||
| 694 | * Clear hugetlb-related page reserves for children. This only | ||
| 695 | * affects MAP_PRIVATE mappings. Faults generated by the child | ||
| 696 | * are not guaranteed to succeed, even if read-only | ||
| 697 | */ | ||
| 698 | if (is_vm_hugetlb_page(tmp)) | ||
| 699 | reset_vma_resv_huge_pages(tmp); | ||
| 700 | |||
| 701 | /* | ||
| 702 | * Link in the new vma and copy the page table entries. | ||
| 703 | */ | ||
| 704 | *pprev = tmp; | ||
| 705 | pprev = &tmp->vm_next; | ||
| 706 | tmp->vm_prev = prev; | ||
| 707 | prev = tmp; | ||
| 708 | |||
| 709 | __vma_link_rb(mm, tmp, rb_link, rb_parent); | ||
| 710 | rb_link = &tmp->vm_rb.rb_right; | ||
| 711 | rb_parent = &tmp->vm_rb; | ||
| 712 | |||
| 713 | mm->map_count++; | ||
| 714 | if (!(tmp->vm_flags & VM_WIPEONFORK)) | ||
| 715 | retval = copy_page_range(mm, oldmm, mpnt); | ||
| 716 | |||
| 717 | if (tmp->vm_ops && tmp->vm_ops->open) | ||
| 718 | tmp->vm_ops->open(tmp); | ||
| 719 | |||
| 720 | if (retval) | ||
| 721 | goto out; | ||
| 722 | } | ||
| 723 | /* a new mm has just been created */ | ||
| 724 | retval = arch_dup_mmap(oldmm, mm); | ||
| 725 | out: | ||
| 726 | up_write(&mm->mmap_sem); | ||
| 727 | flush_tlb_mm(oldmm); | ||
| 728 | up_write(&oldmm->mmap_sem); | ||
| 729 | dup_userfaultfd_complete(&uf); | ||
| 730 | fail_uprobe_end: | ||
| 731 | uprobe_end_dup_mmap(); | ||
| 732 | return retval; | ||
| 733 | fail_nomem_anon_vma_fork: | ||
| 734 | mpol_put(vma_policy(tmp)); | ||
| 735 | fail_nomem_policy: | ||
| 736 | kmem_cache_free(vm_area_cachep, tmp); | ||
| 737 | fail_nomem: | ||
| 738 | retval = -ENOMEM; | ||
| 739 | vm_unacct_memory(charge); | ||
| 740 | goto out; | ||
| 741 | } | ||
| 742 | |||
| 743 | static inline int mm_alloc_pgd(struct mm_struct *mm) | ||
| 744 | { | ||
| 745 | mm->pgd = pgd_alloc(mm); | ||
| 746 | if (unlikely(!mm->pgd)) | ||
| 747 | return -ENOMEM; | ||
| 748 | return 0; | ||
| 749 | } | ||
| 750 | |||
| 751 | static inline void mm_free_pgd(struct mm_struct *mm) | ||
| 752 | { | ||
| 753 | pgd_free(mm, mm->pgd); | ||
| 754 | } | ||
| 755 | #else | ||
| 756 | static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | ||
| 757 | { | ||
| 758 | down_write(&oldmm->mmap_sem); | ||
| 759 | RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm)); | ||
| 760 | up_write(&oldmm->mmap_sem); | ||
| 761 | return 0; | ||
| 762 | } | ||
| 763 | #define mm_alloc_pgd(mm) (0) | ||
| 764 | #define mm_free_pgd(mm) | ||
| 765 | #endif /* CONFIG_MMU */ | ||
| 766 | |||
| 767 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); | 833 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); |
| 768 | 834 | ||
| 769 | #define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) | ||
| 770 | #define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) | ||
| 771 | |||
| 772 | static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT; | 835 | static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT; |
| 773 | 836 | ||
| 774 | static int __init coredump_filter_setup(char *s) | 837 | static int __init coredump_filter_setup(char *s) |
| @@ -858,27 +921,6 @@ fail_nopgd: | |||
| 858 | return NULL; | 921 | return NULL; |
| 859 | } | 922 | } |
| 860 | 923 | ||
| 861 | static void check_mm(struct mm_struct *mm) | ||
| 862 | { | ||
| 863 | int i; | ||
| 864 | |||
| 865 | for (i = 0; i < NR_MM_COUNTERS; i++) { | ||
| 866 | long x = atomic_long_read(&mm->rss_stat.count[i]); | ||
| 867 | |||
| 868 | if (unlikely(x)) | ||
| 869 | printk(KERN_ALERT "BUG: Bad rss-counter state " | ||
| 870 | "mm:%p idx:%d val:%ld\n", mm, i, x); | ||
| 871 | } | ||
| 872 | |||
| 873 | if (mm_pgtables_bytes(mm)) | ||
| 874 | pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n", | ||
| 875 | mm_pgtables_bytes(mm)); | ||
| 876 | |||
| 877 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS | ||
| 878 | VM_BUG_ON_MM(mm->pmd_huge_pte, mm); | ||
| 879 | #endif | ||
| 880 | } | ||
| 881 | |||
| 882 | /* | 924 | /* |
| 883 | * Allocate and initialize an mm_struct. | 925 | * Allocate and initialize an mm_struct. |
| 884 | */ | 926 | */ |
| @@ -894,24 +936,6 @@ struct mm_struct *mm_alloc(void) | |||
| 894 | return mm_init(mm, current, current_user_ns()); | 936 | return mm_init(mm, current, current_user_ns()); |
| 895 | } | 937 | } |
| 896 | 938 | ||
| 897 | /* | ||
| 898 | * Called when the last reference to the mm | ||
| 899 | * is dropped: either by a lazy thread or by | ||
| 900 | * mmput. Free the page directory and the mm. | ||
| 901 | */ | ||
| 902 | void __mmdrop(struct mm_struct *mm) | ||
| 903 | { | ||
| 904 | BUG_ON(mm == &init_mm); | ||
| 905 | mm_free_pgd(mm); | ||
| 906 | destroy_context(mm); | ||
| 907 | hmm_mm_destroy(mm); | ||
| 908 | mmu_notifier_mm_destroy(mm); | ||
| 909 | check_mm(mm); | ||
| 910 | put_user_ns(mm->user_ns); | ||
| 911 | free_mm(mm); | ||
| 912 | } | ||
| 913 | EXPORT_SYMBOL_GPL(__mmdrop); | ||
| 914 | |||
| 915 | static inline void __mmput(struct mm_struct *mm) | 939 | static inline void __mmput(struct mm_struct *mm) |
| 916 | { | 940 | { |
| 917 | VM_BUG_ON(atomic_read(&mm->mm_users)); | 941 | VM_BUG_ON(atomic_read(&mm->mm_users)); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 557d46728577..2fb4e27c636a 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -1374,13 +1374,6 @@ static struct ctl_table vm_table[] = { | |||
| 1374 | .mode = 0644, | 1374 | .mode = 0644, |
| 1375 | .proc_handler = proc_dointvec, | 1375 | .proc_handler = proc_dointvec, |
| 1376 | }, | 1376 | }, |
| 1377 | { | ||
| 1378 | .procname = "hugepages_treat_as_movable", | ||
| 1379 | .data = &hugepages_treat_as_movable, | ||
| 1380 | .maxlen = sizeof(int), | ||
| 1381 | .mode = 0644, | ||
| 1382 | .proc_handler = proc_dointvec, | ||
| 1383 | }, | ||
| 1384 | { | 1377 | { |
| 1385 | .procname = "nr_overcommit_hugepages", | 1378 | .procname = "nr_overcommit_hugepages", |
| 1386 | .data = NULL, | 1379 | .data = NULL, |
diff --git a/mm/Kconfig b/mm/Kconfig index 03ff7703d322..c782e8fb7235 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
| @@ -639,15 +639,10 @@ config MAX_STACK_SIZE_MB | |||
| 639 | 639 | ||
| 640 | A sane initial value is 80 MB. | 640 | A sane initial value is 80 MB. |
| 641 | 641 | ||
| 642 | # For architectures that support deferred memory initialisation | ||
| 643 | config ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT | ||
| 644 | bool | ||
| 645 | |||
| 646 | config DEFERRED_STRUCT_PAGE_INIT | 642 | config DEFERRED_STRUCT_PAGE_INIT |
| 647 | bool "Defer initialisation of struct pages to kthreads" | 643 | bool "Defer initialisation of struct pages to kthreads" |
| 648 | default n | 644 | default n |
| 649 | depends on ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT | 645 | depends on NO_BOOTMEM |
| 650 | depends on NO_BOOTMEM && MEMORY_HOTPLUG | ||
| 651 | depends on !FLATMEM | 646 | depends on !FLATMEM |
| 652 | help | 647 | help |
| 653 | Ordinarily all struct pages are initialised during early boot in a | 648 | Ordinarily all struct pages are initialised during early boot in a |
diff --git a/mm/compaction.c b/mm/compaction.c index 10cd757f1006..2c8999d027ab 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
| @@ -1738,7 +1738,7 @@ int sysctl_extfrag_threshold = 500; | |||
| 1738 | * @order: The order of the current allocation | 1738 | * @order: The order of the current allocation |
| 1739 | * @alloc_flags: The allocation flags of the current allocation | 1739 | * @alloc_flags: The allocation flags of the current allocation |
| 1740 | * @ac: The context of current allocation | 1740 | * @ac: The context of current allocation |
| 1741 | * @mode: The migration mode for async, sync light, or sync migration | 1741 | * @prio: Determines how hard direct compaction should try to succeed |
| 1742 | * | 1742 | * |
| 1743 | * This is the main entry point for direct page compaction. | 1743 | * This is the main entry point for direct page compaction. |
| 1744 | */ | 1744 | */ |
diff --git a/mm/fadvise.c b/mm/fadvise.c index ec70d6e4b86d..767887f5f3bf 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c | |||
| @@ -127,7 +127,15 @@ SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) | |||
| 127 | */ | 127 | */ |
| 128 | start_index = (offset+(PAGE_SIZE-1)) >> PAGE_SHIFT; | 128 | start_index = (offset+(PAGE_SIZE-1)) >> PAGE_SHIFT; |
| 129 | end_index = (endbyte >> PAGE_SHIFT); | 129 | end_index = (endbyte >> PAGE_SHIFT); |
| 130 | if ((endbyte & ~PAGE_MASK) != ~PAGE_MASK) { | 130 | /* |
| 131 | * The page at end_index will be inclusively discarded according | ||
| 132 | * by invalidate_mapping_pages(), so subtracting 1 from | ||
| 133 | * end_index means we will skip the last page. But if endbyte | ||
| 134 | * is page aligned or is at the end of file, we should not skip | ||
| 135 | * that page - discarding the last page is safe enough. | ||
| 136 | */ | ||
| 137 | if ((endbyte & ~PAGE_MASK) != ~PAGE_MASK && | ||
| 138 | endbyte != inode->i_size - 1) { | ||
| 131 | /* First page is tricky as 0 - 1 = -1, but pgoff_t | 139 | /* First page is tricky as 0 - 1 = -1, but pgoff_t |
| 132 | * is unsigned, so the end_index >= start_index | 140 | * is unsigned, so the end_index >= start_index |
| 133 | * check below would be true and we'll discard the whole | 141 | * check below would be true and we'll discard the whole |
diff --git a/mm/filemap.c b/mm/filemap.c index ee83baaf855d..693f62212a59 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
| 32 | #include <linux/security.h> | 32 | #include <linux/security.h> |
| 33 | #include <linux/cpuset.h> | 33 | #include <linux/cpuset.h> |
| 34 | #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ | ||
| 35 | #include <linux/hugetlb.h> | 34 | #include <linux/hugetlb.h> |
| 36 | #include <linux/memcontrol.h> | 35 | #include <linux/memcontrol.h> |
| 37 | #include <linux/cleancache.h> | 36 | #include <linux/cleancache.h> |
| @@ -418,7 +418,7 @@ again: | |||
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | if (!pte_present(pte)) { | 420 | if (!pte_present(pte)) { |
| 421 | swp_entry_t entry; | 421 | swp_entry_t entry = pte_to_swp_entry(pte); |
| 422 | 422 | ||
| 423 | if (!non_swap_entry(entry)) { | 423 | if (!non_swap_entry(entry)) { |
| 424 | if (hmm_vma_walk->fault) | 424 | if (hmm_vma_walk->fault) |
| @@ -426,8 +426,6 @@ again: | |||
| 426 | continue; | 426 | continue; |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | entry = pte_to_swp_entry(pte); | ||
| 430 | |||
| 431 | /* | 429 | /* |
| 432 | * This is a special swap entry, ignore migration, use | 430 | * This is a special swap entry, ignore migration, use |
| 433 | * device and report anything else as error. | 431 | * device and report anything else as error. |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0e7ded98d114..87ab9b8f56b5 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
| @@ -1910,17 +1910,7 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | |||
| 1910 | * pmdp_invalidate() is required to make sure we don't miss | 1910 | * pmdp_invalidate() is required to make sure we don't miss |
| 1911 | * dirty/young flags set by hardware. | 1911 | * dirty/young flags set by hardware. |
| 1912 | */ | 1912 | */ |
| 1913 | entry = *pmd; | 1913 | entry = pmdp_invalidate(vma, addr, pmd); |
| 1914 | pmdp_invalidate(vma, addr, pmd); | ||
| 1915 | |||
| 1916 | /* | ||
| 1917 | * Recover dirty/young flags. It relies on pmdp_invalidate to not | ||
| 1918 | * corrupt them. | ||
| 1919 | */ | ||
| 1920 | if (pmd_dirty(*pmd)) | ||
| 1921 | entry = pmd_mkdirty(entry); | ||
| 1922 | if (pmd_young(*pmd)) | ||
| 1923 | entry = pmd_mkyoung(entry); | ||
| 1924 | 1914 | ||
| 1925 | entry = pmd_modify(entry, newprot); | 1915 | entry = pmd_modify(entry, newprot); |
| 1926 | if (preserve_write) | 1916 | if (preserve_write) |
| @@ -2073,8 +2063,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
| 2073 | struct mm_struct *mm = vma->vm_mm; | 2063 | struct mm_struct *mm = vma->vm_mm; |
| 2074 | struct page *page; | 2064 | struct page *page; |
| 2075 | pgtable_t pgtable; | 2065 | pgtable_t pgtable; |
| 2076 | pmd_t _pmd; | 2066 | pmd_t old_pmd, _pmd; |
| 2077 | bool young, write, dirty, soft_dirty, pmd_migration = false; | 2067 | bool young, write, soft_dirty, pmd_migration = false; |
| 2078 | unsigned long addr; | 2068 | unsigned long addr; |
| 2079 | int i; | 2069 | int i; |
| 2080 | 2070 | ||
| @@ -2116,24 +2106,50 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
| 2116 | return __split_huge_zero_page_pmd(vma, haddr, pmd); | 2106 | return __split_huge_zero_page_pmd(vma, haddr, pmd); |
| 2117 | } | 2107 | } |
| 2118 | 2108 | ||
| 2109 | /* | ||
| 2110 | * Up to this point the pmd is present and huge and userland has the | ||
| 2111 | * whole access to the hugepage during the split (which happens in | ||
| 2112 | * place). If we overwrite the pmd with the not-huge version pointing | ||
| 2113 | * to the pte here (which of course we could if all CPUs were bug | ||
| 2114 | * free), userland could trigger a small page size TLB miss on the | ||
| 2115 | * small sized TLB while the hugepage TLB entry is still established in | ||
| 2116 | * the huge TLB. Some CPU doesn't like that. | ||
| 2117 | * See http://support.amd.com/us/Processor_TechDocs/41322.pdf, Erratum | ||
| 2118 | * 383 on page 93. Intel should be safe but is also warns that it's | ||
| 2119 | * only safe if the permission and cache attributes of the two entries | ||
| 2120 | * loaded in the two TLB is identical (which should be the case here). | ||
| 2121 | * But it is generally safer to never allow small and huge TLB entries | ||
| 2122 | * for the same virtual address to be loaded simultaneously. So instead | ||
| 2123 | * of doing "pmd_populate(); flush_pmd_tlb_range();" we first mark the | ||
| 2124 | * current pmd notpresent (atomically because here the pmd_trans_huge | ||
| 2125 | * must remain set at all times on the pmd until the split is complete | ||
| 2126 | * for this pmd), then we flush the SMP TLB and finally we write the | ||
| 2127 | * non-huge version of the pmd entry with pmd_populate. | ||
| 2128 | */ | ||
| 2129 | old_pmd = pmdp_invalidate(vma, haddr, pmd); | ||
| 2130 | |||
| 2119 | #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION | 2131 | #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION |
| 2120 | pmd_migration = is_pmd_migration_entry(*pmd); | 2132 | pmd_migration = is_pmd_migration_entry(old_pmd); |
| 2121 | if (pmd_migration) { | 2133 | if (pmd_migration) { |
| 2122 | swp_entry_t entry; | 2134 | swp_entry_t entry; |
| 2123 | 2135 | ||
| 2124 | entry = pmd_to_swp_entry(*pmd); | 2136 | entry = pmd_to_swp_entry(old_pmd); |
| 2125 | page = pfn_to_page(swp_offset(entry)); | 2137 | page = pfn_to_page(swp_offset(entry)); |
| 2126 | } else | 2138 | } else |
| 2127 | #endif | 2139 | #endif |
| 2128 | page = pmd_page(*pmd); | 2140 | page = pmd_page(old_pmd); |
| 2129 | VM_BUG_ON_PAGE(!page_count(page), page); | 2141 | VM_BUG_ON_PAGE(!page_count(page), page); |
| 2130 | page_ref_add(page, HPAGE_PMD_NR - 1); | 2142 | page_ref_add(page, HPAGE_PMD_NR - 1); |
| 2131 | write = pmd_write(*pmd); | 2143 | if (pmd_dirty(old_pmd)) |
| 2132 | young = pmd_young(*pmd); | 2144 | SetPageDirty(page); |
| 2133 | dirty = pmd_dirty(*pmd); | 2145 | write = pmd_write(old_pmd); |
| 2134 | soft_dirty = pmd_soft_dirty(*pmd); | 2146 | young = pmd_young(old_pmd); |
| 2147 | soft_dirty = pmd_soft_dirty(old_pmd); | ||
| 2135 | 2148 | ||
| 2136 | pmdp_huge_split_prepare(vma, haddr, pmd); | 2149 | /* |
| 2150 | * Withdraw the table only after we mark the pmd entry invalid. | ||
| 2151 | * This's critical for some architectures (Power). | ||
| 2152 | */ | ||
| 2137 | pgtable = pgtable_trans_huge_withdraw(mm, pmd); | 2153 | pgtable = pgtable_trans_huge_withdraw(mm, pmd); |
| 2138 | pmd_populate(mm, &_pmd, pgtable); | 2154 | pmd_populate(mm, &_pmd, pgtable); |
| 2139 | 2155 | ||
| @@ -2160,8 +2176,6 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
| 2160 | if (soft_dirty) | 2176 | if (soft_dirty) |
| 2161 | entry = pte_mksoft_dirty(entry); | 2177 | entry = pte_mksoft_dirty(entry); |
| 2162 | } | 2178 | } |
| 2163 | if (dirty) | ||
| 2164 | SetPageDirty(page + i); | ||
| 2165 | pte = pte_offset_map(&_pmd, addr); | 2179 | pte = pte_offset_map(&_pmd, addr); |
| 2166 | BUG_ON(!pte_none(*pte)); | 2180 | BUG_ON(!pte_none(*pte)); |
| 2167 | set_pte_at(mm, addr, pte, entry); | 2181 | set_pte_at(mm, addr, pte, entry); |
| @@ -2189,28 +2203,6 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, | |||
| 2189 | } | 2203 | } |
| 2190 | 2204 | ||
| 2191 | smp_wmb(); /* make pte visible before pmd */ | 2205 | smp_wmb(); /* make pte visible before pmd */ |
| 2192 | /* | ||
| 2193 | * Up to this point the pmd is present and huge and userland has the | ||
| 2194 | * whole access to the hugepage during the split (which happens in | ||
| 2195 | * place). If we overwrite the pmd with the not-huge version pointing | ||
| 2196 | * to the pte here (which of course we could if all CPUs were bug | ||
| 2197 | * free), userland could trigger a small page size TLB miss on the | ||
| 2198 | * small sized TLB while the hugepage TLB entry is still established in | ||
| 2199 | * the huge TLB. Some CPU doesn't like that. | ||
| 2200 | * See http://support.amd.com/us/Processor_TechDocs/41322.pdf, Erratum | ||
| 2201 | * 383 on page 93. Intel should be safe but is also warns that it's | ||
| 2202 | * only safe if the permission and cache attributes of the two entries | ||
| 2203 | * loaded in the two TLB is identical (which should be the case here). | ||
| 2204 | * But it is generally safer to never allow small and huge TLB entries | ||
| 2205 | * for the same virtual address to be loaded simultaneously. So instead | ||
| 2206 | * of doing "pmd_populate(); flush_pmd_tlb_range();" we first mark the | ||
| 2207 | * current pmd notpresent (atomically because here the pmd_trans_huge | ||
| 2208 | * and pmd_trans_splitting must remain set at all times on the pmd | ||
| 2209 | * until the split is complete for this pmd), then we flush the SMP TLB | ||
| 2210 | * and finally we write the non-huge version of the pmd entry with | ||
| 2211 | * pmd_populate. | ||
| 2212 | */ | ||
| 2213 | pmdp_invalidate(vma, haddr, pmd); | ||
| 2214 | pmd_populate(mm, pmd, pgtable); | 2206 | pmd_populate(mm, pmd, pgtable); |
| 2215 | 2207 | ||
| 2216 | if (freeze) { | 2208 | if (freeze) { |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9a334f5fb730..7c204e3d132b 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -34,10 +34,9 @@ | |||
| 34 | #include <linux/hugetlb_cgroup.h> | 34 | #include <linux/hugetlb_cgroup.h> |
| 35 | #include <linux/node.h> | 35 | #include <linux/node.h> |
| 36 | #include <linux/userfaultfd_k.h> | 36 | #include <linux/userfaultfd_k.h> |
| 37 | #include <linux/page_owner.h> | ||
| 37 | #include "internal.h" | 38 | #include "internal.h" |
| 38 | 39 | ||
| 39 | int hugepages_treat_as_movable; | ||
| 40 | |||
| 41 | int hugetlb_max_hstate __read_mostly; | 40 | int hugetlb_max_hstate __read_mostly; |
| 42 | unsigned int default_hstate_idx; | 41 | unsigned int default_hstate_idx; |
| 43 | struct hstate hstates[HUGE_MAX_HSTATE]; | 42 | struct hstate hstates[HUGE_MAX_HSTATE]; |
| @@ -926,7 +925,7 @@ retry_cpuset: | |||
| 926 | /* Movability of hugepages depends on migration support. */ | 925 | /* Movability of hugepages depends on migration support. */ |
| 927 | static inline gfp_t htlb_alloc_mask(struct hstate *h) | 926 | static inline gfp_t htlb_alloc_mask(struct hstate *h) |
| 928 | { | 927 | { |
| 929 | if (hugepages_treat_as_movable || hugepage_migration_supported(h)) | 928 | if (hugepage_migration_supported(h)) |
| 930 | return GFP_HIGHUSER_MOVABLE; | 929 | return GFP_HIGHUSER_MOVABLE; |
| 931 | else | 930 | else |
| 932 | return GFP_HIGHUSER; | 931 | return GFP_HIGHUSER; |
| @@ -1108,7 +1107,8 @@ static bool zone_spans_last_pfn(const struct zone *zone, | |||
| 1108 | return zone_spans_pfn(zone, last_pfn); | 1107 | return zone_spans_pfn(zone, last_pfn); |
| 1109 | } | 1108 | } |
| 1110 | 1109 | ||
| 1111 | static struct page *alloc_gigantic_page(int nid, struct hstate *h) | 1110 | static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask, |
| 1111 | int nid, nodemask_t *nodemask) | ||
| 1112 | { | 1112 | { |
| 1113 | unsigned int order = huge_page_order(h); | 1113 | unsigned int order = huge_page_order(h); |
| 1114 | unsigned long nr_pages = 1 << order; | 1114 | unsigned long nr_pages = 1 << order; |
| @@ -1116,11 +1116,9 @@ static struct page *alloc_gigantic_page(int nid, struct hstate *h) | |||
| 1116 | struct zonelist *zonelist; | 1116 | struct zonelist *zonelist; |
| 1117 | struct zone *zone; | 1117 | struct zone *zone; |
| 1118 | struct zoneref *z; | 1118 | struct zoneref *z; |
| 1119 | gfp_t gfp_mask; | ||
| 1120 | 1119 | ||
| 1121 | gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE; | ||
| 1122 | zonelist = node_zonelist(nid, gfp_mask); | 1120 | zonelist = node_zonelist(nid, gfp_mask); |
| 1123 | for_each_zone_zonelist_nodemask(zone, z, zonelist, gfp_zone(gfp_mask), NULL) { | 1121 | for_each_zone_zonelist_nodemask(zone, z, zonelist, gfp_zone(gfp_mask), nodemask) { |
| 1124 | spin_lock_irqsave(&zone->lock, flags); | 1122 | spin_lock_irqsave(&zone->lock, flags); |
| 1125 | 1123 | ||
| 1126 | pfn = ALIGN(zone->zone_start_pfn, nr_pages); | 1124 | pfn = ALIGN(zone->zone_start_pfn, nr_pages); |
| @@ -1151,41 +1149,13 @@ static struct page *alloc_gigantic_page(int nid, struct hstate *h) | |||
| 1151 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid); | 1149 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid); |
| 1152 | static void prep_compound_gigantic_page(struct page *page, unsigned int order); | 1150 | static void prep_compound_gigantic_page(struct page *page, unsigned int order); |
| 1153 | 1151 | ||
| 1154 | static struct page *alloc_fresh_gigantic_page_node(struct hstate *h, int nid) | ||
| 1155 | { | ||
| 1156 | struct page *page; | ||
| 1157 | |||
| 1158 | page = alloc_gigantic_page(nid, h); | ||
| 1159 | if (page) { | ||
| 1160 | prep_compound_gigantic_page(page, huge_page_order(h)); | ||
| 1161 | prep_new_huge_page(h, page, nid); | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | return page; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | static int alloc_fresh_gigantic_page(struct hstate *h, | ||
| 1168 | nodemask_t *nodes_allowed) | ||
| 1169 | { | ||
| 1170 | struct page *page = NULL; | ||
| 1171 | int nr_nodes, node; | ||
| 1172 | |||
| 1173 | for_each_node_mask_to_alloc(h, nr_nodes, node, nodes_allowed) { | ||
| 1174 | page = alloc_fresh_gigantic_page_node(h, node); | ||
| 1175 | if (page) | ||
| 1176 | return 1; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | return 0; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | #else /* !CONFIG_ARCH_HAS_GIGANTIC_PAGE */ | 1152 | #else /* !CONFIG_ARCH_HAS_GIGANTIC_PAGE */ |
| 1183 | static inline bool gigantic_page_supported(void) { return false; } | 1153 | static inline bool gigantic_page_supported(void) { return false; } |
| 1154 | static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask, | ||
| 1155 | int nid, nodemask_t *nodemask) { return NULL; } | ||
| 1184 | static inline void free_gigantic_page(struct page *page, unsigned int order) { } | 1156 | static inline void free_gigantic_page(struct page *page, unsigned int order) { } |
| 1185 | static inline void destroy_compound_gigantic_page(struct page *page, | 1157 | static inline void destroy_compound_gigantic_page(struct page *page, |
| 1186 | unsigned int order) { } | 1158 | unsigned int order) { } |
| 1187 | static inline int alloc_fresh_gigantic_page(struct hstate *h, | ||
| 1188 | nodemask_t *nodes_allowed) { return 0; } | ||
| 1189 | #endif | 1159 | #endif |
| 1190 | 1160 | ||
| 1191 | static void update_and_free_page(struct hstate *h, struct page *page) | 1161 | static void update_and_free_page(struct hstate *h, struct page *page) |
| @@ -1250,6 +1220,28 @@ static void clear_page_huge_active(struct page *page) | |||
| 1250 | ClearPagePrivate(&page[1]); | 1220 | ClearPagePrivate(&page[1]); |
| 1251 | } | 1221 | } |
| 1252 | 1222 | ||
| 1223 | /* | ||
| 1224 | * Internal hugetlb specific page flag. Do not use outside of the hugetlb | ||
| 1225 | * code | ||
| 1226 | */ | ||
| 1227 | static inline bool PageHugeTemporary(struct page *page) | ||
| 1228 | { | ||
| 1229 | if (!PageHuge(page)) | ||
| 1230 | return false; | ||
| 1231 | |||
| 1232 | return (unsigned long)page[2].mapping == -1U; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | static inline void SetPageHugeTemporary(struct page *page) | ||
| 1236 | { | ||
| 1237 | page[2].mapping = (void *)-1U; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | static inline void ClearPageHugeTemporary(struct page *page) | ||
| 1241 | { | ||
| 1242 | page[2].mapping = NULL; | ||
| 1243 | } | ||
| 1244 | |||
| 1253 | void free_huge_page(struct page *page) | 1245 | void free_huge_page(struct page *page) |
| 1254 | { | 1246 | { |
| 1255 | /* | 1247 | /* |
| @@ -1284,7 +1276,11 @@ void free_huge_page(struct page *page) | |||
| 1284 | if (restore_reserve) | 1276 | if (restore_reserve) |
| 1285 | h->resv_huge_pages++; | 1277 | h->resv_huge_pages++; |
| 1286 | 1278 | ||
| 1287 | if (h->surplus_huge_pages_node[nid]) { | 1279 | if (PageHugeTemporary(page)) { |
| 1280 | list_del(&page->lru); | ||
| 1281 | ClearPageHugeTemporary(page); | ||
| 1282 | update_and_free_page(h, page); | ||
| 1283 | } else if (h->surplus_huge_pages_node[nid]) { | ||
| 1288 | /* remove the page from active list */ | 1284 | /* remove the page from active list */ |
| 1289 | list_del(&page->lru); | 1285 | list_del(&page->lru); |
| 1290 | update_and_free_page(h, page); | 1286 | update_and_free_page(h, page); |
| @@ -1306,7 +1302,6 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid) | |||
| 1306 | h->nr_huge_pages++; | 1302 | h->nr_huge_pages++; |
| 1307 | h->nr_huge_pages_node[nid]++; | 1303 | h->nr_huge_pages_node[nid]++; |
| 1308 | spin_unlock(&hugetlb_lock); | 1304 | spin_unlock(&hugetlb_lock); |
| 1309 | put_page(page); /* free it into the hugepage allocator */ | ||
| 1310 | } | 1305 | } |
| 1311 | 1306 | ||
| 1312 | static void prep_compound_gigantic_page(struct page *page, unsigned int order) | 1307 | static void prep_compound_gigantic_page(struct page *page, unsigned int order) |
| @@ -1383,41 +1378,70 @@ pgoff_t __basepage_index(struct page *page) | |||
| 1383 | return (index << compound_order(page_head)) + compound_idx; | 1378 | return (index << compound_order(page_head)) + compound_idx; |
| 1384 | } | 1379 | } |
| 1385 | 1380 | ||
| 1386 | static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | 1381 | static struct page *alloc_buddy_huge_page(struct hstate *h, |
| 1382 | gfp_t gfp_mask, int nid, nodemask_t *nmask) | ||
| 1387 | { | 1383 | { |
| 1384 | int order = huge_page_order(h); | ||
| 1388 | struct page *page; | 1385 | struct page *page; |
| 1389 | 1386 | ||
| 1390 | page = __alloc_pages_node(nid, | 1387 | gfp_mask |= __GFP_COMP|__GFP_RETRY_MAYFAIL|__GFP_NOWARN; |
| 1391 | htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE| | 1388 | if (nid == NUMA_NO_NODE) |
| 1392 | __GFP_RETRY_MAYFAIL|__GFP_NOWARN, | 1389 | nid = numa_mem_id(); |
| 1393 | huge_page_order(h)); | 1390 | page = __alloc_pages_nodemask(gfp_mask, order, nid, nmask); |
| 1394 | if (page) { | 1391 | if (page) |
| 1395 | prep_new_huge_page(h, page, nid); | 1392 | __count_vm_event(HTLB_BUDDY_PGALLOC); |
| 1396 | } | 1393 | else |
| 1394 | __count_vm_event(HTLB_BUDDY_PGALLOC_FAIL); | ||
| 1395 | |||
| 1396 | return page; | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | /* | ||
| 1400 | * Common helper to allocate a fresh hugetlb page. All specific allocators | ||
| 1401 | * should use this function to get new hugetlb pages | ||
| 1402 | */ | ||
| 1403 | static struct page *alloc_fresh_huge_page(struct hstate *h, | ||
| 1404 | gfp_t gfp_mask, int nid, nodemask_t *nmask) | ||
| 1405 | { | ||
| 1406 | struct page *page; | ||
| 1407 | |||
| 1408 | if (hstate_is_gigantic(h)) | ||
| 1409 | page = alloc_gigantic_page(h, gfp_mask, nid, nmask); | ||
| 1410 | else | ||
| 1411 | page = alloc_buddy_huge_page(h, gfp_mask, | ||
| 1412 | nid, nmask); | ||
| 1413 | if (!page) | ||
| 1414 | return NULL; | ||
| 1415 | |||
| 1416 | if (hstate_is_gigantic(h)) | ||
| 1417 | prep_compound_gigantic_page(page, huge_page_order(h)); | ||
| 1418 | prep_new_huge_page(h, page, page_to_nid(page)); | ||
| 1397 | 1419 | ||
| 1398 | return page; | 1420 | return page; |
| 1399 | } | 1421 | } |
| 1400 | 1422 | ||
| 1401 | static int alloc_fresh_huge_page(struct hstate *h, nodemask_t *nodes_allowed) | 1423 | /* |
| 1424 | * Allocates a fresh page to the hugetlb allocator pool in the node interleaved | ||
| 1425 | * manner. | ||
| 1426 | */ | ||
| 1427 | static int alloc_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed) | ||
| 1402 | { | 1428 | { |
| 1403 | struct page *page; | 1429 | struct page *page; |
| 1404 | int nr_nodes, node; | 1430 | int nr_nodes, node; |
| 1405 | int ret = 0; | 1431 | gfp_t gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE; |
| 1406 | 1432 | ||
| 1407 | for_each_node_mask_to_alloc(h, nr_nodes, node, nodes_allowed) { | 1433 | for_each_node_mask_to_alloc(h, nr_nodes, node, nodes_allowed) { |
| 1408 | page = alloc_fresh_huge_page_node(h, node); | 1434 | page = alloc_fresh_huge_page(h, gfp_mask, node, nodes_allowed); |
| 1409 | if (page) { | 1435 | if (page) |
| 1410 | ret = 1; | ||
| 1411 | break; | 1436 | break; |
| 1412 | } | ||
| 1413 | } | 1437 | } |
| 1414 | 1438 | ||
| 1415 | if (ret) | 1439 | if (!page) |
| 1416 | count_vm_event(HTLB_BUDDY_PGALLOC); | 1440 | return 0; |
| 1417 | else | ||
| 1418 | count_vm_event(HTLB_BUDDY_PGALLOC_FAIL); | ||
| 1419 | 1441 | ||
| 1420 | return ret; | 1442 | put_page(page); /* free it into the hugepage allocator */ |
| 1443 | |||
| 1444 | return 1; | ||
| 1421 | } | 1445 | } |
| 1422 | 1446 | ||
| 1423 | /* | 1447 | /* |
| @@ -1525,79 +1549,66 @@ int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) | |||
| 1525 | return rc; | 1549 | return rc; |
| 1526 | } | 1550 | } |
| 1527 | 1551 | ||
| 1528 | static struct page *__hugetlb_alloc_buddy_huge_page(struct hstate *h, | 1552 | /* |
| 1529 | gfp_t gfp_mask, int nid, nodemask_t *nmask) | 1553 | * Allocates a fresh surplus page from the page allocator. |
| 1530 | { | 1554 | */ |
| 1531 | int order = huge_page_order(h); | 1555 | static struct page *alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask, |
| 1532 | |||
| 1533 | gfp_mask |= __GFP_COMP|__GFP_RETRY_MAYFAIL|__GFP_NOWARN; | ||
| 1534 | if (nid == NUMA_NO_NODE) | ||
| 1535 | nid = numa_mem_id(); | ||
| 1536 | return __alloc_pages_nodemask(gfp_mask, order, nid, nmask); | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | static struct page *__alloc_buddy_huge_page(struct hstate *h, gfp_t gfp_mask, | ||
| 1540 | int nid, nodemask_t *nmask) | 1556 | int nid, nodemask_t *nmask) |
| 1541 | { | 1557 | { |
| 1542 | struct page *page; | 1558 | struct page *page = NULL; |
| 1543 | unsigned int r_nid; | ||
| 1544 | 1559 | ||
| 1545 | if (hstate_is_gigantic(h)) | 1560 | if (hstate_is_gigantic(h)) |
| 1546 | return NULL; | 1561 | return NULL; |
| 1547 | 1562 | ||
| 1563 | spin_lock(&hugetlb_lock); | ||
| 1564 | if (h->surplus_huge_pages >= h->nr_overcommit_huge_pages) | ||
| 1565 | goto out_unlock; | ||
| 1566 | spin_unlock(&hugetlb_lock); | ||
| 1567 | |||
| 1568 | page = alloc_fresh_huge_page(h, gfp_mask, nid, nmask); | ||
| 1569 | if (!page) | ||
| 1570 | return NULL; | ||
| 1571 | |||
| 1572 | spin_lock(&hugetlb_lock); | ||
| 1548 | /* | 1573 | /* |
| 1549 | * Assume we will successfully allocate the surplus page to | 1574 | * We could have raced with the pool size change. |
| 1550 | * prevent racing processes from causing the surplus to exceed | 1575 | * Double check that and simply deallocate the new page |
| 1551 | * overcommit | 1576 | * if we would end up overcommiting the surpluses. Abuse |
| 1552 | * | 1577 | * temporary page to workaround the nasty free_huge_page |
| 1553 | * This however introduces a different race, where a process B | 1578 | * codeflow |
| 1554 | * tries to grow the static hugepage pool while alloc_pages() is | ||
| 1555 | * called by process A. B will only examine the per-node | ||
| 1556 | * counters in determining if surplus huge pages can be | ||
| 1557 | * converted to normal huge pages in adjust_pool_surplus(). A | ||
| 1558 | * won't be able to increment the per-node counter, until the | ||
| 1559 | * lock is dropped by B, but B doesn't drop hugetlb_lock until | ||
| 1560 | * no more huge pages can be converted from surplus to normal | ||
| 1561 | * state (and doesn't try to convert again). Thus, we have a | ||
| 1562 | * case where a surplus huge page exists, the pool is grown, and | ||
| 1563 | * the surplus huge page still exists after, even though it | ||
| 1564 | * should just have been converted to a normal huge page. This | ||
| 1565 | * does not leak memory, though, as the hugepage will be freed | ||
| 1566 | * once it is out of use. It also does not allow the counters to | ||
| 1567 | * go out of whack in adjust_pool_surplus() as we don't modify | ||
| 1568 | * the node values until we've gotten the hugepage and only the | ||
| 1569 | * per-node value is checked there. | ||
| 1570 | */ | 1579 | */ |
| 1571 | spin_lock(&hugetlb_lock); | ||
| 1572 | if (h->surplus_huge_pages >= h->nr_overcommit_huge_pages) { | 1580 | if (h->surplus_huge_pages >= h->nr_overcommit_huge_pages) { |
| 1573 | spin_unlock(&hugetlb_lock); | 1581 | SetPageHugeTemporary(page); |
| 1574 | return NULL; | 1582 | put_page(page); |
| 1583 | page = NULL; | ||
| 1575 | } else { | 1584 | } else { |
| 1576 | h->nr_huge_pages++; | ||
| 1577 | h->surplus_huge_pages++; | 1585 | h->surplus_huge_pages++; |
| 1586 | h->nr_huge_pages_node[page_to_nid(page)]++; | ||
| 1578 | } | 1587 | } |
| 1588 | |||
| 1589 | out_unlock: | ||
| 1579 | spin_unlock(&hugetlb_lock); | 1590 | spin_unlock(&hugetlb_lock); |
| 1580 | 1591 | ||
| 1581 | page = __hugetlb_alloc_buddy_huge_page(h, gfp_mask, nid, nmask); | 1592 | return page; |
| 1593 | } | ||
| 1582 | 1594 | ||
| 1583 | spin_lock(&hugetlb_lock); | 1595 | static struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask, |
| 1584 | if (page) { | 1596 | int nid, nodemask_t *nmask) |
| 1585 | INIT_LIST_HEAD(&page->lru); | 1597 | { |
| 1586 | r_nid = page_to_nid(page); | 1598 | struct page *page; |
| 1587 | set_compound_page_dtor(page, HUGETLB_PAGE_DTOR); | 1599 | |
| 1588 | set_hugetlb_cgroup(page, NULL); | 1600 | if (hstate_is_gigantic(h)) |
| 1589 | /* | 1601 | return NULL; |
| 1590 | * We incremented the global counters already | 1602 | |
| 1591 | */ | 1603 | page = alloc_fresh_huge_page(h, gfp_mask, nid, nmask); |
| 1592 | h->nr_huge_pages_node[r_nid]++; | 1604 | if (!page) |
| 1593 | h->surplus_huge_pages_node[r_nid]++; | 1605 | return NULL; |
| 1594 | __count_vm_event(HTLB_BUDDY_PGALLOC); | 1606 | |
| 1595 | } else { | 1607 | /* |
| 1596 | h->nr_huge_pages--; | 1608 | * We do not account these pages as surplus because they are only |
| 1597 | h->surplus_huge_pages--; | 1609 | * temporary and will be released properly on the last reference |
| 1598 | __count_vm_event(HTLB_BUDDY_PGALLOC_FAIL); | 1610 | */ |
| 1599 | } | 1611 | SetPageHugeTemporary(page); |
| 1600 | spin_unlock(&hugetlb_lock); | ||
| 1601 | 1612 | ||
| 1602 | return page; | 1613 | return page; |
| 1603 | } | 1614 | } |
| @@ -1606,7 +1617,7 @@ static struct page *__alloc_buddy_huge_page(struct hstate *h, gfp_t gfp_mask, | |||
| 1606 | * Use the VMA's mpolicy to allocate a huge page from the buddy. | 1617 | * Use the VMA's mpolicy to allocate a huge page from the buddy. |
| 1607 | */ | 1618 | */ |
| 1608 | static | 1619 | static |
| 1609 | struct page *__alloc_buddy_huge_page_with_mpol(struct hstate *h, | 1620 | struct page *alloc_buddy_huge_page_with_mpol(struct hstate *h, |
| 1610 | struct vm_area_struct *vma, unsigned long addr) | 1621 | struct vm_area_struct *vma, unsigned long addr) |
| 1611 | { | 1622 | { |
| 1612 | struct page *page; | 1623 | struct page *page; |
| @@ -1616,17 +1627,13 @@ struct page *__alloc_buddy_huge_page_with_mpol(struct hstate *h, | |||
| 1616 | nodemask_t *nodemask; | 1627 | nodemask_t *nodemask; |
| 1617 | 1628 | ||
| 1618 | nid = huge_node(vma, addr, gfp_mask, &mpol, &nodemask); | 1629 | nid = huge_node(vma, addr, gfp_mask, &mpol, &nodemask); |
| 1619 | page = __alloc_buddy_huge_page(h, gfp_mask, nid, nodemask); | 1630 | page = alloc_surplus_huge_page(h, gfp_mask, nid, nodemask); |
| 1620 | mpol_cond_put(mpol); | 1631 | mpol_cond_put(mpol); |
| 1621 | 1632 | ||
| 1622 | return page; | 1633 | return page; |
| 1623 | } | 1634 | } |
| 1624 | 1635 | ||
| 1625 | /* | 1636 | /* page migration callback function */ |
| 1626 | * This allocation function is useful in the context where vma is irrelevant. | ||
| 1627 | * E.g. soft-offlining uses this function because it only cares physical | ||
| 1628 | * address of error page. | ||
| 1629 | */ | ||
| 1630 | struct page *alloc_huge_page_node(struct hstate *h, int nid) | 1637 | struct page *alloc_huge_page_node(struct hstate *h, int nid) |
| 1631 | { | 1638 | { |
| 1632 | gfp_t gfp_mask = htlb_alloc_mask(h); | 1639 | gfp_t gfp_mask = htlb_alloc_mask(h); |
| @@ -1641,12 +1648,12 @@ struct page *alloc_huge_page_node(struct hstate *h, int nid) | |||
| 1641 | spin_unlock(&hugetlb_lock); | 1648 | spin_unlock(&hugetlb_lock); |
| 1642 | 1649 | ||
| 1643 | if (!page) | 1650 | if (!page) |
| 1644 | page = __alloc_buddy_huge_page(h, gfp_mask, nid, NULL); | 1651 | page = alloc_migrate_huge_page(h, gfp_mask, nid, NULL); |
| 1645 | 1652 | ||
| 1646 | return page; | 1653 | return page; |
| 1647 | } | 1654 | } |
| 1648 | 1655 | ||
| 1649 | 1656 | /* page migration callback function */ | |
| 1650 | struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid, | 1657 | struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid, |
| 1651 | nodemask_t *nmask) | 1658 | nodemask_t *nmask) |
| 1652 | { | 1659 | { |
| @@ -1664,9 +1671,25 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid, | |||
| 1664 | } | 1671 | } |
| 1665 | spin_unlock(&hugetlb_lock); | 1672 | spin_unlock(&hugetlb_lock); |
| 1666 | 1673 | ||
| 1667 | /* No reservations, try to overcommit */ | 1674 | return alloc_migrate_huge_page(h, gfp_mask, preferred_nid, nmask); |
| 1675 | } | ||
| 1676 | |||
| 1677 | /* mempolicy aware migration callback */ | ||
| 1678 | struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma, | ||
| 1679 | unsigned long address) | ||
| 1680 | { | ||
| 1681 | struct mempolicy *mpol; | ||
| 1682 | nodemask_t *nodemask; | ||
| 1683 | struct page *page; | ||
| 1684 | gfp_t gfp_mask; | ||
| 1685 | int node; | ||
| 1686 | |||
| 1687 | gfp_mask = htlb_alloc_mask(h); | ||
| 1688 | node = huge_node(vma, address, gfp_mask, &mpol, &nodemask); | ||
| 1689 | page = alloc_huge_page_nodemask(h, node, nodemask); | ||
| 1690 | mpol_cond_put(mpol); | ||
| 1668 | 1691 | ||
| 1669 | return __alloc_buddy_huge_page(h, gfp_mask, preferred_nid, nmask); | 1692 | return page; |
| 1670 | } | 1693 | } |
| 1671 | 1694 | ||
| 1672 | /* | 1695 | /* |
| @@ -1694,7 +1717,7 @@ static int gather_surplus_pages(struct hstate *h, int delta) | |||
| 1694 | retry: | 1717 | retry: |
| 1695 | spin_unlock(&hugetlb_lock); | 1718 | spin_unlock(&hugetlb_lock); |
| 1696 | for (i = 0; i < needed; i++) { | 1719 | for (i = 0; i < needed; i++) { |
| 1697 | page = __alloc_buddy_huge_page(h, htlb_alloc_mask(h), | 1720 | page = alloc_surplus_huge_page(h, htlb_alloc_mask(h), |
| 1698 | NUMA_NO_NODE, NULL); | 1721 | NUMA_NO_NODE, NULL); |
| 1699 | if (!page) { | 1722 | if (!page) { |
| 1700 | alloc_ok = false; | 1723 | alloc_ok = false; |
| @@ -2031,7 +2054,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, | |||
| 2031 | page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg); | 2054 | page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg); |
| 2032 | if (!page) { | 2055 | if (!page) { |
| 2033 | spin_unlock(&hugetlb_lock); | 2056 | spin_unlock(&hugetlb_lock); |
| 2034 | page = __alloc_buddy_huge_page_with_mpol(h, vma, addr); | 2057 | page = alloc_buddy_huge_page_with_mpol(h, vma, addr); |
| 2035 | if (!page) | 2058 | if (!page) |
| 2036 | goto out_uncharge_cgroup; | 2059 | goto out_uncharge_cgroup; |
| 2037 | if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) { | 2060 | if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) { |
| @@ -2074,20 +2097,6 @@ out_subpool_put: | |||
| 2074 | return ERR_PTR(-ENOSPC); | 2097 | return ERR_PTR(-ENOSPC); |
| 2075 | } | 2098 | } |
| 2076 | 2099 | ||
| 2077 | /* | ||
| 2078 | * alloc_huge_page()'s wrapper which simply returns the page if allocation | ||
| 2079 | * succeeds, otherwise NULL. This function is called from new_vma_page(), | ||
| 2080 | * where no ERR_VALUE is expected to be returned. | ||
| 2081 | */ | ||
| 2082 | struct page *alloc_huge_page_noerr(struct vm_area_struct *vma, | ||
| 2083 | unsigned long addr, int avoid_reserve) | ||
| 2084 | { | ||
| 2085 | struct page *page = alloc_huge_page(vma, addr, avoid_reserve); | ||
| 2086 | if (IS_ERR(page)) | ||
| 2087 | page = NULL; | ||
| 2088 | return page; | ||
| 2089 | } | ||
| 2090 | |||
| 2091 | int alloc_bootmem_huge_page(struct hstate *h) | 2100 | int alloc_bootmem_huge_page(struct hstate *h) |
| 2092 | __attribute__ ((weak, alias("__alloc_bootmem_huge_page"))); | 2101 | __attribute__ ((weak, alias("__alloc_bootmem_huge_page"))); |
| 2093 | int __alloc_bootmem_huge_page(struct hstate *h) | 2102 | int __alloc_bootmem_huge_page(struct hstate *h) |
| @@ -2150,6 +2159,8 @@ static void __init gather_bootmem_prealloc(void) | |||
| 2150 | prep_compound_huge_page(page, h->order); | 2159 | prep_compound_huge_page(page, h->order); |
| 2151 | WARN_ON(PageReserved(page)); | 2160 | WARN_ON(PageReserved(page)); |
| 2152 | prep_new_huge_page(h, page, page_to_nid(page)); | 2161 | prep_new_huge_page(h, page, page_to_nid(page)); |
| 2162 | put_page(page); /* free it into the hugepage allocator */ | ||
| 2163 | |||
| 2153 | /* | 2164 | /* |
| 2154 | * If we had gigantic hugepages allocated at boot time, we need | 2165 | * If we had gigantic hugepages allocated at boot time, we need |
| 2155 | * to restore the 'stolen' pages to totalram_pages in order to | 2166 | * to restore the 'stolen' pages to totalram_pages in order to |
| @@ -2169,7 +2180,7 @@ static void __init hugetlb_hstate_alloc_pages(struct hstate *h) | |||
| 2169 | if (hstate_is_gigantic(h)) { | 2180 | if (hstate_is_gigantic(h)) { |
| 2170 | if (!alloc_bootmem_huge_page(h)) | 2181 | if (!alloc_bootmem_huge_page(h)) |
| 2171 | break; | 2182 | break; |
| 2172 | } else if (!alloc_fresh_huge_page(h, | 2183 | } else if (!alloc_pool_huge_page(h, |
| 2173 | &node_states[N_MEMORY])) | 2184 | &node_states[N_MEMORY])) |
| 2174 | break; | 2185 | break; |
| 2175 | cond_resched(); | 2186 | cond_resched(); |
| @@ -2289,7 +2300,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, | |||
| 2289 | * First take pages out of surplus state. Then make up the | 2300 | * First take pages out of surplus state. Then make up the |
| 2290 | * remaining difference by allocating fresh huge pages. | 2301 | * remaining difference by allocating fresh huge pages. |
| 2291 | * | 2302 | * |
| 2292 | * We might race with __alloc_buddy_huge_page() here and be unable | 2303 | * We might race with alloc_surplus_huge_page() here and be unable |
| 2293 | * to convert a surplus huge page to a normal huge page. That is | 2304 | * to convert a surplus huge page to a normal huge page. That is |
| 2294 | * not critical, though, it just means the overall size of the | 2305 | * not critical, though, it just means the overall size of the |
| 2295 | * pool might be one hugepage larger than it needs to be, but | 2306 | * pool might be one hugepage larger than it needs to be, but |
| @@ -2312,10 +2323,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, | |||
| 2312 | /* yield cpu to avoid soft lockup */ | 2323 | /* yield cpu to avoid soft lockup */ |
| 2313 | cond_resched(); | 2324 | cond_resched(); |
| 2314 | 2325 | ||
| 2315 | if (hstate_is_gigantic(h)) | 2326 | ret = alloc_pool_huge_page(h, nodes_allowed); |
| 2316 | ret = alloc_fresh_gigantic_page(h, nodes_allowed); | ||
| 2317 | else | ||
| 2318 | ret = alloc_fresh_huge_page(h, nodes_allowed); | ||
| 2319 | spin_lock(&hugetlb_lock); | 2327 | spin_lock(&hugetlb_lock); |
| 2320 | if (!ret) | 2328 | if (!ret) |
| 2321 | goto out; | 2329 | goto out; |
| @@ -2335,7 +2343,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, | |||
| 2335 | * By placing pages into the surplus state independent of the | 2343 | * By placing pages into the surplus state independent of the |
| 2336 | * overcommit value, we are allowing the surplus pool size to | 2344 | * overcommit value, we are allowing the surplus pool size to |
| 2337 | * exceed overcommit. There are few sane options here. Since | 2345 | * exceed overcommit. There are few sane options here. Since |
| 2338 | * __alloc_buddy_huge_page() is checking the global counter, | 2346 | * alloc_surplus_huge_page() is checking the global counter, |
| 2339 | * though, we'll note that we're not allowed to exceed surplus | 2347 | * though, we'll note that we're not allowed to exceed surplus |
| 2340 | * and won't grow the pool anywhere else. Not until one of the | 2348 | * and won't grow the pool anywhere else. Not until one of the |
| 2341 | * sysctls are changed, or the surplus pages go out of use. | 2349 | * sysctls are changed, or the surplus pages go out of use. |
| @@ -2975,20 +2983,32 @@ out: | |||
| 2975 | 2983 | ||
| 2976 | void hugetlb_report_meminfo(struct seq_file *m) | 2984 | void hugetlb_report_meminfo(struct seq_file *m) |
| 2977 | { | 2985 | { |
| 2978 | struct hstate *h = &default_hstate; | 2986 | struct hstate *h; |
| 2987 | unsigned long total = 0; | ||
| 2988 | |||
| 2979 | if (!hugepages_supported()) | 2989 | if (!hugepages_supported()) |
| 2980 | return; | 2990 | return; |
| 2981 | seq_printf(m, | 2991 | |
| 2982 | "HugePages_Total: %5lu\n" | 2992 | for_each_hstate(h) { |
| 2983 | "HugePages_Free: %5lu\n" | 2993 | unsigned long count = h->nr_huge_pages; |
| 2984 | "HugePages_Rsvd: %5lu\n" | 2994 | |
| 2985 | "HugePages_Surp: %5lu\n" | 2995 | total += (PAGE_SIZE << huge_page_order(h)) * count; |
| 2986 | "Hugepagesize: %8lu kB\n", | 2996 | |
| 2987 | h->nr_huge_pages, | 2997 | if (h == &default_hstate) |
| 2988 | h->free_huge_pages, | 2998 | seq_printf(m, |
| 2989 | h->resv_huge_pages, | 2999 | "HugePages_Total: %5lu\n" |
| 2990 | h->surplus_huge_pages, | 3000 | "HugePages_Free: %5lu\n" |
| 2991 | 1UL << (huge_page_order(h) + PAGE_SHIFT - 10)); | 3001 | "HugePages_Rsvd: %5lu\n" |
| 3002 | "HugePages_Surp: %5lu\n" | ||
| 3003 | "Hugepagesize: %8lu kB\n", | ||
| 3004 | count, | ||
| 3005 | h->free_huge_pages, | ||
| 3006 | h->resv_huge_pages, | ||
| 3007 | h->surplus_huge_pages, | ||
| 3008 | (PAGE_SIZE << huge_page_order(h)) / 1024); | ||
| 3009 | } | ||
| 3010 | |||
| 3011 | seq_printf(m, "Hugetlb: %8lu kB\n", total / 1024); | ||
| 2992 | } | 3012 | } |
| 2993 | 3013 | ||
| 2994 | int hugetlb_report_node_meminfo(int nid, char *buf) | 3014 | int hugetlb_report_node_meminfo(int nid, char *buf) |
| @@ -4799,3 +4819,36 @@ void putback_active_hugepage(struct page *page) | |||
| 4799 | spin_unlock(&hugetlb_lock); | 4819 | spin_unlock(&hugetlb_lock); |
| 4800 | put_page(page); | 4820 | put_page(page); |
| 4801 | } | 4821 | } |
| 4822 | |||
| 4823 | void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason) | ||
| 4824 | { | ||
| 4825 | struct hstate *h = page_hstate(oldpage); | ||
| 4826 | |||
| 4827 | hugetlb_cgroup_migrate(oldpage, newpage); | ||
| 4828 | set_page_owner_migrate_reason(newpage, reason); | ||
| 4829 | |||
| 4830 | /* | ||
| 4831 | * transfer temporary state of the new huge page. This is | ||
| 4832 | * reverse to other transitions because the newpage is going to | ||
| 4833 | * be final while the old one will be freed so it takes over | ||
| 4834 | * the temporary status. | ||
| 4835 | * | ||
| 4836 | * Also note that we have to transfer the per-node surplus state | ||
| 4837 | * here as well otherwise the global surplus count will not match | ||
| 4838 | * the per-node's. | ||
| 4839 | */ | ||
| 4840 | if (PageHugeTemporary(newpage)) { | ||
| 4841 | int old_nid = page_to_nid(oldpage); | ||
| 4842 | int new_nid = page_to_nid(newpage); | ||
| 4843 | |||
| 4844 | SetPageHugeTemporary(oldpage); | ||
| 4845 | ClearPageHugeTemporary(newpage); | ||
| 4846 | |||
| 4847 | spin_lock(&hugetlb_lock); | ||
| 4848 | if (h->surplus_huge_pages_node[old_nid]) { | ||
| 4849 | h->surplus_huge_pages_node[old_nid]--; | ||
| 4850 | h->surplus_huge_pages_node[new_nid]++; | ||
| 4851 | } | ||
| 4852 | spin_unlock(&hugetlb_lock); | ||
| 4853 | } | ||
| 4854 | } | ||
diff --git a/mm/interval_tree.c b/mm/interval_tree.c index b47664358796..27ddfd29112a 100644 --- a/mm/interval_tree.c +++ b/mm/interval_tree.c | |||
| @@ -18,7 +18,7 @@ static inline unsigned long vma_start_pgoff(struct vm_area_struct *v) | |||
| 18 | 18 | ||
| 19 | static inline unsigned long vma_last_pgoff(struct vm_area_struct *v) | 19 | static inline unsigned long vma_last_pgoff(struct vm_area_struct *v) |
| 20 | { | 20 | { |
| 21 | return v->vm_pgoff + ((v->vm_end - v->vm_start) >> PAGE_SHIFT) - 1; | 21 | return v->vm_pgoff + vma_pages(v) - 1; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.rb, | 24 | INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.rb, |
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index ea4ff259b671..b7e2268dfc9a 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c | |||
| @@ -1399,8 +1399,7 @@ static void collapse_shmem(struct mm_struct *mm, | |||
| 1399 | } | 1399 | } |
| 1400 | 1400 | ||
| 1401 | if (page_mapped(page)) | 1401 | if (page_mapped(page)) |
| 1402 | unmap_mapping_range(mapping, index << PAGE_SHIFT, | 1402 | unmap_mapping_pages(mapping, index, 1, false); |
| 1403 | PAGE_SIZE, 0); | ||
| 1404 | 1403 | ||
| 1405 | spin_lock_irq(&mapping->tree_lock); | 1404 | spin_lock_irq(&mapping->tree_lock); |
| 1406 | 1405 | ||
| @@ -1674,10 +1673,14 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, | |||
| 1674 | spin_unlock(&khugepaged_mm_lock); | 1673 | spin_unlock(&khugepaged_mm_lock); |
| 1675 | 1674 | ||
| 1676 | mm = mm_slot->mm; | 1675 | mm = mm_slot->mm; |
| 1677 | down_read(&mm->mmap_sem); | 1676 | /* |
| 1678 | if (unlikely(khugepaged_test_exit(mm))) | 1677 | * Don't wait for semaphore (to avoid long wait times). Just move to |
| 1679 | vma = NULL; | 1678 | * the next mm on the list. |
| 1680 | else | 1679 | */ |
| 1680 | vma = NULL; | ||
| 1681 | if (unlikely(!down_read_trylock(&mm->mmap_sem))) | ||
| 1682 | goto breakouterloop_mmap_sem; | ||
| 1683 | if (likely(!khugepaged_test_exit(mm))) | ||
| 1681 | vma = find_vma(mm, khugepaged_scan.address); | 1684 | vma = find_vma(mm, khugepaged_scan.address); |
| 1682 | 1685 | ||
| 1683 | progress++; | 1686 | progress++; |
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index f656ca27f6c2..e83987c55a08 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
| @@ -91,7 +91,6 @@ | |||
| 91 | #include <linux/stacktrace.h> | 91 | #include <linux/stacktrace.h> |
| 92 | #include <linux/cache.h> | 92 | #include <linux/cache.h> |
| 93 | #include <linux/percpu.h> | 93 | #include <linux/percpu.h> |
| 94 | #include <linux/hardirq.h> | ||
| 95 | #include <linux/bootmem.h> | 94 | #include <linux/bootmem.h> |
| 96 | #include <linux/pfn.h> | 95 | #include <linux/pfn.h> |
| 97 | #include <linux/mmzone.h> | 96 | #include <linux/mmzone.h> |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 9011997d8a5c..0ae2dc3a1748 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -542,39 +542,10 @@ mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz) | |||
| 542 | return mz; | 542 | return mz; |
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | /* | ||
| 546 | * Return page count for single (non recursive) @memcg. | ||
| 547 | * | ||
| 548 | * Implementation Note: reading percpu statistics for memcg. | ||
| 549 | * | ||
| 550 | * Both of vmstat[] and percpu_counter has threshold and do periodic | ||
| 551 | * synchronization to implement "quick" read. There are trade-off between | ||
| 552 | * reading cost and precision of value. Then, we may have a chance to implement | ||
| 553 | * a periodic synchronization of counter in memcg's counter. | ||
| 554 | * | ||
| 555 | * But this _read() function is used for user interface now. The user accounts | ||
| 556 | * memory usage by memory cgroup and he _always_ requires exact value because | ||
| 557 | * he accounts memory. Even if we provide quick-and-fuzzy read, we always | ||
| 558 | * have to visit all online cpus and make sum. So, for now, unnecessary | ||
| 559 | * synchronization is not implemented. (just implemented for cpu hotplug) | ||
| 560 | * | ||
| 561 | * If there are kernel internal actions which can make use of some not-exact | ||
| 562 | * value, and reading all cpu value can be performance bottleneck in some | ||
| 563 | * common workload, threshold and synchronization as vmstat[] should be | ||
| 564 | * implemented. | ||
| 565 | * | ||
| 566 | * The parameter idx can be of type enum memcg_event_item or vm_event_item. | ||
| 567 | */ | ||
| 568 | |||
| 569 | static unsigned long memcg_sum_events(struct mem_cgroup *memcg, | 545 | static unsigned long memcg_sum_events(struct mem_cgroup *memcg, |
| 570 | int event) | 546 | int event) |
| 571 | { | 547 | { |
| 572 | unsigned long val = 0; | 548 | return atomic_long_read(&memcg->events[event]); |
| 573 | int cpu; | ||
| 574 | |||
| 575 | for_each_possible_cpu(cpu) | ||
| 576 | val += per_cpu(memcg->stat->events[event], cpu); | ||
| 577 | return val; | ||
| 578 | } | 549 | } |
| 579 | 550 | ||
| 580 | static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg, | 551 | static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg, |
| @@ -586,27 +557,27 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg, | |||
| 586 | * counted as CACHE even if it's on ANON LRU. | 557 | * counted as CACHE even if it's on ANON LRU. |
| 587 | */ | 558 | */ |
| 588 | if (PageAnon(page)) | 559 | if (PageAnon(page)) |
| 589 | __this_cpu_add(memcg->stat->count[MEMCG_RSS], nr_pages); | 560 | __mod_memcg_state(memcg, MEMCG_RSS, nr_pages); |
| 590 | else { | 561 | else { |
| 591 | __this_cpu_add(memcg->stat->count[MEMCG_CACHE], nr_pages); | 562 | __mod_memcg_state(memcg, MEMCG_CACHE, nr_pages); |
| 592 | if (PageSwapBacked(page)) | 563 | if (PageSwapBacked(page)) |
| 593 | __this_cpu_add(memcg->stat->count[NR_SHMEM], nr_pages); | 564 | __mod_memcg_state(memcg, NR_SHMEM, nr_pages); |
| 594 | } | 565 | } |
| 595 | 566 | ||
| 596 | if (compound) { | 567 | if (compound) { |
| 597 | VM_BUG_ON_PAGE(!PageTransHuge(page), page); | 568 | VM_BUG_ON_PAGE(!PageTransHuge(page), page); |
| 598 | __this_cpu_add(memcg->stat->count[MEMCG_RSS_HUGE], nr_pages); | 569 | __mod_memcg_state(memcg, MEMCG_RSS_HUGE, nr_pages); |
| 599 | } | 570 | } |
| 600 | 571 | ||
| 601 | /* pagein of a big page is an event. So, ignore page size */ | 572 | /* pagein of a big page is an event. So, ignore page size */ |
| 602 | if (nr_pages > 0) | 573 | if (nr_pages > 0) |
| 603 | __this_cpu_inc(memcg->stat->events[PGPGIN]); | 574 | __count_memcg_events(memcg, PGPGIN, 1); |
| 604 | else { | 575 | else { |
| 605 | __this_cpu_inc(memcg->stat->events[PGPGOUT]); | 576 | __count_memcg_events(memcg, PGPGOUT, 1); |
| 606 | nr_pages = -nr_pages; /* for event */ | 577 | nr_pages = -nr_pages; /* for event */ |
| 607 | } | 578 | } |
| 608 | 579 | ||
| 609 | __this_cpu_add(memcg->stat->nr_page_events, nr_pages); | 580 | __this_cpu_add(memcg->stat_cpu->nr_page_events, nr_pages); |
| 610 | } | 581 | } |
| 611 | 582 | ||
| 612 | unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg, | 583 | unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg, |
| @@ -642,8 +613,8 @@ static bool mem_cgroup_event_ratelimit(struct mem_cgroup *memcg, | |||
| 642 | { | 613 | { |
| 643 | unsigned long val, next; | 614 | unsigned long val, next; |
| 644 | 615 | ||
| 645 | val = __this_cpu_read(memcg->stat->nr_page_events); | 616 | val = __this_cpu_read(memcg->stat_cpu->nr_page_events); |
| 646 | next = __this_cpu_read(memcg->stat->targets[target]); | 617 | next = __this_cpu_read(memcg->stat_cpu->targets[target]); |
| 647 | /* from time_after() in jiffies.h */ | 618 | /* from time_after() in jiffies.h */ |
| 648 | if ((long)(next - val) < 0) { | 619 | if ((long)(next - val) < 0) { |
| 649 | switch (target) { | 620 | switch (target) { |
| @@ -659,7 +630,7 @@ static bool mem_cgroup_event_ratelimit(struct mem_cgroup *memcg, | |||
| 659 | default: | 630 | default: |
| 660 | break; | 631 | break; |
| 661 | } | 632 | } |
| 662 | __this_cpu_write(memcg->stat->targets[target], next); | 633 | __this_cpu_write(memcg->stat_cpu->targets[target], next); |
| 663 | return true; | 634 | return true; |
| 664 | } | 635 | } |
| 665 | return false; | 636 | return false; |
| @@ -1124,7 +1095,7 @@ static bool mem_cgroup_wait_acct_move(struct mem_cgroup *memcg) | |||
| 1124 | return false; | 1095 | return false; |
| 1125 | } | 1096 | } |
| 1126 | 1097 | ||
| 1127 | unsigned int memcg1_stats[] = { | 1098 | static const unsigned int memcg1_stats[] = { |
| 1128 | MEMCG_CACHE, | 1099 | MEMCG_CACHE, |
| 1129 | MEMCG_RSS, | 1100 | MEMCG_RSS, |
| 1130 | MEMCG_RSS_HUGE, | 1101 | MEMCG_RSS_HUGE, |
| @@ -1206,20 +1177,6 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) | |||
| 1206 | } | 1177 | } |
| 1207 | 1178 | ||
| 1208 | /* | 1179 | /* |
| 1209 | * This function returns the number of memcg under hierarchy tree. Returns | ||
| 1210 | * 1(self count) if no children. | ||
| 1211 | */ | ||
| 1212 | static int mem_cgroup_count_children(struct mem_cgroup *memcg) | ||
| 1213 | { | ||
| 1214 | int num = 0; | ||
| 1215 | struct mem_cgroup *iter; | ||
| 1216 | |||
| 1217 | for_each_mem_cgroup_tree(iter, memcg) | ||
| 1218 | num++; | ||
| 1219 | return num; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | /* | ||
| 1223 | * Return the memory (and swap, if configured) limit for a memcg. | 1180 | * Return the memory (and swap, if configured) limit for a memcg. |
| 1224 | */ | 1181 | */ |
| 1225 | unsigned long mem_cgroup_get_limit(struct mem_cgroup *memcg) | 1182 | unsigned long mem_cgroup_get_limit(struct mem_cgroup *memcg) |
| @@ -1707,11 +1664,6 @@ void unlock_page_memcg(struct page *page) | |||
| 1707 | } | 1664 | } |
| 1708 | EXPORT_SYMBOL(unlock_page_memcg); | 1665 | EXPORT_SYMBOL(unlock_page_memcg); |
| 1709 | 1666 | ||
| 1710 | /* | ||
| 1711 | * size of first charge trial. "32" comes from vmscan.c's magic value. | ||
| 1712 | * TODO: maybe necessary to use big numbers in big irons. | ||
| 1713 | */ | ||
| 1714 | #define CHARGE_BATCH 32U | ||
| 1715 | struct memcg_stock_pcp { | 1667 | struct memcg_stock_pcp { |
| 1716 | struct mem_cgroup *cached; /* this never be root cgroup */ | 1668 | struct mem_cgroup *cached; /* this never be root cgroup */ |
| 1717 | unsigned int nr_pages; | 1669 | unsigned int nr_pages; |
| @@ -1739,7 +1691,7 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) | |||
| 1739 | unsigned long flags; | 1691 | unsigned long flags; |
| 1740 | bool ret = false; | 1692 | bool ret = false; |
| 1741 | 1693 | ||
| 1742 | if (nr_pages > CHARGE_BATCH) | 1694 | if (nr_pages > MEMCG_CHARGE_BATCH) |
| 1743 | return ret; | 1695 | return ret; |
| 1744 | 1696 | ||
| 1745 | local_irq_save(flags); | 1697 | local_irq_save(flags); |
| @@ -1808,7 +1760,7 @@ static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) | |||
| 1808 | } | 1760 | } |
| 1809 | stock->nr_pages += nr_pages; | 1761 | stock->nr_pages += nr_pages; |
| 1810 | 1762 | ||
| 1811 | if (stock->nr_pages > CHARGE_BATCH) | 1763 | if (stock->nr_pages > MEMCG_CHARGE_BATCH) |
| 1812 | drain_stock(stock); | 1764 | drain_stock(stock); |
| 1813 | 1765 | ||
| 1814 | local_irq_restore(flags); | 1766 | local_irq_restore(flags); |
| @@ -1858,9 +1810,44 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) | |||
| 1858 | static int memcg_hotplug_cpu_dead(unsigned int cpu) | 1810 | static int memcg_hotplug_cpu_dead(unsigned int cpu) |
| 1859 | { | 1811 | { |
| 1860 | struct memcg_stock_pcp *stock; | 1812 | struct memcg_stock_pcp *stock; |
| 1813 | struct mem_cgroup *memcg; | ||
| 1861 | 1814 | ||
| 1862 | stock = &per_cpu(memcg_stock, cpu); | 1815 | stock = &per_cpu(memcg_stock, cpu); |
| 1863 | drain_stock(stock); | 1816 | drain_stock(stock); |
| 1817 | |||
| 1818 | for_each_mem_cgroup(memcg) { | ||
| 1819 | int i; | ||
| 1820 | |||
| 1821 | for (i = 0; i < MEMCG_NR_STAT; i++) { | ||
| 1822 | int nid; | ||
| 1823 | long x; | ||
| 1824 | |||
| 1825 | x = this_cpu_xchg(memcg->stat_cpu->count[i], 0); | ||
| 1826 | if (x) | ||
| 1827 | atomic_long_add(x, &memcg->stat[i]); | ||
| 1828 | |||
| 1829 | if (i >= NR_VM_NODE_STAT_ITEMS) | ||
| 1830 | continue; | ||
| 1831 | |||
| 1832 | for_each_node(nid) { | ||
| 1833 | struct mem_cgroup_per_node *pn; | ||
| 1834 | |||
| 1835 | pn = mem_cgroup_nodeinfo(memcg, nid); | ||
| 1836 | x = this_cpu_xchg(pn->lruvec_stat_cpu->count[i], 0); | ||
| 1837 | if (x) | ||
| 1838 | atomic_long_add(x, &pn->lruvec_stat[i]); | ||
| 1839 | } | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | for (i = 0; i < MEMCG_NR_EVENTS; i++) { | ||
| 1843 | long x; | ||
| 1844 | |||
| 1845 | x = this_cpu_xchg(memcg->stat_cpu->events[i], 0); | ||
| 1846 | if (x) | ||
| 1847 | atomic_long_add(x, &memcg->events[i]); | ||
| 1848 | } | ||
| 1849 | } | ||
| 1850 | |||
| 1864 | return 0; | 1851 | return 0; |
| 1865 | } | 1852 | } |
| 1866 | 1853 | ||
| @@ -1881,7 +1868,7 @@ static void high_work_func(struct work_struct *work) | |||
| 1881 | struct mem_cgroup *memcg; | 1868 | struct mem_cgroup *memcg; |
| 1882 | 1869 | ||
| 1883 | memcg = container_of(work, struct mem_cgroup, high_work); | 1870 | memcg = container_of(work, struct mem_cgroup, high_work); |
| 1884 | reclaim_high(memcg, CHARGE_BATCH, GFP_KERNEL); | 1871 | reclaim_high(memcg, MEMCG_CHARGE_BATCH, GFP_KERNEL); |
| 1885 | } | 1872 | } |
| 1886 | 1873 | ||
| 1887 | /* | 1874 | /* |
| @@ -1905,7 +1892,7 @@ void mem_cgroup_handle_over_high(void) | |||
| 1905 | static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, | 1892 | static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, |
| 1906 | unsigned int nr_pages) | 1893 | unsigned int nr_pages) |
| 1907 | { | 1894 | { |
| 1908 | unsigned int batch = max(CHARGE_BATCH, nr_pages); | 1895 | unsigned int batch = max(MEMCG_CHARGE_BATCH, nr_pages); |
| 1909 | int nr_retries = MEM_CGROUP_RECLAIM_RETRIES; | 1896 | int nr_retries = MEM_CGROUP_RECLAIM_RETRIES; |
| 1910 | struct mem_cgroup *mem_over_limit; | 1897 | struct mem_cgroup *mem_over_limit; |
| 1911 | struct page_counter *counter; | 1898 | struct page_counter *counter; |
| @@ -2415,18 +2402,11 @@ void mem_cgroup_split_huge_fixup(struct page *head) | |||
| 2415 | for (i = 1; i < HPAGE_PMD_NR; i++) | 2402 | for (i = 1; i < HPAGE_PMD_NR; i++) |
| 2416 | head[i].mem_cgroup = head->mem_cgroup; | 2403 | head[i].mem_cgroup = head->mem_cgroup; |
| 2417 | 2404 | ||
| 2418 | __this_cpu_sub(head->mem_cgroup->stat->count[MEMCG_RSS_HUGE], | 2405 | __mod_memcg_state(head->mem_cgroup, MEMCG_RSS_HUGE, -HPAGE_PMD_NR); |
| 2419 | HPAGE_PMD_NR); | ||
| 2420 | } | 2406 | } |
| 2421 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 2407 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| 2422 | 2408 | ||
| 2423 | #ifdef CONFIG_MEMCG_SWAP | 2409 | #ifdef CONFIG_MEMCG_SWAP |
| 2424 | static void mem_cgroup_swap_statistics(struct mem_cgroup *memcg, | ||
| 2425 | int nr_entries) | ||
| 2426 | { | ||
| 2427 | this_cpu_add(memcg->stat->count[MEMCG_SWAP], nr_entries); | ||
| 2428 | } | ||
| 2429 | |||
| 2430 | /** | 2410 | /** |
| 2431 | * mem_cgroup_move_swap_account - move swap charge and swap_cgroup's record. | 2411 | * mem_cgroup_move_swap_account - move swap charge and swap_cgroup's record. |
| 2432 | * @entry: swap entry to be moved | 2412 | * @entry: swap entry to be moved |
| @@ -2450,8 +2430,8 @@ static int mem_cgroup_move_swap_account(swp_entry_t entry, | |||
| 2450 | new_id = mem_cgroup_id(to); | 2430 | new_id = mem_cgroup_id(to); |
| 2451 | 2431 | ||
| 2452 | if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) { | 2432 | if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) { |
| 2453 | mem_cgroup_swap_statistics(from, -1); | 2433 | mod_memcg_state(from, MEMCG_SWAP, -1); |
| 2454 | mem_cgroup_swap_statistics(to, 1); | 2434 | mod_memcg_state(to, MEMCG_SWAP, 1); |
| 2455 | return 0; | 2435 | return 0; |
| 2456 | } | 2436 | } |
| 2457 | return -EINVAL; | 2437 | return -EINVAL; |
| @@ -2467,23 +2447,12 @@ static inline int mem_cgroup_move_swap_account(swp_entry_t entry, | |||
| 2467 | static DEFINE_MUTEX(memcg_limit_mutex); | 2447 | static DEFINE_MUTEX(memcg_limit_mutex); |
| 2468 | 2448 | ||
| 2469 | static int mem_cgroup_resize_limit(struct mem_cgroup *memcg, | 2449 | static int mem_cgroup_resize_limit(struct mem_cgroup *memcg, |
| 2470 | unsigned long limit) | 2450 | unsigned long limit, bool memsw) |
| 2471 | { | 2451 | { |
| 2472 | unsigned long curusage; | ||
| 2473 | unsigned long oldusage; | ||
| 2474 | bool enlarge = false; | 2452 | bool enlarge = false; |
| 2475 | int retry_count; | ||
| 2476 | int ret; | 2453 | int ret; |
| 2477 | 2454 | bool limits_invariant; | |
| 2478 | /* | 2455 | struct page_counter *counter = memsw ? &memcg->memsw : &memcg->memory; |
| 2479 | * For keeping hierarchical_reclaim simple, how long we should retry | ||
| 2480 | * is depends on callers. We set our retry-count to be function | ||
| 2481 | * of # of children which we should visit in this loop. | ||
| 2482 | */ | ||
| 2483 | retry_count = MEM_CGROUP_RECLAIM_RETRIES * | ||
| 2484 | mem_cgroup_count_children(memcg); | ||
| 2485 | |||
| 2486 | oldusage = page_counter_read(&memcg->memory); | ||
| 2487 | 2456 | ||
| 2488 | do { | 2457 | do { |
| 2489 | if (signal_pending(current)) { | 2458 | if (signal_pending(current)) { |
| @@ -2492,79 +2461,31 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg, | |||
| 2492 | } | 2461 | } |
| 2493 | 2462 | ||
| 2494 | mutex_lock(&memcg_limit_mutex); | 2463 | mutex_lock(&memcg_limit_mutex); |
| 2495 | if (limit > memcg->memsw.limit) { | 2464 | /* |
| 2465 | * Make sure that the new limit (memsw or memory limit) doesn't | ||
| 2466 | * break our basic invariant rule memory.limit <= memsw.limit. | ||
| 2467 | */ | ||
| 2468 | limits_invariant = memsw ? limit >= memcg->memory.limit : | ||
| 2469 | limit <= memcg->memsw.limit; | ||
| 2470 | if (!limits_invariant) { | ||
| 2496 | mutex_unlock(&memcg_limit_mutex); | 2471 | mutex_unlock(&memcg_limit_mutex); |
| 2497 | ret = -EINVAL; | 2472 | ret = -EINVAL; |
| 2498 | break; | 2473 | break; |
| 2499 | } | 2474 | } |
| 2500 | if (limit > memcg->memory.limit) | 2475 | if (limit > counter->limit) |
| 2501 | enlarge = true; | 2476 | enlarge = true; |
| 2502 | ret = page_counter_limit(&memcg->memory, limit); | 2477 | ret = page_counter_limit(counter, limit); |
| 2503 | mutex_unlock(&memcg_limit_mutex); | 2478 | mutex_unlock(&memcg_limit_mutex); |
| 2504 | 2479 | ||
| 2505 | if (!ret) | 2480 | if (!ret) |
| 2506 | break; | 2481 | break; |
| 2507 | 2482 | ||
| 2508 | try_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL, true); | 2483 | if (!try_to_free_mem_cgroup_pages(memcg, 1, |
| 2509 | 2484 | GFP_KERNEL, !memsw)) { | |
| 2510 | curusage = page_counter_read(&memcg->memory); | 2485 | ret = -EBUSY; |
| 2511 | /* Usage is reduced ? */ | ||
| 2512 | if (curusage >= oldusage) | ||
| 2513 | retry_count--; | ||
| 2514 | else | ||
| 2515 | oldusage = curusage; | ||
| 2516 | } while (retry_count); | ||
| 2517 | |||
| 2518 | if (!ret && enlarge) | ||
| 2519 | memcg_oom_recover(memcg); | ||
| 2520 | |||
| 2521 | return ret; | ||
| 2522 | } | ||
| 2523 | |||
| 2524 | static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg, | ||
| 2525 | unsigned long limit) | ||
| 2526 | { | ||
| 2527 | unsigned long curusage; | ||
| 2528 | unsigned long oldusage; | ||
| 2529 | bool enlarge = false; | ||
| 2530 | int retry_count; | ||
| 2531 | int ret; | ||
| 2532 | |||
| 2533 | /* see mem_cgroup_resize_res_limit */ | ||
| 2534 | retry_count = MEM_CGROUP_RECLAIM_RETRIES * | ||
| 2535 | mem_cgroup_count_children(memcg); | ||
| 2536 | |||
| 2537 | oldusage = page_counter_read(&memcg->memsw); | ||
| 2538 | |||
| 2539 | do { | ||
| 2540 | if (signal_pending(current)) { | ||
| 2541 | ret = -EINTR; | ||
| 2542 | break; | 2486 | break; |
| 2543 | } | 2487 | } |
| 2544 | 2488 | } while (true); | |
| 2545 | mutex_lock(&memcg_limit_mutex); | ||
| 2546 | if (limit < memcg->memory.limit) { | ||
| 2547 | mutex_unlock(&memcg_limit_mutex); | ||
| 2548 | ret = -EINVAL; | ||
| 2549 | break; | ||
| 2550 | } | ||
| 2551 | if (limit > memcg->memsw.limit) | ||
| 2552 | enlarge = true; | ||
| 2553 | ret = page_counter_limit(&memcg->memsw, limit); | ||
| 2554 | mutex_unlock(&memcg_limit_mutex); | ||
| 2555 | |||
| 2556 | if (!ret) | ||
| 2557 | break; | ||
| 2558 | |||
| 2559 | try_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL, false); | ||
| 2560 | |||
| 2561 | curusage = page_counter_read(&memcg->memsw); | ||
| 2562 | /* Usage is reduced ? */ | ||
| 2563 | if (curusage >= oldusage) | ||
| 2564 | retry_count--; | ||
| 2565 | else | ||
| 2566 | oldusage = curusage; | ||
| 2567 | } while (retry_count); | ||
| 2568 | 2489 | ||
| 2569 | if (!ret && enlarge) | 2490 | if (!ret && enlarge) |
| 2570 | memcg_oom_recover(memcg); | 2491 | memcg_oom_recover(memcg); |
| @@ -3020,10 +2941,10 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of, | |||
| 3020 | } | 2941 | } |
| 3021 | switch (MEMFILE_TYPE(of_cft(of)->private)) { | 2942 | switch (MEMFILE_TYPE(of_cft(of)->private)) { |
| 3022 | case _MEM: | 2943 | case _MEM: |
| 3023 | ret = mem_cgroup_resize_limit(memcg, nr_pages); | 2944 | ret = mem_cgroup_resize_limit(memcg, nr_pages, false); |
| 3024 | break; | 2945 | break; |
| 3025 | case _MEMSWAP: | 2946 | case _MEMSWAP: |
| 3026 | ret = mem_cgroup_resize_memsw_limit(memcg, nr_pages); | 2947 | ret = mem_cgroup_resize_limit(memcg, nr_pages, true); |
| 3027 | break; | 2948 | break; |
| 3028 | case _KMEM: | 2949 | case _KMEM: |
| 3029 | ret = memcg_update_kmem_limit(memcg, nr_pages); | 2950 | ret = memcg_update_kmem_limit(memcg, nr_pages); |
| @@ -4168,8 +4089,8 @@ static int alloc_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) | |||
| 4168 | if (!pn) | 4089 | if (!pn) |
| 4169 | return 1; | 4090 | return 1; |
| 4170 | 4091 | ||
| 4171 | pn->lruvec_stat = alloc_percpu(struct lruvec_stat); | 4092 | pn->lruvec_stat_cpu = alloc_percpu(struct lruvec_stat); |
| 4172 | if (!pn->lruvec_stat) { | 4093 | if (!pn->lruvec_stat_cpu) { |
| 4173 | kfree(pn); | 4094 | kfree(pn); |
| 4174 | return 1; | 4095 | return 1; |
| 4175 | } | 4096 | } |
| @@ -4187,7 +4108,7 @@ static void free_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) | |||
| 4187 | { | 4108 | { |
| 4188 | struct mem_cgroup_per_node *pn = memcg->nodeinfo[node]; | 4109 | struct mem_cgroup_per_node *pn = memcg->nodeinfo[node]; |
| 4189 | 4110 | ||
| 4190 | free_percpu(pn->lruvec_stat); | 4111 | free_percpu(pn->lruvec_stat_cpu); |
| 4191 | kfree(pn); | 4112 | kfree(pn); |
| 4192 | } | 4113 | } |
| 4193 | 4114 | ||
| @@ -4197,7 +4118,7 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) | |||
| 4197 | 4118 | ||
| 4198 | for_each_node(node) | 4119 | for_each_node(node) |
| 4199 | free_mem_cgroup_per_node_info(memcg, node); | 4120 | free_mem_cgroup_per_node_info(memcg, node); |
| 4200 | free_percpu(memcg->stat); | 4121 | free_percpu(memcg->stat_cpu); |
| 4201 | kfree(memcg); | 4122 | kfree(memcg); |
| 4202 | } | 4123 | } |
| 4203 | 4124 | ||
| @@ -4226,8 +4147,8 @@ static struct mem_cgroup *mem_cgroup_alloc(void) | |||
| 4226 | if (memcg->id.id < 0) | 4147 | if (memcg->id.id < 0) |
| 4227 | goto fail; | 4148 | goto fail; |
| 4228 | 4149 | ||
| 4229 | memcg->stat = alloc_percpu(struct mem_cgroup_stat_cpu); | 4150 | memcg->stat_cpu = alloc_percpu(struct mem_cgroup_stat_cpu); |
| 4230 | if (!memcg->stat) | 4151 | if (!memcg->stat_cpu) |
| 4231 | goto fail; | 4152 | goto fail; |
| 4232 | 4153 | ||
| 4233 | for_each_node(node) | 4154 | for_each_node(node) |
| @@ -4584,8 +4505,8 @@ static int mem_cgroup_move_account(struct page *page, | |||
| 4584 | spin_lock_irqsave(&from->move_lock, flags); | 4505 | spin_lock_irqsave(&from->move_lock, flags); |
| 4585 | 4506 | ||
| 4586 | if (!anon && page_mapped(page)) { | 4507 | if (!anon && page_mapped(page)) { |
| 4587 | __this_cpu_sub(from->stat->count[NR_FILE_MAPPED], nr_pages); | 4508 | __mod_memcg_state(from, NR_FILE_MAPPED, -nr_pages); |
| 4588 | __this_cpu_add(to->stat->count[NR_FILE_MAPPED], nr_pages); | 4509 | __mod_memcg_state(to, NR_FILE_MAPPED, nr_pages); |
| 4589 | } | 4510 | } |
| 4590 | 4511 | ||
| 4591 | /* | 4512 | /* |
| @@ -4597,16 +4518,14 @@ static int mem_cgroup_move_account(struct page *page, | |||
| 4597 | struct address_space *mapping = page_mapping(page); | 4518 | struct address_space *mapping = page_mapping(page); |
| 4598 | 4519 | ||
| 4599 | if (mapping_cap_account_dirty(mapping)) { | 4520 | if (mapping_cap_account_dirty(mapping)) { |
| 4600 | __this_cpu_sub(from->stat->count[NR_FILE_DIRTY], | 4521 | __mod_memcg_state(from, NR_FILE_DIRTY, -nr_pages); |
| 4601 | nr_pages); | 4522 | __mod_memcg_state(to, NR_FILE_DIRTY, nr_pages); |
| 4602 | __this_cpu_add(to->stat->count[NR_FILE_DIRTY], | ||
| 4603 | nr_pages); | ||
| 4604 | } | 4523 | } |
| 4605 | } | 4524 | } |
| 4606 | 4525 | ||
| 4607 | if (PageWriteback(page)) { | 4526 | if (PageWriteback(page)) { |
| 4608 | __this_cpu_sub(from->stat->count[NR_WRITEBACK], nr_pages); | 4527 | __mod_memcg_state(from, NR_WRITEBACK, -nr_pages); |
| 4609 | __this_cpu_add(to->stat->count[NR_WRITEBACK], nr_pages); | 4528 | __mod_memcg_state(to, NR_WRITEBACK, nr_pages); |
| 4610 | } | 4529 | } |
| 4611 | 4530 | ||
| 4612 | /* | 4531 | /* |
| @@ -5642,12 +5561,12 @@ static void uncharge_batch(const struct uncharge_gather *ug) | |||
| 5642 | } | 5561 | } |
| 5643 | 5562 | ||
| 5644 | local_irq_save(flags); | 5563 | local_irq_save(flags); |
| 5645 | __this_cpu_sub(ug->memcg->stat->count[MEMCG_RSS], ug->nr_anon); | 5564 | __mod_memcg_state(ug->memcg, MEMCG_RSS, -ug->nr_anon); |
| 5646 | __this_cpu_sub(ug->memcg->stat->count[MEMCG_CACHE], ug->nr_file); | 5565 | __mod_memcg_state(ug->memcg, MEMCG_CACHE, -ug->nr_file); |
| 5647 | __this_cpu_sub(ug->memcg->stat->count[MEMCG_RSS_HUGE], ug->nr_huge); | 5566 | __mod_memcg_state(ug->memcg, MEMCG_RSS_HUGE, -ug->nr_huge); |
| 5648 | __this_cpu_sub(ug->memcg->stat->count[NR_SHMEM], ug->nr_shmem); | 5567 | __mod_memcg_state(ug->memcg, NR_SHMEM, -ug->nr_shmem); |
| 5649 | __this_cpu_add(ug->memcg->stat->events[PGPGOUT], ug->pgpgout); | 5568 | __count_memcg_events(ug->memcg, PGPGOUT, ug->pgpgout); |
| 5650 | __this_cpu_add(ug->memcg->stat->nr_page_events, nr_pages); | 5569 | __this_cpu_add(ug->memcg->stat_cpu->nr_page_events, nr_pages); |
| 5651 | memcg_check_events(ug->memcg, ug->dummy_page); | 5570 | memcg_check_events(ug->memcg, ug->dummy_page); |
| 5652 | local_irq_restore(flags); | 5571 | local_irq_restore(flags); |
| 5653 | 5572 | ||
| @@ -5874,7 +5793,7 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) | |||
| 5874 | if (in_softirq()) | 5793 | if (in_softirq()) |
| 5875 | gfp_mask = GFP_NOWAIT; | 5794 | gfp_mask = GFP_NOWAIT; |
| 5876 | 5795 | ||
| 5877 | this_cpu_add(memcg->stat->count[MEMCG_SOCK], nr_pages); | 5796 | mod_memcg_state(memcg, MEMCG_SOCK, nr_pages); |
| 5878 | 5797 | ||
| 5879 | if (try_charge(memcg, gfp_mask, nr_pages) == 0) | 5798 | if (try_charge(memcg, gfp_mask, nr_pages) == 0) |
| 5880 | return true; | 5799 | return true; |
| @@ -5895,7 +5814,7 @@ void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages) | |||
| 5895 | return; | 5814 | return; |
| 5896 | } | 5815 | } |
| 5897 | 5816 | ||
| 5898 | this_cpu_sub(memcg->stat->count[MEMCG_SOCK], nr_pages); | 5817 | mod_memcg_state(memcg, MEMCG_SOCK, -nr_pages); |
| 5899 | 5818 | ||
| 5900 | refill_stock(memcg, nr_pages); | 5819 | refill_stock(memcg, nr_pages); |
| 5901 | } | 5820 | } |
| @@ -6019,7 +5938,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) | |||
| 6019 | oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), | 5938 | oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), |
| 6020 | nr_entries); | 5939 | nr_entries); |
| 6021 | VM_BUG_ON_PAGE(oldid, page); | 5940 | VM_BUG_ON_PAGE(oldid, page); |
| 6022 | mem_cgroup_swap_statistics(swap_memcg, nr_entries); | 5941 | mod_memcg_state(swap_memcg, MEMCG_SWAP, nr_entries); |
| 6023 | 5942 | ||
| 6024 | page->mem_cgroup = NULL; | 5943 | page->mem_cgroup = NULL; |
| 6025 | 5944 | ||
| @@ -6085,7 +6004,7 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry) | |||
| 6085 | mem_cgroup_id_get_many(memcg, nr_pages - 1); | 6004 | mem_cgroup_id_get_many(memcg, nr_pages - 1); |
| 6086 | oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg), nr_pages); | 6005 | oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg), nr_pages); |
| 6087 | VM_BUG_ON_PAGE(oldid, page); | 6006 | VM_BUG_ON_PAGE(oldid, page); |
| 6088 | mem_cgroup_swap_statistics(memcg, nr_pages); | 6007 | mod_memcg_state(memcg, MEMCG_SWAP, nr_pages); |
| 6089 | 6008 | ||
| 6090 | return 0; | 6009 | return 0; |
| 6091 | } | 6010 | } |
| @@ -6113,7 +6032,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages) | |||
| 6113 | else | 6032 | else |
| 6114 | page_counter_uncharge(&memcg->memsw, nr_pages); | 6033 | page_counter_uncharge(&memcg->memsw, nr_pages); |
| 6115 | } | 6034 | } |
| 6116 | mem_cgroup_swap_statistics(memcg, -nr_pages); | 6035 | mod_memcg_state(memcg, MEMCG_SWAP, -nr_pages); |
| 6117 | mem_cgroup_id_put_many(memcg, nr_pages); | 6036 | mem_cgroup_id_put_many(memcg, nr_pages); |
| 6118 | } | 6037 | } |
| 6119 | rcu_read_unlock(); | 6038 | rcu_read_unlock(); |
diff --git a/mm/memory.c b/mm/memory.c index 793004608332..53373b7a1512 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -400,10 +400,17 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table) | |||
| 400 | 400 | ||
| 401 | #endif /* CONFIG_HAVE_RCU_TABLE_FREE */ | 401 | #endif /* CONFIG_HAVE_RCU_TABLE_FREE */ |
| 402 | 402 | ||
| 403 | /* tlb_gather_mmu | 403 | /** |
| 404 | * Called to initialize an (on-stack) mmu_gather structure for page-table | 404 | * tlb_gather_mmu - initialize an mmu_gather structure for page-table tear-down |
| 405 | * tear-down from @mm. The @fullmm argument is used when @mm is without | 405 | * @tlb: the mmu_gather structure to initialize |
| 406 | * users and we're going to destroy the full address space (exit/execve). | 406 | * @mm: the mm_struct of the target address space |
| 407 | * @start: start of the region that will be removed from the page-table | ||
| 408 | * @end: end of the region that will be removed from the page-table | ||
| 409 | * | ||
| 410 | * Called to initialize an (on-stack) mmu_gather structure for page-table | ||
| 411 | * tear-down from @mm. The @start and @end are set to 0 and -1 | ||
| 412 | * respectively when @mm is without users and we're going to destroy | ||
| 413 | * the full address space (exit/execve). | ||
| 407 | */ | 414 | */ |
| 408 | void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, | 415 | void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, |
| 409 | unsigned long start, unsigned long end) | 416 | unsigned long start, unsigned long end) |
| @@ -2792,8 +2799,37 @@ static inline void unmap_mapping_range_tree(struct rb_root_cached *root, | |||
| 2792 | } | 2799 | } |
| 2793 | 2800 | ||
| 2794 | /** | 2801 | /** |
| 2802 | * unmap_mapping_pages() - Unmap pages from processes. | ||
| 2803 | * @mapping: The address space containing pages to be unmapped. | ||
| 2804 | * @start: Index of first page to be unmapped. | ||
| 2805 | * @nr: Number of pages to be unmapped. 0 to unmap to end of file. | ||
| 2806 | * @even_cows: Whether to unmap even private COWed pages. | ||
| 2807 | * | ||
| 2808 | * Unmap the pages in this address space from any userspace process which | ||
| 2809 | * has them mmaped. Generally, you want to remove COWed pages as well when | ||
| 2810 | * a file is being truncated, but not when invalidating pages from the page | ||
| 2811 | * cache. | ||
| 2812 | */ | ||
| 2813 | void unmap_mapping_pages(struct address_space *mapping, pgoff_t start, | ||
| 2814 | pgoff_t nr, bool even_cows) | ||
| 2815 | { | ||
| 2816 | struct zap_details details = { }; | ||
| 2817 | |||
| 2818 | details.check_mapping = even_cows ? NULL : mapping; | ||
| 2819 | details.first_index = start; | ||
| 2820 | details.last_index = start + nr - 1; | ||
| 2821 | if (details.last_index < details.first_index) | ||
| 2822 | details.last_index = ULONG_MAX; | ||
| 2823 | |||
| 2824 | i_mmap_lock_write(mapping); | ||
| 2825 | if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))) | ||
| 2826 | unmap_mapping_range_tree(&mapping->i_mmap, &details); | ||
| 2827 | i_mmap_unlock_write(mapping); | ||
| 2828 | } | ||
| 2829 | |||
| 2830 | /** | ||
| 2795 | * unmap_mapping_range - unmap the portion of all mmaps in the specified | 2831 | * unmap_mapping_range - unmap the portion of all mmaps in the specified |
| 2796 | * address_space corresponding to the specified page range in the underlying | 2832 | * address_space corresponding to the specified byte range in the underlying |
| 2797 | * file. | 2833 | * file. |
| 2798 | * | 2834 | * |
| 2799 | * @mapping: the address space containing mmaps to be unmapped. | 2835 | * @mapping: the address space containing mmaps to be unmapped. |
| @@ -2811,7 +2847,6 @@ static inline void unmap_mapping_range_tree(struct rb_root_cached *root, | |||
| 2811 | void unmap_mapping_range(struct address_space *mapping, | 2847 | void unmap_mapping_range(struct address_space *mapping, |
| 2812 | loff_t const holebegin, loff_t const holelen, int even_cows) | 2848 | loff_t const holebegin, loff_t const holelen, int even_cows) |
| 2813 | { | 2849 | { |
| 2814 | struct zap_details details = { }; | ||
| 2815 | pgoff_t hba = holebegin >> PAGE_SHIFT; | 2850 | pgoff_t hba = holebegin >> PAGE_SHIFT; |
| 2816 | pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; | 2851 | pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; |
| 2817 | 2852 | ||
| @@ -2823,16 +2858,7 @@ void unmap_mapping_range(struct address_space *mapping, | |||
| 2823 | hlen = ULONG_MAX - hba + 1; | 2858 | hlen = ULONG_MAX - hba + 1; |
| 2824 | } | 2859 | } |
| 2825 | 2860 | ||
| 2826 | details.check_mapping = even_cows ? NULL : mapping; | 2861 | unmap_mapping_pages(mapping, hba, hlen, even_cows); |
| 2827 | details.first_index = hba; | ||
| 2828 | details.last_index = hba + hlen - 1; | ||
| 2829 | if (details.last_index < details.first_index) | ||
| 2830 | details.last_index = ULONG_MAX; | ||
| 2831 | |||
| 2832 | i_mmap_lock_write(mapping); | ||
| 2833 | if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))) | ||
| 2834 | unmap_mapping_range_tree(&mapping->i_mmap, &details); | ||
| 2835 | i_mmap_unlock_write(mapping); | ||
| 2836 | } | 2862 | } |
| 2837 | EXPORT_SYMBOL(unmap_mapping_range); | 2863 | EXPORT_SYMBOL(unmap_mapping_range); |
| 2838 | 2864 | ||
| @@ -3485,9 +3511,8 @@ static int fault_around_bytes_get(void *data, u64 *val) | |||
| 3485 | } | 3511 | } |
| 3486 | 3512 | ||
| 3487 | /* | 3513 | /* |
| 3488 | * fault_around_pages() and fault_around_mask() expects fault_around_bytes | 3514 | * fault_around_bytes must be rounded down to the nearest page order as it's |
| 3489 | * rounded down to nearest page order. It's what do_fault_around() expects to | 3515 | * what do_fault_around() expects to see. |
| 3490 | * see. | ||
| 3491 | */ | 3516 | */ |
| 3492 | static int fault_around_bytes_set(void *data, u64 val) | 3517 | static int fault_around_bytes_set(void *data, u64 val) |
| 3493 | { | 3518 | { |
| @@ -3530,13 +3555,14 @@ late_initcall(fault_around_debugfs); | |||
| 3530 | * This function doesn't cross the VMA boundaries, in order to call map_pages() | 3555 | * This function doesn't cross the VMA boundaries, in order to call map_pages() |
| 3531 | * only once. | 3556 | * only once. |
| 3532 | * | 3557 | * |
| 3533 | * fault_around_pages() defines how many pages we'll try to map. | 3558 | * fault_around_bytes defines how many bytes we'll try to map. |
| 3534 | * do_fault_around() expects it to return a power of two less than or equal to | 3559 | * do_fault_around() expects it to be set to a power of two less than or equal |
| 3535 | * PTRS_PER_PTE. | 3560 | * to PTRS_PER_PTE. |
| 3536 | * | 3561 | * |
| 3537 | * The virtual address of the area that we map is naturally aligned to the | 3562 | * The virtual address of the area that we map is naturally aligned to |
| 3538 | * fault_around_pages() value (and therefore to page order). This way it's | 3563 | * fault_around_bytes rounded down to the machine page size |
| 3539 | * easier to guarantee that we don't cross page table boundaries. | 3564 | * (and therefore to page order). This way it's easier to guarantee |
| 3565 | * that we don't cross page table boundaries. | ||
| 3540 | */ | 3566 | */ |
| 3541 | static int do_fault_around(struct vm_fault *vmf) | 3567 | static int do_fault_around(struct vm_fault *vmf) |
| 3542 | { | 3568 | { |
| @@ -3553,8 +3579,8 @@ static int do_fault_around(struct vm_fault *vmf) | |||
| 3553 | start_pgoff -= off; | 3579 | start_pgoff -= off; |
| 3554 | 3580 | ||
| 3555 | /* | 3581 | /* |
| 3556 | * end_pgoff is either end of page table or end of vma | 3582 | * end_pgoff is either the end of the page table, the end of |
| 3557 | * or fault_around_pages() from start_pgoff, depending what is nearest. | 3583 | * the vma or nr_pages from start_pgoff, depending what is nearest. |
| 3558 | */ | 3584 | */ |
| 3559 | end_pgoff = start_pgoff - | 3585 | end_pgoff = start_pgoff - |
| 3560 | ((vmf->address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + | 3586 | ((vmf->address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index c52aa05b106c..9bbd6982d4e4 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
| @@ -184,7 +184,7 @@ static void register_page_bootmem_info_section(unsigned long start_pfn) | |||
| 184 | for (i = 0; i < mapsize; i++, page++) | 184 | for (i = 0; i < mapsize; i++, page++) |
| 185 | get_page_bootmem(section_nr, page, SECTION_INFO); | 185 | get_page_bootmem(section_nr, page, SECTION_INFO); |
| 186 | 186 | ||
| 187 | usemap = __nr_to_section(section_nr)->pageblock_flags; | 187 | usemap = ms->pageblock_flags; |
| 188 | page = virt_to_page(usemap); | 188 | page = virt_to_page(usemap); |
| 189 | 189 | ||
| 190 | mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT; | 190 | mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT; |
| @@ -200,9 +200,6 @@ static void register_page_bootmem_info_section(unsigned long start_pfn) | |||
| 200 | struct mem_section *ms; | 200 | struct mem_section *ms; |
| 201 | struct page *page, *memmap; | 201 | struct page *page, *memmap; |
| 202 | 202 | ||
| 203 | if (!pfn_valid(start_pfn)) | ||
| 204 | return; | ||
| 205 | |||
| 206 | section_nr = pfn_to_section_nr(start_pfn); | 203 | section_nr = pfn_to_section_nr(start_pfn); |
| 207 | ms = __nr_to_section(section_nr); | 204 | ms = __nr_to_section(section_nr); |
| 208 | 205 | ||
| @@ -210,7 +207,7 @@ static void register_page_bootmem_info_section(unsigned long start_pfn) | |||
| 210 | 207 | ||
| 211 | register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION); | 208 | register_page_bootmem_memmap(section_nr, memmap, PAGES_PER_SECTION); |
| 212 | 209 | ||
| 213 | usemap = __nr_to_section(section_nr)->pageblock_flags; | 210 | usemap = ms->pageblock_flags; |
| 214 | page = virt_to_page(usemap); | 211 | page = virt_to_page(usemap); |
| 215 | 212 | ||
| 216 | mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT; | 213 | mapsize = PAGE_ALIGN(usemap_size()) >> PAGE_SHIFT; |
| @@ -1637,7 +1634,7 @@ repeat: | |||
| 1637 | goto failed_removal; | 1634 | goto failed_removal; |
| 1638 | 1635 | ||
| 1639 | cond_resched(); | 1636 | cond_resched(); |
| 1640 | lru_add_drain_all_cpuslocked(); | 1637 | lru_add_drain_all(); |
| 1641 | drain_all_pages(zone); | 1638 | drain_all_pages(zone); |
| 1642 | 1639 | ||
| 1643 | pfn = scan_movable_pages(start_pfn, end_pfn); | 1640 | pfn = scan_movable_pages(start_pfn, end_pfn); |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 4ce44d3ff03d..d879f1d8a44a 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
| @@ -1121,8 +1121,8 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) | |||
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | if (PageHuge(page)) { | 1123 | if (PageHuge(page)) { |
| 1124 | BUG_ON(!vma); | 1124 | return alloc_huge_page_vma(page_hstate(compound_head(page)), |
| 1125 | return alloc_huge_page_noerr(vma, address, 1); | 1125 | vma, address); |
| 1126 | } else if (thp_migration_supported() && PageTransHuge(page)) { | 1126 | } else if (thp_migration_supported() && PageTransHuge(page)) { |
| 1127 | struct page *thp; | 1127 | struct page *thp; |
| 1128 | 1128 | ||
| @@ -1263,6 +1263,7 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, | |||
| 1263 | unsigned long maxnode) | 1263 | unsigned long maxnode) |
| 1264 | { | 1264 | { |
| 1265 | unsigned long k; | 1265 | unsigned long k; |
| 1266 | unsigned long t; | ||
| 1266 | unsigned long nlongs; | 1267 | unsigned long nlongs; |
| 1267 | unsigned long endmask; | 1268 | unsigned long endmask; |
| 1268 | 1269 | ||
| @@ -1279,13 +1280,17 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, | |||
| 1279 | else | 1280 | else |
| 1280 | endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1; | 1281 | endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1; |
| 1281 | 1282 | ||
| 1282 | /* When the user specified more nodes than supported just check | 1283 | /* |
| 1283 | if the non supported part is all zero. */ | 1284 | * When the user specified more nodes than supported just check |
| 1285 | * if the non supported part is all zero. | ||
| 1286 | * | ||
| 1287 | * If maxnode have more longs than MAX_NUMNODES, check | ||
| 1288 | * the bits in that area first. And then go through to | ||
| 1289 | * check the rest bits which equal or bigger than MAX_NUMNODES. | ||
| 1290 | * Otherwise, just check bits [MAX_NUMNODES, maxnode). | ||
| 1291 | */ | ||
| 1284 | if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) { | 1292 | if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) { |
| 1285 | if (nlongs > PAGE_SIZE/sizeof(long)) | ||
| 1286 | return -EINVAL; | ||
| 1287 | for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) { | 1293 | for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) { |
| 1288 | unsigned long t; | ||
| 1289 | if (get_user(t, nmask + k)) | 1294 | if (get_user(t, nmask + k)) |
| 1290 | return -EFAULT; | 1295 | return -EFAULT; |
| 1291 | if (k == nlongs - 1) { | 1296 | if (k == nlongs - 1) { |
| @@ -1298,6 +1303,16 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask, | |||
| 1298 | endmask = ~0UL; | 1303 | endmask = ~0UL; |
| 1299 | } | 1304 | } |
| 1300 | 1305 | ||
| 1306 | if (maxnode > MAX_NUMNODES && MAX_NUMNODES % BITS_PER_LONG != 0) { | ||
| 1307 | unsigned long valid_mask = endmask; | ||
| 1308 | |||
| 1309 | valid_mask &= ~((1UL << (MAX_NUMNODES % BITS_PER_LONG)) - 1); | ||
| 1310 | if (get_user(t, nmask + nlongs - 1)) | ||
| 1311 | return -EFAULT; | ||
| 1312 | if (t & valid_mask) | ||
| 1313 | return -EINVAL; | ||
| 1314 | } | ||
| 1315 | |||
| 1301 | if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long))) | 1316 | if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long))) |
| 1302 | return -EFAULT; | 1317 | return -EFAULT; |
| 1303 | nodes_addr(*nodes)[nlongs-1] &= endmask; | 1318 | nodes_addr(*nodes)[nlongs-1] &= endmask; |
| @@ -1418,10 +1433,14 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, | |||
| 1418 | goto out_put; | 1433 | goto out_put; |
| 1419 | } | 1434 | } |
| 1420 | 1435 | ||
| 1421 | if (!nodes_subset(*new, node_states[N_MEMORY])) { | 1436 | task_nodes = cpuset_mems_allowed(current); |
| 1422 | err = -EINVAL; | 1437 | nodes_and(*new, *new, task_nodes); |
| 1438 | if (nodes_empty(*new)) | ||
| 1439 | goto out_put; | ||
| 1440 | |||
| 1441 | nodes_and(*new, *new, node_states[N_MEMORY]); | ||
| 1442 | if (nodes_empty(*new)) | ||
| 1423 | goto out_put; | 1443 | goto out_put; |
| 1424 | } | ||
| 1425 | 1444 | ||
| 1426 | err = security_task_movememory(task); | 1445 | err = security_task_movememory(task); |
| 1427 | if (err) | 1446 | if (err) |
diff --git a/mm/migrate.c b/mm/migrate.c index 4d0be47a322a..1e5525a25691 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
| @@ -1323,9 +1323,8 @@ put_anon: | |||
| 1323 | put_anon_vma(anon_vma); | 1323 | put_anon_vma(anon_vma); |
| 1324 | 1324 | ||
| 1325 | if (rc == MIGRATEPAGE_SUCCESS) { | 1325 | if (rc == MIGRATEPAGE_SUCCESS) { |
| 1326 | hugetlb_cgroup_migrate(hpage, new_hpage); | 1326 | move_hugetlb_state(hpage, new_hpage, reason); |
| 1327 | put_new_page = NULL; | 1327 | put_new_page = NULL; |
| 1328 | set_page_owner_migrate_reason(new_hpage, reason); | ||
| 1329 | } | 1328 | } |
| 1330 | 1329 | ||
| 1331 | unlock_page(hpage); | 1330 | unlock_page(hpage); |
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 96edb33fd09a..eff6b88a993f 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c | |||
| @@ -236,6 +236,37 @@ void __mmu_notifier_invalidate_range(struct mm_struct *mm, | |||
| 236 | } | 236 | } |
| 237 | EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range); | 237 | EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range); |
| 238 | 238 | ||
| 239 | /* | ||
| 240 | * Must be called while holding mm->mmap_sem for either read or write. | ||
| 241 | * The result is guaranteed to be valid until mm->mmap_sem is dropped. | ||
| 242 | */ | ||
| 243 | bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm) | ||
| 244 | { | ||
| 245 | struct mmu_notifier *mn; | ||
| 246 | int id; | ||
| 247 | bool ret = false; | ||
| 248 | |||
| 249 | WARN_ON_ONCE(!rwsem_is_locked(&mm->mmap_sem)); | ||
| 250 | |||
| 251 | if (!mm_has_notifiers(mm)) | ||
| 252 | return ret; | ||
| 253 | |||
| 254 | id = srcu_read_lock(&srcu); | ||
| 255 | hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) { | ||
| 256 | if (!mn->ops->invalidate_range && | ||
| 257 | !mn->ops->invalidate_range_start && | ||
| 258 | !mn->ops->invalidate_range_end) | ||
| 259 | continue; | ||
| 260 | |||
| 261 | if (!(mn->ops->flags & MMU_INVALIDATE_DOES_NOT_BLOCK)) { | ||
| 262 | ret = true; | ||
| 263 | break; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | srcu_read_unlock(&srcu, id); | ||
| 267 | return ret; | ||
| 268 | } | ||
| 269 | |||
| 239 | static int do_mmu_notifier_register(struct mmu_notifier *mn, | 270 | static int do_mmu_notifier_register(struct mmu_notifier *mn, |
| 240 | struct mm_struct *mm, | 271 | struct mm_struct *mm, |
| 241 | int take_mmap_sem) | 272 | int take_mmap_sem) |
diff --git a/mm/mprotect.c b/mm/mprotect.c index 58b629bb70de..e3309fcf586b 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
| @@ -84,6 +84,11 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
| 84 | if (!page || PageKsm(page)) | 84 | if (!page || PageKsm(page)) |
| 85 | continue; | 85 | continue; |
| 86 | 86 | ||
| 87 | /* Also skip shared copy-on-write pages */ | ||
| 88 | if (is_cow_mapping(vma->vm_flags) && | ||
| 89 | page_mapcount(page) != 1) | ||
| 90 | continue; | ||
| 91 | |||
| 87 | /* Avoid TLB flush if possible */ | 92 | /* Avoid TLB flush if possible */ |
| 88 | if (pte_protnone(oldpte)) | 93 | if (pte_protnone(oldpte)) |
| 89 | continue; | 94 | continue; |
diff --git a/mm/nommu.c b/mm/nommu.c index 17c00d93de2e..4b9864b17cb0 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -1788,13 +1788,6 @@ unsigned long arch_get_unmapped_area(struct file *file, unsigned long addr, | |||
| 1788 | return -ENOMEM; | 1788 | return -ENOMEM; |
| 1789 | } | 1789 | } |
| 1790 | 1790 | ||
| 1791 | void unmap_mapping_range(struct address_space *mapping, | ||
| 1792 | loff_t const holebegin, loff_t const holelen, | ||
| 1793 | int even_cows) | ||
| 1794 | { | ||
| 1795 | } | ||
| 1796 | EXPORT_SYMBOL(unmap_mapping_range); | ||
| 1797 | |||
| 1798 | int filemap_fault(struct vm_fault *vmf) | 1791 | int filemap_fault(struct vm_fault *vmf) |
| 1799 | { | 1792 | { |
| 1800 | BUG(); | 1793 | BUG(); |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 29f855551efe..f2e7dfb81eee 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
| @@ -514,15 +514,12 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) | |||
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | /* | 516 | /* |
| 517 | * If the mm has notifiers then we would need to invalidate them around | 517 | * If the mm has invalidate_{start,end}() notifiers that could block, |
| 518 | * unmap_page_range and that is risky because notifiers can sleep and | ||
| 519 | * what they do is basically undeterministic. So let's have a short | ||
| 520 | * sleep to give the oom victim some more time. | 518 | * sleep to give the oom victim some more time. |
| 521 | * TODO: we really want to get rid of this ugly hack and make sure that | 519 | * TODO: we really want to get rid of this ugly hack and make sure that |
| 522 | * notifiers cannot block for unbounded amount of time and add | 520 | * notifiers cannot block for unbounded amount of time |
| 523 | * mmu_notifier_invalidate_range_{start,end} around unmap_page_range | ||
| 524 | */ | 521 | */ |
| 525 | if (mm_has_notifiers(mm)) { | 522 | if (mm_has_blockable_invalidate_notifiers(mm)) { |
| 526 | up_read(&mm->mmap_sem); | 523 | up_read(&mm->mmap_sem); |
| 527 | schedule_timeout_idle(HZ); | 524 | schedule_timeout_idle(HZ); |
| 528 | goto unlock_oom; | 525 | goto unlock_oom; |
| @@ -565,10 +562,14 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm) | |||
| 565 | * count elevated without a good reason. | 562 | * count elevated without a good reason. |
| 566 | */ | 563 | */ |
| 567 | if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { | 564 | if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) { |
| 568 | tlb_gather_mmu(&tlb, mm, vma->vm_start, vma->vm_end); | 565 | const unsigned long start = vma->vm_start; |
| 569 | unmap_page_range(&tlb, vma, vma->vm_start, vma->vm_end, | 566 | const unsigned long end = vma->vm_end; |
| 570 | NULL); | 567 | |
| 571 | tlb_finish_mmu(&tlb, vma->vm_start, vma->vm_end); | 568 | tlb_gather_mmu(&tlb, mm, start, end); |
| 569 | mmu_notifier_invalidate_range_start(mm, start, end); | ||
| 570 | unmap_page_range(&tlb, vma, start, end, NULL); | ||
| 571 | mmu_notifier_invalidate_range_end(mm, start, end); | ||
| 572 | tlb_finish_mmu(&tlb, start, end); | ||
| 572 | } | 573 | } |
| 573 | } | 574 | } |
| 574 | pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", | 575 | pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 76c9688b6a0a..c7dd9c86e353 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -293,7 +293,7 @@ int page_group_by_mobility_disabled __read_mostly; | |||
| 293 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT | 293 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT |
| 294 | 294 | ||
| 295 | /* | 295 | /* |
| 296 | * Determine how many pages need to be initialized durig early boot | 296 | * Determine how many pages need to be initialized during early boot |
| 297 | * (non-deferred initialization). | 297 | * (non-deferred initialization). |
| 298 | * The value of first_deferred_pfn will be set later, once non-deferred pages | 298 | * The value of first_deferred_pfn will be set later, once non-deferred pages |
| 299 | * are initialized, but for now set it ULONG_MAX. | 299 | * are initialized, but for now set it ULONG_MAX. |
| @@ -344,7 +344,7 @@ static inline bool update_defer_init(pg_data_t *pgdat, | |||
| 344 | unsigned long pfn, unsigned long zone_end, | 344 | unsigned long pfn, unsigned long zone_end, |
| 345 | unsigned long *nr_initialised) | 345 | unsigned long *nr_initialised) |
| 346 | { | 346 | { |
| 347 | /* Always populate low zones for address-contrained allocations */ | 347 | /* Always populate low zones for address-constrained allocations */ |
| 348 | if (zone_end < pgdat_end_pfn(pgdat)) | 348 | if (zone_end < pgdat_end_pfn(pgdat)) |
| 349 | return true; | 349 | return true; |
| 350 | (*nr_initialised)++; | 350 | (*nr_initialised)++; |
| @@ -1177,9 +1177,10 @@ static void free_one_page(struct zone *zone, | |||
| 1177 | } | 1177 | } |
| 1178 | 1178 | ||
| 1179 | static void __meminit __init_single_page(struct page *page, unsigned long pfn, | 1179 | static void __meminit __init_single_page(struct page *page, unsigned long pfn, |
| 1180 | unsigned long zone, int nid) | 1180 | unsigned long zone, int nid, bool zero) |
| 1181 | { | 1181 | { |
| 1182 | mm_zero_struct_page(page); | 1182 | if (zero) |
| 1183 | mm_zero_struct_page(page); | ||
| 1183 | set_page_links(page, zone, nid, pfn); | 1184 | set_page_links(page, zone, nid, pfn); |
| 1184 | init_page_count(page); | 1185 | init_page_count(page); |
| 1185 | page_mapcount_reset(page); | 1186 | page_mapcount_reset(page); |
| @@ -1194,9 +1195,9 @@ static void __meminit __init_single_page(struct page *page, unsigned long pfn, | |||
| 1194 | } | 1195 | } |
| 1195 | 1196 | ||
| 1196 | static void __meminit __init_single_pfn(unsigned long pfn, unsigned long zone, | 1197 | static void __meminit __init_single_pfn(unsigned long pfn, unsigned long zone, |
| 1197 | int nid) | 1198 | int nid, bool zero) |
| 1198 | { | 1199 | { |
| 1199 | return __init_single_page(pfn_to_page(pfn), pfn, zone, nid); | 1200 | return __init_single_page(pfn_to_page(pfn), pfn, zone, nid, zero); |
| 1200 | } | 1201 | } |
| 1201 | 1202 | ||
| 1202 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT | 1203 | #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT |
| @@ -1217,7 +1218,7 @@ static void __meminit init_reserved_page(unsigned long pfn) | |||
| 1217 | if (pfn >= zone->zone_start_pfn && pfn < zone_end_pfn(zone)) | 1218 | if (pfn >= zone->zone_start_pfn && pfn < zone_end_pfn(zone)) |
| 1218 | break; | 1219 | break; |
| 1219 | } | 1220 | } |
| 1220 | __init_single_pfn(pfn, zid, nid); | 1221 | __init_single_pfn(pfn, zid, nid, true); |
| 1221 | } | 1222 | } |
| 1222 | #else | 1223 | #else |
| 1223 | static inline void init_reserved_page(unsigned long pfn) | 1224 | static inline void init_reserved_page(unsigned long pfn) |
| @@ -1457,92 +1458,87 @@ static inline void __init pgdat_init_report_one_done(void) | |||
| 1457 | } | 1458 | } |
| 1458 | 1459 | ||
| 1459 | /* | 1460 | /* |
| 1460 | * Helper for deferred_init_range, free the given range, reset the counters, and | 1461 | * Returns true if page needs to be initialized or freed to buddy allocator. |
| 1461 | * return number of pages freed. | 1462 | * |
| 1463 | * First we check if pfn is valid on architectures where it is possible to have | ||
| 1464 | * holes within pageblock_nr_pages. On systems where it is not possible, this | ||
| 1465 | * function is optimized out. | ||
| 1466 | * | ||
| 1467 | * Then, we check if a current large page is valid by only checking the validity | ||
| 1468 | * of the head pfn. | ||
| 1469 | * | ||
| 1470 | * Finally, meminit_pfn_in_nid is checked on systems where pfns can interleave | ||
| 1471 | * within a node: a pfn is between start and end of a node, but does not belong | ||
| 1472 | * to this memory node. | ||
| 1462 | */ | 1473 | */ |
| 1463 | static inline unsigned long __init __def_free(unsigned long *nr_free, | 1474 | static inline bool __init |
| 1464 | unsigned long *free_base_pfn, | 1475 | deferred_pfn_valid(int nid, unsigned long pfn, |
| 1465 | struct page **page) | 1476 | struct mminit_pfnnid_cache *nid_init_state) |
| 1466 | { | 1477 | { |
| 1467 | unsigned long nr = *nr_free; | 1478 | if (!pfn_valid_within(pfn)) |
| 1479 | return false; | ||
| 1480 | if (!(pfn & (pageblock_nr_pages - 1)) && !pfn_valid(pfn)) | ||
| 1481 | return false; | ||
| 1482 | if (!meminit_pfn_in_nid(pfn, nid, nid_init_state)) | ||
| 1483 | return false; | ||
| 1484 | return true; | ||
| 1485 | } | ||
| 1468 | 1486 | ||
| 1469 | deferred_free_range(*free_base_pfn, nr); | 1487 | /* |
| 1470 | *free_base_pfn = 0; | 1488 | * Free pages to buddy allocator. Try to free aligned pages in |
| 1471 | *nr_free = 0; | 1489 | * pageblock_nr_pages sizes. |
| 1472 | *page = NULL; | 1490 | */ |
| 1491 | static void __init deferred_free_pages(int nid, int zid, unsigned long pfn, | ||
| 1492 | unsigned long end_pfn) | ||
| 1493 | { | ||
| 1494 | struct mminit_pfnnid_cache nid_init_state = { }; | ||
| 1495 | unsigned long nr_pgmask = pageblock_nr_pages - 1; | ||
| 1496 | unsigned long nr_free = 0; | ||
| 1473 | 1497 | ||
| 1474 | return nr; | 1498 | for (; pfn < end_pfn; pfn++) { |
| 1499 | if (!deferred_pfn_valid(nid, pfn, &nid_init_state)) { | ||
| 1500 | deferred_free_range(pfn - nr_free, nr_free); | ||
| 1501 | nr_free = 0; | ||
| 1502 | } else if (!(pfn & nr_pgmask)) { | ||
| 1503 | deferred_free_range(pfn - nr_free, nr_free); | ||
| 1504 | nr_free = 1; | ||
| 1505 | cond_resched(); | ||
| 1506 | } else { | ||
| 1507 | nr_free++; | ||
| 1508 | } | ||
| 1509 | } | ||
| 1510 | /* Free the last block of pages to allocator */ | ||
| 1511 | deferred_free_range(pfn - nr_free, nr_free); | ||
| 1475 | } | 1512 | } |
| 1476 | 1513 | ||
| 1477 | static unsigned long __init deferred_init_range(int nid, int zid, | 1514 | /* |
| 1478 | unsigned long start_pfn, | 1515 | * Initialize struct pages. We minimize pfn page lookups and scheduler checks |
| 1479 | unsigned long end_pfn) | 1516 | * by performing it only once every pageblock_nr_pages. |
| 1517 | * Return number of pages initialized. | ||
| 1518 | */ | ||
| 1519 | static unsigned long __init deferred_init_pages(int nid, int zid, | ||
| 1520 | unsigned long pfn, | ||
| 1521 | unsigned long end_pfn) | ||
| 1480 | { | 1522 | { |
| 1481 | struct mminit_pfnnid_cache nid_init_state = { }; | 1523 | struct mminit_pfnnid_cache nid_init_state = { }; |
| 1482 | unsigned long nr_pgmask = pageblock_nr_pages - 1; | 1524 | unsigned long nr_pgmask = pageblock_nr_pages - 1; |
| 1483 | unsigned long free_base_pfn = 0; | ||
| 1484 | unsigned long nr_pages = 0; | 1525 | unsigned long nr_pages = 0; |
| 1485 | unsigned long nr_free = 0; | ||
| 1486 | struct page *page = NULL; | 1526 | struct page *page = NULL; |
| 1487 | unsigned long pfn; | ||
| 1488 | 1527 | ||
| 1489 | /* | 1528 | for (; pfn < end_pfn; pfn++) { |
| 1490 | * First we check if pfn is valid on architectures where it is possible | 1529 | if (!deferred_pfn_valid(nid, pfn, &nid_init_state)) { |
| 1491 | * to have holes within pageblock_nr_pages. On systems where it is not | 1530 | page = NULL; |
| 1492 | * possible, this function is optimized out. | ||
| 1493 | * | ||
| 1494 | * Then, we check if a current large page is valid by only checking the | ||
| 1495 | * validity of the head pfn. | ||
| 1496 | * | ||
| 1497 | * meminit_pfn_in_nid is checked on systems where pfns can interleave | ||
| 1498 | * within a node: a pfn is between start and end of a node, but does not | ||
| 1499 | * belong to this memory node. | ||
| 1500 | * | ||
| 1501 | * Finally, we minimize pfn page lookups and scheduler checks by | ||
| 1502 | * performing it only once every pageblock_nr_pages. | ||
| 1503 | * | ||
| 1504 | * We do it in two loops: first we initialize struct page, than free to | ||
| 1505 | * buddy allocator, becuse while we are freeing pages we can access | ||
| 1506 | * pages that are ahead (computing buddy page in __free_one_page()). | ||
| 1507 | */ | ||
| 1508 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | ||
| 1509 | if (!pfn_valid_within(pfn)) | ||
| 1510 | continue; | 1531 | continue; |
| 1511 | if ((pfn & nr_pgmask) || pfn_valid(pfn)) { | 1532 | } else if (!page || !(pfn & nr_pgmask)) { |
| 1512 | if (meminit_pfn_in_nid(pfn, nid, &nid_init_state)) { | ||
| 1513 | if (page && (pfn & nr_pgmask)) | ||
| 1514 | page++; | ||
| 1515 | else | ||
| 1516 | page = pfn_to_page(pfn); | ||
| 1517 | __init_single_page(page, pfn, zid, nid); | ||
| 1518 | cond_resched(); | ||
| 1519 | } | ||
| 1520 | } | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | page = NULL; | ||
| 1524 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | ||
| 1525 | if (!pfn_valid_within(pfn)) { | ||
| 1526 | nr_pages += __def_free(&nr_free, &free_base_pfn, &page); | ||
| 1527 | } else if (!(pfn & nr_pgmask) && !pfn_valid(pfn)) { | ||
| 1528 | nr_pages += __def_free(&nr_free, &free_base_pfn, &page); | ||
| 1529 | } else if (!meminit_pfn_in_nid(pfn, nid, &nid_init_state)) { | ||
| 1530 | nr_pages += __def_free(&nr_free, &free_base_pfn, &page); | ||
| 1531 | } else if (page && (pfn & nr_pgmask)) { | ||
| 1532 | page++; | ||
| 1533 | nr_free++; | ||
| 1534 | } else { | ||
| 1535 | nr_pages += __def_free(&nr_free, &free_base_pfn, &page); | ||
| 1536 | page = pfn_to_page(pfn); | 1533 | page = pfn_to_page(pfn); |
| 1537 | free_base_pfn = pfn; | ||
| 1538 | nr_free = 1; | ||
| 1539 | cond_resched(); | 1534 | cond_resched(); |
| 1535 | } else { | ||
| 1536 | page++; | ||
| 1540 | } | 1537 | } |
| 1538 | __init_single_page(page, pfn, zid, nid, true); | ||
| 1539 | nr_pages++; | ||
| 1541 | } | 1540 | } |
| 1542 | /* Free the last block of pages to allocator */ | 1541 | return (nr_pages); |
| 1543 | nr_pages += __def_free(&nr_free, &free_base_pfn, &page); | ||
| 1544 | |||
| 1545 | return nr_pages; | ||
| 1546 | } | 1542 | } |
| 1547 | 1543 | ||
| 1548 | /* Initialise remaining memory on a node */ | 1544 | /* Initialise remaining memory on a node */ |
| @@ -1582,10 +1578,21 @@ static int __init deferred_init_memmap(void *data) | |||
| 1582 | } | 1578 | } |
| 1583 | first_init_pfn = max(zone->zone_start_pfn, first_init_pfn); | 1579 | first_init_pfn = max(zone->zone_start_pfn, first_init_pfn); |
| 1584 | 1580 | ||
| 1581 | /* | ||
| 1582 | * Initialize and free pages. We do it in two loops: first we initialize | ||
| 1583 | * struct page, than free to buddy allocator, because while we are | ||
| 1584 | * freeing pages we can access pages that are ahead (computing buddy | ||
| 1585 | * page in __free_one_page()). | ||
| 1586 | */ | ||
| 1587 | for_each_free_mem_range(i, nid, MEMBLOCK_NONE, &spa, &epa, NULL) { | ||
| 1588 | spfn = max_t(unsigned long, first_init_pfn, PFN_UP(spa)); | ||
| 1589 | epfn = min_t(unsigned long, zone_end_pfn(zone), PFN_DOWN(epa)); | ||
| 1590 | nr_pages += deferred_init_pages(nid, zid, spfn, epfn); | ||
| 1591 | } | ||
| 1585 | for_each_free_mem_range(i, nid, MEMBLOCK_NONE, &spa, &epa, NULL) { | 1592 | for_each_free_mem_range(i, nid, MEMBLOCK_NONE, &spa, &epa, NULL) { |
| 1586 | spfn = max_t(unsigned long, first_init_pfn, PFN_UP(spa)); | 1593 | spfn = max_t(unsigned long, first_init_pfn, PFN_UP(spa)); |
| 1587 | epfn = min_t(unsigned long, zone_end_pfn(zone), PFN_DOWN(epa)); | 1594 | epfn = min_t(unsigned long, zone_end_pfn(zone), PFN_DOWN(epa)); |
| 1588 | nr_pages += deferred_init_range(nid, zid, spfn, epfn); | 1595 | deferred_free_pages(nid, zid, spfn, epfn); |
| 1589 | } | 1596 | } |
| 1590 | 1597 | ||
| 1591 | /* Sanity check that the next zone really is unpopulated */ | 1598 | /* Sanity check that the next zone really is unpopulated */ |
| @@ -3391,7 +3398,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, | |||
| 3391 | if (gfp_mask & __GFP_THISNODE) | 3398 | if (gfp_mask & __GFP_THISNODE) |
| 3392 | goto out; | 3399 | goto out; |
| 3393 | 3400 | ||
| 3394 | /* Exhausted what can be done so it's blamo time */ | 3401 | /* Exhausted what can be done so it's blame time */ |
| 3395 | if (out_of_memory(&oc) || WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL)) { | 3402 | if (out_of_memory(&oc) || WARN_ON_ONCE(gfp_mask & __GFP_NOFAIL)) { |
| 3396 | *did_some_progress = 1; | 3403 | *did_some_progress = 1; |
| 3397 | 3404 | ||
| @@ -4272,7 +4279,7 @@ unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) | |||
| 4272 | struct page *page; | 4279 | struct page *page; |
| 4273 | 4280 | ||
| 4274 | /* | 4281 | /* |
| 4275 | * __get_free_pages() returns a 32-bit address, which cannot represent | 4282 | * __get_free_pages() returns a virtual address, which cannot represent |
| 4276 | * a highmem page | 4283 | * a highmem page |
| 4277 | */ | 4284 | */ |
| 4278 | VM_BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0); | 4285 | VM_BUG_ON((gfp_mask & __GFP_HIGHMEM) != 0); |
| @@ -5393,15 +5400,20 @@ not_early: | |||
| 5393 | * can be created for invalid pages (for alignment) | 5400 | * can be created for invalid pages (for alignment) |
| 5394 | * check here not to call set_pageblock_migratetype() against | 5401 | * check here not to call set_pageblock_migratetype() against |
| 5395 | * pfn out of zone. | 5402 | * pfn out of zone. |
| 5403 | * | ||
| 5404 | * Please note that MEMMAP_HOTPLUG path doesn't clear memmap | ||
| 5405 | * because this is done early in sparse_add_one_section | ||
| 5396 | */ | 5406 | */ |
| 5397 | if (!(pfn & (pageblock_nr_pages - 1))) { | 5407 | if (!(pfn & (pageblock_nr_pages - 1))) { |
| 5398 | struct page *page = pfn_to_page(pfn); | 5408 | struct page *page = pfn_to_page(pfn); |
| 5399 | 5409 | ||
| 5400 | __init_single_page(page, pfn, zone, nid); | 5410 | __init_single_page(page, pfn, zone, nid, |
| 5411 | context != MEMMAP_HOTPLUG); | ||
| 5401 | set_pageblock_migratetype(page, MIGRATE_MOVABLE); | 5412 | set_pageblock_migratetype(page, MIGRATE_MOVABLE); |
| 5402 | cond_resched(); | 5413 | cond_resched(); |
| 5403 | } else { | 5414 | } else { |
| 5404 | __init_single_pfn(pfn, zone, nid); | 5415 | __init_single_pfn(pfn, zone, nid, |
| 5416 | context != MEMMAP_HOTPLUG); | ||
| 5405 | } | 5417 | } |
| 5406 | } | 5418 | } |
| 5407 | } | 5419 | } |
diff --git a/mm/page_ext.c b/mm/page_ext.c index 2c16216c29b6..5295ef331165 100644 --- a/mm/page_ext.c +++ b/mm/page_ext.c | |||
| @@ -59,7 +59,9 @@ | |||
| 59 | */ | 59 | */ |
| 60 | 60 | ||
| 61 | static struct page_ext_operations *page_ext_ops[] = { | 61 | static struct page_ext_operations *page_ext_ops[] = { |
| 62 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
| 62 | &debug_guardpage_ops, | 63 | &debug_guardpage_ops, |
| 64 | #endif | ||
| 63 | #ifdef CONFIG_PAGE_OWNER | 65 | #ifdef CONFIG_PAGE_OWNER |
| 64 | &page_owner_ops, | 66 | &page_owner_ops, |
| 65 | #endif | 67 | #endif |
diff --git a/mm/page_owner.c b/mm/page_owner.c index 270a8219ccd0..9886c6073828 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c | |||
| @@ -528,21 +528,18 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
| 528 | 528 | ||
| 529 | static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone) | 529 | static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone) |
| 530 | { | 530 | { |
| 531 | struct page *page; | 531 | unsigned long pfn = zone->zone_start_pfn; |
| 532 | struct page_ext *page_ext; | 532 | unsigned long end_pfn = zone_end_pfn(zone); |
| 533 | unsigned long pfn = zone->zone_start_pfn, block_end_pfn; | ||
| 534 | unsigned long end_pfn = pfn + zone->spanned_pages; | ||
| 535 | unsigned long count = 0; | 533 | unsigned long count = 0; |
| 536 | 534 | ||
| 537 | /* Scan block by block. First and last block may be incomplete */ | ||
| 538 | pfn = zone->zone_start_pfn; | ||
| 539 | |||
| 540 | /* | 535 | /* |
| 541 | * Walk the zone in pageblock_nr_pages steps. If a page block spans | 536 | * Walk the zone in pageblock_nr_pages steps. If a page block spans |
| 542 | * a zone boundary, it will be double counted between zones. This does | 537 | * a zone boundary, it will be double counted between zones. This does |
| 543 | * not matter as the mixed block count will still be correct | 538 | * not matter as the mixed block count will still be correct |
| 544 | */ | 539 | */ |
| 545 | for (; pfn < end_pfn; ) { | 540 | for (; pfn < end_pfn; ) { |
| 541 | unsigned long block_end_pfn; | ||
| 542 | |||
| 546 | if (!pfn_valid(pfn)) { | 543 | if (!pfn_valid(pfn)) { |
| 547 | pfn = ALIGN(pfn + 1, MAX_ORDER_NR_PAGES); | 544 | pfn = ALIGN(pfn + 1, MAX_ORDER_NR_PAGES); |
| 548 | continue; | 545 | continue; |
| @@ -551,9 +548,10 @@ static void init_pages_in_zone(pg_data_t *pgdat, struct zone *zone) | |||
| 551 | block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); | 548 | block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); |
| 552 | block_end_pfn = min(block_end_pfn, end_pfn); | 549 | block_end_pfn = min(block_end_pfn, end_pfn); |
| 553 | 550 | ||
| 554 | page = pfn_to_page(pfn); | ||
| 555 | |||
| 556 | for (; pfn < block_end_pfn; pfn++) { | 551 | for (; pfn < block_end_pfn; pfn++) { |
| 552 | struct page *page; | ||
| 553 | struct page_ext *page_ext; | ||
| 554 | |||
| 557 | if (!pfn_valid_within(pfn)) | 555 | if (!pfn_valid_within(pfn)) |
| 558 | continue; | 556 | continue; |
| 559 | 557 | ||
| @@ -635,9 +633,7 @@ static int __init pageowner_init(void) | |||
| 635 | 633 | ||
| 636 | dentry = debugfs_create_file("page_owner", S_IRUSR, NULL, | 634 | dentry = debugfs_create_file("page_owner", S_IRUSR, NULL, |
| 637 | NULL, &proc_page_owner_operations); | 635 | NULL, &proc_page_owner_operations); |
| 638 | if (IS_ERR(dentry)) | ||
| 639 | return PTR_ERR(dentry); | ||
| 640 | 636 | ||
| 641 | return 0; | 637 | return PTR_ERR_OR_ZERO(dentry); |
| 642 | } | 638 | } |
| 643 | late_initcall(pageowner_init) | 639 | late_initcall(pageowner_init) |
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c index 1e4ee763c190..cf2af04b34b9 100644 --- a/mm/pgtable-generic.c +++ b/mm/pgtable-generic.c | |||
| @@ -181,12 +181,12 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp) | |||
| 181 | #endif | 181 | #endif |
| 182 | 182 | ||
| 183 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE | 183 | #ifndef __HAVE_ARCH_PMDP_INVALIDATE |
| 184 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | 184 | pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, |
| 185 | pmd_t *pmdp) | 185 | pmd_t *pmdp) |
| 186 | { | 186 | { |
| 187 | pmd_t entry = *pmdp; | 187 | pmd_t old = pmdp_establish(vma, address, pmdp, pmd_mknotpresent(*pmdp)); |
| 188 | set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(entry)); | ||
| 189 | flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | 188 | flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE); |
| 189 | return old; | ||
| 190 | } | 190 | } |
| 191 | #endif | 191 | #endif |
| 192 | 192 | ||
diff --git a/mm/shmem.c b/mm/shmem.c index 7fbe67be86fa..1907688b75ee 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -2717,15 +2717,28 @@ continue_resched: | |||
| 2717 | return error; | 2717 | return error; |
| 2718 | } | 2718 | } |
| 2719 | 2719 | ||
| 2720 | static unsigned int *memfd_file_seals_ptr(struct file *file) | ||
| 2721 | { | ||
| 2722 | if (file->f_op == &shmem_file_operations) | ||
| 2723 | return &SHMEM_I(file_inode(file))->seals; | ||
| 2724 | |||
| 2725 | #ifdef CONFIG_HUGETLBFS | ||
| 2726 | if (file->f_op == &hugetlbfs_file_operations) | ||
| 2727 | return &HUGETLBFS_I(file_inode(file))->seals; | ||
| 2728 | #endif | ||
| 2729 | |||
| 2730 | return NULL; | ||
| 2731 | } | ||
| 2732 | |||
| 2720 | #define F_ALL_SEALS (F_SEAL_SEAL | \ | 2733 | #define F_ALL_SEALS (F_SEAL_SEAL | \ |
| 2721 | F_SEAL_SHRINK | \ | 2734 | F_SEAL_SHRINK | \ |
| 2722 | F_SEAL_GROW | \ | 2735 | F_SEAL_GROW | \ |
| 2723 | F_SEAL_WRITE) | 2736 | F_SEAL_WRITE) |
| 2724 | 2737 | ||
| 2725 | int shmem_add_seals(struct file *file, unsigned int seals) | 2738 | static int memfd_add_seals(struct file *file, unsigned int seals) |
| 2726 | { | 2739 | { |
| 2727 | struct inode *inode = file_inode(file); | 2740 | struct inode *inode = file_inode(file); |
| 2728 | struct shmem_inode_info *info = SHMEM_I(inode); | 2741 | unsigned int *file_seals; |
| 2729 | int error; | 2742 | int error; |
| 2730 | 2743 | ||
| 2731 | /* | 2744 | /* |
| @@ -2758,8 +2771,6 @@ int shmem_add_seals(struct file *file, unsigned int seals) | |||
| 2758 | * other file types. | 2771 | * other file types. |
| 2759 | */ | 2772 | */ |
| 2760 | 2773 | ||
| 2761 | if (file->f_op != &shmem_file_operations) | ||
| 2762 | return -EINVAL; | ||
| 2763 | if (!(file->f_mode & FMODE_WRITE)) | 2774 | if (!(file->f_mode & FMODE_WRITE)) |
| 2764 | return -EPERM; | 2775 | return -EPERM; |
| 2765 | if (seals & ~(unsigned int)F_ALL_SEALS) | 2776 | if (seals & ~(unsigned int)F_ALL_SEALS) |
| @@ -2767,12 +2778,18 @@ int shmem_add_seals(struct file *file, unsigned int seals) | |||
| 2767 | 2778 | ||
| 2768 | inode_lock(inode); | 2779 | inode_lock(inode); |
| 2769 | 2780 | ||
| 2770 | if (info->seals & F_SEAL_SEAL) { | 2781 | file_seals = memfd_file_seals_ptr(file); |
| 2782 | if (!file_seals) { | ||
| 2783 | error = -EINVAL; | ||
| 2784 | goto unlock; | ||
| 2785 | } | ||
| 2786 | |||
| 2787 | if (*file_seals & F_SEAL_SEAL) { | ||
| 2771 | error = -EPERM; | 2788 | error = -EPERM; |
| 2772 | goto unlock; | 2789 | goto unlock; |
| 2773 | } | 2790 | } |
| 2774 | 2791 | ||
| 2775 | if ((seals & F_SEAL_WRITE) && !(info->seals & F_SEAL_WRITE)) { | 2792 | if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) { |
| 2776 | error = mapping_deny_writable(file->f_mapping); | 2793 | error = mapping_deny_writable(file->f_mapping); |
| 2777 | if (error) | 2794 | if (error) |
| 2778 | goto unlock; | 2795 | goto unlock; |
| @@ -2784,25 +2801,22 @@ int shmem_add_seals(struct file *file, unsigned int seals) | |||
| 2784 | } | 2801 | } |
| 2785 | } | 2802 | } |
| 2786 | 2803 | ||
| 2787 | info->seals |= seals; | 2804 | *file_seals |= seals; |
| 2788 | error = 0; | 2805 | error = 0; |
| 2789 | 2806 | ||
| 2790 | unlock: | 2807 | unlock: |
| 2791 | inode_unlock(inode); | 2808 | inode_unlock(inode); |
| 2792 | return error; | 2809 | return error; |
| 2793 | } | 2810 | } |
| 2794 | EXPORT_SYMBOL_GPL(shmem_add_seals); | ||
| 2795 | 2811 | ||
| 2796 | int shmem_get_seals(struct file *file) | 2812 | static int memfd_get_seals(struct file *file) |
| 2797 | { | 2813 | { |
| 2798 | if (file->f_op != &shmem_file_operations) | 2814 | unsigned int *seals = memfd_file_seals_ptr(file); |
| 2799 | return -EINVAL; | ||
| 2800 | 2815 | ||
| 2801 | return SHMEM_I(file_inode(file))->seals; | 2816 | return seals ? *seals : -EINVAL; |
| 2802 | } | 2817 | } |
| 2803 | EXPORT_SYMBOL_GPL(shmem_get_seals); | ||
| 2804 | 2818 | ||
| 2805 | long shmem_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | 2819 | long memfd_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
| 2806 | { | 2820 | { |
| 2807 | long error; | 2821 | long error; |
| 2808 | 2822 | ||
| @@ -2812,10 +2826,10 @@ long shmem_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 2812 | if (arg > UINT_MAX) | 2826 | if (arg > UINT_MAX) |
| 2813 | return -EINVAL; | 2827 | return -EINVAL; |
| 2814 | 2828 | ||
| 2815 | error = shmem_add_seals(file, arg); | 2829 | error = memfd_add_seals(file, arg); |
| 2816 | break; | 2830 | break; |
| 2817 | case F_GET_SEALS: | 2831 | case F_GET_SEALS: |
| 2818 | error = shmem_get_seals(file); | 2832 | error = memfd_get_seals(file); |
| 2819 | break; | 2833 | break; |
| 2820 | default: | 2834 | default: |
| 2821 | error = -EINVAL; | 2835 | error = -EINVAL; |
| @@ -3657,7 +3671,7 @@ SYSCALL_DEFINE2(memfd_create, | |||
| 3657 | const char __user *, uname, | 3671 | const char __user *, uname, |
| 3658 | unsigned int, flags) | 3672 | unsigned int, flags) |
| 3659 | { | 3673 | { |
| 3660 | struct shmem_inode_info *info; | 3674 | unsigned int *file_seals; |
| 3661 | struct file *file; | 3675 | struct file *file; |
| 3662 | int fd, error; | 3676 | int fd, error; |
| 3663 | char *name; | 3677 | char *name; |
| @@ -3667,9 +3681,6 @@ SYSCALL_DEFINE2(memfd_create, | |||
| 3667 | if (flags & ~(unsigned int)MFD_ALL_FLAGS) | 3681 | if (flags & ~(unsigned int)MFD_ALL_FLAGS) |
| 3668 | return -EINVAL; | 3682 | return -EINVAL; |
| 3669 | } else { | 3683 | } else { |
| 3670 | /* Sealing not supported in hugetlbfs (MFD_HUGETLB) */ | ||
| 3671 | if (flags & MFD_ALLOW_SEALING) | ||
| 3672 | return -EINVAL; | ||
| 3673 | /* Allow huge page size encoding in flags. */ | 3684 | /* Allow huge page size encoding in flags. */ |
| 3674 | if (flags & ~(unsigned int)(MFD_ALL_FLAGS | | 3685 | if (flags & ~(unsigned int)(MFD_ALL_FLAGS | |
| 3675 | (MFD_HUGE_MASK << MFD_HUGE_SHIFT))) | 3686 | (MFD_HUGE_MASK << MFD_HUGE_SHIFT))) |
| @@ -3722,12 +3733,8 @@ SYSCALL_DEFINE2(memfd_create, | |||
| 3722 | file->f_flags |= O_RDWR | O_LARGEFILE; | 3733 | file->f_flags |= O_RDWR | O_LARGEFILE; |
| 3723 | 3734 | ||
| 3724 | if (flags & MFD_ALLOW_SEALING) { | 3735 | if (flags & MFD_ALLOW_SEALING) { |
| 3725 | /* | 3736 | file_seals = memfd_file_seals_ptr(file); |
| 3726 | * flags check at beginning of function ensures | 3737 | *file_seals &= ~F_SEAL_SEAL; |
| 3727 | * this is not a hugetlbfs (MFD_HUGETLB) file. | ||
| 3728 | */ | ||
| 3729 | info = SHMEM_I(file_inode(file)); | ||
| 3730 | info->seals &= ~F_SEAL_SEAL; | ||
| 3731 | } | 3738 | } |
| 3732 | 3739 | ||
| 3733 | fd_install(fd, file); | 3740 | fd_install(fd, file); |
| @@ -1316,8 +1316,6 @@ void __init kmem_cache_init_late(void) | |||
| 1316 | { | 1316 | { |
| 1317 | struct kmem_cache *cachep; | 1317 | struct kmem_cache *cachep; |
| 1318 | 1318 | ||
| 1319 | slab_state = UP; | ||
| 1320 | |||
| 1321 | /* 6) resize the head arrays to their final sizes */ | 1319 | /* 6) resize the head arrays to their final sizes */ |
| 1322 | mutex_lock(&slab_mutex); | 1320 | mutex_lock(&slab_mutex); |
| 1323 | list_for_each_entry(cachep, &slab_caches, list) | 1321 | list_for_each_entry(cachep, &slab_caches, list) |
| @@ -1353,8 +1351,6 @@ static int __init cpucache_init(void) | |||
| 1353 | slab_online_cpu, slab_offline_cpu); | 1351 | slab_online_cpu, slab_offline_cpu); |
| 1354 | WARN_ON(ret < 0); | 1352 | WARN_ON(ret < 0); |
| 1355 | 1353 | ||
| 1356 | /* Done! */ | ||
| 1357 | slab_state = FULL; | ||
| 1358 | return 0; | 1354 | return 0; |
| 1359 | } | 1355 | } |
| 1360 | __initcall(cpucache_init); | 1356 | __initcall(cpucache_init); |
| @@ -78,9 +78,6 @@ extern const struct kmalloc_info_struct { | |||
| 78 | unsigned long size; | 78 | unsigned long size; |
| 79 | } kmalloc_info[]; | 79 | } kmalloc_info[]; |
| 80 | 80 | ||
| 81 | unsigned long calculate_alignment(slab_flags_t flags, | ||
| 82 | unsigned long align, unsigned long size); | ||
| 83 | |||
| 84 | #ifndef CONFIG_SLOB | 81 | #ifndef CONFIG_SLOB |
| 85 | /* Kmalloc array related functions */ | 82 | /* Kmalloc array related functions */ |
| 86 | void setup_kmalloc_cache_index_table(void); | 83 | void setup_kmalloc_cache_index_table(void); |
diff --git a/mm/slab_common.c b/mm/slab_common.c index c8cb36774ba1..deeddf95cdcf 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
| @@ -268,6 +268,35 @@ static inline void memcg_unlink_cache(struct kmem_cache *s) | |||
| 268 | #endif /* CONFIG_MEMCG && !CONFIG_SLOB */ | 268 | #endif /* CONFIG_MEMCG && !CONFIG_SLOB */ |
| 269 | 269 | ||
| 270 | /* | 270 | /* |
| 271 | * Figure out what the alignment of the objects will be given a set of | ||
| 272 | * flags, a user specified alignment and the size of the objects. | ||
| 273 | */ | ||
| 274 | static unsigned long calculate_alignment(unsigned long flags, | ||
| 275 | unsigned long align, unsigned long size) | ||
| 276 | { | ||
| 277 | /* | ||
| 278 | * If the user wants hardware cache aligned objects then follow that | ||
| 279 | * suggestion if the object is sufficiently large. | ||
| 280 | * | ||
| 281 | * The hardware cache alignment cannot override the specified | ||
| 282 | * alignment though. If that is greater then use it. | ||
| 283 | */ | ||
| 284 | if (flags & SLAB_HWCACHE_ALIGN) { | ||
| 285 | unsigned long ralign; | ||
| 286 | |||
| 287 | ralign = cache_line_size(); | ||
| 288 | while (size <= ralign / 2) | ||
| 289 | ralign /= 2; | ||
| 290 | align = max(align, ralign); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (align < ARCH_SLAB_MINALIGN) | ||
| 294 | align = ARCH_SLAB_MINALIGN; | ||
| 295 | |||
| 296 | return ALIGN(align, sizeof(void *)); | ||
| 297 | } | ||
| 298 | |||
| 299 | /* | ||
| 271 | * Find a mergeable slab cache | 300 | * Find a mergeable slab cache |
| 272 | */ | 301 | */ |
| 273 | int slab_unmergeable(struct kmem_cache *s) | 302 | int slab_unmergeable(struct kmem_cache *s) |
| @@ -337,33 +366,6 @@ struct kmem_cache *find_mergeable(size_t size, size_t align, | |||
| 337 | return NULL; | 366 | return NULL; |
| 338 | } | 367 | } |
| 339 | 368 | ||
| 340 | /* | ||
| 341 | * Figure out what the alignment of the objects will be given a set of | ||
| 342 | * flags, a user specified alignment and the size of the objects. | ||
| 343 | */ | ||
| 344 | unsigned long calculate_alignment(slab_flags_t flags, | ||
| 345 | unsigned long align, unsigned long size) | ||
| 346 | { | ||
| 347 | /* | ||
| 348 | * If the user wants hardware cache aligned objects then follow that | ||
| 349 | * suggestion if the object is sufficiently large. | ||
| 350 | * | ||
| 351 | * The hardware cache alignment cannot override the specified | ||
| 352 | * alignment though. If that is greater then use it. | ||
| 353 | */ | ||
| 354 | if (flags & SLAB_HWCACHE_ALIGN) { | ||
| 355 | unsigned long ralign = cache_line_size(); | ||
| 356 | while (size <= ralign / 2) | ||
| 357 | ralign /= 2; | ||
| 358 | align = max(align, ralign); | ||
| 359 | } | ||
| 360 | |||
| 361 | if (align < ARCH_SLAB_MINALIGN) | ||
| 362 | align = ARCH_SLAB_MINALIGN; | ||
| 363 | |||
| 364 | return ALIGN(align, sizeof(void *)); | ||
| 365 | } | ||
| 366 | |||
| 367 | static struct kmem_cache *create_cache(const char *name, | 369 | static struct kmem_cache *create_cache(const char *name, |
| 368 | size_t object_size, size_t size, size_t align, | 370 | size_t object_size, size_t size, size_t align, |
| 369 | slab_flags_t flags, void (*ctor)(void *), | 371 | slab_flags_t flags, void (*ctor)(void *), |
| @@ -838,6 +838,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page) | |||
| 838 | u8 *start; | 838 | u8 *start; |
| 839 | u8 *fault; | 839 | u8 *fault; |
| 840 | u8 *end; | 840 | u8 *end; |
| 841 | u8 *pad; | ||
| 841 | int length; | 842 | int length; |
| 842 | int remainder; | 843 | int remainder; |
| 843 | 844 | ||
| @@ -851,8 +852,9 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page) | |||
| 851 | if (!remainder) | 852 | if (!remainder) |
| 852 | return 1; | 853 | return 1; |
| 853 | 854 | ||
| 855 | pad = end - remainder; | ||
| 854 | metadata_access_enable(); | 856 | metadata_access_enable(); |
| 855 | fault = memchr_inv(end - remainder, POISON_INUSE, remainder); | 857 | fault = memchr_inv(pad, POISON_INUSE, remainder); |
| 856 | metadata_access_disable(); | 858 | metadata_access_disable(); |
| 857 | if (!fault) | 859 | if (!fault) |
| 858 | return 1; | 860 | return 1; |
| @@ -860,9 +862,9 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page) | |||
| 860 | end--; | 862 | end--; |
| 861 | 863 | ||
| 862 | slab_err(s, page, "Padding overwritten. 0x%p-0x%p", fault, end - 1); | 864 | slab_err(s, page, "Padding overwritten. 0x%p-0x%p", fault, end - 1); |
| 863 | print_section(KERN_ERR, "Padding ", end - remainder, remainder); | 865 | print_section(KERN_ERR, "Padding ", pad, remainder); |
| 864 | 866 | ||
| 865 | restore_bytes(s, "slab padding", POISON_INUSE, end - remainder, end); | 867 | restore_bytes(s, "slab padding", POISON_INUSE, fault, end); |
| 866 | return 0; | 868 | return 0; |
| 867 | } | 869 | } |
| 868 | 870 | ||
| @@ -2220,9 +2222,7 @@ static void unfreeze_partials(struct kmem_cache *s, | |||
| 2220 | 2222 | ||
| 2221 | /* | 2223 | /* |
| 2222 | * Put a page that was just frozen (in __slab_free) into a partial page | 2224 | * Put a page that was just frozen (in __slab_free) into a partial page |
| 2223 | * slot if available. This is done without interrupts disabled and without | 2225 | * slot if available. |
| 2224 | * preemption disabled. The cmpxchg is racy and may put the partial page | ||
| 2225 | * onto a random cpus partial slot. | ||
| 2226 | * | 2226 | * |
| 2227 | * If we did not find a slot then simply move all the partials to the | 2227 | * If we did not find a slot then simply move all the partials to the |
| 2228 | * per node partial list. | 2228 | * per node partial list. |
diff --git a/mm/sparse.c b/mm/sparse.c index 2609aba121e8..6b8b5e91ceef 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
| @@ -264,7 +264,11 @@ unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn, | |||
| 264 | */ | 264 | */ |
| 265 | static unsigned long sparse_encode_mem_map(struct page *mem_map, unsigned long pnum) | 265 | static unsigned long sparse_encode_mem_map(struct page *mem_map, unsigned long pnum) |
| 266 | { | 266 | { |
| 267 | return (unsigned long)(mem_map - (section_nr_to_pfn(pnum))); | 267 | unsigned long coded_mem_map = |
| 268 | (unsigned long)(mem_map - (section_nr_to_pfn(pnum))); | ||
| 269 | BUILD_BUG_ON(SECTION_MAP_LAST_BIT > (1UL<<PFN_SECTION_SHIFT)); | ||
| 270 | BUG_ON(coded_mem_map & ~SECTION_MAP_MASK); | ||
| 271 | return coded_mem_map; | ||
| 268 | } | 272 | } |
| 269 | 273 | ||
| 270 | /* | 274 | /* |
| @@ -411,7 +411,7 @@ static void __lru_cache_add(struct page *page) | |||
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | /** | 413 | /** |
| 414 | * lru_cache_add: add a page to the page lists | 414 | * lru_cache_add_anon - add a page to the page lists |
| 415 | * @page: the page to add | 415 | * @page: the page to add |
| 416 | */ | 416 | */ |
| 417 | void lru_cache_add_anon(struct page *page) | 417 | void lru_cache_add_anon(struct page *page) |
| @@ -688,7 +688,14 @@ static void lru_add_drain_per_cpu(struct work_struct *dummy) | |||
| 688 | 688 | ||
| 689 | static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work); | 689 | static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work); |
| 690 | 690 | ||
| 691 | void lru_add_drain_all_cpuslocked(void) | 691 | /* |
| 692 | * Doesn't need any cpu hotplug locking because we do rely on per-cpu | ||
| 693 | * kworkers being shut down before our page_alloc_cpu_dead callback is | ||
| 694 | * executed on the offlined cpu. | ||
| 695 | * Calling this function with cpu hotplug locks held can actually lead | ||
| 696 | * to obscure indirect dependencies via WQ context. | ||
| 697 | */ | ||
| 698 | void lru_add_drain_all(void) | ||
| 692 | { | 699 | { |
| 693 | static DEFINE_MUTEX(lock); | 700 | static DEFINE_MUTEX(lock); |
| 694 | static struct cpumask has_work; | 701 | static struct cpumask has_work; |
| @@ -724,13 +731,6 @@ void lru_add_drain_all_cpuslocked(void) | |||
| 724 | mutex_unlock(&lock); | 731 | mutex_unlock(&lock); |
| 725 | } | 732 | } |
| 726 | 733 | ||
| 727 | void lru_add_drain_all(void) | ||
| 728 | { | ||
| 729 | get_online_cpus(); | ||
| 730 | lru_add_drain_all_cpuslocked(); | ||
| 731 | put_online_cpus(); | ||
| 732 | } | ||
| 733 | |||
| 734 | /** | 734 | /** |
| 735 | * release_pages - batched put_page() | 735 | * release_pages - batched put_page() |
| 736 | * @pages: array of pages to release | 736 | * @pages: array of pages to release |
| @@ -930,10 +930,10 @@ EXPORT_SYMBOL(__pagevec_lru_add); | |||
| 930 | */ | 930 | */ |
| 931 | unsigned pagevec_lookup_entries(struct pagevec *pvec, | 931 | unsigned pagevec_lookup_entries(struct pagevec *pvec, |
| 932 | struct address_space *mapping, | 932 | struct address_space *mapping, |
| 933 | pgoff_t start, unsigned nr_pages, | 933 | pgoff_t start, unsigned nr_entries, |
| 934 | pgoff_t *indices) | 934 | pgoff_t *indices) |
| 935 | { | 935 | { |
| 936 | pvec->nr = find_get_entries(mapping, start, nr_pages, | 936 | pvec->nr = find_get_entries(mapping, start, nr_entries, |
| 937 | pvec->pages, indices); | 937 | pvec->pages, indices); |
| 938 | return pagevec_count(pvec); | 938 | return pagevec_count(pvec); |
| 939 | } | 939 | } |
| @@ -965,9 +965,8 @@ void pagevec_remove_exceptionals(struct pagevec *pvec) | |||
| 965 | * @mapping: The address_space to search | 965 | * @mapping: The address_space to search |
| 966 | * @start: The starting page index | 966 | * @start: The starting page index |
| 967 | * @end: The final page index | 967 | * @end: The final page index |
| 968 | * @nr_pages: The maximum number of pages | ||
| 969 | * | 968 | * |
| 970 | * pagevec_lookup_range() will search for and return a group of up to @nr_pages | 969 | * pagevec_lookup_range() will search for & return a group of up to PAGEVEC_SIZE |
| 971 | * pages in the mapping starting from index @start and upto index @end | 970 | * pages in the mapping starting from index @start and upto index @end |
| 972 | * (inclusive). The pages are placed in @pvec. pagevec_lookup() takes a | 971 | * (inclusive). The pages are placed in @pvec. pagevec_lookup() takes a |
| 973 | * reference against the pages in @pvec. | 972 | * reference against the pages in @pvec. |
| @@ -977,7 +976,7 @@ void pagevec_remove_exceptionals(struct pagevec *pvec) | |||
| 977 | * also update @start to index the next page for the traversal. | 976 | * also update @start to index the next page for the traversal. |
| 978 | * | 977 | * |
| 979 | * pagevec_lookup_range() returns the number of pages which were found. If this | 978 | * pagevec_lookup_range() returns the number of pages which were found. If this |
| 980 | * number is smaller than @nr_pages, the end of specified range has been | 979 | * number is smaller than PAGEVEC_SIZE, the end of specified range has been |
| 981 | * reached. | 980 | * reached. |
| 982 | */ | 981 | */ |
| 983 | unsigned pagevec_lookup_range(struct pagevec *pvec, | 982 | unsigned pagevec_lookup_range(struct pagevec *pvec, |
diff --git a/mm/truncate.c b/mm/truncate.c index e4b4cf0f4070..c34e2fd4f583 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
| @@ -179,12 +179,8 @@ static void | |||
| 179 | truncate_cleanup_page(struct address_space *mapping, struct page *page) | 179 | truncate_cleanup_page(struct address_space *mapping, struct page *page) |
| 180 | { | 180 | { |
| 181 | if (page_mapped(page)) { | 181 | if (page_mapped(page)) { |
| 182 | loff_t holelen; | 182 | pgoff_t nr = PageTransHuge(page) ? HPAGE_PMD_NR : 1; |
| 183 | 183 | unmap_mapping_pages(mapping, page->index, nr, false); | |
| 184 | holelen = PageTransHuge(page) ? HPAGE_PMD_SIZE : PAGE_SIZE; | ||
| 185 | unmap_mapping_range(mapping, | ||
| 186 | (loff_t)page->index << PAGE_SHIFT, | ||
| 187 | holelen, 0); | ||
| 188 | } | 184 | } |
| 189 | 185 | ||
| 190 | if (page_has_private(page)) | 186 | if (page_has_private(page)) |
| @@ -715,19 +711,15 @@ int invalidate_inode_pages2_range(struct address_space *mapping, | |||
| 715 | /* | 711 | /* |
| 716 | * Zap the rest of the file in one hit. | 712 | * Zap the rest of the file in one hit. |
| 717 | */ | 713 | */ |
| 718 | unmap_mapping_range(mapping, | 714 | unmap_mapping_pages(mapping, index, |
| 719 | (loff_t)index << PAGE_SHIFT, | 715 | (1 + end - index), false); |
| 720 | (loff_t)(1 + end - index) | ||
| 721 | << PAGE_SHIFT, | ||
| 722 | 0); | ||
| 723 | did_range_unmap = 1; | 716 | did_range_unmap = 1; |
| 724 | } else { | 717 | } else { |
| 725 | /* | 718 | /* |
| 726 | * Just zap this page | 719 | * Just zap this page |
| 727 | */ | 720 | */ |
| 728 | unmap_mapping_range(mapping, | 721 | unmap_mapping_pages(mapping, index, |
| 729 | (loff_t)index << PAGE_SHIFT, | 722 | 1, false); |
| 730 | PAGE_SIZE, 0); | ||
| 731 | } | 723 | } |
| 732 | } | 724 | } |
| 733 | BUG_ON(page_mapped(page)); | 725 | BUG_ON(page_mapped(page)); |
| @@ -753,8 +745,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, | |||
| 753 | * get remapped later. | 745 | * get remapped later. |
| 754 | */ | 746 | */ |
| 755 | if (dax_mapping(mapping)) { | 747 | if (dax_mapping(mapping)) { |
| 756 | unmap_mapping_range(mapping, (loff_t)start << PAGE_SHIFT, | 748 | unmap_mapping_pages(mapping, start, end - start + 1, false); |
| 757 | (loff_t)(end - start + 1) << PAGE_SHIFT, 0); | ||
| 758 | } | 749 | } |
| 759 | out: | 750 | out: |
| 760 | cleancache_invalidate_inode(mapping); | 751 | cleancache_invalidate_inode(mapping); |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 47d5ced51f2d..fdd3fc6be862 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -220,22 +220,6 @@ unsigned long zone_reclaimable_pages(struct zone *zone) | |||
| 220 | return nr; | 220 | return nr; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | unsigned long pgdat_reclaimable_pages(struct pglist_data *pgdat) | ||
| 224 | { | ||
| 225 | unsigned long nr; | ||
| 226 | |||
| 227 | nr = node_page_state_snapshot(pgdat, NR_ACTIVE_FILE) + | ||
| 228 | node_page_state_snapshot(pgdat, NR_INACTIVE_FILE) + | ||
| 229 | node_page_state_snapshot(pgdat, NR_ISOLATED_FILE); | ||
| 230 | |||
| 231 | if (get_nr_swap_pages() > 0) | ||
| 232 | nr += node_page_state_snapshot(pgdat, NR_ACTIVE_ANON) + | ||
| 233 | node_page_state_snapshot(pgdat, NR_INACTIVE_ANON) + | ||
| 234 | node_page_state_snapshot(pgdat, NR_ISOLATED_ANON); | ||
| 235 | |||
| 236 | return nr; | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | 223 | /** |
| 240 | * lruvec_lru_size - Returns the number of pages on the given LRU list. | 224 | * lruvec_lru_size - Returns the number of pages on the given LRU list. |
| 241 | * @lruvec: lru vector | 225 | * @lruvec: lru vector |
| @@ -310,9 +294,7 @@ EXPORT_SYMBOL(unregister_shrinker); | |||
| 310 | #define SHRINK_BATCH 128 | 294 | #define SHRINK_BATCH 128 |
| 311 | 295 | ||
| 312 | static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, | 296 | static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, |
| 313 | struct shrinker *shrinker, | 297 | struct shrinker *shrinker, int priority) |
| 314 | unsigned long nr_scanned, | ||
| 315 | unsigned long nr_eligible) | ||
| 316 | { | 298 | { |
| 317 | unsigned long freed = 0; | 299 | unsigned long freed = 0; |
| 318 | unsigned long long delta; | 300 | unsigned long long delta; |
| @@ -337,9 +319,9 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, | |||
| 337 | nr = atomic_long_xchg(&shrinker->nr_deferred[nid], 0); | 319 | nr = atomic_long_xchg(&shrinker->nr_deferred[nid], 0); |
| 338 | 320 | ||
| 339 | total_scan = nr; | 321 | total_scan = nr; |
| 340 | delta = (4 * nr_scanned) / shrinker->seeks; | 322 | delta = freeable >> priority; |
| 341 | delta *= freeable; | 323 | delta *= 4; |
| 342 | do_div(delta, nr_eligible + 1); | 324 | do_div(delta, shrinker->seeks); |
| 343 | total_scan += delta; | 325 | total_scan += delta; |
| 344 | if (total_scan < 0) { | 326 | if (total_scan < 0) { |
| 345 | pr_err("shrink_slab: %pF negative objects to delete nr=%ld\n", | 327 | pr_err("shrink_slab: %pF negative objects to delete nr=%ld\n", |
| @@ -373,8 +355,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, | |||
| 373 | total_scan = freeable * 2; | 355 | total_scan = freeable * 2; |
| 374 | 356 | ||
| 375 | trace_mm_shrink_slab_start(shrinker, shrinkctl, nr, | 357 | trace_mm_shrink_slab_start(shrinker, shrinkctl, nr, |
| 376 | nr_scanned, nr_eligible, | 358 | freeable, delta, total_scan, priority); |
| 377 | freeable, delta, total_scan); | ||
| 378 | 359 | ||
| 379 | /* | 360 | /* |
| 380 | * Normally, we should not scan less than batch_size objects in one | 361 | * Normally, we should not scan less than batch_size objects in one |
| @@ -434,8 +415,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, | |||
| 434 | * @gfp_mask: allocation context | 415 | * @gfp_mask: allocation context |
| 435 | * @nid: node whose slab caches to target | 416 | * @nid: node whose slab caches to target |
| 436 | * @memcg: memory cgroup whose slab caches to target | 417 | * @memcg: memory cgroup whose slab caches to target |
| 437 | * @nr_scanned: pressure numerator | 418 | * @priority: the reclaim priority |
| 438 | * @nr_eligible: pressure denominator | ||
| 439 | * | 419 | * |
| 440 | * Call the shrink functions to age shrinkable caches. | 420 | * Call the shrink functions to age shrinkable caches. |
| 441 | * | 421 | * |
| @@ -447,20 +427,14 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, | |||
| 447 | * objects from the memory cgroup specified. Otherwise, only unaware | 427 | * objects from the memory cgroup specified. Otherwise, only unaware |
| 448 | * shrinkers are called. | 428 | * shrinkers are called. |
| 449 | * | 429 | * |
| 450 | * @nr_scanned and @nr_eligible form a ratio that indicate how much of | 430 | * @priority is sc->priority, we take the number of objects and >> by priority |
| 451 | * the available objects should be scanned. Page reclaim for example | 431 | * in order to get the scan target. |
| 452 | * passes the number of pages scanned and the number of pages on the | ||
| 453 | * LRU lists that it considered on @nid, plus a bias in @nr_scanned | ||
| 454 | * when it encountered mapped pages. The ratio is further biased by | ||
| 455 | * the ->seeks setting of the shrink function, which indicates the | ||
| 456 | * cost to recreate an object relative to that of an LRU page. | ||
| 457 | * | 432 | * |
| 458 | * Returns the number of reclaimed slab objects. | 433 | * Returns the number of reclaimed slab objects. |
| 459 | */ | 434 | */ |
| 460 | static unsigned long shrink_slab(gfp_t gfp_mask, int nid, | 435 | static unsigned long shrink_slab(gfp_t gfp_mask, int nid, |
| 461 | struct mem_cgroup *memcg, | 436 | struct mem_cgroup *memcg, |
| 462 | unsigned long nr_scanned, | 437 | int priority) |
| 463 | unsigned long nr_eligible) | ||
| 464 | { | 438 | { |
| 465 | struct shrinker *shrinker; | 439 | struct shrinker *shrinker; |
| 466 | unsigned long freed = 0; | 440 | unsigned long freed = 0; |
| @@ -468,9 +442,6 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, | |||
| 468 | if (memcg && (!memcg_kmem_enabled() || !mem_cgroup_online(memcg))) | 442 | if (memcg && (!memcg_kmem_enabled() || !mem_cgroup_online(memcg))) |
| 469 | return 0; | 443 | return 0; |
| 470 | 444 | ||
| 471 | if (nr_scanned == 0) | ||
| 472 | nr_scanned = SWAP_CLUSTER_MAX; | ||
| 473 | |||
| 474 | if (!down_read_trylock(&shrinker_rwsem)) { | 445 | if (!down_read_trylock(&shrinker_rwsem)) { |
| 475 | /* | 446 | /* |
| 476 | * If we would return 0, our callers would understand that we | 447 | * If we would return 0, our callers would understand that we |
| @@ -501,7 +472,16 @@ static unsigned long shrink_slab(gfp_t gfp_mask, int nid, | |||
| 501 | if (!(shrinker->flags & SHRINKER_NUMA_AWARE)) | 472 | if (!(shrinker->flags & SHRINKER_NUMA_AWARE)) |
| 502 | sc.nid = 0; | 473 | sc.nid = 0; |
| 503 | 474 | ||
| 504 | freed += do_shrink_slab(&sc, shrinker, nr_scanned, nr_eligible); | 475 | freed += do_shrink_slab(&sc, shrinker, priority); |
| 476 | /* | ||
| 477 | * Bail out if someone want to register a new shrinker to | ||
| 478 | * prevent the regsitration from being stalled for long periods | ||
| 479 | * by parallel ongoing shrinking. | ||
| 480 | */ | ||
| 481 | if (rwsem_is_contended(&shrinker_rwsem)) { | ||
| 482 | freed = freed ? : 1; | ||
| 483 | break; | ||
| 484 | } | ||
| 505 | } | 485 | } |
| 506 | 486 | ||
| 507 | up_read(&shrinker_rwsem); | 487 | up_read(&shrinker_rwsem); |
| @@ -519,8 +499,7 @@ void drop_slab_node(int nid) | |||
| 519 | 499 | ||
| 520 | freed = 0; | 500 | freed = 0; |
| 521 | do { | 501 | do { |
| 522 | freed += shrink_slab(GFP_KERNEL, nid, memcg, | 502 | freed += shrink_slab(GFP_KERNEL, nid, memcg, 0); |
| 523 | 1000, 1000); | ||
| 524 | } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL); | 503 | } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)) != NULL); |
| 525 | } while (freed > 10); | 504 | } while (freed > 10); |
| 526 | } | 505 | } |
| @@ -1436,14 +1415,24 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode) | |||
| 1436 | 1415 | ||
| 1437 | if (PageDirty(page)) { | 1416 | if (PageDirty(page)) { |
| 1438 | struct address_space *mapping; | 1417 | struct address_space *mapping; |
| 1418 | bool migrate_dirty; | ||
| 1439 | 1419 | ||
| 1440 | /* | 1420 | /* |
| 1441 | * Only pages without mappings or that have a | 1421 | * Only pages without mappings or that have a |
| 1442 | * ->migratepage callback are possible to migrate | 1422 | * ->migratepage callback are possible to migrate |
| 1443 | * without blocking | 1423 | * without blocking. However, we can be racing with |
| 1424 | * truncation so it's necessary to lock the page | ||
| 1425 | * to stabilise the mapping as truncation holds | ||
| 1426 | * the page lock until after the page is removed | ||
| 1427 | * from the page cache. | ||
| 1444 | */ | 1428 | */ |
| 1429 | if (!trylock_page(page)) | ||
| 1430 | return ret; | ||
| 1431 | |||
| 1445 | mapping = page_mapping(page); | 1432 | mapping = page_mapping(page); |
| 1446 | if (mapping && !mapping->a_ops->migratepage) | 1433 | migrate_dirty = mapping && mapping->a_ops->migratepage; |
| 1434 | unlock_page(page); | ||
| 1435 | if (!migrate_dirty) | ||
| 1447 | return ret; | 1436 | return ret; |
| 1448 | } | 1437 | } |
| 1449 | } | 1438 | } |
| @@ -2615,14 +2604,12 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc) | |||
| 2615 | 2604 | ||
| 2616 | reclaimed = sc->nr_reclaimed; | 2605 | reclaimed = sc->nr_reclaimed; |
| 2617 | scanned = sc->nr_scanned; | 2606 | scanned = sc->nr_scanned; |
| 2618 | |||
| 2619 | shrink_node_memcg(pgdat, memcg, sc, &lru_pages); | 2607 | shrink_node_memcg(pgdat, memcg, sc, &lru_pages); |
| 2620 | node_lru_pages += lru_pages; | 2608 | node_lru_pages += lru_pages; |
| 2621 | 2609 | ||
| 2622 | if (memcg) | 2610 | if (memcg) |
| 2623 | shrink_slab(sc->gfp_mask, pgdat->node_id, | 2611 | shrink_slab(sc->gfp_mask, pgdat->node_id, |
| 2624 | memcg, sc->nr_scanned - scanned, | 2612 | memcg, sc->priority); |
| 2625 | lru_pages); | ||
| 2626 | 2613 | ||
| 2627 | /* Record the group's reclaim efficiency */ | 2614 | /* Record the group's reclaim efficiency */ |
| 2628 | vmpressure(sc->gfp_mask, memcg, false, | 2615 | vmpressure(sc->gfp_mask, memcg, false, |
| @@ -2646,14 +2633,9 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc) | |||
| 2646 | } | 2633 | } |
| 2647 | } while ((memcg = mem_cgroup_iter(root, memcg, &reclaim))); | 2634 | } while ((memcg = mem_cgroup_iter(root, memcg, &reclaim))); |
| 2648 | 2635 | ||
| 2649 | /* | ||
| 2650 | * Shrink the slab caches in the same proportion that | ||
| 2651 | * the eligible LRU pages were scanned. | ||
| 2652 | */ | ||
| 2653 | if (global_reclaim(sc)) | 2636 | if (global_reclaim(sc)) |
| 2654 | shrink_slab(sc->gfp_mask, pgdat->node_id, NULL, | 2637 | shrink_slab(sc->gfp_mask, pgdat->node_id, NULL, |
| 2655 | sc->nr_scanned - nr_scanned, | 2638 | sc->priority); |
| 2656 | node_lru_pages); | ||
| 2657 | 2639 | ||
| 2658 | if (reclaim_state) { | 2640 | if (reclaim_state) { |
| 2659 | sc->nr_reclaimed += reclaim_state->reclaimed_slab; | 2641 | sc->nr_reclaimed += reclaim_state->reclaimed_slab; |
diff --git a/mm/zpool.c b/mm/zpool.c index fd3ff719c32c..e1e7aa6d1d06 100644 --- a/mm/zpool.c +++ b/mm/zpool.c | |||
| @@ -21,6 +21,7 @@ struct zpool { | |||
| 21 | struct zpool_driver *driver; | 21 | struct zpool_driver *driver; |
| 22 | void *pool; | 22 | void *pool; |
| 23 | const struct zpool_ops *ops; | 23 | const struct zpool_ops *ops; |
| 24 | bool evictable; | ||
| 24 | 25 | ||
| 25 | struct list_head list; | 26 | struct list_head list; |
| 26 | }; | 27 | }; |
| @@ -142,7 +143,7 @@ EXPORT_SYMBOL(zpool_has_pool); | |||
| 142 | * | 143 | * |
| 143 | * This creates a new zpool of the specified type. The gfp flags will be | 144 | * This creates a new zpool of the specified type. The gfp flags will be |
| 144 | * used when allocating memory, if the implementation supports it. If the | 145 | * used when allocating memory, if the implementation supports it. If the |
| 145 | * ops param is NULL, then the created zpool will not be shrinkable. | 146 | * ops param is NULL, then the created zpool will not be evictable. |
| 146 | * | 147 | * |
| 147 | * Implementations must guarantee this to be thread-safe. | 148 | * Implementations must guarantee this to be thread-safe. |
| 148 | * | 149 | * |
| @@ -180,6 +181,7 @@ struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp, | |||
| 180 | zpool->driver = driver; | 181 | zpool->driver = driver; |
| 181 | zpool->pool = driver->create(name, gfp, ops, zpool); | 182 | zpool->pool = driver->create(name, gfp, ops, zpool); |
| 182 | zpool->ops = ops; | 183 | zpool->ops = ops; |
| 184 | zpool->evictable = driver->shrink && ops && ops->evict; | ||
| 183 | 185 | ||
| 184 | if (!zpool->pool) { | 186 | if (!zpool->pool) { |
| 185 | pr_err("couldn't create %s pool\n", type); | 187 | pr_err("couldn't create %s pool\n", type); |
| @@ -296,7 +298,8 @@ void zpool_free(struct zpool *zpool, unsigned long handle) | |||
| 296 | int zpool_shrink(struct zpool *zpool, unsigned int pages, | 298 | int zpool_shrink(struct zpool *zpool, unsigned int pages, |
| 297 | unsigned int *reclaimed) | 299 | unsigned int *reclaimed) |
| 298 | { | 300 | { |
| 299 | return zpool->driver->shrink(zpool->pool, pages, reclaimed); | 301 | return zpool->driver->shrink ? |
| 302 | zpool->driver->shrink(zpool->pool, pages, reclaimed) : -EINVAL; | ||
| 300 | } | 303 | } |
| 301 | 304 | ||
| 302 | /** | 305 | /** |
| @@ -355,6 +358,24 @@ u64 zpool_get_total_size(struct zpool *zpool) | |||
| 355 | return zpool->driver->total_size(zpool->pool); | 358 | return zpool->driver->total_size(zpool->pool); |
| 356 | } | 359 | } |
| 357 | 360 | ||
| 361 | /** | ||
| 362 | * zpool_evictable() - Test if zpool is potentially evictable | ||
| 363 | * @pool The zpool to test | ||
| 364 | * | ||
| 365 | * Zpool is only potentially evictable when it's created with struct | ||
| 366 | * zpool_ops.evict and its driver implements struct zpool_driver.shrink. | ||
| 367 | * | ||
| 368 | * However, it doesn't necessarily mean driver will use zpool_ops.evict | ||
| 369 | * in its implementation of zpool_driver.shrink. It could do internal | ||
| 370 | * defragmentation instead. | ||
| 371 | * | ||
| 372 | * Returns: true if potentially evictable; false otherwise. | ||
| 373 | */ | ||
| 374 | bool zpool_evictable(struct zpool *zpool) | ||
| 375 | { | ||
| 376 | return zpool->evictable; | ||
| 377 | } | ||
| 378 | |||
| 358 | MODULE_LICENSE("GPL"); | 379 | MODULE_LICENSE("GPL"); |
| 359 | MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>"); | 380 | MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>"); |
| 360 | MODULE_DESCRIPTION("Common API for compressed memory storage"); | 381 | MODULE_DESCRIPTION("Common API for compressed memory storage"); |
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 683c0651098c..c3013505c305 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
| 47 | #include <linux/preempt.h> | 47 | #include <linux/preempt.h> |
| 48 | #include <linux/spinlock.h> | 48 | #include <linux/spinlock.h> |
| 49 | #include <linux/shrinker.h> | ||
| 49 | #include <linux/types.h> | 50 | #include <linux/types.h> |
| 50 | #include <linux/debugfs.h> | 51 | #include <linux/debugfs.h> |
| 51 | #include <linux/zsmalloc.h> | 52 | #include <linux/zsmalloc.h> |
| @@ -257,11 +258,7 @@ struct zs_pool { | |||
| 257 | 258 | ||
| 258 | /* Compact classes */ | 259 | /* Compact classes */ |
| 259 | struct shrinker shrinker; | 260 | struct shrinker shrinker; |
| 260 | /* | 261 | |
| 261 | * To signify that register_shrinker() was successful | ||
| 262 | * and unregister_shrinker() will not Oops. | ||
| 263 | */ | ||
| 264 | bool shrinker_enabled; | ||
| 265 | #ifdef CONFIG_ZSMALLOC_STAT | 262 | #ifdef CONFIG_ZSMALLOC_STAT |
| 266 | struct dentry *stat_dentry; | 263 | struct dentry *stat_dentry; |
| 267 | #endif | 264 | #endif |
| @@ -407,12 +404,6 @@ static void zs_zpool_free(void *pool, unsigned long handle) | |||
| 407 | zs_free(pool, handle); | 404 | zs_free(pool, handle); |
| 408 | } | 405 | } |
| 409 | 406 | ||
| 410 | static int zs_zpool_shrink(void *pool, unsigned int pages, | ||
| 411 | unsigned int *reclaimed) | ||
| 412 | { | ||
| 413 | return -EINVAL; | ||
| 414 | } | ||
| 415 | |||
| 416 | static void *zs_zpool_map(void *pool, unsigned long handle, | 407 | static void *zs_zpool_map(void *pool, unsigned long handle, |
| 417 | enum zpool_mapmode mm) | 408 | enum zpool_mapmode mm) |
| 418 | { | 409 | { |
| @@ -450,7 +441,6 @@ static struct zpool_driver zs_zpool_driver = { | |||
| 450 | .destroy = zs_zpool_destroy, | 441 | .destroy = zs_zpool_destroy, |
| 451 | .malloc = zs_zpool_malloc, | 442 | .malloc = zs_zpool_malloc, |
| 452 | .free = zs_zpool_free, | 443 | .free = zs_zpool_free, |
| 453 | .shrink = zs_zpool_shrink, | ||
| 454 | .map = zs_zpool_map, | 444 | .map = zs_zpool_map, |
| 455 | .unmap = zs_zpool_unmap, | 445 | .unmap = zs_zpool_unmap, |
| 456 | .total_size = zs_zpool_total_size, | 446 | .total_size = zs_zpool_total_size, |
| @@ -1057,7 +1047,7 @@ static void init_zspage(struct size_class *class, struct zspage *zspage) | |||
| 1057 | * Reset OBJ_TAG_BITS bit to last link to tell | 1047 | * Reset OBJ_TAG_BITS bit to last link to tell |
| 1058 | * whether it's allocated object or not. | 1048 | * whether it's allocated object or not. |
| 1059 | */ | 1049 | */ |
| 1060 | link->next = -1 << OBJ_TAG_BITS; | 1050 | link->next = -1UL << OBJ_TAG_BITS; |
| 1061 | } | 1051 | } |
| 1062 | kunmap_atomic(vaddr); | 1052 | kunmap_atomic(vaddr); |
| 1063 | page = next_page; | 1053 | page = next_page; |
| @@ -2324,10 +2314,7 @@ static unsigned long zs_shrinker_count(struct shrinker *shrinker, | |||
| 2324 | 2314 | ||
| 2325 | static void zs_unregister_shrinker(struct zs_pool *pool) | 2315 | static void zs_unregister_shrinker(struct zs_pool *pool) |
| 2326 | { | 2316 | { |
| 2327 | if (pool->shrinker_enabled) { | 2317 | unregister_shrinker(&pool->shrinker); |
| 2328 | unregister_shrinker(&pool->shrinker); | ||
| 2329 | pool->shrinker_enabled = false; | ||
| 2330 | } | ||
| 2331 | } | 2318 | } |
| 2332 | 2319 | ||
| 2333 | static int zs_register_shrinker(struct zs_pool *pool) | 2320 | static int zs_register_shrinker(struct zs_pool *pool) |
| @@ -2426,11 +2413,13 @@ struct zs_pool *zs_create_pool(const char *name) | |||
| 2426 | goto err; | 2413 | goto err; |
| 2427 | 2414 | ||
| 2428 | /* | 2415 | /* |
| 2429 | * Not critical, we still can use the pool | 2416 | * Not critical since shrinker is only used to trigger internal |
| 2430 | * and user can trigger compaction manually. | 2417 | * defragmentation of the pool which is pretty optional thing. If |
| 2418 | * registration fails we still can use the pool normally and user can | ||
| 2419 | * trigger compaction manually. Thus, ignore return code. | ||
| 2431 | */ | 2420 | */ |
| 2432 | if (zs_register_shrinker(pool) == 0) | 2421 | zs_register_shrinker(pool); |
| 2433 | pool->shrinker_enabled = true; | 2422 | |
| 2434 | return pool; | 2423 | return pool; |
| 2435 | 2424 | ||
| 2436 | err: | 2425 | err: |
diff --git a/mm/zswap.c b/mm/zswap.c index d39581a076c3..c004aa4fd3f4 100644 --- a/mm/zswap.c +++ b/mm/zswap.c | |||
| @@ -49,6 +49,8 @@ | |||
| 49 | static u64 zswap_pool_total_size; | 49 | static u64 zswap_pool_total_size; |
| 50 | /* The number of compressed pages currently stored in zswap */ | 50 | /* The number of compressed pages currently stored in zswap */ |
| 51 | static atomic_t zswap_stored_pages = ATOMIC_INIT(0); | 51 | static atomic_t zswap_stored_pages = ATOMIC_INIT(0); |
| 52 | /* The number of same-value filled pages currently stored in zswap */ | ||
| 53 | static atomic_t zswap_same_filled_pages = ATOMIC_INIT(0); | ||
| 52 | 54 | ||
| 53 | /* | 55 | /* |
| 54 | * The statistics below are not protected from concurrent access for | 56 | * The statistics below are not protected from concurrent access for |
| @@ -116,6 +118,11 @@ module_param_cb(zpool, &zswap_zpool_param_ops, &zswap_zpool_type, 0644); | |||
| 116 | static unsigned int zswap_max_pool_percent = 20; | 118 | static unsigned int zswap_max_pool_percent = 20; |
| 117 | module_param_named(max_pool_percent, zswap_max_pool_percent, uint, 0644); | 119 | module_param_named(max_pool_percent, zswap_max_pool_percent, uint, 0644); |
| 118 | 120 | ||
| 121 | /* Enable/disable handling same-value filled pages (enabled by default) */ | ||
| 122 | static bool zswap_same_filled_pages_enabled = true; | ||
| 123 | module_param_named(same_filled_pages_enabled, zswap_same_filled_pages_enabled, | ||
| 124 | bool, 0644); | ||
| 125 | |||
| 119 | /********************************* | 126 | /********************************* |
| 120 | * data structures | 127 | * data structures |
| 121 | **********************************/ | 128 | **********************************/ |
| @@ -145,9 +152,10 @@ struct zswap_pool { | |||
| 145 | * be held while changing the refcount. Since the lock must | 152 | * be held while changing the refcount. Since the lock must |
| 146 | * be held, there is no reason to also make refcount atomic. | 153 | * be held, there is no reason to also make refcount atomic. |
| 147 | * length - the length in bytes of the compressed page data. Needed during | 154 | * length - the length in bytes of the compressed page data. Needed during |
| 148 | * decompression | 155 | * decompression. For a same value filled page length is 0. |
| 149 | * pool - the zswap_pool the entry's data is in | 156 | * pool - the zswap_pool the entry's data is in |
| 150 | * handle - zpool allocation handle that stores the compressed page data | 157 | * handle - zpool allocation handle that stores the compressed page data |
| 158 | * value - value of the same-value filled pages which have same content | ||
| 151 | */ | 159 | */ |
| 152 | struct zswap_entry { | 160 | struct zswap_entry { |
| 153 | struct rb_node rbnode; | 161 | struct rb_node rbnode; |
| @@ -155,7 +163,10 @@ struct zswap_entry { | |||
| 155 | int refcount; | 163 | int refcount; |
| 156 | unsigned int length; | 164 | unsigned int length; |
| 157 | struct zswap_pool *pool; | 165 | struct zswap_pool *pool; |
| 158 | unsigned long handle; | 166 | union { |
| 167 | unsigned long handle; | ||
| 168 | unsigned long value; | ||
| 169 | }; | ||
| 159 | }; | 170 | }; |
| 160 | 171 | ||
| 161 | struct zswap_header { | 172 | struct zswap_header { |
| @@ -320,8 +331,12 @@ static void zswap_rb_erase(struct rb_root *root, struct zswap_entry *entry) | |||
| 320 | */ | 331 | */ |
| 321 | static void zswap_free_entry(struct zswap_entry *entry) | 332 | static void zswap_free_entry(struct zswap_entry *entry) |
| 322 | { | 333 | { |
| 323 | zpool_free(entry->pool->zpool, entry->handle); | 334 | if (!entry->length) |
| 324 | zswap_pool_put(entry->pool); | 335 | atomic_dec(&zswap_same_filled_pages); |
| 336 | else { | ||
| 337 | zpool_free(entry->pool->zpool, entry->handle); | ||
| 338 | zswap_pool_put(entry->pool); | ||
| 339 | } | ||
| 325 | zswap_entry_cache_free(entry); | 340 | zswap_entry_cache_free(entry); |
| 326 | atomic_dec(&zswap_stored_pages); | 341 | atomic_dec(&zswap_stored_pages); |
| 327 | zswap_update_total_size(); | 342 | zswap_update_total_size(); |
| @@ -953,6 +968,28 @@ static int zswap_shrink(void) | |||
| 953 | return ret; | 968 | return ret; |
| 954 | } | 969 | } |
| 955 | 970 | ||
| 971 | static int zswap_is_page_same_filled(void *ptr, unsigned long *value) | ||
| 972 | { | ||
| 973 | unsigned int pos; | ||
| 974 | unsigned long *page; | ||
| 975 | |||
| 976 | page = (unsigned long *)ptr; | ||
| 977 | for (pos = 1; pos < PAGE_SIZE / sizeof(*page); pos++) { | ||
| 978 | if (page[pos] != page[0]) | ||
| 979 | return 0; | ||
| 980 | } | ||
| 981 | *value = page[0]; | ||
| 982 | return 1; | ||
| 983 | } | ||
| 984 | |||
| 985 | static void zswap_fill_page(void *ptr, unsigned long value) | ||
| 986 | { | ||
| 987 | unsigned long *page; | ||
| 988 | |||
| 989 | page = (unsigned long *)ptr; | ||
| 990 | memset_l(page, value, PAGE_SIZE / sizeof(unsigned long)); | ||
| 991 | } | ||
| 992 | |||
| 956 | /********************************* | 993 | /********************************* |
| 957 | * frontswap hooks | 994 | * frontswap hooks |
| 958 | **********************************/ | 995 | **********************************/ |
| @@ -964,11 +1001,11 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
| 964 | struct zswap_entry *entry, *dupentry; | 1001 | struct zswap_entry *entry, *dupentry; |
| 965 | struct crypto_comp *tfm; | 1002 | struct crypto_comp *tfm; |
| 966 | int ret; | 1003 | int ret; |
| 967 | unsigned int dlen = PAGE_SIZE, len; | 1004 | unsigned int hlen, dlen = PAGE_SIZE; |
| 968 | unsigned long handle; | 1005 | unsigned long handle, value; |
| 969 | char *buf; | 1006 | char *buf; |
| 970 | u8 *src, *dst; | 1007 | u8 *src, *dst; |
| 971 | struct zswap_header *zhdr; | 1008 | struct zswap_header zhdr = { .swpentry = swp_entry(type, offset) }; |
| 972 | 1009 | ||
| 973 | if (!zswap_enabled || !tree) { | 1010 | if (!zswap_enabled || !tree) { |
| 974 | ret = -ENODEV; | 1011 | ret = -ENODEV; |
| @@ -993,6 +1030,19 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
| 993 | goto reject; | 1030 | goto reject; |
| 994 | } | 1031 | } |
| 995 | 1032 | ||
| 1033 | if (zswap_same_filled_pages_enabled) { | ||
| 1034 | src = kmap_atomic(page); | ||
| 1035 | if (zswap_is_page_same_filled(src, &value)) { | ||
| 1036 | kunmap_atomic(src); | ||
| 1037 | entry->offset = offset; | ||
| 1038 | entry->length = 0; | ||
| 1039 | entry->value = value; | ||
| 1040 | atomic_inc(&zswap_same_filled_pages); | ||
| 1041 | goto insert_entry; | ||
| 1042 | } | ||
| 1043 | kunmap_atomic(src); | ||
| 1044 | } | ||
| 1045 | |||
| 996 | /* if entry is successfully added, it keeps the reference */ | 1046 | /* if entry is successfully added, it keeps the reference */ |
| 997 | entry->pool = zswap_pool_current_get(); | 1047 | entry->pool = zswap_pool_current_get(); |
| 998 | if (!entry->pool) { | 1048 | if (!entry->pool) { |
| @@ -1013,8 +1063,8 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
| 1013 | } | 1063 | } |
| 1014 | 1064 | ||
| 1015 | /* store */ | 1065 | /* store */ |
| 1016 | len = dlen + sizeof(struct zswap_header); | 1066 | hlen = zpool_evictable(entry->pool->zpool) ? sizeof(zhdr) : 0; |
| 1017 | ret = zpool_malloc(entry->pool->zpool, len, | 1067 | ret = zpool_malloc(entry->pool->zpool, hlen + dlen, |
| 1018 | __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM, | 1068 | __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM, |
| 1019 | &handle); | 1069 | &handle); |
| 1020 | if (ret == -ENOSPC) { | 1070 | if (ret == -ENOSPC) { |
| @@ -1025,10 +1075,9 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
| 1025 | zswap_reject_alloc_fail++; | 1075 | zswap_reject_alloc_fail++; |
| 1026 | goto put_dstmem; | 1076 | goto put_dstmem; |
| 1027 | } | 1077 | } |
| 1028 | zhdr = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW); | 1078 | buf = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW); |
| 1029 | zhdr->swpentry = swp_entry(type, offset); | 1079 | memcpy(buf, &zhdr, hlen); |
| 1030 | buf = (u8 *)(zhdr + 1); | 1080 | memcpy(buf + hlen, dst, dlen); |
| 1031 | memcpy(buf, dst, dlen); | ||
| 1032 | zpool_unmap_handle(entry->pool->zpool, handle); | 1081 | zpool_unmap_handle(entry->pool->zpool, handle); |
| 1033 | put_cpu_var(zswap_dstmem); | 1082 | put_cpu_var(zswap_dstmem); |
| 1034 | 1083 | ||
| @@ -1037,6 +1086,7 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
| 1037 | entry->handle = handle; | 1086 | entry->handle = handle; |
| 1038 | entry->length = dlen; | 1087 | entry->length = dlen; |
| 1039 | 1088 | ||
| 1089 | insert_entry: | ||
| 1040 | /* map */ | 1090 | /* map */ |
| 1041 | spin_lock(&tree->lock); | 1091 | spin_lock(&tree->lock); |
| 1042 | do { | 1092 | do { |
| @@ -1089,10 +1139,18 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset, | |||
| 1089 | } | 1139 | } |
| 1090 | spin_unlock(&tree->lock); | 1140 | spin_unlock(&tree->lock); |
| 1091 | 1141 | ||
| 1142 | if (!entry->length) { | ||
| 1143 | dst = kmap_atomic(page); | ||
| 1144 | zswap_fill_page(dst, entry->value); | ||
| 1145 | kunmap_atomic(dst); | ||
| 1146 | goto freeentry; | ||
| 1147 | } | ||
| 1148 | |||
| 1092 | /* decompress */ | 1149 | /* decompress */ |
| 1093 | dlen = PAGE_SIZE; | 1150 | dlen = PAGE_SIZE; |
| 1094 | src = (u8 *)zpool_map_handle(entry->pool->zpool, entry->handle, | 1151 | src = zpool_map_handle(entry->pool->zpool, entry->handle, ZPOOL_MM_RO); |
| 1095 | ZPOOL_MM_RO) + sizeof(struct zswap_header); | 1152 | if (zpool_evictable(entry->pool->zpool)) |
| 1153 | src += sizeof(struct zswap_header); | ||
| 1096 | dst = kmap_atomic(page); | 1154 | dst = kmap_atomic(page); |
| 1097 | tfm = *get_cpu_ptr(entry->pool->tfm); | 1155 | tfm = *get_cpu_ptr(entry->pool->tfm); |
| 1098 | ret = crypto_comp_decompress(tfm, src, entry->length, dst, &dlen); | 1156 | ret = crypto_comp_decompress(tfm, src, entry->length, dst, &dlen); |
| @@ -1101,6 +1159,7 @@ static int zswap_frontswap_load(unsigned type, pgoff_t offset, | |||
| 1101 | zpool_unmap_handle(entry->pool->zpool, entry->handle); | 1159 | zpool_unmap_handle(entry->pool->zpool, entry->handle); |
| 1102 | BUG_ON(ret); | 1160 | BUG_ON(ret); |
| 1103 | 1161 | ||
| 1162 | freeentry: | ||
| 1104 | spin_lock(&tree->lock); | 1163 | spin_lock(&tree->lock); |
| 1105 | zswap_entry_put(tree, entry); | 1164 | zswap_entry_put(tree, entry); |
| 1106 | spin_unlock(&tree->lock); | 1165 | spin_unlock(&tree->lock); |
| @@ -1209,6 +1268,8 @@ static int __init zswap_debugfs_init(void) | |||
| 1209 | zswap_debugfs_root, &zswap_pool_total_size); | 1268 | zswap_debugfs_root, &zswap_pool_total_size); |
| 1210 | debugfs_create_atomic_t("stored_pages", S_IRUGO, | 1269 | debugfs_create_atomic_t("stored_pages", S_IRUGO, |
| 1211 | zswap_debugfs_root, &zswap_stored_pages); | 1270 | zswap_debugfs_root, &zswap_stored_pages); |
| 1271 | debugfs_create_atomic_t("same_filled_pages", 0444, | ||
| 1272 | zswap_debugfs_root, &zswap_same_filled_pages); | ||
| 1212 | 1273 | ||
| 1213 | return 0; | 1274 | return 0; |
| 1214 | } | 1275 | } |
diff --git a/scripts/decodecode b/scripts/decodecode index 5ea071099330..9cef558528aa 100755 --- a/scripts/decodecode +++ b/scripts/decodecode | |||
| @@ -21,12 +21,24 @@ trap cleanup EXIT | |||
| 21 | 21 | ||
| 22 | T=`mktemp` || die "cannot create temp file" | 22 | T=`mktemp` || die "cannot create temp file" |
| 23 | code= | 23 | code= |
| 24 | cont= | ||
| 24 | 25 | ||
| 25 | while read i ; do | 26 | while read i ; do |
| 26 | 27 | ||
| 27 | case "$i" in | 28 | case "$i" in |
| 28 | *Code:*) | 29 | *Code:*) |
| 29 | code=$i | 30 | code=$i |
| 31 | cont=yes | ||
| 32 | ;; | ||
| 33 | *) | ||
| 34 | [ -n "$cont" ] && { | ||
| 35 | xdump="$(echo $i | grep '^[[:xdigit:]<>[:space:]]\+$')" | ||
| 36 | if [ -n "$xdump" ]; then | ||
| 37 | code="$code $xdump" | ||
| 38 | else | ||
| 39 | cont= | ||
| 40 | fi | ||
| 41 | } | ||
| 30 | ;; | 42 | ;; |
| 31 | esac | 43 | esac |
| 32 | 44 | ||
diff --git a/scripts/tags.sh b/scripts/tags.sh index d23dcbf17457..78e546ff689c 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
| @@ -77,7 +77,7 @@ find_include_sources() | |||
| 77 | find_other_sources() | 77 | find_other_sources() |
| 78 | { | 78 | { |
| 79 | find ${tree}* $ignore \ | 79 | find ${tree}* $ignore \ |
| 80 | \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ | 80 | \( -path ${tree}include -o -path ${tree}arch -o -name '.tmp_*' \) -prune -o \ |
| 81 | -name "$1" -not -type l -print; | 81 | -name "$1" -not -type l -print; |
| 82 | } | 82 | } |
| 83 | 83 | ||
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 3926a0409dda..a5276a91dfbf 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile | |||
| @@ -12,3 +12,8 @@ fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) | |||
| 12 | include ../lib.mk | 12 | include ../lib.mk |
| 13 | 13 | ||
| 14 | $(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) | 14 | $(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) |
| 15 | |||
| 16 | $(OUTPUT)/memfd_test: memfd_test.c common.o | ||
| 17 | $(OUTPUT)/fuse_test: fuse_test.c common.o | ||
| 18 | |||
| 19 | EXTRA_CLEAN = common.o | ||
diff --git a/tools/testing/selftests/memfd/common.c b/tools/testing/selftests/memfd/common.c new file mode 100644 index 000000000000..8eb3d75f6e60 --- /dev/null +++ b/tools/testing/selftests/memfd/common.c | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | #define _GNU_SOURCE | ||
| 3 | #define __EXPORTED_HEADERS__ | ||
| 4 | |||
| 5 | #include <stdio.h> | ||
| 6 | #include <stdlib.h> | ||
| 7 | #include <linux/fcntl.h> | ||
| 8 | #include <linux/memfd.h> | ||
| 9 | #include <unistd.h> | ||
| 10 | #include <sys/syscall.h> | ||
| 11 | |||
| 12 | #include "common.h" | ||
| 13 | |||
| 14 | int hugetlbfs_test = 0; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Copied from mlock2-tests.c | ||
| 18 | */ | ||
| 19 | unsigned long default_huge_page_size(void) | ||
| 20 | { | ||
| 21 | unsigned long hps = 0; | ||
| 22 | char *line = NULL; | ||
| 23 | size_t linelen = 0; | ||
| 24 | FILE *f = fopen("/proc/meminfo", "r"); | ||
| 25 | |||
| 26 | if (!f) | ||
| 27 | return 0; | ||
| 28 | while (getline(&line, &linelen, f) > 0) { | ||
| 29 | if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) { | ||
| 30 | hps <<= 10; | ||
| 31 | break; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | free(line); | ||
| 36 | fclose(f); | ||
| 37 | return hps; | ||
| 38 | } | ||
| 39 | |||
| 40 | int sys_memfd_create(const char *name, unsigned int flags) | ||
| 41 | { | ||
| 42 | if (hugetlbfs_test) | ||
| 43 | flags |= MFD_HUGETLB; | ||
| 44 | |||
| 45 | return syscall(__NR_memfd_create, name, flags); | ||
| 46 | } | ||
diff --git a/tools/testing/selftests/memfd/common.h b/tools/testing/selftests/memfd/common.h new file mode 100644 index 000000000000..522d2c630bd8 --- /dev/null +++ b/tools/testing/selftests/memfd/common.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #ifndef COMMON_H_ | ||
| 2 | #define COMMON_H_ | ||
| 3 | |||
| 4 | extern int hugetlbfs_test; | ||
| 5 | |||
| 6 | unsigned long default_huge_page_size(void); | ||
| 7 | int sys_memfd_create(const char *name, unsigned int flags); | ||
| 8 | |||
| 9 | #endif | ||
diff --git a/tools/testing/selftests/memfd/fuse_test.c b/tools/testing/selftests/memfd/fuse_test.c index 1ccb7a3eb14b..b018e835737d 100644 --- a/tools/testing/selftests/memfd/fuse_test.c +++ b/tools/testing/selftests/memfd/fuse_test.c | |||
| @@ -33,14 +33,12 @@ | |||
| 33 | #include <sys/wait.h> | 33 | #include <sys/wait.h> |
| 34 | #include <unistd.h> | 34 | #include <unistd.h> |
| 35 | 35 | ||
| 36 | #include "common.h" | ||
| 37 | |||
| 36 | #define MFD_DEF_SIZE 8192 | 38 | #define MFD_DEF_SIZE 8192 |
| 37 | #define STACK_SIZE 65536 | 39 | #define STACK_SIZE 65536 |
| 38 | 40 | ||
| 39 | static int sys_memfd_create(const char *name, | 41 | static size_t mfd_def_size = MFD_DEF_SIZE; |
| 40 | unsigned int flags) | ||
| 41 | { | ||
| 42 | return syscall(__NR_memfd_create, name, flags); | ||
| 43 | } | ||
| 44 | 42 | ||
| 45 | static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) | 43 | static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) |
| 46 | { | 44 | { |
| @@ -127,7 +125,7 @@ static void *mfd_assert_mmap_shared(int fd) | |||
| 127 | void *p; | 125 | void *p; |
| 128 | 126 | ||
| 129 | p = mmap(NULL, | 127 | p = mmap(NULL, |
| 130 | MFD_DEF_SIZE, | 128 | mfd_def_size, |
| 131 | PROT_READ | PROT_WRITE, | 129 | PROT_READ | PROT_WRITE, |
| 132 | MAP_SHARED, | 130 | MAP_SHARED, |
| 133 | fd, | 131 | fd, |
| @@ -145,7 +143,7 @@ static void *mfd_assert_mmap_private(int fd) | |||
| 145 | void *p; | 143 | void *p; |
| 146 | 144 | ||
| 147 | p = mmap(NULL, | 145 | p = mmap(NULL, |
| 148 | MFD_DEF_SIZE, | 146 | mfd_def_size, |
| 149 | PROT_READ | PROT_WRITE, | 147 | PROT_READ | PROT_WRITE, |
| 150 | MAP_PRIVATE, | 148 | MAP_PRIVATE, |
| 151 | fd, | 149 | fd, |
| @@ -178,7 +176,7 @@ static int sealing_thread_fn(void *arg) | |||
| 178 | usleep(200000); | 176 | usleep(200000); |
| 179 | 177 | ||
| 180 | /* unmount mapping before sealing to avoid i_mmap_writable failures */ | 178 | /* unmount mapping before sealing to avoid i_mmap_writable failures */ |
| 181 | munmap(global_p, MFD_DEF_SIZE); | 179 | munmap(global_p, mfd_def_size); |
| 182 | 180 | ||
| 183 | /* Try sealing the global file; expect EBUSY or success. Current | 181 | /* Try sealing the global file; expect EBUSY or success. Current |
| 184 | * kernels will never succeed, but in the future, kernels might | 182 | * kernels will never succeed, but in the future, kernels might |
| @@ -228,7 +226,7 @@ static void join_sealing_thread(pid_t pid) | |||
| 228 | 226 | ||
| 229 | int main(int argc, char **argv) | 227 | int main(int argc, char **argv) |
| 230 | { | 228 | { |
| 231 | static const char zero[MFD_DEF_SIZE]; | 229 | char *zero; |
| 232 | int fd, mfd, r; | 230 | int fd, mfd, r; |
| 233 | void *p; | 231 | void *p; |
| 234 | int was_sealed; | 232 | int was_sealed; |
| @@ -239,6 +237,25 @@ int main(int argc, char **argv) | |||
| 239 | abort(); | 237 | abort(); |
| 240 | } | 238 | } |
| 241 | 239 | ||
| 240 | if (argc >= 3) { | ||
| 241 | if (!strcmp(argv[2], "hugetlbfs")) { | ||
| 242 | unsigned long hpage_size = default_huge_page_size(); | ||
| 243 | |||
| 244 | if (!hpage_size) { | ||
| 245 | printf("Unable to determine huge page size\n"); | ||
| 246 | abort(); | ||
| 247 | } | ||
| 248 | |||
| 249 | hugetlbfs_test = 1; | ||
| 250 | mfd_def_size = hpage_size * 2; | ||
| 251 | } else { | ||
| 252 | printf("Unknown option: %s\n", argv[2]); | ||
| 253 | abort(); | ||
| 254 | } | ||
| 255 | } | ||
| 256 | |||
| 257 | zero = calloc(sizeof(*zero), mfd_def_size); | ||
| 258 | |||
| 242 | /* open FUSE memfd file for GUP testing */ | 259 | /* open FUSE memfd file for GUP testing */ |
| 243 | printf("opening: %s\n", argv[1]); | 260 | printf("opening: %s\n", argv[1]); |
| 244 | fd = open(argv[1], O_RDONLY | O_CLOEXEC); | 261 | fd = open(argv[1], O_RDONLY | O_CLOEXEC); |
| @@ -249,7 +266,7 @@ int main(int argc, char **argv) | |||
| 249 | 266 | ||
| 250 | /* create new memfd-object */ | 267 | /* create new memfd-object */ |
| 251 | mfd = mfd_assert_new("kern_memfd_fuse", | 268 | mfd = mfd_assert_new("kern_memfd_fuse", |
| 252 | MFD_DEF_SIZE, | 269 | mfd_def_size, |
| 253 | MFD_CLOEXEC | MFD_ALLOW_SEALING); | 270 | MFD_CLOEXEC | MFD_ALLOW_SEALING); |
| 254 | 271 | ||
| 255 | /* mmap memfd-object for writing */ | 272 | /* mmap memfd-object for writing */ |
| @@ -268,7 +285,7 @@ int main(int argc, char **argv) | |||
| 268 | * This guarantees that the receive-buffer is pinned for 1s until the | 285 | * This guarantees that the receive-buffer is pinned for 1s until the |
| 269 | * data is written into it. The racing ADD_SEALS should thus fail as | 286 | * data is written into it. The racing ADD_SEALS should thus fail as |
| 270 | * the pages are still pinned. */ | 287 | * the pages are still pinned. */ |
| 271 | r = read(fd, p, MFD_DEF_SIZE); | 288 | r = read(fd, p, mfd_def_size); |
| 272 | if (r < 0) { | 289 | if (r < 0) { |
| 273 | printf("read() failed: %m\n"); | 290 | printf("read() failed: %m\n"); |
| 274 | abort(); | 291 | abort(); |
| @@ -295,10 +312,10 @@ int main(int argc, char **argv) | |||
| 295 | * enough to avoid any in-flight writes. */ | 312 | * enough to avoid any in-flight writes. */ |
| 296 | 313 | ||
| 297 | p = mfd_assert_mmap_private(mfd); | 314 | p = mfd_assert_mmap_private(mfd); |
| 298 | if (was_sealed && memcmp(p, zero, MFD_DEF_SIZE)) { | 315 | if (was_sealed && memcmp(p, zero, mfd_def_size)) { |
| 299 | printf("memfd sealed during read() but data not discarded\n"); | 316 | printf("memfd sealed during read() but data not discarded\n"); |
| 300 | abort(); | 317 | abort(); |
| 301 | } else if (!was_sealed && !memcmp(p, zero, MFD_DEF_SIZE)) { | 318 | } else if (!was_sealed && !memcmp(p, zero, mfd_def_size)) { |
| 302 | printf("memfd sealed after read() but data discarded\n"); | 319 | printf("memfd sealed after read() but data discarded\n"); |
| 303 | abort(); | 320 | abort(); |
| 304 | } | 321 | } |
| @@ -307,6 +324,7 @@ int main(int argc, char **argv) | |||
| 307 | close(fd); | 324 | close(fd); |
| 308 | 325 | ||
| 309 | printf("fuse: DONE\n"); | 326 | printf("fuse: DONE\n"); |
| 327 | free(zero); | ||
| 310 | 328 | ||
| 311 | return 0; | 329 | return 0; |
| 312 | } | 330 | } |
diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c index 132a54f74e88..10baa1652fc2 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c | |||
| @@ -19,7 +19,10 @@ | |||
| 19 | #include <sys/wait.h> | 19 | #include <sys/wait.h> |
| 20 | #include <unistd.h> | 20 | #include <unistd.h> |
| 21 | 21 | ||
| 22 | #include "common.h" | ||
| 23 | |||
| 22 | #define MEMFD_STR "memfd:" | 24 | #define MEMFD_STR "memfd:" |
| 25 | #define MEMFD_HUGE_STR "memfd-hugetlb:" | ||
| 23 | #define SHARED_FT_STR "(shared file-table)" | 26 | #define SHARED_FT_STR "(shared file-table)" |
| 24 | 27 | ||
| 25 | #define MFD_DEF_SIZE 8192 | 28 | #define MFD_DEF_SIZE 8192 |
| @@ -28,41 +31,8 @@ | |||
| 28 | /* | 31 | /* |
| 29 | * Default is not to test hugetlbfs | 32 | * Default is not to test hugetlbfs |
| 30 | */ | 33 | */ |
| 31 | static int hugetlbfs_test; | ||
| 32 | static size_t mfd_def_size = MFD_DEF_SIZE; | 34 | static size_t mfd_def_size = MFD_DEF_SIZE; |
| 33 | 35 | static const char *memfd_str = MEMFD_STR; | |
| 34 | /* | ||
| 35 | * Copied from mlock2-tests.c | ||
| 36 | */ | ||
| 37 | static unsigned long default_huge_page_size(void) | ||
| 38 | { | ||
| 39 | unsigned long hps = 0; | ||
| 40 | char *line = NULL; | ||
| 41 | size_t linelen = 0; | ||
| 42 | FILE *f = fopen("/proc/meminfo", "r"); | ||
| 43 | |||
| 44 | if (!f) | ||
| 45 | return 0; | ||
| 46 | while (getline(&line, &linelen, f) > 0) { | ||
| 47 | if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) { | ||
| 48 | hps <<= 10; | ||
| 49 | break; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | free(line); | ||
| 54 | fclose(f); | ||
| 55 | return hps; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int sys_memfd_create(const char *name, | ||
| 59 | unsigned int flags) | ||
| 60 | { | ||
| 61 | if (hugetlbfs_test) | ||
| 62 | flags |= MFD_HUGETLB; | ||
| 63 | |||
| 64 | return syscall(__NR_memfd_create, name, flags); | ||
| 65 | } | ||
| 66 | 36 | ||
| 67 | static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) | 37 | static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) |
| 68 | { | 38 | { |
| @@ -513,6 +483,10 @@ static void mfd_assert_grow_write(int fd) | |||
| 513 | static char *buf; | 483 | static char *buf; |
| 514 | ssize_t l; | 484 | ssize_t l; |
| 515 | 485 | ||
| 486 | /* hugetlbfs does not support write */ | ||
| 487 | if (hugetlbfs_test) | ||
| 488 | return; | ||
| 489 | |||
| 516 | buf = malloc(mfd_def_size * 8); | 490 | buf = malloc(mfd_def_size * 8); |
| 517 | if (!buf) { | 491 | if (!buf) { |
| 518 | printf("malloc(%zu) failed: %m\n", mfd_def_size * 8); | 492 | printf("malloc(%zu) failed: %m\n", mfd_def_size * 8); |
| @@ -533,6 +507,10 @@ static void mfd_fail_grow_write(int fd) | |||
| 533 | static char *buf; | 507 | static char *buf; |
| 534 | ssize_t l; | 508 | ssize_t l; |
| 535 | 509 | ||
| 510 | /* hugetlbfs does not support write */ | ||
| 511 | if (hugetlbfs_test) | ||
| 512 | return; | ||
| 513 | |||
| 536 | buf = malloc(mfd_def_size * 8); | 514 | buf = malloc(mfd_def_size * 8); |
| 537 | if (!buf) { | 515 | if (!buf) { |
| 538 | printf("malloc(%zu) failed: %m\n", mfd_def_size * 8); | 516 | printf("malloc(%zu) failed: %m\n", mfd_def_size * 8); |
| @@ -598,7 +576,7 @@ static void test_create(void) | |||
| 598 | char buf[2048]; | 576 | char buf[2048]; |
| 599 | int fd; | 577 | int fd; |
| 600 | 578 | ||
| 601 | printf("%s CREATE\n", MEMFD_STR); | 579 | printf("%s CREATE\n", memfd_str); |
| 602 | 580 | ||
| 603 | /* test NULL name */ | 581 | /* test NULL name */ |
| 604 | mfd_fail_new(NULL, 0); | 582 | mfd_fail_new(NULL, 0); |
| @@ -627,18 +605,13 @@ static void test_create(void) | |||
| 627 | fd = mfd_assert_new("", 0, MFD_CLOEXEC); | 605 | fd = mfd_assert_new("", 0, MFD_CLOEXEC); |
| 628 | close(fd); | 606 | close(fd); |
| 629 | 607 | ||
| 630 | if (!hugetlbfs_test) { | 608 | /* verify MFD_ALLOW_SEALING is allowed */ |
| 631 | /* verify MFD_ALLOW_SEALING is allowed */ | 609 | fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING); |
| 632 | fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING); | 610 | close(fd); |
| 633 | close(fd); | 611 | |
| 634 | 612 | /* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */ | |
| 635 | /* verify MFD_ALLOW_SEALING | MFD_CLOEXEC is allowed */ | 613 | fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC); |
| 636 | fd = mfd_assert_new("", 0, MFD_ALLOW_SEALING | MFD_CLOEXEC); | 614 | close(fd); |
| 637 | close(fd); | ||
| 638 | } else { | ||
| 639 | /* sealing is not supported on hugetlbfs */ | ||
| 640 | mfd_fail_new("", MFD_ALLOW_SEALING); | ||
| 641 | } | ||
| 642 | } | 615 | } |
| 643 | 616 | ||
| 644 | /* | 617 | /* |
| @@ -649,11 +622,7 @@ static void test_basic(void) | |||
| 649 | { | 622 | { |
| 650 | int fd; | 623 | int fd; |
| 651 | 624 | ||
| 652 | /* hugetlbfs does not contain sealing support */ | 625 | printf("%s BASIC\n", memfd_str); |
| 653 | if (hugetlbfs_test) | ||
| 654 | return; | ||
| 655 | |||
| 656 | printf("%s BASIC\n", MEMFD_STR); | ||
| 657 | 626 | ||
| 658 | fd = mfd_assert_new("kern_memfd_basic", | 627 | fd = mfd_assert_new("kern_memfd_basic", |
| 659 | mfd_def_size, | 628 | mfd_def_size, |
| @@ -698,28 +667,6 @@ static void test_basic(void) | |||
| 698 | } | 667 | } |
| 699 | 668 | ||
| 700 | /* | 669 | /* |
| 701 | * hugetlbfs doesn't support seals or write, so just verify grow and shrink | ||
| 702 | * on a hugetlbfs file created via memfd_create. | ||
| 703 | */ | ||
| 704 | static void test_hugetlbfs_grow_shrink(void) | ||
| 705 | { | ||
| 706 | int fd; | ||
| 707 | |||
| 708 | printf("%s HUGETLBFS-GROW-SHRINK\n", MEMFD_STR); | ||
| 709 | |||
| 710 | fd = mfd_assert_new("kern_memfd_seal_write", | ||
| 711 | mfd_def_size, | ||
| 712 | MFD_CLOEXEC); | ||
| 713 | |||
| 714 | mfd_assert_read(fd); | ||
| 715 | mfd_assert_write(fd); | ||
| 716 | mfd_assert_shrink(fd); | ||
| 717 | mfd_assert_grow(fd); | ||
| 718 | |||
| 719 | close(fd); | ||
| 720 | } | ||
| 721 | |||
| 722 | /* | ||
| 723 | * Test SEAL_WRITE | 670 | * Test SEAL_WRITE |
| 724 | * Test whether SEAL_WRITE actually prevents modifications. | 671 | * Test whether SEAL_WRITE actually prevents modifications. |
| 725 | */ | 672 | */ |
| @@ -727,14 +674,7 @@ static void test_seal_write(void) | |||
| 727 | { | 674 | { |
| 728 | int fd; | 675 | int fd; |
| 729 | 676 | ||
| 730 | /* | 677 | printf("%s SEAL-WRITE\n", memfd_str); |
| 731 | * hugetlbfs does not contain sealing or write support. Just test | ||
| 732 | * basic grow and shrink via test_hugetlbfs_grow_shrink. | ||
| 733 | */ | ||
| 734 | if (hugetlbfs_test) | ||
| 735 | return test_hugetlbfs_grow_shrink(); | ||
| 736 | |||
| 737 | printf("%s SEAL-WRITE\n", MEMFD_STR); | ||
| 738 | 678 | ||
| 739 | fd = mfd_assert_new("kern_memfd_seal_write", | 679 | fd = mfd_assert_new("kern_memfd_seal_write", |
| 740 | mfd_def_size, | 680 | mfd_def_size, |
| @@ -760,11 +700,7 @@ static void test_seal_shrink(void) | |||
| 760 | { | 700 | { |
| 761 | int fd; | 701 | int fd; |
| 762 | 702 | ||
| 763 | /* hugetlbfs does not contain sealing support */ | 703 | printf("%s SEAL-SHRINK\n", memfd_str); |
| 764 | if (hugetlbfs_test) | ||
| 765 | return; | ||
| 766 | |||
| 767 | printf("%s SEAL-SHRINK\n", MEMFD_STR); | ||
| 768 | 704 | ||
| 769 | fd = mfd_assert_new("kern_memfd_seal_shrink", | 705 | fd = mfd_assert_new("kern_memfd_seal_shrink", |
| 770 | mfd_def_size, | 706 | mfd_def_size, |
| @@ -790,11 +726,7 @@ static void test_seal_grow(void) | |||
| 790 | { | 726 | { |
| 791 | int fd; | 727 | int fd; |
| 792 | 728 | ||
| 793 | /* hugetlbfs does not contain sealing support */ | 729 | printf("%s SEAL-GROW\n", memfd_str); |
| 794 | if (hugetlbfs_test) | ||
| 795 | return; | ||
| 796 | |||
| 797 | printf("%s SEAL-GROW\n", MEMFD_STR); | ||
| 798 | 730 | ||
| 799 | fd = mfd_assert_new("kern_memfd_seal_grow", | 731 | fd = mfd_assert_new("kern_memfd_seal_grow", |
| 800 | mfd_def_size, | 732 | mfd_def_size, |
| @@ -820,11 +752,7 @@ static void test_seal_resize(void) | |||
| 820 | { | 752 | { |
| 821 | int fd; | 753 | int fd; |
| 822 | 754 | ||
| 823 | /* hugetlbfs does not contain sealing support */ | 755 | printf("%s SEAL-RESIZE\n", memfd_str); |
| 824 | if (hugetlbfs_test) | ||
| 825 | return; | ||
| 826 | |||
| 827 | printf("%s SEAL-RESIZE\n", MEMFD_STR); | ||
| 828 | 756 | ||
| 829 | fd = mfd_assert_new("kern_memfd_seal_resize", | 757 | fd = mfd_assert_new("kern_memfd_seal_resize", |
| 830 | mfd_def_size, | 758 | mfd_def_size, |
| @@ -843,32 +771,6 @@ static void test_seal_resize(void) | |||
| 843 | } | 771 | } |
| 844 | 772 | ||
| 845 | /* | 773 | /* |
| 846 | * hugetlbfs does not support seals. Basic test to dup the memfd created | ||
| 847 | * fd and perform some basic operations on it. | ||
| 848 | */ | ||
| 849 | static void hugetlbfs_dup(char *b_suffix) | ||
| 850 | { | ||
| 851 | int fd, fd2; | ||
| 852 | |||
| 853 | printf("%s HUGETLBFS-DUP %s\n", MEMFD_STR, b_suffix); | ||
| 854 | |||
| 855 | fd = mfd_assert_new("kern_memfd_share_dup", | ||
| 856 | mfd_def_size, | ||
| 857 | MFD_CLOEXEC); | ||
| 858 | |||
| 859 | fd2 = mfd_assert_dup(fd); | ||
| 860 | |||
| 861 | mfd_assert_read(fd); | ||
| 862 | mfd_assert_write(fd); | ||
| 863 | |||
| 864 | mfd_assert_shrink(fd2); | ||
| 865 | mfd_assert_grow(fd2); | ||
| 866 | |||
| 867 | close(fd2); | ||
| 868 | close(fd); | ||
| 869 | } | ||
| 870 | |||
| 871 | /* | ||
| 872 | * Test sharing via dup() | 774 | * Test sharing via dup() |
| 873 | * Test that seals are shared between dupped FDs and they're all equal. | 775 | * Test that seals are shared between dupped FDs and they're all equal. |
| 874 | */ | 776 | */ |
| @@ -876,16 +778,7 @@ static void test_share_dup(char *banner, char *b_suffix) | |||
| 876 | { | 778 | { |
| 877 | int fd, fd2; | 779 | int fd, fd2; |
| 878 | 780 | ||
| 879 | /* | 781 | printf("%s %s %s\n", memfd_str, banner, b_suffix); |
| 880 | * hugetlbfs does not contain sealing support. Perform some | ||
| 881 | * basic testing on dup'ed fd instead via hugetlbfs_dup. | ||
| 882 | */ | ||
| 883 | if (hugetlbfs_test) { | ||
| 884 | hugetlbfs_dup(b_suffix); | ||
| 885 | return; | ||
| 886 | } | ||
| 887 | |||
| 888 | printf("%s %s %s\n", MEMFD_STR, banner, b_suffix); | ||
| 889 | 782 | ||
| 890 | fd = mfd_assert_new("kern_memfd_share_dup", | 783 | fd = mfd_assert_new("kern_memfd_share_dup", |
| 891 | mfd_def_size, | 784 | mfd_def_size, |
| @@ -927,11 +820,7 @@ static void test_share_mmap(char *banner, char *b_suffix) | |||
| 927 | int fd; | 820 | int fd; |
| 928 | void *p; | 821 | void *p; |
| 929 | 822 | ||
| 930 | /* hugetlbfs does not contain sealing support */ | 823 | printf("%s %s %s\n", memfd_str, banner, b_suffix); |
| 931 | if (hugetlbfs_test) | ||
| 932 | return; | ||
| 933 | |||
| 934 | printf("%s %s %s\n", MEMFD_STR, banner, b_suffix); | ||
| 935 | 824 | ||
| 936 | fd = mfd_assert_new("kern_memfd_share_mmap", | 825 | fd = mfd_assert_new("kern_memfd_share_mmap", |
| 937 | mfd_def_size, | 826 | mfd_def_size, |
| @@ -956,32 +845,6 @@ static void test_share_mmap(char *banner, char *b_suffix) | |||
| 956 | } | 845 | } |
| 957 | 846 | ||
| 958 | /* | 847 | /* |
| 959 | * Basic test to make sure we can open the hugetlbfs fd via /proc and | ||
| 960 | * perform some simple operations on it. | ||
| 961 | */ | ||
| 962 | static void hugetlbfs_proc_open(char *b_suffix) | ||
| 963 | { | ||
| 964 | int fd, fd2; | ||
| 965 | |||
| 966 | printf("%s HUGETLBFS-PROC-OPEN %s\n", MEMFD_STR, b_suffix); | ||
| 967 | |||
| 968 | fd = mfd_assert_new("kern_memfd_share_open", | ||
| 969 | mfd_def_size, | ||
| 970 | MFD_CLOEXEC); | ||
| 971 | |||
| 972 | fd2 = mfd_assert_open(fd, O_RDWR, 0); | ||
| 973 | |||
| 974 | mfd_assert_read(fd); | ||
| 975 | mfd_assert_write(fd); | ||
| 976 | |||
| 977 | mfd_assert_shrink(fd2); | ||
| 978 | mfd_assert_grow(fd2); | ||
| 979 | |||
| 980 | close(fd2); | ||
| 981 | close(fd); | ||
| 982 | } | ||
| 983 | |||
| 984 | /* | ||
| 985 | * Test sealing with open(/proc/self/fd/%d) | 848 | * Test sealing with open(/proc/self/fd/%d) |
| 986 | * Via /proc we can get access to a separate file-context for the same memfd. | 849 | * Via /proc we can get access to a separate file-context for the same memfd. |
| 987 | * This is *not* like dup(), but like a real separate open(). Make sure the | 850 | * This is *not* like dup(), but like a real separate open(). Make sure the |
| @@ -991,16 +854,7 @@ static void test_share_open(char *banner, char *b_suffix) | |||
| 991 | { | 854 | { |
| 992 | int fd, fd2; | 855 | int fd, fd2; |
| 993 | 856 | ||
| 994 | /* | 857 | printf("%s %s %s\n", memfd_str, banner, b_suffix); |
| 995 | * hugetlbfs does not contain sealing support. So test basic | ||
| 996 | * functionality of using /proc fd via hugetlbfs_proc_open | ||
| 997 | */ | ||
| 998 | if (hugetlbfs_test) { | ||
| 999 | hugetlbfs_proc_open(b_suffix); | ||
| 1000 | return; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | printf("%s %s %s\n", MEMFD_STR, banner, b_suffix); | ||
| 1004 | 858 | ||
| 1005 | fd = mfd_assert_new("kern_memfd_share_open", | 859 | fd = mfd_assert_new("kern_memfd_share_open", |
| 1006 | mfd_def_size, | 860 | mfd_def_size, |
| @@ -1043,11 +897,7 @@ static void test_share_fork(char *banner, char *b_suffix) | |||
| 1043 | int fd; | 897 | int fd; |
| 1044 | pid_t pid; | 898 | pid_t pid; |
| 1045 | 899 | ||
| 1046 | /* hugetlbfs does not contain sealing support */ | 900 | printf("%s %s %s\n", memfd_str, banner, b_suffix); |
| 1047 | if (hugetlbfs_test) | ||
| 1048 | return; | ||
| 1049 | |||
| 1050 | printf("%s %s %s\n", MEMFD_STR, banner, b_suffix); | ||
| 1051 | 901 | ||
| 1052 | fd = mfd_assert_new("kern_memfd_share_fork", | 902 | fd = mfd_assert_new("kern_memfd_share_fork", |
| 1053 | mfd_def_size, | 903 | mfd_def_size, |
| @@ -1083,7 +933,11 @@ int main(int argc, char **argv) | |||
| 1083 | } | 933 | } |
| 1084 | 934 | ||
| 1085 | hugetlbfs_test = 1; | 935 | hugetlbfs_test = 1; |
| 936 | memfd_str = MEMFD_HUGE_STR; | ||
| 1086 | mfd_def_size = hpage_size * 2; | 937 | mfd_def_size = hpage_size * 2; |
| 938 | } else { | ||
| 939 | printf("Unknown option: %s\n", argv[1]); | ||
| 940 | abort(); | ||
| 1087 | } | 941 | } |
| 1088 | } | 942 | } |
| 1089 | 943 | ||
diff --git a/tools/testing/selftests/memfd/run_fuse_test.sh b/tools/testing/selftests/memfd/run_fuse_test.sh index 407df68dfe27..22e572e2d66a 100755 --- a/tools/testing/selftests/memfd/run_fuse_test.sh +++ b/tools/testing/selftests/memfd/run_fuse_test.sh | |||
| @@ -10,6 +10,6 @@ set -e | |||
| 10 | 10 | ||
| 11 | mkdir mnt | 11 | mkdir mnt |
| 12 | ./fuse_mnt ./mnt | 12 | ./fuse_mnt ./mnt |
| 13 | ./fuse_test ./mnt/memfd | 13 | ./fuse_test ./mnt/memfd $@ |
| 14 | fusermount -u ./mnt | 14 | fusermount -u ./mnt |
| 15 | rmdir ./mnt | 15 | rmdir ./mnt |
diff --git a/tools/testing/selftests/memfd/run_tests.sh b/tools/testing/selftests/memfd/run_tests.sh index daabb350697c..c2d41ed81b24 100755 --- a/tools/testing/selftests/memfd/run_tests.sh +++ b/tools/testing/selftests/memfd/run_tests.sh | |||
| @@ -60,6 +60,7 @@ fi | |||
| 60 | # Run the hugetlbfs test | 60 | # Run the hugetlbfs test |
| 61 | # | 61 | # |
| 62 | ./memfd_test hugetlbfs | 62 | ./memfd_test hugetlbfs |
| 63 | ./run_fuse_test.sh hugetlbfs | ||
| 63 | 64 | ||
| 64 | # | 65 | # |
| 65 | # Give back any huge pages allocated for the test | 66 | # Give back any huge pages allocated for the test |
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 7f45806bd863..fdefa2295ddc 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile | |||
| @@ -8,17 +8,18 @@ endif | |||
| 8 | CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) | 8 | CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) |
| 9 | LDLIBS = -lrt | 9 | LDLIBS = -lrt |
| 10 | TEST_GEN_FILES = compaction_test | 10 | TEST_GEN_FILES = compaction_test |
| 11 | TEST_GEN_FILES += gup_benchmark | ||
| 11 | TEST_GEN_FILES += hugepage-mmap | 12 | TEST_GEN_FILES += hugepage-mmap |
| 12 | TEST_GEN_FILES += hugepage-shm | 13 | TEST_GEN_FILES += hugepage-shm |
| 13 | TEST_GEN_FILES += map_hugetlb | 14 | TEST_GEN_FILES += map_hugetlb |
| 15 | TEST_GEN_FILES += mlock-random-test | ||
| 14 | TEST_GEN_FILES += mlock2-tests | 16 | TEST_GEN_FILES += mlock2-tests |
| 15 | TEST_GEN_FILES += on-fault-limit | 17 | TEST_GEN_FILES += on-fault-limit |
| 16 | TEST_GEN_FILES += thuge-gen | 18 | TEST_GEN_FILES += thuge-gen |
| 17 | TEST_GEN_FILES += transhuge-stress | 19 | TEST_GEN_FILES += transhuge-stress |
| 18 | TEST_GEN_FILES += userfaultfd | 20 | TEST_GEN_FILES += userfaultfd |
| 19 | TEST_GEN_FILES += mlock-random-test | 21 | TEST_GEN_FILES += va_128TBswitch |
| 20 | TEST_GEN_FILES += virtual_address_range | 22 | TEST_GEN_FILES += virtual_address_range |
| 21 | TEST_GEN_FILES += gup_benchmark | ||
| 22 | 23 | ||
| 23 | TEST_PROGS := run_vmtests | 24 | TEST_PROGS := run_vmtests |
| 24 | 25 | ||
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests index cc826326de87..d2561895a021 100755 --- a/tools/testing/selftests/vm/run_vmtests +++ b/tools/testing/selftests/vm/run_vmtests | |||
| @@ -177,4 +177,15 @@ else | |||
| 177 | echo "[PASS]" | 177 | echo "[PASS]" |
| 178 | fi | 178 | fi |
| 179 | 179 | ||
| 180 | echo "-----------------------------" | ||
| 181 | echo "running virtual address 128TB switch test" | ||
| 182 | echo "-----------------------------" | ||
| 183 | ./va_128TBswitch | ||
| 184 | if [ $? -ne 0 ]; then | ||
| 185 | echo "[FAIL]" | ||
| 186 | exitcode=1 | ||
| 187 | else | ||
| 188 | echo "[PASS]" | ||
| 189 | fi | ||
| 190 | |||
| 180 | exit $exitcode | 191 | exit $exitcode |
diff --git a/tools/testing/selftests/vm/va_128TBswitch.c b/tools/testing/selftests/vm/va_128TBswitch.c new file mode 100644 index 000000000000..e7fe734c374f --- /dev/null +++ b/tools/testing/selftests/vm/va_128TBswitch.c | |||
| @@ -0,0 +1,297 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Authors: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | ||
| 4 | * Authors: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License, version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | |||
| 10 | * This program is distributed in the hope that it would be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <stdio.h> | ||
| 17 | #include <sys/mman.h> | ||
| 18 | #include <string.h> | ||
| 19 | |||
| 20 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | ||
| 21 | |||
| 22 | #ifdef __powerpc64__ | ||
| 23 | #define PAGE_SIZE (64 << 10) | ||
| 24 | /* | ||
| 25 | * This will work with 16M and 2M hugepage size | ||
| 26 | */ | ||
| 27 | #define HUGETLB_SIZE (16 << 20) | ||
| 28 | #else | ||
| 29 | #define PAGE_SIZE (4 << 10) | ||
| 30 | #define HUGETLB_SIZE (2 << 20) | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /* | ||
| 34 | * >= 128TB is the hint addr value we used to select | ||
| 35 | * large address space. | ||
| 36 | */ | ||
| 37 | #define ADDR_SWITCH_HINT (1UL << 47) | ||
| 38 | #define LOW_ADDR ((void *) (1UL << 30)) | ||
| 39 | #define HIGH_ADDR ((void *) (1UL << 48)) | ||
| 40 | |||
| 41 | struct testcase { | ||
| 42 | void *addr; | ||
| 43 | unsigned long size; | ||
| 44 | unsigned long flags; | ||
| 45 | const char *msg; | ||
| 46 | unsigned int low_addr_required:1; | ||
| 47 | unsigned int keep_mapped:1; | ||
| 48 | }; | ||
| 49 | |||
| 50 | static struct testcase testcases[] = { | ||
| 51 | { | ||
| 52 | /* | ||
| 53 | * If stack is moved, we could possibly allocate | ||
| 54 | * this at the requested address. | ||
| 55 | */ | ||
| 56 | .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)), | ||
| 57 | .size = PAGE_SIZE, | ||
| 58 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 59 | .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)", | ||
| 60 | .low_addr_required = 1, | ||
| 61 | }, | ||
| 62 | { | ||
| 63 | /* | ||
| 64 | * We should never allocate at the requested address or above it | ||
| 65 | * The len cross the 128TB boundary. Without MAP_FIXED | ||
| 66 | * we will always search in the lower address space. | ||
| 67 | */ | ||
| 68 | .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)), | ||
| 69 | .size = 2 * PAGE_SIZE, | ||
| 70 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 71 | .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, (2 * PAGE_SIZE))", | ||
| 72 | .low_addr_required = 1, | ||
| 73 | }, | ||
| 74 | { | ||
| 75 | /* | ||
| 76 | * Exact mapping at 128TB, the area is free we should get that | ||
| 77 | * even without MAP_FIXED. | ||
| 78 | */ | ||
| 79 | .addr = ((void *)(ADDR_SWITCH_HINT)), | ||
| 80 | .size = PAGE_SIZE, | ||
| 81 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 82 | .msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)", | ||
| 83 | .keep_mapped = 1, | ||
| 84 | }, | ||
| 85 | { | ||
| 86 | .addr = (void *)(ADDR_SWITCH_HINT), | ||
| 87 | .size = 2 * PAGE_SIZE, | ||
| 88 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 89 | .msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)", | ||
| 90 | }, | ||
| 91 | { | ||
| 92 | .addr = NULL, | ||
| 93 | .size = 2 * PAGE_SIZE, | ||
| 94 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 95 | .msg = "mmap(NULL)", | ||
| 96 | .low_addr_required = 1, | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | .addr = LOW_ADDR, | ||
| 100 | .size = 2 * PAGE_SIZE, | ||
| 101 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 102 | .msg = "mmap(LOW_ADDR)", | ||
| 103 | .low_addr_required = 1, | ||
| 104 | }, | ||
| 105 | { | ||
| 106 | .addr = HIGH_ADDR, | ||
| 107 | .size = 2 * PAGE_SIZE, | ||
| 108 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 109 | .msg = "mmap(HIGH_ADDR)", | ||
| 110 | .keep_mapped = 1, | ||
| 111 | }, | ||
| 112 | { | ||
| 113 | .addr = HIGH_ADDR, | ||
| 114 | .size = 2 * PAGE_SIZE, | ||
| 115 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 116 | .msg = "mmap(HIGH_ADDR) again", | ||
| 117 | .keep_mapped = 1, | ||
| 118 | }, | ||
| 119 | { | ||
| 120 | .addr = HIGH_ADDR, | ||
| 121 | .size = 2 * PAGE_SIZE, | ||
| 122 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 123 | .msg = "mmap(HIGH_ADDR, MAP_FIXED)", | ||
| 124 | }, | ||
| 125 | { | ||
| 126 | .addr = (void *) -1, | ||
| 127 | .size = 2 * PAGE_SIZE, | ||
| 128 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 129 | .msg = "mmap(-1)", | ||
| 130 | .keep_mapped = 1, | ||
| 131 | }, | ||
| 132 | { | ||
| 133 | .addr = (void *) -1, | ||
| 134 | .size = 2 * PAGE_SIZE, | ||
| 135 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 136 | .msg = "mmap(-1) again", | ||
| 137 | }, | ||
| 138 | { | ||
| 139 | .addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)), | ||
| 140 | .size = PAGE_SIZE, | ||
| 141 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 142 | .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)", | ||
| 143 | .low_addr_required = 1, | ||
| 144 | }, | ||
| 145 | { | ||
| 146 | .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE), | ||
| 147 | .size = 2 * PAGE_SIZE, | ||
| 148 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 149 | .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2 * PAGE_SIZE)", | ||
| 150 | .low_addr_required = 1, | ||
| 151 | .keep_mapped = 1, | ||
| 152 | }, | ||
| 153 | { | ||
| 154 | .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE / 2), | ||
| 155 | .size = 2 * PAGE_SIZE, | ||
| 156 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 157 | .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE/2 , 2 * PAGE_SIZE)", | ||
| 158 | .low_addr_required = 1, | ||
| 159 | .keep_mapped = 1, | ||
| 160 | }, | ||
| 161 | { | ||
| 162 | .addr = ((void *)(ADDR_SWITCH_HINT)), | ||
| 163 | .size = PAGE_SIZE, | ||
| 164 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 165 | .msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)", | ||
| 166 | }, | ||
| 167 | { | ||
| 168 | .addr = (void *)(ADDR_SWITCH_HINT), | ||
| 169 | .size = 2 * PAGE_SIZE, | ||
| 170 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 171 | .msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)", | ||
| 172 | }, | ||
| 173 | }; | ||
| 174 | |||
| 175 | static struct testcase hugetlb_testcases[] = { | ||
| 176 | { | ||
| 177 | .addr = NULL, | ||
| 178 | .size = HUGETLB_SIZE, | ||
| 179 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 180 | .msg = "mmap(NULL, MAP_HUGETLB)", | ||
| 181 | .low_addr_required = 1, | ||
| 182 | }, | ||
| 183 | { | ||
| 184 | .addr = LOW_ADDR, | ||
| 185 | .size = HUGETLB_SIZE, | ||
| 186 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 187 | .msg = "mmap(LOW_ADDR, MAP_HUGETLB)", | ||
| 188 | .low_addr_required = 1, | ||
| 189 | }, | ||
| 190 | { | ||
| 191 | .addr = HIGH_ADDR, | ||
| 192 | .size = HUGETLB_SIZE, | ||
| 193 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 194 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)", | ||
| 195 | .keep_mapped = 1, | ||
| 196 | }, | ||
| 197 | { | ||
| 198 | .addr = HIGH_ADDR, | ||
| 199 | .size = HUGETLB_SIZE, | ||
| 200 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 201 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again", | ||
| 202 | .keep_mapped = 1, | ||
| 203 | }, | ||
| 204 | { | ||
| 205 | .addr = HIGH_ADDR, | ||
| 206 | .size = HUGETLB_SIZE, | ||
| 207 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 208 | .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)", | ||
| 209 | }, | ||
| 210 | { | ||
| 211 | .addr = (void *) -1, | ||
| 212 | .size = HUGETLB_SIZE, | ||
| 213 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 214 | .msg = "mmap(-1, MAP_HUGETLB)", | ||
| 215 | .keep_mapped = 1, | ||
| 216 | }, | ||
| 217 | { | ||
| 218 | .addr = (void *) -1, | ||
| 219 | .size = HUGETLB_SIZE, | ||
| 220 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 221 | .msg = "mmap(-1, MAP_HUGETLB) again", | ||
| 222 | }, | ||
| 223 | { | ||
| 224 | .addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE), | ||
| 225 | .size = 2 * HUGETLB_SIZE, | ||
| 226 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 227 | .msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2*HUGETLB_SIZE, MAP_HUGETLB)", | ||
| 228 | .low_addr_required = 1, | ||
| 229 | .keep_mapped = 1, | ||
| 230 | }, | ||
| 231 | { | ||
| 232 | .addr = (void *)(ADDR_SWITCH_HINT), | ||
| 233 | .size = 2 * HUGETLB_SIZE, | ||
| 234 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 235 | .msg = "mmap(ADDR_SWITCH_HINT , 2*HUGETLB_SIZE, MAP_FIXED | MAP_HUGETLB)", | ||
| 236 | }, | ||
| 237 | }; | ||
| 238 | |||
| 239 | static int run_test(struct testcase *test, int count) | ||
| 240 | { | ||
| 241 | void *p; | ||
| 242 | int i, ret = 0; | ||
| 243 | |||
| 244 | for (i = 0; i < count; i++) { | ||
| 245 | struct testcase *t = test + i; | ||
| 246 | |||
| 247 | p = mmap(t->addr, t->size, PROT_READ | PROT_WRITE, t->flags, -1, 0); | ||
| 248 | |||
| 249 | printf("%s: %p - ", t->msg, p); | ||
| 250 | |||
| 251 | if (p == MAP_FAILED) { | ||
| 252 | printf("FAILED\n"); | ||
| 253 | ret = 1; | ||
| 254 | continue; | ||
| 255 | } | ||
| 256 | |||
| 257 | if (t->low_addr_required && p >= (void *)(ADDR_SWITCH_HINT)) { | ||
| 258 | printf("FAILED\n"); | ||
| 259 | ret = 1; | ||
| 260 | } else { | ||
| 261 | /* | ||
| 262 | * Do a dereference of the address returned so that we catch | ||
| 263 | * bugs in page fault handling | ||
| 264 | */ | ||
| 265 | memset(p, 0, t->size); | ||
| 266 | printf("OK\n"); | ||
| 267 | } | ||
| 268 | if (!t->keep_mapped) | ||
| 269 | munmap(p, t->size); | ||
| 270 | } | ||
| 271 | |||
| 272 | return ret; | ||
| 273 | } | ||
| 274 | |||
| 275 | static int supported_arch(void) | ||
| 276 | { | ||
| 277 | #if defined(__powerpc64__) | ||
| 278 | return 1; | ||
| 279 | #elif defined(__x86_64__) | ||
| 280 | return 1; | ||
| 281 | #else | ||
| 282 | return 0; | ||
| 283 | #endif | ||
| 284 | } | ||
| 285 | |||
| 286 | int main(int argc, char **argv) | ||
| 287 | { | ||
| 288 | int ret; | ||
| 289 | |||
| 290 | if (!supported_arch()) | ||
| 291 | return 0; | ||
| 292 | |||
| 293 | ret = run_test(testcases, ARRAY_SIZE(testcases)); | ||
| 294 | if (argc == 2 && !strcmp(argv[1], "--run-hugetlb")) | ||
| 295 | ret = run_test(hugetlb_testcases, ARRAY_SIZE(hugetlb_testcases)); | ||
| 296 | return ret; | ||
| 297 | } | ||
diff --git a/tools/testing/selftests/x86/5lvl.c b/tools/testing/selftests/x86/5lvl.c deleted file mode 100644 index 2eafdcd4c2b3..000000000000 --- a/tools/testing/selftests/x86/5lvl.c +++ /dev/null | |||
| @@ -1,177 +0,0 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <sys/mman.h> | ||
| 3 | |||
| 4 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | ||
| 5 | |||
| 6 | #define PAGE_SIZE 4096 | ||
| 7 | #define LOW_ADDR ((void *) (1UL << 30)) | ||
| 8 | #define HIGH_ADDR ((void *) (1UL << 50)) | ||
| 9 | |||
| 10 | struct testcase { | ||
| 11 | void *addr; | ||
| 12 | unsigned long size; | ||
| 13 | unsigned long flags; | ||
| 14 | const char *msg; | ||
| 15 | unsigned int low_addr_required:1; | ||
| 16 | unsigned int keep_mapped:1; | ||
| 17 | }; | ||
| 18 | |||
| 19 | static struct testcase testcases[] = { | ||
| 20 | { | ||
| 21 | .addr = NULL, | ||
| 22 | .size = 2 * PAGE_SIZE, | ||
| 23 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 24 | .msg = "mmap(NULL)", | ||
| 25 | .low_addr_required = 1, | ||
| 26 | }, | ||
| 27 | { | ||
| 28 | .addr = LOW_ADDR, | ||
| 29 | .size = 2 * PAGE_SIZE, | ||
| 30 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 31 | .msg = "mmap(LOW_ADDR)", | ||
| 32 | .low_addr_required = 1, | ||
| 33 | }, | ||
| 34 | { | ||
| 35 | .addr = HIGH_ADDR, | ||
| 36 | .size = 2 * PAGE_SIZE, | ||
| 37 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 38 | .msg = "mmap(HIGH_ADDR)", | ||
| 39 | .keep_mapped = 1, | ||
| 40 | }, | ||
| 41 | { | ||
| 42 | .addr = HIGH_ADDR, | ||
| 43 | .size = 2 * PAGE_SIZE, | ||
| 44 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 45 | .msg = "mmap(HIGH_ADDR) again", | ||
| 46 | .keep_mapped = 1, | ||
| 47 | }, | ||
| 48 | { | ||
| 49 | .addr = HIGH_ADDR, | ||
| 50 | .size = 2 * PAGE_SIZE, | ||
| 51 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 52 | .msg = "mmap(HIGH_ADDR, MAP_FIXED)", | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | .addr = (void*) -1, | ||
| 56 | .size = 2 * PAGE_SIZE, | ||
| 57 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 58 | .msg = "mmap(-1)", | ||
| 59 | .keep_mapped = 1, | ||
| 60 | }, | ||
| 61 | { | ||
| 62 | .addr = (void*) -1, | ||
| 63 | .size = 2 * PAGE_SIZE, | ||
| 64 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 65 | .msg = "mmap(-1) again", | ||
| 66 | }, | ||
| 67 | { | ||
| 68 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | ||
| 69 | .size = 2 * PAGE_SIZE, | ||
| 70 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 71 | .msg = "mmap((1UL << 47), 2 * PAGE_SIZE)", | ||
| 72 | .low_addr_required = 1, | ||
| 73 | .keep_mapped = 1, | ||
| 74 | }, | ||
| 75 | { | ||
| 76 | .addr = (void *)((1UL << 47) - PAGE_SIZE / 2), | ||
| 77 | .size = 2 * PAGE_SIZE, | ||
| 78 | .flags = MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 79 | .msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)", | ||
| 80 | .low_addr_required = 1, | ||
| 81 | .keep_mapped = 1, | ||
| 82 | }, | ||
| 83 | { | ||
| 84 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | ||
| 85 | .size = 2 * PAGE_SIZE, | ||
| 86 | .flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 87 | .msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)", | ||
| 88 | }, | ||
| 89 | { | ||
| 90 | .addr = NULL, | ||
| 91 | .size = 2UL << 20, | ||
| 92 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 93 | .msg = "mmap(NULL, MAP_HUGETLB)", | ||
| 94 | .low_addr_required = 1, | ||
| 95 | }, | ||
| 96 | { | ||
| 97 | .addr = LOW_ADDR, | ||
| 98 | .size = 2UL << 20, | ||
| 99 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 100 | .msg = "mmap(LOW_ADDR, MAP_HUGETLB)", | ||
| 101 | .low_addr_required = 1, | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | .addr = HIGH_ADDR, | ||
| 105 | .size = 2UL << 20, | ||
| 106 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 107 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB)", | ||
| 108 | .keep_mapped = 1, | ||
| 109 | }, | ||
| 110 | { | ||
| 111 | .addr = HIGH_ADDR, | ||
| 112 | .size = 2UL << 20, | ||
| 113 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 114 | .msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again", | ||
| 115 | .keep_mapped = 1, | ||
| 116 | }, | ||
| 117 | { | ||
| 118 | .addr = HIGH_ADDR, | ||
| 119 | .size = 2UL << 20, | ||
| 120 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 121 | .msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)", | ||
| 122 | }, | ||
| 123 | { | ||
| 124 | .addr = (void*) -1, | ||
| 125 | .size = 2UL << 20, | ||
| 126 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 127 | .msg = "mmap(-1, MAP_HUGETLB)", | ||
| 128 | .keep_mapped = 1, | ||
| 129 | }, | ||
| 130 | { | ||
| 131 | .addr = (void*) -1, | ||
| 132 | .size = 2UL << 20, | ||
| 133 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 134 | .msg = "mmap(-1, MAP_HUGETLB) again", | ||
| 135 | }, | ||
| 136 | { | ||
| 137 | .addr = (void *)((1UL << 47) - PAGE_SIZE), | ||
| 138 | .size = 4UL << 20, | ||
| 139 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS, | ||
| 140 | .msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)", | ||
| 141 | .low_addr_required = 1, | ||
| 142 | .keep_mapped = 1, | ||
| 143 | }, | ||
| 144 | { | ||
| 145 | .addr = (void *)((1UL << 47) - (2UL << 20)), | ||
| 146 | .size = 4UL << 20, | ||
| 147 | .flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | ||
| 148 | .msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)", | ||
| 149 | }, | ||
| 150 | }; | ||
| 151 | |||
| 152 | int main(int argc, char **argv) | ||
| 153 | { | ||
| 154 | int i; | ||
| 155 | void *p; | ||
| 156 | |||
| 157 | for (i = 0; i < ARRAY_SIZE(testcases); i++) { | ||
| 158 | struct testcase *t = testcases + i; | ||
| 159 | |||
| 160 | p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0); | ||
| 161 | |||
| 162 | printf("%s: %p - ", t->msg, p); | ||
| 163 | |||
| 164 | if (p == MAP_FAILED) { | ||
| 165 | printf("FAILED\n"); | ||
| 166 | continue; | ||
| 167 | } | ||
| 168 | |||
| 169 | if (t->low_addr_required && p >= (void *)(1UL << 47)) | ||
| 170 | printf("FAILED\n"); | ||
| 171 | else | ||
| 172 | printf("OK\n"); | ||
| 173 | if (!t->keep_mapped) | ||
| 174 | munmap(p, t->size); | ||
| 175 | } | ||
| 176 | return 0; | ||
| 177 | } | ||
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index e92903fc7113..a8783f48f77f 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c | |||
| @@ -169,9 +169,10 @@ static int opt_raw; /* for kernel developers */ | |||
| 169 | static int opt_list; /* list pages (in ranges) */ | 169 | static int opt_list; /* list pages (in ranges) */ |
| 170 | static int opt_no_summary; /* don't show summary */ | 170 | static int opt_no_summary; /* don't show summary */ |
| 171 | static pid_t opt_pid; /* process to walk */ | 171 | static pid_t opt_pid; /* process to walk */ |
| 172 | const char * opt_file; /* file or directory path */ | 172 | const char *opt_file; /* file or directory path */ |
| 173 | static uint64_t opt_cgroup; /* cgroup inode */ | 173 | static uint64_t opt_cgroup; /* cgroup inode */ |
| 174 | static int opt_list_cgroup;/* list page cgroup */ | 174 | static int opt_list_cgroup;/* list page cgroup */ |
| 175 | static const char *opt_kpageflags;/* kpageflags file to parse */ | ||
| 175 | 176 | ||
| 176 | #define MAX_ADDR_RANGES 1024 | 177 | #define MAX_ADDR_RANGES 1024 |
| 177 | static int nr_addr_ranges; | 178 | static int nr_addr_ranges; |
| @@ -258,7 +259,7 @@ static int checked_open(const char *pathname, int flags) | |||
| 258 | * pagemap/kpageflags routines | 259 | * pagemap/kpageflags routines |
| 259 | */ | 260 | */ |
| 260 | 261 | ||
| 261 | static unsigned long do_u64_read(int fd, char *name, | 262 | static unsigned long do_u64_read(int fd, const char *name, |
| 262 | uint64_t *buf, | 263 | uint64_t *buf, |
| 263 | unsigned long index, | 264 | unsigned long index, |
| 264 | unsigned long count) | 265 | unsigned long count) |
| @@ -283,7 +284,7 @@ static unsigned long kpageflags_read(uint64_t *buf, | |||
| 283 | unsigned long index, | 284 | unsigned long index, |
| 284 | unsigned long pages) | 285 | unsigned long pages) |
| 285 | { | 286 | { |
| 286 | return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages); | 287 | return do_u64_read(kpageflags_fd, opt_kpageflags, buf, index, pages); |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | static unsigned long kpagecgroup_read(uint64_t *buf, | 290 | static unsigned long kpagecgroup_read(uint64_t *buf, |
| @@ -293,7 +294,7 @@ static unsigned long kpagecgroup_read(uint64_t *buf, | |||
| 293 | if (kpagecgroup_fd < 0) | 294 | if (kpagecgroup_fd < 0) |
| 294 | return pages; | 295 | return pages; |
| 295 | 296 | ||
| 296 | return do_u64_read(kpagecgroup_fd, PROC_KPAGEFLAGS, buf, index, pages); | 297 | return do_u64_read(kpagecgroup_fd, opt_kpageflags, buf, index, pages); |
| 297 | } | 298 | } |
| 298 | 299 | ||
| 299 | static unsigned long pagemap_read(uint64_t *buf, | 300 | static unsigned long pagemap_read(uint64_t *buf, |
| @@ -743,7 +744,7 @@ static void walk_addr_ranges(void) | |||
| 743 | { | 744 | { |
| 744 | int i; | 745 | int i; |
| 745 | 746 | ||
| 746 | kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY); | 747 | kpageflags_fd = checked_open(opt_kpageflags, O_RDONLY); |
| 747 | 748 | ||
| 748 | if (!nr_addr_ranges) | 749 | if (!nr_addr_ranges) |
| 749 | add_addr_range(0, ULONG_MAX); | 750 | add_addr_range(0, ULONG_MAX); |
| @@ -790,6 +791,7 @@ static void usage(void) | |||
| 790 | " -N|--no-summary Don't show summary info\n" | 791 | " -N|--no-summary Don't show summary info\n" |
| 791 | " -X|--hwpoison hwpoison pages\n" | 792 | " -X|--hwpoison hwpoison pages\n" |
| 792 | " -x|--unpoison unpoison pages\n" | 793 | " -x|--unpoison unpoison pages\n" |
| 794 | " -F|--kpageflags filename kpageflags file to parse\n" | ||
| 793 | " -h|--help Show this usage message\n" | 795 | " -h|--help Show this usage message\n" |
| 794 | "flags:\n" | 796 | "flags:\n" |
| 795 | " 0x10 bitfield format, e.g.\n" | 797 | " 0x10 bitfield format, e.g.\n" |
| @@ -1013,7 +1015,7 @@ static void walk_page_cache(void) | |||
| 1013 | { | 1015 | { |
| 1014 | struct stat st; | 1016 | struct stat st; |
| 1015 | 1017 | ||
| 1016 | kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY); | 1018 | kpageflags_fd = checked_open(opt_kpageflags, O_RDONLY); |
| 1017 | pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY); | 1019 | pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY); |
| 1018 | sigaction(SIGBUS, &sigbus_action, NULL); | 1020 | sigaction(SIGBUS, &sigbus_action, NULL); |
| 1019 | 1021 | ||
| @@ -1164,6 +1166,11 @@ static void parse_bits_mask(const char *optarg) | |||
| 1164 | add_bits_filter(mask, bits); | 1166 | add_bits_filter(mask, bits); |
| 1165 | } | 1167 | } |
| 1166 | 1168 | ||
| 1169 | static void parse_kpageflags(const char *name) | ||
| 1170 | { | ||
| 1171 | opt_kpageflags = name; | ||
| 1172 | } | ||
| 1173 | |||
| 1167 | static void describe_flags(const char *optarg) | 1174 | static void describe_flags(const char *optarg) |
| 1168 | { | 1175 | { |
| 1169 | uint64_t flags = parse_flag_names(optarg, 0); | 1176 | uint64_t flags = parse_flag_names(optarg, 0); |
| @@ -1188,6 +1195,7 @@ static const struct option opts[] = { | |||
| 1188 | { "no-summary", 0, NULL, 'N' }, | 1195 | { "no-summary", 0, NULL, 'N' }, |
| 1189 | { "hwpoison" , 0, NULL, 'X' }, | 1196 | { "hwpoison" , 0, NULL, 'X' }, |
| 1190 | { "unpoison" , 0, NULL, 'x' }, | 1197 | { "unpoison" , 0, NULL, 'x' }, |
| 1198 | { "kpageflags", 0, NULL, 'F' }, | ||
| 1191 | { "help" , 0, NULL, 'h' }, | 1199 | { "help" , 0, NULL, 'h' }, |
| 1192 | { NULL , 0, NULL, 0 } | 1200 | { NULL , 0, NULL, 0 } |
| 1193 | }; | 1201 | }; |
| @@ -1199,7 +1207,7 @@ int main(int argc, char *argv[]) | |||
| 1199 | page_size = getpagesize(); | 1207 | page_size = getpagesize(); |
| 1200 | 1208 | ||
| 1201 | while ((c = getopt_long(argc, argv, | 1209 | while ((c = getopt_long(argc, argv, |
| 1202 | "rp:f:a:b:d:c:ClLNXxh", opts, NULL)) != -1) { | 1210 | "rp:f:a:b:d:c:ClLNXxF:h", opts, NULL)) != -1) { |
| 1203 | switch (c) { | 1211 | switch (c) { |
| 1204 | case 'r': | 1212 | case 'r': |
| 1205 | opt_raw = 1; | 1213 | opt_raw = 1; |
| @@ -1242,6 +1250,9 @@ int main(int argc, char *argv[]) | |||
| 1242 | opt_unpoison = 1; | 1250 | opt_unpoison = 1; |
| 1243 | prepare_hwpoison_fd(); | 1251 | prepare_hwpoison_fd(); |
| 1244 | break; | 1252 | break; |
| 1253 | case 'F': | ||
| 1254 | parse_kpageflags(optarg); | ||
| 1255 | break; | ||
| 1245 | case 'h': | 1256 | case 'h': |
| 1246 | usage(); | 1257 | usage(); |
| 1247 | exit(0); | 1258 | exit(0); |
| @@ -1251,6 +1262,9 @@ int main(int argc, char *argv[]) | |||
| 1251 | } | 1262 | } |
| 1252 | } | 1263 | } |
| 1253 | 1264 | ||
| 1265 | if (!opt_kpageflags) | ||
| 1266 | opt_kpageflags = PROC_KPAGEFLAGS; | ||
| 1267 | |||
| 1254 | if (opt_cgroup || opt_list_cgroup) | 1268 | if (opt_cgroup || opt_list_cgroup) |
| 1255 | kpagecgroup_fd = checked_open(PROC_KPAGECGROUP, O_RDONLY); | 1269 | kpagecgroup_fd = checked_open(PROC_KPAGECGROUP, O_RDONLY); |
| 1256 | 1270 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d6b9370806f8..35db929f92f0 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -476,6 +476,7 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn, | |||
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { | 478 | static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { |
| 479 | .flags = MMU_INVALIDATE_DOES_NOT_BLOCK, | ||
| 479 | .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, | 480 | .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, |
| 480 | .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, | 481 | .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, |
| 481 | .clear_flush_young = kvm_mmu_notifier_clear_flush_young, | 482 | .clear_flush_young = kvm_mmu_notifier_clear_flush_young, |
