diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-28 19:55:46 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-28 19:55:46 -0500 |
| commit | f346b0becb1bc62e45495f9cdbae3eef35d0b635 (patch) | |
| tree | ae79f3dfb8e031da51d38f0f095f89d7d23f3643 /include/linux | |
| parent | 00d59fde8532b2d42e80909d2e58678755e04da9 (diff) | |
| parent | 0f4991e8fd48987ae476a92cdee6bfec4aff31b8 (diff) | |
Merge branch 'akpm' (patches from Andrew)
Merge misc updates from Andrew Morton:
- large KASAN update to use arm's "software tag-based mode"
- a few misc things
- sh updates
- ocfs2 updates
- just about all of MM
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (167 commits)
kernel/fork.c: mark 'stack_vm_area' with __maybe_unused
memcg, oom: notify on oom killer invocation from the charge path
mm, swap: fix swapoff with KSM pages
include/linux/gfp.h: fix typo
mm/hmm: fix memremap.h, move dev_page_fault_t callback to hmm
hugetlbfs: Use i_mmap_rwsem to fix page fault/truncate race
hugetlbfs: use i_mmap_rwsem for more pmd sharing synchronization
memory_hotplug: add missing newlines to debugging output
mm: remove __hugepage_set_anon_rmap()
include/linux/vmstat.h: remove unused page state adjustment macro
mm/page_alloc.c: allow error injection
mm: migrate: drop unused argument of migrate_page_move_mapping()
blkdev: avoid migration stalls for blkdev pages
mm: migrate: provide buffer_migrate_page_norefs()
mm: migrate: move migrate_page_lock_buffers()
mm: migrate: lock buffers before migrate_page_move_mapping()
mm: migration: factor out code to compute expected number of page references
mm, page_alloc: enable pcpu_drain with zone capability
kmemleak: add config to select auto scan
mm/page_alloc.c: don't call kasan_free_pages() at deferred mem init
...
Diffstat (limited to 'include/linux')
29 files changed, 431 insertions, 188 deletions
diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index 9a6bc0951cfa..c31157135598 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h | |||
| @@ -258,6 +258,14 @@ static inline void wb_get(struct bdi_writeback *wb) | |||
| 258 | */ | 258 | */ |
| 259 | static inline void wb_put(struct bdi_writeback *wb) | 259 | static inline void wb_put(struct bdi_writeback *wb) |
| 260 | { | 260 | { |
| 261 | if (WARN_ON_ONCE(!wb->bdi)) { | ||
| 262 | /* | ||
| 263 | * A driver bug might cause a file to be removed before bdi was | ||
| 264 | * initialized. | ||
| 265 | */ | ||
| 266 | return; | ||
| 267 | } | ||
| 268 | |||
| 261 | if (wb != &wb->bdi->wb) | 269 | if (wb != &wb->bdi->wb) |
| 262 | percpu_ref_put(&wb->refcnt); | 270 | percpu_ref_put(&wb->refcnt); |
| 263 | } | 271 | } |
diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index 3e7dafb3ea80..39f668d5066b 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h | |||
| @@ -16,9 +16,13 @@ | |||
| 16 | /* all clang versions usable with the kernel support KASAN ABI version 5 */ | 16 | /* all clang versions usable with the kernel support KASAN ABI version 5 */ |
| 17 | #define KASAN_ABI_VERSION 5 | 17 | #define KASAN_ABI_VERSION 5 |
| 18 | 18 | ||
| 19 | #if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer) | ||
| 19 | /* emulate gcc's __SANITIZE_ADDRESS__ flag */ | 20 | /* emulate gcc's __SANITIZE_ADDRESS__ flag */ |
| 20 | #if __has_feature(address_sanitizer) | ||
| 21 | #define __SANITIZE_ADDRESS__ | 21 | #define __SANITIZE_ADDRESS__ |
| 22 | #define __no_sanitize_address \ | ||
| 23 | __attribute__((no_sanitize("address", "hwaddress"))) | ||
| 24 | #else | ||
| 25 | #define __no_sanitize_address | ||
| 22 | #endif | 26 | #endif |
| 23 | 27 | ||
| 24 | /* | 28 | /* |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 2010493e1040..5776da43da97 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
| @@ -143,6 +143,12 @@ | |||
| 143 | #define KASAN_ABI_VERSION 3 | 143 | #define KASAN_ABI_VERSION 3 |
| 144 | #endif | 144 | #endif |
| 145 | 145 | ||
| 146 | #if __has_attribute(__no_sanitize_address__) | ||
| 147 | #define __no_sanitize_address __attribute__((no_sanitize_address)) | ||
| 148 | #else | ||
| 149 | #define __no_sanitize_address | ||
| 150 | #endif | ||
| 151 | |||
| 146 | #if GCC_VERSION >= 50100 | 152 | #if GCC_VERSION >= 50100 |
| 147 | #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 | 153 | #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 |
| 148 | #endif | 154 | #endif |
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index fe07b680dd4a..19f32b0c29af 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h | |||
| @@ -200,19 +200,6 @@ | |||
| 200 | #define __noreturn __attribute__((__noreturn__)) | 200 | #define __noreturn __attribute__((__noreturn__)) |
| 201 | 201 | ||
| 202 | /* | 202 | /* |
| 203 | * Optional: only supported since gcc >= 4.8 | ||
| 204 | * Optional: not supported by icc | ||
| 205 | * | ||
| 206 | * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fsanitize_005faddress-function-attribute | ||
| 207 | * clang: https://clang.llvm.org/docs/AttributeReference.html#no-sanitize-address-no-address-safety-analysis | ||
| 208 | */ | ||
| 209 | #if __has_attribute(__no_sanitize_address__) | ||
| 210 | # define __no_sanitize_address __attribute__((__no_sanitize_address__)) | ||
| 211 | #else | ||
| 212 | # define __no_sanitize_address | ||
| 213 | #endif | ||
| 214 | |||
| 215 | /* | ||
| 216 | * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute | 203 | * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute |
| 217 | * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute | 204 | * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute |
| 218 | */ | 205 | */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 6d52ce6af4ff..811c77743dad 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -3269,8 +3269,12 @@ extern int generic_check_addressable(unsigned, u64); | |||
| 3269 | extern int buffer_migrate_page(struct address_space *, | 3269 | extern int buffer_migrate_page(struct address_space *, |
| 3270 | struct page *, struct page *, | 3270 | struct page *, struct page *, |
| 3271 | enum migrate_mode); | 3271 | enum migrate_mode); |
| 3272 | extern int buffer_migrate_page_norefs(struct address_space *, | ||
| 3273 | struct page *, struct page *, | ||
| 3274 | enum migrate_mode); | ||
| 3272 | #else | 3275 | #else |
| 3273 | #define buffer_migrate_page NULL | 3276 | #define buffer_migrate_page NULL |
| 3277 | #define buffer_migrate_page_norefs NULL | ||
| 3274 | #endif | 3278 | #endif |
| 3275 | 3279 | ||
| 3276 | extern int setattr_prepare(struct dentry *, struct iattr *); | 3280 | extern int setattr_prepare(struct dentry *, struct iattr *); |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0705164f928c..5f5e25fd6149 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
| @@ -81,7 +81,7 @@ struct vm_area_struct; | |||
| 81 | * | 81 | * |
| 82 | * %__GFP_HARDWALL enforces the cpuset memory allocation policy. | 82 | * %__GFP_HARDWALL enforces the cpuset memory allocation policy. |
| 83 | * | 83 | * |
| 84 | * %__GFP_THISNODE forces the allocation to be satisified from the requested | 84 | * %__GFP_THISNODE forces the allocation to be satisfied from the requested |
| 85 | * node with no fallbacks or placement policy enforcements. | 85 | * node with no fallbacks or placement policy enforcements. |
| 86 | * | 86 | * |
| 87 | * %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg. | 87 | * %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg. |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 0690679832d4..ea5cdbd8c2c3 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
| @@ -36,7 +36,31 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size) | |||
| 36 | 36 | ||
| 37 | /* declarations for linux/mm/highmem.c */ | 37 | /* declarations for linux/mm/highmem.c */ |
| 38 | unsigned int nr_free_highpages(void); | 38 | unsigned int nr_free_highpages(void); |
| 39 | extern unsigned long totalhigh_pages; | 39 | extern atomic_long_t _totalhigh_pages; |
| 40 | static inline unsigned long totalhigh_pages(void) | ||
| 41 | { | ||
| 42 | return (unsigned long)atomic_long_read(&_totalhigh_pages); | ||
| 43 | } | ||
| 44 | |||
| 45 | static inline void totalhigh_pages_inc(void) | ||
| 46 | { | ||
| 47 | atomic_long_inc(&_totalhigh_pages); | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline void totalhigh_pages_dec(void) | ||
| 51 | { | ||
| 52 | atomic_long_dec(&_totalhigh_pages); | ||
| 53 | } | ||
| 54 | |||
| 55 | static inline void totalhigh_pages_add(long count) | ||
| 56 | { | ||
| 57 | atomic_long_add(count, &_totalhigh_pages); | ||
| 58 | } | ||
| 59 | |||
| 60 | static inline void totalhigh_pages_set(long val) | ||
| 61 | { | ||
| 62 | atomic_long_set(&_totalhigh_pages, val); | ||
| 63 | } | ||
| 40 | 64 | ||
| 41 | void kmap_flush_unused(void); | 65 | void kmap_flush_unused(void); |
| 42 | 66 | ||
| @@ -51,7 +75,7 @@ static inline struct page *kmap_to_page(void *addr) | |||
| 51 | return virt_to_page(addr); | 75 | return virt_to_page(addr); |
| 52 | } | 76 | } |
| 53 | 77 | ||
| 54 | #define totalhigh_pages 0UL | 78 | static inline unsigned long totalhigh_pages(void) { return 0UL; } |
| 55 | 79 | ||
| 56 | #ifndef ARCH_HAS_KMAP | 80 | #ifndef ARCH_HAS_KMAP |
| 57 | static inline void *kmap(struct page *page) | 81 | static inline void *kmap(struct page *page) |
diff --git a/include/linux/hmm.h b/include/linux/hmm.h index c6fb869a81c0..66f9ebbb1df3 100644 --- a/include/linux/hmm.h +++ b/include/linux/hmm.h | |||
| @@ -69,6 +69,7 @@ | |||
| 69 | #define LINUX_HMM_H | 69 | #define LINUX_HMM_H |
| 70 | 70 | ||
| 71 | #include <linux/kconfig.h> | 71 | #include <linux/kconfig.h> |
| 72 | #include <asm/pgtable.h> | ||
| 72 | 73 | ||
| 73 | #if IS_ENABLED(CONFIG_HMM) | 74 | #if IS_ENABLED(CONFIG_HMM) |
| 74 | 75 | ||
| @@ -486,6 +487,7 @@ struct hmm_devmem_ops { | |||
| 486 | * @device: device to bind resource to | 487 | * @device: device to bind resource to |
| 487 | * @ops: memory operations callback | 488 | * @ops: memory operations callback |
| 488 | * @ref: per CPU refcount | 489 | * @ref: per CPU refcount |
| 490 | * @page_fault: callback when CPU fault on an unaddressable device page | ||
| 489 | * | 491 | * |
| 490 | * This an helper structure for device drivers that do not wish to implement | 492 | * This an helper structure for device drivers that do not wish to implement |
| 491 | * the gory details related to hotplugging new memoy and allocating struct | 493 | * the gory details related to hotplugging new memoy and allocating struct |
| @@ -493,7 +495,28 @@ struct hmm_devmem_ops { | |||
| 493 | * | 495 | * |
| 494 | * Device drivers can directly use ZONE_DEVICE memory on their own if they | 496 | * Device drivers can directly use ZONE_DEVICE memory on their own if they |
| 495 | * wish to do so. | 497 | * wish to do so. |
| 498 | * | ||
| 499 | * The page_fault() callback must migrate page back, from device memory to | ||
| 500 | * system memory, so that the CPU can access it. This might fail for various | ||
| 501 | * reasons (device issues, device have been unplugged, ...). When such error | ||
| 502 | * conditions happen, the page_fault() callback must return VM_FAULT_SIGBUS and | ||
| 503 | * set the CPU page table entry to "poisoned". | ||
| 504 | * | ||
| 505 | * Note that because memory cgroup charges are transferred to the device memory, | ||
| 506 | * this should never fail due to memory restrictions. However, allocation | ||
| 507 | * of a regular system page might still fail because we are out of memory. If | ||
| 508 | * that happens, the page_fault() callback must return VM_FAULT_OOM. | ||
| 509 | * | ||
| 510 | * The page_fault() callback can also try to migrate back multiple pages in one | ||
| 511 | * chunk, as an optimization. It must, however, prioritize the faulting address | ||
| 512 | * over all the others. | ||
| 496 | */ | 513 | */ |
| 514 | typedef int (*dev_page_fault_t)(struct vm_area_struct *vma, | ||
| 515 | unsigned long addr, | ||
| 516 | const struct page *page, | ||
| 517 | unsigned int flags, | ||
| 518 | pmd_t *pmdp); | ||
| 519 | |||
| 497 | struct hmm_devmem { | 520 | struct hmm_devmem { |
| 498 | struct completion completion; | 521 | struct completion completion; |
| 499 | unsigned long pfn_first; | 522 | unsigned long pfn_first; |
| @@ -503,6 +526,7 @@ struct hmm_devmem { | |||
| 503 | struct dev_pagemap pagemap; | 526 | struct dev_pagemap pagemap; |
| 504 | const struct hmm_devmem_ops *ops; | 527 | const struct hmm_devmem_ops *ops; |
| 505 | struct percpu_ref ref; | 528 | struct percpu_ref ref; |
| 529 | dev_page_fault_t page_fault; | ||
| 506 | }; | 530 | }; |
| 507 | 531 | ||
| 508 | /* | 532 | /* |
| @@ -512,8 +536,7 @@ struct hmm_devmem { | |||
| 512 | * enough and allocate struct page for it. | 536 | * enough and allocate struct page for it. |
| 513 | * | 537 | * |
| 514 | * The device driver can wrap the hmm_devmem struct inside a private device | 538 | * The device driver can wrap the hmm_devmem struct inside a private device |
| 515 | * driver struct. The device driver must call hmm_devmem_remove() before the | 539 | * driver struct. |
| 516 | * device goes away and before freeing the hmm_devmem struct memory. | ||
| 517 | */ | 540 | */ |
| 518 | struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, | 541 | struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, |
| 519 | struct device *device, | 542 | struct device *device, |
| @@ -521,7 +544,6 @@ struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, | |||
| 521 | struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops, | 544 | struct hmm_devmem *hmm_devmem_add_resource(const struct hmm_devmem_ops *ops, |
| 522 | struct device *device, | 545 | struct device *device, |
| 523 | struct resource *res); | 546 | struct resource *res); |
| 524 | void hmm_devmem_remove(struct hmm_devmem *devmem); | ||
| 525 | 547 | ||
| 526 | /* | 548 | /* |
| 527 | * hmm_devmem_page_set_drvdata - set per-page driver data field | 549 | * hmm_devmem_page_set_drvdata - set per-page driver data field |
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 4663ee96cf59..381e872bfde0 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h | |||
| @@ -93,7 +93,11 @@ extern bool is_vma_temporary_stack(struct vm_area_struct *vma); | |||
| 93 | 93 | ||
| 94 | extern unsigned long transparent_hugepage_flags; | 94 | extern unsigned long transparent_hugepage_flags; |
| 95 | 95 | ||
| 96 | static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) | 96 | /* |
| 97 | * to be used on vmas which are known to support THP. | ||
| 98 | * Use transparent_hugepage_enabled otherwise | ||
| 99 | */ | ||
| 100 | static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma) | ||
| 97 | { | 101 | { |
| 98 | if (vma->vm_flags & VM_NOHUGEPAGE) | 102 | if (vma->vm_flags & VM_NOHUGEPAGE) |
| 99 | return false; | 103 | return false; |
| @@ -117,6 +121,8 @@ static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) | |||
| 117 | return false; | 121 | return false; |
| 118 | } | 122 | } |
| 119 | 123 | ||
| 124 | bool transparent_hugepage_enabled(struct vm_area_struct *vma); | ||
| 125 | |||
| 120 | #define transparent_hugepage_use_zero_page() \ | 126 | #define transparent_hugepage_use_zero_page() \ |
| 121 | (transparent_hugepage_flags & \ | 127 | (transparent_hugepage_flags & \ |
| 122 | (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG)) | 128 | (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG)) |
| @@ -257,6 +263,11 @@ static inline bool thp_migration_supported(void) | |||
| 257 | 263 | ||
| 258 | #define hpage_nr_pages(x) 1 | 264 | #define hpage_nr_pages(x) 1 |
| 259 | 265 | ||
| 266 | static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma) | ||
| 267 | { | ||
| 268 | return false; | ||
| 269 | } | ||
| 270 | |||
| 260 | static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) | 271 | static inline bool transparent_hugepage_enabled(struct vm_area_struct *vma) |
| 261 | { | 272 | { |
| 262 | return false; | 273 | return false; |
diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 46aae129917c..b40ea104dd36 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h | |||
| @@ -14,13 +14,13 @@ struct task_struct; | |||
| 14 | #include <asm/kasan.h> | 14 | #include <asm/kasan.h> |
| 15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
| 16 | 16 | ||
| 17 | extern unsigned char kasan_zero_page[PAGE_SIZE]; | 17 | extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; |
| 18 | extern pte_t kasan_zero_pte[PTRS_PER_PTE]; | 18 | extern pte_t kasan_early_shadow_pte[PTRS_PER_PTE]; |
| 19 | extern pmd_t kasan_zero_pmd[PTRS_PER_PMD]; | 19 | extern pmd_t kasan_early_shadow_pmd[PTRS_PER_PMD]; |
| 20 | extern pud_t kasan_zero_pud[PTRS_PER_PUD]; | 20 | extern pud_t kasan_early_shadow_pud[PTRS_PER_PUD]; |
| 21 | extern p4d_t kasan_zero_p4d[MAX_PTRS_PER_P4D]; | 21 | extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; |
| 22 | 22 | ||
| 23 | int kasan_populate_zero_shadow(const void *shadow_start, | 23 | int kasan_populate_early_shadow(const void *shadow_start, |
| 24 | const void *shadow_end); | 24 | const void *shadow_end); |
| 25 | 25 | ||
| 26 | static inline void *kasan_mem_to_shadow(const void *addr) | 26 | static inline void *kasan_mem_to_shadow(const void *addr) |
| @@ -45,22 +45,24 @@ void kasan_free_pages(struct page *page, unsigned int order); | |||
| 45 | 45 | ||
| 46 | void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, | 46 | void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, |
| 47 | slab_flags_t *flags); | 47 | slab_flags_t *flags); |
| 48 | void kasan_cache_shrink(struct kmem_cache *cache); | ||
| 49 | void kasan_cache_shutdown(struct kmem_cache *cache); | ||
| 50 | 48 | ||
| 51 | void kasan_poison_slab(struct page *page); | 49 | void kasan_poison_slab(struct page *page); |
| 52 | void kasan_unpoison_object_data(struct kmem_cache *cache, void *object); | 50 | void kasan_unpoison_object_data(struct kmem_cache *cache, void *object); |
| 53 | void kasan_poison_object_data(struct kmem_cache *cache, void *object); | 51 | void kasan_poison_object_data(struct kmem_cache *cache, void *object); |
| 54 | void kasan_init_slab_obj(struct kmem_cache *cache, const void *object); | 52 | void * __must_check kasan_init_slab_obj(struct kmem_cache *cache, |
| 53 | const void *object); | ||
| 55 | 54 | ||
| 56 | void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags); | 55 | void * __must_check kasan_kmalloc_large(const void *ptr, size_t size, |
| 56 | gfp_t flags); | ||
| 57 | void kasan_kfree_large(void *ptr, unsigned long ip); | 57 | void kasan_kfree_large(void *ptr, unsigned long ip); |
| 58 | void kasan_poison_kfree(void *ptr, unsigned long ip); | 58 | void kasan_poison_kfree(void *ptr, unsigned long ip); |
| 59 | void kasan_kmalloc(struct kmem_cache *s, const void *object, size_t size, | 59 | void * __must_check kasan_kmalloc(struct kmem_cache *s, const void *object, |
| 60 | gfp_t flags); | 60 | size_t size, gfp_t flags); |
| 61 | void kasan_krealloc(const void *object, size_t new_size, gfp_t flags); | 61 | void * __must_check kasan_krealloc(const void *object, size_t new_size, |
| 62 | gfp_t flags); | ||
| 62 | 63 | ||
| 63 | void kasan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags); | 64 | void * __must_check kasan_slab_alloc(struct kmem_cache *s, void *object, |
| 65 | gfp_t flags); | ||
| 64 | bool kasan_slab_free(struct kmem_cache *s, void *object, unsigned long ip); | 66 | bool kasan_slab_free(struct kmem_cache *s, void *object, unsigned long ip); |
| 65 | 67 | ||
| 66 | struct kasan_cache { | 68 | struct kasan_cache { |
| @@ -97,27 +99,40 @@ static inline void kasan_free_pages(struct page *page, unsigned int order) {} | |||
| 97 | static inline void kasan_cache_create(struct kmem_cache *cache, | 99 | static inline void kasan_cache_create(struct kmem_cache *cache, |
| 98 | unsigned int *size, | 100 | unsigned int *size, |
| 99 | slab_flags_t *flags) {} | 101 | slab_flags_t *flags) {} |
| 100 | static inline void kasan_cache_shrink(struct kmem_cache *cache) {} | ||
| 101 | static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} | ||
| 102 | 102 | ||
| 103 | static inline void kasan_poison_slab(struct page *page) {} | 103 | static inline void kasan_poison_slab(struct page *page) {} |
| 104 | static inline void kasan_unpoison_object_data(struct kmem_cache *cache, | 104 | static inline void kasan_unpoison_object_data(struct kmem_cache *cache, |
| 105 | void *object) {} | 105 | void *object) {} |
| 106 | static inline void kasan_poison_object_data(struct kmem_cache *cache, | 106 | static inline void kasan_poison_object_data(struct kmem_cache *cache, |
| 107 | void *object) {} | 107 | void *object) {} |
| 108 | static inline void kasan_init_slab_obj(struct kmem_cache *cache, | 108 | static inline void *kasan_init_slab_obj(struct kmem_cache *cache, |
| 109 | const void *object) {} | 109 | const void *object) |
| 110 | { | ||
| 111 | return (void *)object; | ||
| 112 | } | ||
| 110 | 113 | ||
| 111 | static inline void kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) {} | 114 | static inline void *kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) |
| 115 | { | ||
| 116 | return ptr; | ||
| 117 | } | ||
| 112 | static inline void kasan_kfree_large(void *ptr, unsigned long ip) {} | 118 | static inline void kasan_kfree_large(void *ptr, unsigned long ip) {} |
| 113 | static inline void kasan_poison_kfree(void *ptr, unsigned long ip) {} | 119 | static inline void kasan_poison_kfree(void *ptr, unsigned long ip) {} |
| 114 | static inline void kasan_kmalloc(struct kmem_cache *s, const void *object, | 120 | static inline void *kasan_kmalloc(struct kmem_cache *s, const void *object, |
| 115 | size_t size, gfp_t flags) {} | 121 | size_t size, gfp_t flags) |
| 116 | static inline void kasan_krealloc(const void *object, size_t new_size, | 122 | { |
| 117 | gfp_t flags) {} | 123 | return (void *)object; |
| 124 | } | ||
| 125 | static inline void *kasan_krealloc(const void *object, size_t new_size, | ||
| 126 | gfp_t flags) | ||
| 127 | { | ||
| 128 | return (void *)object; | ||
| 129 | } | ||
| 118 | 130 | ||
| 119 | static inline void kasan_slab_alloc(struct kmem_cache *s, void *object, | 131 | static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, |
| 120 | gfp_t flags) {} | 132 | gfp_t flags) |
| 133 | { | ||
| 134 | return object; | ||
| 135 | } | ||
| 121 | static inline bool kasan_slab_free(struct kmem_cache *s, void *object, | 136 | static inline bool kasan_slab_free(struct kmem_cache *s, void *object, |
| 122 | unsigned long ip) | 137 | unsigned long ip) |
| 123 | { | 138 | { |
| @@ -140,4 +155,40 @@ static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } | |||
| 140 | 155 | ||
| 141 | #endif /* CONFIG_KASAN */ | 156 | #endif /* CONFIG_KASAN */ |
| 142 | 157 | ||
| 158 | #ifdef CONFIG_KASAN_GENERIC | ||
| 159 | |||
| 160 | #define KASAN_SHADOW_INIT 0 | ||
| 161 | |||
| 162 | void kasan_cache_shrink(struct kmem_cache *cache); | ||
| 163 | void kasan_cache_shutdown(struct kmem_cache *cache); | ||
| 164 | |||
| 165 | #else /* CONFIG_KASAN_GENERIC */ | ||
| 166 | |||
| 167 | static inline void kasan_cache_shrink(struct kmem_cache *cache) {} | ||
| 168 | static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} | ||
| 169 | |||
| 170 | #endif /* CONFIG_KASAN_GENERIC */ | ||
| 171 | |||
| 172 | #ifdef CONFIG_KASAN_SW_TAGS | ||
| 173 | |||
| 174 | #define KASAN_SHADOW_INIT 0xFF | ||
| 175 | |||
| 176 | void kasan_init_tags(void); | ||
| 177 | |||
| 178 | void *kasan_reset_tag(const void *addr); | ||
| 179 | |||
| 180 | void kasan_report(unsigned long addr, size_t size, | ||
| 181 | bool is_write, unsigned long ip); | ||
| 182 | |||
| 183 | #else /* CONFIG_KASAN_SW_TAGS */ | ||
| 184 | |||
| 185 | static inline void kasan_init_tags(void) { } | ||
| 186 | |||
| 187 | static inline void *kasan_reset_tag(const void *addr) | ||
| 188 | { | ||
| 189 | return (void *)addr; | ||
| 190 | } | ||
| 191 | |||
| 192 | #endif /* CONFIG_KASAN_SW_TAGS */ | ||
| 193 | |||
| 143 | #endif /* LINUX_KASAN_H */ | 194 | #endif /* LINUX_KASAN_H */ |
diff --git a/include/linux/memblock.h b/include/linux/memblock.h index aee299a6aa76..64c41cf45590 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h | |||
| @@ -154,7 +154,6 @@ void __next_mem_range_rev(u64 *idx, int nid, enum memblock_flags flags, | |||
| 154 | void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start, | 154 | void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start, |
| 155 | phys_addr_t *out_end); | 155 | phys_addr_t *out_end); |
| 156 | 156 | ||
| 157 | void __memblock_free_early(phys_addr_t base, phys_addr_t size); | ||
| 158 | void __memblock_free_late(phys_addr_t base, phys_addr_t size); | 157 | void __memblock_free_late(phys_addr_t base, phys_addr_t size); |
| 159 | 158 | ||
| 160 | /** | 159 | /** |
| @@ -320,6 +319,7 @@ static inline int memblock_get_region_node(const struct memblock_region *r) | |||
| 320 | /* Flags for memblock allocation APIs */ | 319 | /* Flags for memblock allocation APIs */ |
| 321 | #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) | 320 | #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) |
| 322 | #define MEMBLOCK_ALLOC_ACCESSIBLE 0 | 321 | #define MEMBLOCK_ALLOC_ACCESSIBLE 0 |
| 322 | #define MEMBLOCK_ALLOC_KASAN 1 | ||
| 323 | 323 | ||
| 324 | /* We are using top down, so it is safe to use 0 here */ | 324 | /* We are using top down, so it is safe to use 0 here */ |
| 325 | #define MEMBLOCK_LOW_LIMIT 0 | 325 | #define MEMBLOCK_LOW_LIMIT 0 |
| @@ -414,13 +414,13 @@ static inline void * __init memblock_alloc_node_nopanic(phys_addr_t size, | |||
| 414 | static inline void __init memblock_free_early(phys_addr_t base, | 414 | static inline void __init memblock_free_early(phys_addr_t base, |
| 415 | phys_addr_t size) | 415 | phys_addr_t size) |
| 416 | { | 416 | { |
| 417 | __memblock_free_early(base, size); | 417 | memblock_free(base, size); |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | static inline void __init memblock_free_early_nid(phys_addr_t base, | 420 | static inline void __init memblock_free_early_nid(phys_addr_t base, |
| 421 | phys_addr_t size, int nid) | 421 | phys_addr_t size, int nid) |
| 422 | { | 422 | { |
| 423 | __memblock_free_early(base, size); | 423 | memblock_free(base, size); |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | static inline void __init memblock_free_late(phys_addr_t base, phys_addr_t size) | 426 | static inline void __init memblock_free_late(phys_addr_t base, phys_addr_t size) |
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 7ab2120155a4..83ae11cbd12c 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
| @@ -526,9 +526,11 @@ void mem_cgroup_handle_over_high(void); | |||
| 526 | 526 | ||
| 527 | unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); | 527 | unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); |
| 528 | 528 | ||
| 529 | void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, | 529 | void mem_cgroup_print_oom_context(struct mem_cgroup *memcg, |
| 530 | struct task_struct *p); | 530 | struct task_struct *p); |
| 531 | 531 | ||
| 532 | void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg); | ||
| 533 | |||
| 532 | static inline void mem_cgroup_enter_user_fault(void) | 534 | static inline void mem_cgroup_enter_user_fault(void) |
| 533 | { | 535 | { |
| 534 | WARN_ON(current->in_user_fault); | 536 | WARN_ON(current->in_user_fault); |
| @@ -970,7 +972,12 @@ static inline unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) | |||
| 970 | } | 972 | } |
| 971 | 973 | ||
| 972 | static inline void | 974 | static inline void |
| 973 | mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) | 975 | mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *p) |
| 976 | { | ||
| 977 | } | ||
| 978 | |||
| 979 | static inline void | ||
| 980 | mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg) | ||
| 974 | { | 981 | { |
| 975 | } | 982 | } |
| 976 | 983 | ||
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index ffd9cd10fcf3..07da5c6c5ba0 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
| @@ -107,8 +107,8 @@ static inline bool movable_node_is_enabled(void) | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | #ifdef CONFIG_MEMORY_HOTREMOVE | 109 | #ifdef CONFIG_MEMORY_HOTREMOVE |
| 110 | extern int arch_remove_memory(u64 start, u64 size, | 110 | extern int arch_remove_memory(int nid, u64 start, u64 size, |
| 111 | struct vmem_altmap *altmap); | 111 | struct vmem_altmap *altmap); |
| 112 | extern int __remove_pages(struct zone *zone, unsigned long start_pfn, | 112 | extern int __remove_pages(struct zone *zone, unsigned long start_pfn, |
| 113 | unsigned long nr_pages, struct vmem_altmap *altmap); | 113 | unsigned long nr_pages, struct vmem_altmap *altmap); |
| 114 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | 114 | #endif /* CONFIG_MEMORY_HOTREMOVE */ |
| @@ -326,15 +326,14 @@ extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, | |||
| 326 | void *arg, int (*func)(struct memory_block *, void *)); | 326 | void *arg, int (*func)(struct memory_block *, void *)); |
| 327 | extern int __add_memory(int nid, u64 start, u64 size); | 327 | extern int __add_memory(int nid, u64 start, u64 size); |
| 328 | extern int add_memory(int nid, u64 start, u64 size); | 328 | extern int add_memory(int nid, u64 start, u64 size); |
| 329 | extern int add_memory_resource(int nid, struct resource *resource, bool online); | 329 | extern int add_memory_resource(int nid, struct resource *resource); |
| 330 | extern int arch_add_memory(int nid, u64 start, u64 size, | 330 | extern int arch_add_memory(int nid, u64 start, u64 size, |
| 331 | struct vmem_altmap *altmap, bool want_memblock); | 331 | struct vmem_altmap *altmap, bool want_memblock); |
| 332 | extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, | 332 | extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, |
| 333 | unsigned long nr_pages, struct vmem_altmap *altmap); | 333 | unsigned long nr_pages, struct vmem_altmap *altmap); |
| 334 | extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); | ||
| 335 | extern bool is_memblock_offlined(struct memory_block *mem); | 334 | extern bool is_memblock_offlined(struct memory_block *mem); |
| 336 | extern int sparse_add_one_section(struct pglist_data *pgdat, | 335 | extern int sparse_add_one_section(int nid, unsigned long start_pfn, |
| 337 | unsigned long start_pfn, struct vmem_altmap *altmap); | 336 | struct vmem_altmap *altmap); |
| 338 | extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, | 337 | extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, |
| 339 | unsigned long map_offset, struct vmem_altmap *altmap); | 338 | unsigned long map_offset, struct vmem_altmap *altmap); |
| 340 | extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, | 339 | extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map, |
diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 0ac69ddf5fc4..f0628660d541 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | #include <linux/ioport.h> | 4 | #include <linux/ioport.h> |
| 5 | #include <linux/percpu-refcount.h> | 5 | #include <linux/percpu-refcount.h> |
| 6 | 6 | ||
| 7 | #include <asm/pgtable.h> | ||
| 8 | |||
| 9 | struct resource; | 7 | struct resource; |
| 10 | struct device; | 8 | struct device; |
| 11 | 9 | ||
| @@ -66,62 +64,34 @@ enum memory_type { | |||
| 66 | }; | 64 | }; |
| 67 | 65 | ||
| 68 | /* | 66 | /* |
| 69 | * For MEMORY_DEVICE_PRIVATE we use ZONE_DEVICE and extend it with two | ||
| 70 | * callbacks: | ||
| 71 | * page_fault() | ||
| 72 | * page_free() | ||
| 73 | * | ||
| 74 | * Additional notes about MEMORY_DEVICE_PRIVATE may be found in | 67 | * Additional notes about MEMORY_DEVICE_PRIVATE may be found in |
| 75 | * include/linux/hmm.h and Documentation/vm/hmm.rst. There is also a brief | 68 | * include/linux/hmm.h and Documentation/vm/hmm.rst. There is also a brief |
| 76 | * explanation in include/linux/memory_hotplug.h. | 69 | * explanation in include/linux/memory_hotplug.h. |
| 77 | * | 70 | * |
| 78 | * The page_fault() callback must migrate page back, from device memory to | ||
| 79 | * system memory, so that the CPU can access it. This might fail for various | ||
| 80 | * reasons (device issues, device have been unplugged, ...). When such error | ||
| 81 | * conditions happen, the page_fault() callback must return VM_FAULT_SIGBUS and | ||
| 82 | * set the CPU page table entry to "poisoned". | ||
| 83 | * | ||
| 84 | * Note that because memory cgroup charges are transferred to the device memory, | ||
| 85 | * this should never fail due to memory restrictions. However, allocation | ||
| 86 | * of a regular system page might still fail because we are out of memory. If | ||
| 87 | * that happens, the page_fault() callback must return VM_FAULT_OOM. | ||
| 88 | * | ||
| 89 | * The page_fault() callback can also try to migrate back multiple pages in one | ||
| 90 | * chunk, as an optimization. It must, however, prioritize the faulting address | ||
| 91 | * over all the others. | ||
| 92 | * | ||
| 93 | * | ||
| 94 | * The page_free() callback is called once the page refcount reaches 1 | 71 | * The page_free() callback is called once the page refcount reaches 1 |
| 95 | * (ZONE_DEVICE pages never reach 0 refcount unless there is a refcount bug. | 72 | * (ZONE_DEVICE pages never reach 0 refcount unless there is a refcount bug. |
| 96 | * This allows the device driver to implement its own memory management.) | 73 | * This allows the device driver to implement its own memory management.) |
| 97 | * | ||
| 98 | * For MEMORY_DEVICE_PUBLIC only the page_free() callback matter. | ||
| 99 | */ | 74 | */ |
| 100 | typedef int (*dev_page_fault_t)(struct vm_area_struct *vma, | ||
| 101 | unsigned long addr, | ||
| 102 | const struct page *page, | ||
| 103 | unsigned int flags, | ||
| 104 | pmd_t *pmdp); | ||
| 105 | typedef void (*dev_page_free_t)(struct page *page, void *data); | 75 | typedef void (*dev_page_free_t)(struct page *page, void *data); |
| 106 | 76 | ||
| 107 | /** | 77 | /** |
| 108 | * struct dev_pagemap - metadata for ZONE_DEVICE mappings | 78 | * struct dev_pagemap - metadata for ZONE_DEVICE mappings |
| 109 | * @page_fault: callback when CPU fault on an unaddressable device page | ||
| 110 | * @page_free: free page callback when page refcount reaches 1 | 79 | * @page_free: free page callback when page refcount reaches 1 |
| 111 | * @altmap: pre-allocated/reserved memory for vmemmap allocations | 80 | * @altmap: pre-allocated/reserved memory for vmemmap allocations |
| 112 | * @res: physical address range covered by @ref | 81 | * @res: physical address range covered by @ref |
| 113 | * @ref: reference count that pins the devm_memremap_pages() mapping | 82 | * @ref: reference count that pins the devm_memremap_pages() mapping |
| 83 | * @kill: callback to transition @ref to the dead state | ||
| 114 | * @dev: host device of the mapping for debug | 84 | * @dev: host device of the mapping for debug |
| 115 | * @data: private data pointer for page_free() | 85 | * @data: private data pointer for page_free() |
| 116 | * @type: memory type: see MEMORY_* in memory_hotplug.h | 86 | * @type: memory type: see MEMORY_* in memory_hotplug.h |
| 117 | */ | 87 | */ |
| 118 | struct dev_pagemap { | 88 | struct dev_pagemap { |
| 119 | dev_page_fault_t page_fault; | ||
| 120 | dev_page_free_t page_free; | 89 | dev_page_free_t page_free; |
| 121 | struct vmem_altmap altmap; | 90 | struct vmem_altmap altmap; |
| 122 | bool altmap_valid; | 91 | bool altmap_valid; |
| 123 | struct resource res; | 92 | struct resource res; |
| 124 | struct percpu_ref *ref; | 93 | struct percpu_ref *ref; |
| 94 | void (*kill)(struct percpu_ref *ref); | ||
| 125 | struct device *dev; | 95 | struct device *dev; |
| 126 | void *data; | 96 | void *data; |
| 127 | enum memory_type type; | 97 | enum memory_type type; |
diff --git a/include/linux/migrate.h b/include/linux/migrate.h index f2b4abbca55e..e13d9bf2f9a5 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h | |||
| @@ -29,7 +29,7 @@ enum migrate_reason { | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | /* In mm/debug.c; also keep sync with include/trace/events/migrate.h */ | 31 | /* In mm/debug.c; also keep sync with include/trace/events/migrate.h */ |
| 32 | extern char *migrate_reason_names[MR_TYPES]; | 32 | extern const char *migrate_reason_names[MR_TYPES]; |
| 33 | 33 | ||
| 34 | static inline struct page *new_page_nodemask(struct page *page, | 34 | static inline struct page *new_page_nodemask(struct page *page, |
| 35 | int preferred_nid, nodemask_t *nodemask) | 35 | int preferred_nid, nodemask_t *nodemask) |
| @@ -77,8 +77,7 @@ extern void migrate_page_copy(struct page *newpage, struct page *page); | |||
| 77 | extern int migrate_huge_page_move_mapping(struct address_space *mapping, | 77 | extern int migrate_huge_page_move_mapping(struct address_space *mapping, |
| 78 | struct page *newpage, struct page *page); | 78 | struct page *newpage, struct page *page); |
| 79 | extern int migrate_page_move_mapping(struct address_space *mapping, | 79 | extern int migrate_page_move_mapping(struct address_space *mapping, |
| 80 | struct page *newpage, struct page *page, | 80 | struct page *newpage, struct page *page, enum migrate_mode mode, |
| 81 | struct buffer_head *head, enum migrate_mode mode, | ||
| 82 | int extra_count); | 81 | int extra_count); |
| 83 | #else | 82 | #else |
| 84 | 83 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index 5411de93a363..ea1f12d15365 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -48,7 +48,32 @@ static inline void set_max_mapnr(unsigned long limit) | |||
| 48 | static inline void set_max_mapnr(unsigned long limit) { } | 48 | static inline void set_max_mapnr(unsigned long limit) { } |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | extern unsigned long totalram_pages; | 51 | extern atomic_long_t _totalram_pages; |
| 52 | static inline unsigned long totalram_pages(void) | ||
| 53 | { | ||
| 54 | return (unsigned long)atomic_long_read(&_totalram_pages); | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline void totalram_pages_inc(void) | ||
| 58 | { | ||
| 59 | atomic_long_inc(&_totalram_pages); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void totalram_pages_dec(void) | ||
| 63 | { | ||
| 64 | atomic_long_dec(&_totalram_pages); | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline void totalram_pages_add(long count) | ||
| 68 | { | ||
| 69 | atomic_long_add(count, &_totalram_pages); | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline void totalram_pages_set(long val) | ||
| 73 | { | ||
| 74 | atomic_long_set(&_totalram_pages, val); | ||
| 75 | } | ||
| 76 | |||
| 52 | extern void * high_memory; | 77 | extern void * high_memory; |
| 53 | extern int page_cluster; | 78 | extern int page_cluster; |
| 54 | 79 | ||
| @@ -804,6 +829,7 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); | |||
| 804 | #define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH) | 829 | #define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH) |
| 805 | #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) | 830 | #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) |
| 806 | #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH) | 831 | #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH) |
| 832 | #define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH) | ||
| 807 | 833 | ||
| 808 | /* | 834 | /* |
| 809 | * Define the bit shifts to access each section. For non-existent | 835 | * Define the bit shifts to access each section. For non-existent |
| @@ -814,6 +840,7 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); | |||
| 814 | #define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0)) | 840 | #define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0)) |
| 815 | #define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) | 841 | #define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) |
| 816 | #define LAST_CPUPID_PGSHIFT (LAST_CPUPID_PGOFF * (LAST_CPUPID_WIDTH != 0)) | 842 | #define LAST_CPUPID_PGSHIFT (LAST_CPUPID_PGOFF * (LAST_CPUPID_WIDTH != 0)) |
| 843 | #define KASAN_TAG_PGSHIFT (KASAN_TAG_PGOFF * (KASAN_TAG_WIDTH != 0)) | ||
| 817 | 844 | ||
| 818 | /* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allocator */ | 845 | /* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allocator */ |
| 819 | #ifdef NODE_NOT_IN_PAGE_FLAGS | 846 | #ifdef NODE_NOT_IN_PAGE_FLAGS |
| @@ -836,6 +863,7 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); | |||
| 836 | #define NODES_MASK ((1UL << NODES_WIDTH) - 1) | 863 | #define NODES_MASK ((1UL << NODES_WIDTH) - 1) |
| 837 | #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) | 864 | #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) |
| 838 | #define LAST_CPUPID_MASK ((1UL << LAST_CPUPID_SHIFT) - 1) | 865 | #define LAST_CPUPID_MASK ((1UL << LAST_CPUPID_SHIFT) - 1) |
| 866 | #define KASAN_TAG_MASK ((1UL << KASAN_TAG_WIDTH) - 1) | ||
| 839 | #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) | 867 | #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) |
| 840 | 868 | ||
| 841 | static inline enum zone_type page_zonenum(const struct page *page) | 869 | static inline enum zone_type page_zonenum(const struct page *page) |
| @@ -1101,6 +1129,32 @@ static inline bool cpupid_match_pid(struct task_struct *task, int cpupid) | |||
| 1101 | } | 1129 | } |
| 1102 | #endif /* CONFIG_NUMA_BALANCING */ | 1130 | #endif /* CONFIG_NUMA_BALANCING */ |
| 1103 | 1131 | ||
| 1132 | #ifdef CONFIG_KASAN_SW_TAGS | ||
| 1133 | static inline u8 page_kasan_tag(const struct page *page) | ||
| 1134 | { | ||
| 1135 | return (page->flags >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | static inline void page_kasan_tag_set(struct page *page, u8 tag) | ||
| 1139 | { | ||
| 1140 | page->flags &= ~(KASAN_TAG_MASK << KASAN_TAG_PGSHIFT); | ||
| 1141 | page->flags |= (tag & KASAN_TAG_MASK) << KASAN_TAG_PGSHIFT; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | static inline void page_kasan_tag_reset(struct page *page) | ||
| 1145 | { | ||
| 1146 | page_kasan_tag_set(page, 0xff); | ||
| 1147 | } | ||
| 1148 | #else | ||
| 1149 | static inline u8 page_kasan_tag(const struct page *page) | ||
| 1150 | { | ||
| 1151 | return 0xff; | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | static inline void page_kasan_tag_set(struct page *page, u8 tag) { } | ||
| 1155 | static inline void page_kasan_tag_reset(struct page *page) { } | ||
| 1156 | #endif | ||
| 1157 | |||
| 1104 | static inline struct zone *page_zone(const struct page *page) | 1158 | static inline struct zone *page_zone(const struct page *page) |
| 1105 | { | 1159 | { |
| 1106 | return &NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)]; | 1160 | return &NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)]; |
| @@ -1397,6 +1451,8 @@ struct mm_walk { | |||
| 1397 | void *private; | 1451 | void *private; |
| 1398 | }; | 1452 | }; |
| 1399 | 1453 | ||
| 1454 | struct mmu_notifier_range; | ||
| 1455 | |||
| 1400 | int walk_page_range(unsigned long addr, unsigned long end, | 1456 | int walk_page_range(unsigned long addr, unsigned long end, |
| 1401 | struct mm_walk *walk); | 1457 | struct mm_walk *walk); |
| 1402 | int walk_page_vma(struct vm_area_struct *vma, struct mm_walk *walk); | 1458 | int walk_page_vma(struct vm_area_struct *vma, struct mm_walk *walk); |
| @@ -1405,8 +1461,8 @@ void free_pgd_range(struct mmu_gather *tlb, unsigned long addr, | |||
| 1405 | int copy_page_range(struct mm_struct *dst, struct mm_struct *src, | 1461 | int copy_page_range(struct mm_struct *dst, struct mm_struct *src, |
| 1406 | struct vm_area_struct *vma); | 1462 | struct vm_area_struct *vma); |
| 1407 | int follow_pte_pmd(struct mm_struct *mm, unsigned long address, | 1463 | int follow_pte_pmd(struct mm_struct *mm, unsigned long address, |
| 1408 | unsigned long *start, unsigned long *end, | 1464 | struct mmu_notifier_range *range, |
| 1409 | pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); | 1465 | pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); |
| 1410 | int follow_pfn(struct vm_area_struct *vma, unsigned long address, | 1466 | int follow_pfn(struct vm_area_struct *vma, unsigned long address, |
| 1411 | unsigned long *pfn); | 1467 | unsigned long *pfn); |
| 1412 | int follow_phys(struct vm_area_struct *vma, unsigned long address, | 1468 | int follow_phys(struct vm_area_struct *vma, unsigned long address, |
| @@ -1900,13 +1956,6 @@ static inline bool ptlock_init(struct page *page) | |||
| 1900 | return true; | 1956 | return true; |
| 1901 | } | 1957 | } |
| 1902 | 1958 | ||
| 1903 | /* Reset page->mapping so free_pages_check won't complain. */ | ||
| 1904 | static inline void pte_lock_deinit(struct page *page) | ||
| 1905 | { | ||
| 1906 | page->mapping = NULL; | ||
| 1907 | ptlock_free(page); | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | #else /* !USE_SPLIT_PTE_PTLOCKS */ | 1959 | #else /* !USE_SPLIT_PTE_PTLOCKS */ |
| 1911 | /* | 1960 | /* |
| 1912 | * We use mm->page_table_lock to guard all pagetable pages of the mm. | 1961 | * We use mm->page_table_lock to guard all pagetable pages of the mm. |
| @@ -1917,7 +1966,7 @@ static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd) | |||
| 1917 | } | 1966 | } |
| 1918 | static inline void ptlock_cache_init(void) {} | 1967 | static inline void ptlock_cache_init(void) {} |
| 1919 | static inline bool ptlock_init(struct page *page) { return true; } | 1968 | static inline bool ptlock_init(struct page *page) { return true; } |
| 1920 | static inline void pte_lock_deinit(struct page *page) {} | 1969 | static inline void ptlock_free(struct page *page) {} |
| 1921 | #endif /* USE_SPLIT_PTE_PTLOCKS */ | 1970 | #endif /* USE_SPLIT_PTE_PTLOCKS */ |
| 1922 | 1971 | ||
| 1923 | static inline void pgtable_init(void) | 1972 | static inline void pgtable_init(void) |
| @@ -1937,7 +1986,7 @@ static inline bool pgtable_page_ctor(struct page *page) | |||
| 1937 | 1986 | ||
| 1938 | static inline void pgtable_page_dtor(struct page *page) | 1987 | static inline void pgtable_page_dtor(struct page *page) |
| 1939 | { | 1988 | { |
| 1940 | pte_lock_deinit(page); | 1989 | ptlock_free(page); |
| 1941 | __ClearPageTable(page); | 1990 | __ClearPageTable(page); |
| 1942 | dec_zone_page_state(page, NR_PAGETABLE); | 1991 | dec_zone_page_state(page, NR_PAGETABLE); |
| 1943 | } | 1992 | } |
| @@ -2054,7 +2103,7 @@ extern void free_initmem(void); | |||
| 2054 | * Return pages freed into the buddy system. | 2103 | * Return pages freed into the buddy system. |
| 2055 | */ | 2104 | */ |
| 2056 | extern unsigned long free_reserved_area(void *start, void *end, | 2105 | extern unsigned long free_reserved_area(void *start, void *end, |
| 2057 | int poison, char *s); | 2106 | int poison, const char *s); |
| 2058 | 2107 | ||
| 2059 | #ifdef CONFIG_HIGHMEM | 2108 | #ifdef CONFIG_HIGHMEM |
| 2060 | /* | 2109 | /* |
| @@ -2202,6 +2251,7 @@ extern void zone_pcp_reset(struct zone *zone); | |||
| 2202 | 2251 | ||
| 2203 | /* page_alloc.c */ | 2252 | /* page_alloc.c */ |
| 2204 | extern int min_free_kbytes; | 2253 | extern int min_free_kbytes; |
| 2254 | extern int watermark_boost_factor; | ||
| 2205 | extern int watermark_scale_factor; | 2255 | extern int watermark_scale_factor; |
| 2206 | 2256 | ||
| 2207 | /* nommu.c */ | 2257 | /* nommu.c */ |
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 9893a6432adf..4050ec1c3b45 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h | |||
| @@ -25,6 +25,13 @@ struct mmu_notifier_mm { | |||
| 25 | spinlock_t lock; | 25 | spinlock_t lock; |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | struct mmu_notifier_range { | ||
| 29 | struct mm_struct *mm; | ||
| 30 | unsigned long start; | ||
| 31 | unsigned long end; | ||
| 32 | bool blockable; | ||
| 33 | }; | ||
| 34 | |||
| 28 | struct mmu_notifier_ops { | 35 | struct mmu_notifier_ops { |
| 29 | /* | 36 | /* |
| 30 | * Called either by mmu_notifier_unregister or when the mm is | 37 | * Called either by mmu_notifier_unregister or when the mm is |
| @@ -146,12 +153,9 @@ struct mmu_notifier_ops { | |||
| 146 | * | 153 | * |
| 147 | */ | 154 | */ |
| 148 | int (*invalidate_range_start)(struct mmu_notifier *mn, | 155 | int (*invalidate_range_start)(struct mmu_notifier *mn, |
| 149 | struct mm_struct *mm, | 156 | const struct mmu_notifier_range *range); |
| 150 | unsigned long start, unsigned long end, | ||
| 151 | bool blockable); | ||
| 152 | void (*invalidate_range_end)(struct mmu_notifier *mn, | 157 | void (*invalidate_range_end)(struct mmu_notifier *mn, |
| 153 | struct mm_struct *mm, | 158 | const struct mmu_notifier_range *range); |
| 154 | unsigned long start, unsigned long end); | ||
| 155 | 159 | ||
| 156 | /* | 160 | /* |
| 157 | * invalidate_range() is either called between | 161 | * invalidate_range() is either called between |
| @@ -216,11 +220,8 @@ extern int __mmu_notifier_test_young(struct mm_struct *mm, | |||
| 216 | unsigned long address); | 220 | unsigned long address); |
| 217 | extern void __mmu_notifier_change_pte(struct mm_struct *mm, | 221 | extern void __mmu_notifier_change_pte(struct mm_struct *mm, |
| 218 | unsigned long address, pte_t pte); | 222 | unsigned long address, pte_t pte); |
| 219 | extern int __mmu_notifier_invalidate_range_start(struct mm_struct *mm, | 223 | extern int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *r); |
| 220 | unsigned long start, unsigned long end, | 224 | extern void __mmu_notifier_invalidate_range_end(struct mmu_notifier_range *r, |
| 221 | bool blockable); | ||
| 222 | extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, | ||
| 223 | unsigned long start, unsigned long end, | ||
| 224 | bool only_end); | 225 | bool only_end); |
| 225 | extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, | 226 | extern void __mmu_notifier_invalidate_range(struct mm_struct *mm, |
| 226 | unsigned long start, unsigned long end); | 227 | unsigned long start, unsigned long end); |
| @@ -264,33 +265,37 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm, | |||
| 264 | __mmu_notifier_change_pte(mm, address, pte); | 265 | __mmu_notifier_change_pte(mm, address, pte); |
| 265 | } | 266 | } |
| 266 | 267 | ||
| 267 | static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, | 268 | static inline void |
| 268 | unsigned long start, unsigned long end) | 269 | mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range) |
| 269 | { | 270 | { |
| 270 | if (mm_has_notifiers(mm)) | 271 | if (mm_has_notifiers(range->mm)) { |
| 271 | __mmu_notifier_invalidate_range_start(mm, start, end, true); | 272 | range->blockable = true; |
| 273 | __mmu_notifier_invalidate_range_start(range); | ||
| 274 | } | ||
| 272 | } | 275 | } |
| 273 | 276 | ||
| 274 | static inline int mmu_notifier_invalidate_range_start_nonblock(struct mm_struct *mm, | 277 | static inline int |
| 275 | unsigned long start, unsigned long end) | 278 | mmu_notifier_invalidate_range_start_nonblock(struct mmu_notifier_range *range) |
| 276 | { | 279 | { |
| 277 | if (mm_has_notifiers(mm)) | 280 | if (mm_has_notifiers(range->mm)) { |
| 278 | return __mmu_notifier_invalidate_range_start(mm, start, end, false); | 281 | range->blockable = false; |
| 282 | return __mmu_notifier_invalidate_range_start(range); | ||
| 283 | } | ||
| 279 | return 0; | 284 | return 0; |
| 280 | } | 285 | } |
| 281 | 286 | ||
| 282 | static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, | 287 | static inline void |
| 283 | unsigned long start, unsigned long end) | 288 | mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range) |
| 284 | { | 289 | { |
| 285 | if (mm_has_notifiers(mm)) | 290 | if (mm_has_notifiers(range->mm)) |
| 286 | __mmu_notifier_invalidate_range_end(mm, start, end, false); | 291 | __mmu_notifier_invalidate_range_end(range, false); |
| 287 | } | 292 | } |
| 288 | 293 | ||
| 289 | static inline void mmu_notifier_invalidate_range_only_end(struct mm_struct *mm, | 294 | static inline void |
| 290 | unsigned long start, unsigned long end) | 295 | mmu_notifier_invalidate_range_only_end(struct mmu_notifier_range *range) |
| 291 | { | 296 | { |
| 292 | if (mm_has_notifiers(mm)) | 297 | if (mm_has_notifiers(range->mm)) |
| 293 | __mmu_notifier_invalidate_range_end(mm, start, end, true); | 298 | __mmu_notifier_invalidate_range_end(range, true); |
| 294 | } | 299 | } |
| 295 | 300 | ||
| 296 | static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, | 301 | static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, |
| @@ -311,6 +316,17 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) | |||
| 311 | __mmu_notifier_mm_destroy(mm); | 316 | __mmu_notifier_mm_destroy(mm); |
| 312 | } | 317 | } |
| 313 | 318 | ||
| 319 | |||
| 320 | static inline void mmu_notifier_range_init(struct mmu_notifier_range *range, | ||
| 321 | struct mm_struct *mm, | ||
| 322 | unsigned long start, | ||
| 323 | unsigned long end) | ||
| 324 | { | ||
| 325 | range->mm = mm; | ||
| 326 | range->start = start; | ||
| 327 | range->end = end; | ||
| 328 | } | ||
| 329 | |||
| 314 | #define ptep_clear_flush_young_notify(__vma, __address, __ptep) \ | 330 | #define ptep_clear_flush_young_notify(__vma, __address, __ptep) \ |
| 315 | ({ \ | 331 | ({ \ |
| 316 | int __young; \ | 332 | int __young; \ |
| @@ -420,10 +436,26 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) | |||
| 420 | 436 | ||
| 421 | extern void mmu_notifier_call_srcu(struct rcu_head *rcu, | 437 | extern void mmu_notifier_call_srcu(struct rcu_head *rcu, |
| 422 | void (*func)(struct rcu_head *rcu)); | 438 | void (*func)(struct rcu_head *rcu)); |
| 423 | extern void mmu_notifier_synchronize(void); | ||
| 424 | 439 | ||
| 425 | #else /* CONFIG_MMU_NOTIFIER */ | 440 | #else /* CONFIG_MMU_NOTIFIER */ |
| 426 | 441 | ||
| 442 | struct mmu_notifier_range { | ||
| 443 | unsigned long start; | ||
| 444 | unsigned long end; | ||
| 445 | }; | ||
| 446 | |||
| 447 | static inline void _mmu_notifier_range_init(struct mmu_notifier_range *range, | ||
| 448 | unsigned long start, | ||
| 449 | unsigned long end) | ||
| 450 | { | ||
| 451 | range->start = start; | ||
| 452 | range->end = end; | ||
| 453 | } | ||
| 454 | |||
| 455 | #define mmu_notifier_range_init(range, mm, start, end) \ | ||
| 456 | _mmu_notifier_range_init(range, start, end) | ||
| 457 | |||
| 458 | |||
| 427 | static inline int mm_has_notifiers(struct mm_struct *mm) | 459 | static inline int mm_has_notifiers(struct mm_struct *mm) |
| 428 | { | 460 | { |
| 429 | return 0; | 461 | return 0; |
| @@ -451,24 +483,24 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm, | |||
| 451 | { | 483 | { |
| 452 | } | 484 | } |
| 453 | 485 | ||
| 454 | static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, | 486 | static inline void |
| 455 | unsigned long start, unsigned long end) | 487 | mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range) |
| 456 | { | 488 | { |
| 457 | } | 489 | } |
| 458 | 490 | ||
| 459 | static inline int mmu_notifier_invalidate_range_start_nonblock(struct mm_struct *mm, | 491 | static inline int |
| 460 | unsigned long start, unsigned long end) | 492 | mmu_notifier_invalidate_range_start_nonblock(struct mmu_notifier_range *range) |
| 461 | { | 493 | { |
| 462 | return 0; | 494 | return 0; |
| 463 | } | 495 | } |
| 464 | 496 | ||
| 465 | static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, | 497 | static inline |
| 466 | unsigned long start, unsigned long end) | 498 | void mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range) |
| 467 | { | 499 | { |
| 468 | } | 500 | } |
| 469 | 501 | ||
| 470 | static inline void mmu_notifier_invalidate_range_only_end(struct mm_struct *mm, | 502 | static inline void |
| 471 | unsigned long start, unsigned long end) | 503 | mmu_notifier_invalidate_range_only_end(struct mmu_notifier_range *range) |
| 472 | { | 504 | { |
| 473 | } | 505 | } |
| 474 | 506 | ||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 077d797d1f60..cc4a507d7ca4 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
| @@ -65,7 +65,7 @@ enum migratetype { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | /* In mm/page_alloc.c; keep in sync also with show_migration_types() there */ | 67 | /* In mm/page_alloc.c; keep in sync also with show_migration_types() there */ |
| 68 | extern char * const migratetype_names[MIGRATE_TYPES]; | 68 | extern const char * const migratetype_names[MIGRATE_TYPES]; |
| 69 | 69 | ||
| 70 | #ifdef CONFIG_CMA | 70 | #ifdef CONFIG_CMA |
| 71 | # define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) | 71 | # define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) |
| @@ -269,9 +269,10 @@ enum zone_watermarks { | |||
| 269 | NR_WMARK | 269 | NR_WMARK |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | #define min_wmark_pages(z) (z->watermark[WMARK_MIN]) | 272 | #define min_wmark_pages(z) (z->_watermark[WMARK_MIN] + z->watermark_boost) |
| 273 | #define low_wmark_pages(z) (z->watermark[WMARK_LOW]) | 273 | #define low_wmark_pages(z) (z->_watermark[WMARK_LOW] + z->watermark_boost) |
| 274 | #define high_wmark_pages(z) (z->watermark[WMARK_HIGH]) | 274 | #define high_wmark_pages(z) (z->_watermark[WMARK_HIGH] + z->watermark_boost) |
| 275 | #define wmark_pages(z, i) (z->_watermark[i] + z->watermark_boost) | ||
| 275 | 276 | ||
| 276 | struct per_cpu_pages { | 277 | struct per_cpu_pages { |
| 277 | int count; /* number of pages in the list */ | 278 | int count; /* number of pages in the list */ |
| @@ -362,7 +363,8 @@ struct zone { | |||
| 362 | /* Read-mostly fields */ | 363 | /* Read-mostly fields */ |
| 363 | 364 | ||
| 364 | /* zone watermarks, access with *_wmark_pages(zone) macros */ | 365 | /* zone watermarks, access with *_wmark_pages(zone) macros */ |
| 365 | unsigned long watermark[NR_WMARK]; | 366 | unsigned long _watermark[NR_WMARK]; |
| 367 | unsigned long watermark_boost; | ||
| 366 | 368 | ||
| 367 | unsigned long nr_reserved_highatomic; | 369 | unsigned long nr_reserved_highatomic; |
| 368 | 370 | ||
| @@ -428,14 +430,8 @@ struct zone { | |||
| 428 | * Write access to present_pages at runtime should be protected by | 430 | * Write access to present_pages at runtime should be protected by |
| 429 | * mem_hotplug_begin/end(). Any reader who can't tolerant drift of | 431 | * mem_hotplug_begin/end(). Any reader who can't tolerant drift of |
| 430 | * present_pages should get_online_mems() to get a stable value. | 432 | * present_pages should get_online_mems() to get a stable value. |
| 431 | * | ||
| 432 | * Read access to managed_pages should be safe because it's unsigned | ||
| 433 | * long. Write access to zone->managed_pages and totalram_pages are | ||
| 434 | * protected by managed_page_count_lock at runtime. Idealy only | ||
| 435 | * adjust_managed_page_count() should be used instead of directly | ||
| 436 | * touching zone->managed_pages and totalram_pages. | ||
| 437 | */ | 433 | */ |
| 438 | unsigned long managed_pages; | 434 | atomic_long_t managed_pages; |
| 439 | unsigned long spanned_pages; | 435 | unsigned long spanned_pages; |
| 440 | unsigned long present_pages; | 436 | unsigned long present_pages; |
| 441 | 437 | ||
| @@ -524,6 +520,11 @@ enum pgdat_flags { | |||
| 524 | PGDAT_RECLAIM_LOCKED, /* prevents concurrent reclaim */ | 520 | PGDAT_RECLAIM_LOCKED, /* prevents concurrent reclaim */ |
| 525 | }; | 521 | }; |
| 526 | 522 | ||
| 523 | static inline unsigned long zone_managed_pages(struct zone *zone) | ||
| 524 | { | ||
| 525 | return (unsigned long)atomic_long_read(&zone->managed_pages); | ||
| 526 | } | ||
| 527 | |||
| 527 | static inline unsigned long zone_end_pfn(const struct zone *zone) | 528 | static inline unsigned long zone_end_pfn(const struct zone *zone) |
| 528 | { | 529 | { |
| 529 | return zone->zone_start_pfn + zone->spanned_pages; | 530 | return zone->zone_start_pfn + zone->spanned_pages; |
| @@ -635,9 +636,8 @@ typedef struct pglist_data { | |||
| 635 | #endif | 636 | #endif |
| 636 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT) | 637 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT) |
| 637 | /* | 638 | /* |
| 638 | * Must be held any time you expect node_start_pfn, node_present_pages | 639 | * Must be held any time you expect node_start_pfn, |
| 639 | * or node_spanned_pages stay constant. Holding this will also | 640 | * node_present_pages, node_spanned_pages or nr_zones to stay constant. |
| 640 | * guarantee that any pfn_valid() stays that way. | ||
| 641 | * | 641 | * |
| 642 | * pgdat_resize_lock() and pgdat_resize_unlock() are provided to | 642 | * pgdat_resize_lock() and pgdat_resize_unlock() are provided to |
| 643 | * manipulate node_size_lock without checking for CONFIG_MEMORY_HOTPLUG | 643 | * manipulate node_size_lock without checking for CONFIG_MEMORY_HOTPLUG |
| @@ -691,8 +691,6 @@ typedef struct pglist_data { | |||
| 691 | * is the first PFN that needs to be initialised. | 691 | * is the first PFN that needs to be initialised. |
| 692 | */ | 692 | */ |
| 693 | unsigned long first_deferred_pfn; | 693 | unsigned long first_deferred_pfn; |
| 694 | /* Number of non-deferred pages */ | ||
| 695 | unsigned long static_init_pgcnt; | ||
| 696 | #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */ | 694 | #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */ |
| 697 | 695 | ||
| 698 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 696 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| @@ -820,7 +818,7 @@ static inline bool is_dev_zone(const struct zone *zone) | |||
| 820 | */ | 818 | */ |
| 821 | static inline bool managed_zone(struct zone *zone) | 819 | static inline bool managed_zone(struct zone *zone) |
| 822 | { | 820 | { |
| 823 | return zone->managed_pages; | 821 | return zone_managed_pages(zone); |
| 824 | } | 822 | } |
| 825 | 823 | ||
| 826 | /* Returns true if a zone has memory */ | 824 | /* Returns true if a zone has memory */ |
| @@ -890,6 +888,8 @@ static inline int is_highmem(struct zone *zone) | |||
| 890 | struct ctl_table; | 888 | struct ctl_table; |
| 891 | int min_free_kbytes_sysctl_handler(struct ctl_table *, int, | 889 | int min_free_kbytes_sysctl_handler(struct ctl_table *, int, |
| 892 | void __user *, size_t *, loff_t *); | 890 | void __user *, size_t *, loff_t *); |
| 891 | int watermark_boost_factor_sysctl_handler(struct ctl_table *, int, | ||
| 892 | void __user *, size_t *, loff_t *); | ||
| 893 | int watermark_scale_factor_sysctl_handler(struct ctl_table *, int, | 893 | int watermark_scale_factor_sysctl_handler(struct ctl_table *, int, |
| 894 | void __user *, size_t *, loff_t *); | 894 | void __user *, size_t *, loff_t *); |
| 895 | extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES]; | 895 | extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES]; |
diff --git a/include/linux/oom.h b/include/linux/oom.h index 69864a547663..d07992009265 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h | |||
| @@ -15,6 +15,13 @@ struct notifier_block; | |||
| 15 | struct mem_cgroup; | 15 | struct mem_cgroup; |
| 16 | struct task_struct; | 16 | struct task_struct; |
| 17 | 17 | ||
| 18 | enum oom_constraint { | ||
| 19 | CONSTRAINT_NONE, | ||
| 20 | CONSTRAINT_CPUSET, | ||
| 21 | CONSTRAINT_MEMORY_POLICY, | ||
| 22 | CONSTRAINT_MEMCG, | ||
| 23 | }; | ||
| 24 | |||
| 18 | /* | 25 | /* |
| 19 | * Details of the page allocation that triggered the oom killer that are used to | 26 | * Details of the page allocation that triggered the oom killer that are used to |
| 20 | * determine what should be killed. | 27 | * determine what should be killed. |
| @@ -42,6 +49,9 @@ struct oom_control { | |||
| 42 | unsigned long totalpages; | 49 | unsigned long totalpages; |
| 43 | struct task_struct *chosen; | 50 | struct task_struct *chosen; |
| 44 | unsigned long chosen_points; | 51 | unsigned long chosen_points; |
| 52 | |||
| 53 | /* Used to print the constraint info. */ | ||
| 54 | enum oom_constraint constraint; | ||
| 45 | }; | 55 | }; |
| 46 | 56 | ||
| 47 | extern struct mutex oom_lock; | 57 | extern struct mutex oom_lock; |
diff --git a/include/linux/page-flags-layout.h b/include/linux/page-flags-layout.h index 7ec86bf31ce4..1dda31825ec4 100644 --- a/include/linux/page-flags-layout.h +++ b/include/linux/page-flags-layout.h | |||
| @@ -82,6 +82,16 @@ | |||
| 82 | #define LAST_CPUPID_WIDTH 0 | 82 | #define LAST_CPUPID_WIDTH 0 |
| 83 | #endif | 83 | #endif |
| 84 | 84 | ||
| 85 | #ifdef CONFIG_KASAN_SW_TAGS | ||
| 86 | #define KASAN_TAG_WIDTH 8 | ||
| 87 | #if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH+LAST_CPUPID_WIDTH+KASAN_TAG_WIDTH \ | ||
| 88 | > BITS_PER_LONG - NR_PAGEFLAGS | ||
| 89 | #error "KASAN: not enough bits in page flags for tag" | ||
| 90 | #endif | ||
| 91 | #else | ||
| 92 | #define KASAN_TAG_WIDTH 0 | ||
| 93 | #endif | ||
| 94 | |||
| 85 | /* | 95 | /* |
| 86 | * We are going to use the flags for the page to node mapping if its in | 96 | * We are going to use the flags for the page to node mapping if its in |
| 87 | * there. This includes the case where there is no node, so it is implicit. | 97 | * there. This includes the case where there is no node, so it is implicit. |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 50ce1bddaf56..39b4494e29f1 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
| @@ -669,6 +669,7 @@ PAGEFLAG_FALSE(DoubleMap) | |||
| 669 | 669 | ||
| 670 | #define PAGE_TYPE_BASE 0xf0000000 | 670 | #define PAGE_TYPE_BASE 0xf0000000 |
| 671 | /* Reserve 0x0000007f to catch underflows of page_mapcount */ | 671 | /* Reserve 0x0000007f to catch underflows of page_mapcount */ |
| 672 | #define PAGE_MAPCOUNT_RESERVE -128 | ||
| 672 | #define PG_buddy 0x00000080 | 673 | #define PG_buddy 0x00000080 |
| 673 | #define PG_balloon 0x00000100 | 674 | #define PG_balloon 0x00000100 |
| 674 | #define PG_kmemcg 0x00000200 | 675 | #define PG_kmemcg 0x00000200 |
| @@ -677,6 +678,11 @@ PAGEFLAG_FALSE(DoubleMap) | |||
| 677 | #define PageType(page, flag) \ | 678 | #define PageType(page, flag) \ |
| 678 | ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE) | 679 | ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE) |
| 679 | 680 | ||
| 681 | static inline int page_has_type(struct page *page) | ||
| 682 | { | ||
| 683 | return (int)page->page_type < PAGE_MAPCOUNT_RESERVE; | ||
| 684 | } | ||
| 685 | |||
| 680 | #define PAGE_TYPE_OPS(uname, lname) \ | 686 | #define PAGE_TYPE_OPS(uname, lname) \ |
| 681 | static __always_inline int Page##uname(struct page *page) \ | 687 | static __always_inline int Page##uname(struct page *page) \ |
| 682 | { \ | 688 | { \ |
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h index 4ae347cbc36d..4eb26d278046 100644 --- a/include/linux/page-isolation.h +++ b/include/linux/page-isolation.h | |||
| @@ -30,8 +30,11 @@ static inline bool is_migrate_isolate(int migratetype) | |||
| 30 | } | 30 | } |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | #define SKIP_HWPOISON 0x1 | ||
| 34 | #define REPORT_FAILURE 0x2 | ||
| 35 | |||
| 33 | bool has_unmovable_pages(struct zone *zone, struct page *page, int count, | 36 | bool has_unmovable_pages(struct zone *zone, struct page *page, int count, |
| 34 | int migratetype, bool skip_hwpoisoned_pages); | 37 | int migratetype, int flags); |
| 35 | void set_pageblock_migratetype(struct page *page, int migratetype); | 38 | void set_pageblock_migratetype(struct page *page, int migratetype); |
| 36 | int move_freepages_block(struct zone *zone, struct page *page, | 39 | int move_freepages_block(struct zone *zone, struct page *page, |
| 37 | int migratetype, int *num_movable); | 40 | int migratetype, int *num_movable); |
| @@ -44,10 +47,14 @@ int move_freepages_block(struct zone *zone, struct page *page, | |||
| 44 | * For isolating all pages in the range finally, the caller have to | 47 | * For isolating all pages in the range finally, the caller have to |
| 45 | * free all pages in the range. test_page_isolated() can be used for | 48 | * free all pages in the range. test_page_isolated() can be used for |
| 46 | * test it. | 49 | * test it. |
| 50 | * | ||
| 51 | * The following flags are allowed (they can be combined in a bit mask) | ||
| 52 | * SKIP_HWPOISON - ignore hwpoison pages | ||
| 53 | * REPORT_FAILURE - report details about the failure to isolate the range | ||
| 47 | */ | 54 | */ |
| 48 | int | 55 | int |
| 49 | start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, | 56 | start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, |
| 50 | unsigned migratetype, bool skip_hwpoisoned_pages); | 57 | unsigned migratetype, int flags); |
| 51 | 58 | ||
| 52 | /* | 59 | /* |
| 53 | * Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE. | 60 | * Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE. |
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h index 9132c5cb41f1..06a66327333d 100644 --- a/include/linux/pageblock-flags.h +++ b/include/linux/pageblock-flags.h | |||
| @@ -25,10 +25,11 @@ | |||
| 25 | 25 | ||
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | 27 | ||
| 28 | #define PB_migratetype_bits 3 | ||
| 28 | /* Bit indices that affect a whole block of pages */ | 29 | /* Bit indices that affect a whole block of pages */ |
| 29 | enum pageblock_bits { | 30 | enum pageblock_bits { |
| 30 | PB_migrate, | 31 | PB_migrate, |
| 31 | PB_migrate_end = PB_migrate + 3 - 1, | 32 | PB_migrate_end = PB_migrate + PB_migratetype_bits - 1, |
| 32 | /* 3 bits required for migrate types */ | 33 | /* 3 bits required for migrate types */ |
| 33 | PB_migrate_skip,/* If set the block is skipped by compaction */ | 34 | PB_migrate_skip,/* If set the block is skipped by compaction */ |
| 34 | 35 | ||
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 226f96f0dee0..e2d7039af6a3 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
| @@ -537,6 +537,8 @@ static inline int wait_on_page_locked_killable(struct page *page) | |||
| 537 | return wait_on_page_bit_killable(compound_head(page), PG_locked); | 537 | return wait_on_page_bit_killable(compound_head(page), PG_locked); |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | extern void put_and_wait_on_page_locked(struct page *page); | ||
| 541 | |||
| 540 | /* | 542 | /* |
| 541 | * Wait for a page to complete writeback | 543 | * Wait for a page to complete writeback |
| 542 | */ | 544 | */ |
diff --git a/include/linux/slab.h b/include/linux/slab.h index 918f374e7156..6d9bd6fc0c57 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h | |||
| @@ -314,22 +314,22 @@ kmalloc_caches[NR_KMALLOC_TYPES][KMALLOC_SHIFT_HIGH + 1]; | |||
| 314 | 314 | ||
| 315 | static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags) | 315 | static __always_inline enum kmalloc_cache_type kmalloc_type(gfp_t flags) |
| 316 | { | 316 | { |
| 317 | int is_dma = 0; | ||
| 318 | int type_dma = 0; | ||
| 319 | int is_reclaimable; | ||
| 320 | |||
| 321 | #ifdef CONFIG_ZONE_DMA | 317 | #ifdef CONFIG_ZONE_DMA |
| 322 | is_dma = !!(flags & __GFP_DMA); | 318 | /* |
| 323 | type_dma = is_dma * KMALLOC_DMA; | 319 | * The most common case is KMALLOC_NORMAL, so test for it |
| 324 | #endif | 320 | * with a single branch for both flags. |
| 325 | 321 | */ | |
| 326 | is_reclaimable = !!(flags & __GFP_RECLAIMABLE); | 322 | if (likely((flags & (__GFP_DMA | __GFP_RECLAIMABLE)) == 0)) |
| 323 | return KMALLOC_NORMAL; | ||
| 327 | 324 | ||
| 328 | /* | 325 | /* |
| 329 | * If an allocation is both __GFP_DMA and __GFP_RECLAIMABLE, return | 326 | * At least one of the flags has to be set. If both are, __GFP_DMA |
| 330 | * KMALLOC_DMA and effectively ignore __GFP_RECLAIMABLE | 327 | * is more important. |
| 331 | */ | 328 | */ |
| 332 | return type_dma + (is_reclaimable & !is_dma) * KMALLOC_RECLAIM; | 329 | return flags & __GFP_DMA ? KMALLOC_DMA : KMALLOC_RECLAIM; |
| 330 | #else | ||
| 331 | return flags & __GFP_RECLAIMABLE ? KMALLOC_RECLAIM : KMALLOC_NORMAL; | ||
| 332 | #endif | ||
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | /* | 335 | /* |
| @@ -444,7 +444,7 @@ static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s, | |||
| 444 | { | 444 | { |
| 445 | void *ret = kmem_cache_alloc(s, flags); | 445 | void *ret = kmem_cache_alloc(s, flags); |
| 446 | 446 | ||
| 447 | kasan_kmalloc(s, ret, size, flags); | 447 | ret = kasan_kmalloc(s, ret, size, flags); |
| 448 | return ret; | 448 | return ret; |
| 449 | } | 449 | } |
| 450 | 450 | ||
| @@ -455,7 +455,7 @@ kmem_cache_alloc_node_trace(struct kmem_cache *s, | |||
| 455 | { | 455 | { |
| 456 | void *ret = kmem_cache_alloc_node(s, gfpflags, node); | 456 | void *ret = kmem_cache_alloc_node(s, gfpflags, node); |
| 457 | 457 | ||
| 458 | kasan_kmalloc(s, ret, size, gfpflags); | 458 | ret = kasan_kmalloc(s, ret, size, gfpflags); |
| 459 | return ret; | 459 | return ret; |
| 460 | } | 460 | } |
| 461 | #endif /* CONFIG_TRACING */ | 461 | #endif /* CONFIG_TRACING */ |
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 3485c58cfd1c..9a5eafb7145b 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h | |||
| @@ -104,4 +104,17 @@ static inline void *nearest_obj(struct kmem_cache *cache, struct page *page, | |||
| 104 | return object; | 104 | return object; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | /* | ||
| 108 | * We want to avoid an expensive divide : (offset / cache->size) | ||
| 109 | * Using the fact that size is a constant for a particular cache, | ||
| 110 | * we can replace (offset / cache->size) by | ||
| 111 | * reciprocal_divide(offset, cache->reciprocal_buffer_size) | ||
| 112 | */ | ||
| 113 | static inline unsigned int obj_to_index(const struct kmem_cache *cache, | ||
| 114 | const struct page *page, void *obj) | ||
| 115 | { | ||
| 116 | u32 offset = (obj - page->s_mem); | ||
| 117 | return reciprocal_divide(offset, cache->reciprocal_buffer_size); | ||
| 118 | } | ||
| 119 | |||
| 107 | #endif /* _LINUX_SLAB_DEF_H */ | 120 | #endif /* _LINUX_SLAB_DEF_H */ |
diff --git a/include/linux/swap.h b/include/linux/swap.h index a8f6d5d89524..622025ac1461 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
| @@ -235,7 +235,6 @@ struct swap_info_struct { | |||
| 235 | unsigned long flags; /* SWP_USED etc: see above */ | 235 | unsigned long flags; /* SWP_USED etc: see above */ |
| 236 | signed short prio; /* swap priority of this type */ | 236 | signed short prio; /* swap priority of this type */ |
| 237 | struct plist_node list; /* entry in swap_active_head */ | 237 | struct plist_node list; /* entry in swap_active_head */ |
| 238 | struct plist_node avail_lists[MAX_NUMNODES];/* entry in swap_avail_heads */ | ||
| 239 | signed char type; /* strange name for an index */ | 238 | signed char type; /* strange name for an index */ |
| 240 | unsigned int max; /* extent of the swap_map */ | 239 | unsigned int max; /* extent of the swap_map */ |
| 241 | unsigned char *swap_map; /* vmalloc'ed array of usage counts */ | 240 | unsigned char *swap_map; /* vmalloc'ed array of usage counts */ |
| @@ -276,6 +275,16 @@ struct swap_info_struct { | |||
| 276 | */ | 275 | */ |
| 277 | struct work_struct discard_work; /* discard worker */ | 276 | struct work_struct discard_work; /* discard worker */ |
| 278 | struct swap_cluster_list discard_clusters; /* discard clusters list */ | 277 | struct swap_cluster_list discard_clusters; /* discard clusters list */ |
| 278 | struct plist_node avail_lists[0]; /* | ||
| 279 | * entries in swap_avail_heads, one | ||
| 280 | * entry per node. | ||
| 281 | * Must be last as the number of the | ||
| 282 | * array is nr_node_ids, which is not | ||
| 283 | * a fixed value so have to allocate | ||
| 284 | * dynamically. | ||
| 285 | * And it has to be an array so that | ||
| 286 | * plist_for_each_* can work. | ||
| 287 | */ | ||
| 279 | }; | 288 | }; |
| 280 | 289 | ||
| 281 | #ifdef CONFIG_64BIT | 290 | #ifdef CONFIG_64BIT |
| @@ -310,7 +319,6 @@ void workingset_update_node(struct xa_node *node); | |||
| 310 | } while (0) | 319 | } while (0) |
| 311 | 320 | ||
| 312 | /* linux/mm/page_alloc.c */ | 321 | /* linux/mm/page_alloc.c */ |
| 313 | extern unsigned long totalram_pages; | ||
| 314 | extern unsigned long totalreserve_pages; | 322 | extern unsigned long totalreserve_pages; |
| 315 | extern unsigned long nr_free_buffer_pages(void); | 323 | extern unsigned long nr_free_buffer_pages(void); |
| 316 | extern unsigned long nr_free_pagecache_pages(void); | 324 | extern unsigned long nr_free_pagecache_pages(void); |
| @@ -360,14 +368,8 @@ extern unsigned long vm_total_pages; | |||
| 360 | extern int node_reclaim_mode; | 368 | extern int node_reclaim_mode; |
| 361 | extern int sysctl_min_unmapped_ratio; | 369 | extern int sysctl_min_unmapped_ratio; |
| 362 | extern int sysctl_min_slab_ratio; | 370 | extern int sysctl_min_slab_ratio; |
| 363 | extern int node_reclaim(struct pglist_data *, gfp_t, unsigned int); | ||
| 364 | #else | 371 | #else |
| 365 | #define node_reclaim_mode 0 | 372 | #define node_reclaim_mode 0 |
| 366 | static inline int node_reclaim(struct pglist_data *pgdat, gfp_t mask, | ||
| 367 | unsigned int order) | ||
| 368 | { | ||
| 369 | return 0; | ||
| 370 | } | ||
| 371 | #endif | 373 | #endif |
| 372 | 374 | ||
| 373 | extern int page_evictable(struct page *page); | 375 | extern int page_evictable(struct page *page); |
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index f25cef84b41d..2db8d60981fe 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h | |||
| @@ -239,11 +239,6 @@ extern unsigned long node_page_state(struct pglist_data *pgdat, | |||
| 239 | #define node_page_state(node, item) global_node_page_state(item) | 239 | #define node_page_state(node, item) global_node_page_state(item) |
| 240 | #endif /* CONFIG_NUMA */ | 240 | #endif /* CONFIG_NUMA */ |
| 241 | 241 | ||
| 242 | #define add_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, __d) | ||
| 243 | #define sub_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, -(__d)) | ||
| 244 | #define add_node_page_state(__p, __i, __d) mod_node_page_state(__p, __i, __d) | ||
| 245 | #define sub_node_page_state(__p, __i, __d) mod_node_page_state(__p, __i, -(__d)) | ||
| 246 | |||
| 247 | #ifdef CONFIG_SMP | 242 | #ifdef CONFIG_SMP |
| 248 | void __mod_zone_page_state(struct zone *, enum zone_stat_item item, long); | 243 | void __mod_zone_page_state(struct zone *, enum zone_stat_item item, long); |
| 249 | void __inc_zone_page_state(struct page *, enum zone_stat_item); | 244 | void __inc_zone_page_state(struct page *, enum zone_stat_item); |
diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h index 9e1f42cb57e9..52b073fea17f 100644 --- a/include/linux/xxhash.h +++ b/include/linux/xxhash.h | |||
| @@ -107,6 +107,29 @@ uint32_t xxh32(const void *input, size_t length, uint32_t seed); | |||
| 107 | */ | 107 | */ |
| 108 | uint64_t xxh64(const void *input, size_t length, uint64_t seed); | 108 | uint64_t xxh64(const void *input, size_t length, uint64_t seed); |
| 109 | 109 | ||
| 110 | /** | ||
| 111 | * xxhash() - calculate wordsize hash of the input with a given seed | ||
| 112 | * @input: The data to hash. | ||
| 113 | * @length: The length of the data to hash. | ||
| 114 | * @seed: The seed can be used to alter the result predictably. | ||
| 115 | * | ||
| 116 | * If the hash does not need to be comparable between machines with | ||
| 117 | * different word sizes, this function will call whichever of xxh32() | ||
| 118 | * or xxh64() is faster. | ||
| 119 | * | ||
| 120 | * Return: wordsize hash of the data. | ||
| 121 | */ | ||
| 122 | |||
| 123 | static inline unsigned long xxhash(const void *input, size_t length, | ||
| 124 | uint64_t seed) | ||
| 125 | { | ||
| 126 | #if BITS_PER_LONG == 64 | ||
| 127 | return xxh64(input, length, seed); | ||
| 128 | #else | ||
| 129 | return xxh32(input, length, seed); | ||
| 130 | #endif | ||
| 131 | } | ||
| 132 | |||
| 110 | /*-**************************** | 133 | /*-**************************** |
| 111 | * Streaming Hash Functions | 134 | * Streaming Hash Functions |
| 112 | *****************************/ | 135 | *****************************/ |
