diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 11:58:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 11:58:04 -0400 |
commit | 57a8ec387e1441ea5e1232bc0749fb99a8cba7e7 (patch) | |
tree | b5fb03fc6bc5754de8b5b1f8b0e4f36d67c8315c /mm/z3fold.c | |
parent | 0a8ad0ffa4d80a544f6cbff703bf6394339afcdf (diff) | |
parent | 43e11fa2d1d3b6e35629fa556eb7d571edba2010 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton:
"VM:
- z3fold fixes and enhancements by Henry Burns and Vitaly Wool
- more accurate reclaimed slab caches calculations by Yafang Shao
- fix MAP_UNINITIALIZED UAPI symbol to not depend on config, by
Christoph Hellwig
- !CONFIG_MMU fixes by Christoph Hellwig
- new novmcoredd parameter to omit device dumps from vmcore, by
Kairui Song
- new test_meminit module for testing heap and pagealloc
initialization, by Alexander Potapenko
- ioremap improvements for huge mappings, by Anshuman Khandual
- generalize kprobe page fault handling, by Anshuman Khandual
- device-dax hotplug fixes and improvements, by Pavel Tatashin
- enable synchronous DAX fault on powerpc, by Aneesh Kumar K.V
- add pte_devmap() support for arm64, by Robin Murphy
- unify locked_vm accounting with a helper, by Daniel Jordan
- several misc fixes
core/lib:
- new typeof_member() macro including some users, by Alexey Dobriyan
- make BIT() and GENMASK() available in asm, by Masahiro Yamada
- changed LIST_POISON2 on x86_64 to 0xdead000000000122 for better
code generation, by Alexey Dobriyan
- rbtree code size optimizations, by Michel Lespinasse
- convert struct pid count to refcount_t, by Joel Fernandes
get_maintainer.pl:
- add --no-moderated switch to skip moderated ML's, by Joe Perches
misc:
- ptrace PTRACE_GET_SYSCALL_INFO interface
- coda updates
- gdb scripts, various"
[ Using merge message suggestion from Vlastimil Babka, with some editing - Linus ]
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (100 commits)
fs/select.c: use struct_size() in kmalloc()
mm: add account_locked_vm utility function
arm64: mm: implement pte_devmap support
mm: introduce ARCH_HAS_PTE_DEVMAP
mm: clean up is_device_*_page() definitions
mm/mmap: move common defines to mman-common.h
mm: move MAP_SYNC to asm-generic/mman-common.h
device-dax: "Hotremove" persistent memory that is used like normal RAM
mm/hotplug: make remove_memory() interface usable
device-dax: fix memory and resource leak if hotplug fails
include/linux/lz4.h: fix spelling and copy-paste errors in documentation
ipc/mqueue.c: only perform resource calculation if user valid
include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT architectures
scripts/gdb: add helpers to find and list devices
scripts/gdb: add lx-genpd-summary command
drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl
kernel/pid.c: convert struct pid count to refcount_t
drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings
select: shift restore_saved_sigmask_unless() into poll_select_copy_remaining()
select: change do_poll() to return -ERESTARTNOHAND rather than -EINTR
...
Diffstat (limited to 'mm/z3fold.c')
-rw-r--r-- | mm/z3fold.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/mm/z3fold.c b/mm/z3fold.c index dfcd69d08c1e..6c72b18d8b9c 100644 --- a/mm/z3fold.c +++ b/mm/z3fold.c | |||
@@ -101,6 +101,7 @@ struct z3fold_buddy_slots { | |||
101 | * @refcount: reference count for the z3fold page | 101 | * @refcount: reference count for the z3fold page |
102 | * @work: work_struct for page layout optimization | 102 | * @work: work_struct for page layout optimization |
103 | * @slots: pointer to the structure holding buddy slots | 103 | * @slots: pointer to the structure holding buddy slots |
104 | * @pool: pointer to the containing pool | ||
104 | * @cpu: CPU which this page "belongs" to | 105 | * @cpu: CPU which this page "belongs" to |
105 | * @first_chunks: the size of the first buddy in chunks, 0 if free | 106 | * @first_chunks: the size of the first buddy in chunks, 0 if free |
106 | * @middle_chunks: the size of the middle buddy in chunks, 0 if free | 107 | * @middle_chunks: the size of the middle buddy in chunks, 0 if free |
@@ -114,6 +115,7 @@ struct z3fold_header { | |||
114 | struct kref refcount; | 115 | struct kref refcount; |
115 | struct work_struct work; | 116 | struct work_struct work; |
116 | struct z3fold_buddy_slots *slots; | 117 | struct z3fold_buddy_slots *slots; |
118 | struct z3fold_pool *pool; | ||
117 | short cpu; | 119 | short cpu; |
118 | unsigned short first_chunks; | 120 | unsigned short first_chunks; |
119 | unsigned short middle_chunks; | 121 | unsigned short middle_chunks; |
@@ -193,8 +195,10 @@ static void compact_page_work(struct work_struct *w); | |||
193 | static inline struct z3fold_buddy_slots *alloc_slots(struct z3fold_pool *pool, | 195 | static inline struct z3fold_buddy_slots *alloc_slots(struct z3fold_pool *pool, |
194 | gfp_t gfp) | 196 | gfp_t gfp) |
195 | { | 197 | { |
196 | struct z3fold_buddy_slots *slots = kmem_cache_alloc(pool->c_handle, | 198 | struct z3fold_buddy_slots *slots; |
197 | gfp); | 199 | |
200 | slots = kmem_cache_alloc(pool->c_handle, | ||
201 | (gfp & ~(__GFP_HIGHMEM | __GFP_MOVABLE))); | ||
198 | 202 | ||
199 | if (slots) { | 203 | if (slots) { |
200 | memset(slots->slot, 0, sizeof(slots->slot)); | 204 | memset(slots->slot, 0, sizeof(slots->slot)); |
@@ -320,6 +324,7 @@ static struct z3fold_header *init_z3fold_page(struct page *page, | |||
320 | zhdr->start_middle = 0; | 324 | zhdr->start_middle = 0; |
321 | zhdr->cpu = -1; | 325 | zhdr->cpu = -1; |
322 | zhdr->slots = slots; | 326 | zhdr->slots = slots; |
327 | zhdr->pool = pool; | ||
323 | INIT_LIST_HEAD(&zhdr->buddy); | 328 | INIT_LIST_HEAD(&zhdr->buddy); |
324 | INIT_WORK(&zhdr->work, compact_page_work); | 329 | INIT_WORK(&zhdr->work, compact_page_work); |
325 | return zhdr; | 330 | return zhdr; |
@@ -426,7 +431,7 @@ static enum buddy handle_to_buddy(unsigned long handle) | |||
426 | 431 | ||
427 | static inline struct z3fold_pool *zhdr_to_pool(struct z3fold_header *zhdr) | 432 | static inline struct z3fold_pool *zhdr_to_pool(struct z3fold_header *zhdr) |
428 | { | 433 | { |
429 | return slots_to_pool(zhdr->slots); | 434 | return zhdr->pool; |
430 | } | 435 | } |
431 | 436 | ||
432 | static void __release_z3fold_page(struct z3fold_header *zhdr, bool locked) | 437 | static void __release_z3fold_page(struct z3fold_header *zhdr, bool locked) |
@@ -850,7 +855,7 @@ static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, | |||
850 | enum buddy bud; | 855 | enum buddy bud; |
851 | bool can_sleep = gfpflags_allow_blocking(gfp); | 856 | bool can_sleep = gfpflags_allow_blocking(gfp); |
852 | 857 | ||
853 | if (!size || (gfp & __GFP_HIGHMEM)) | 858 | if (!size) |
854 | return -EINVAL; | 859 | return -EINVAL; |
855 | 860 | ||
856 | if (size > PAGE_SIZE) | 861 | if (size > PAGE_SIZE) |
@@ -1345,24 +1350,29 @@ static int z3fold_page_migrate(struct address_space *mapping, struct page *newpa | |||
1345 | zhdr = page_address(page); | 1350 | zhdr = page_address(page); |
1346 | pool = zhdr_to_pool(zhdr); | 1351 | pool = zhdr_to_pool(zhdr); |
1347 | 1352 | ||
1348 | if (!trylock_page(page)) | ||
1349 | return -EAGAIN; | ||
1350 | |||
1351 | if (!z3fold_page_trylock(zhdr)) { | 1353 | if (!z3fold_page_trylock(zhdr)) { |
1352 | unlock_page(page); | ||
1353 | return -EAGAIN; | 1354 | return -EAGAIN; |
1354 | } | 1355 | } |
1355 | if (zhdr->mapped_count != 0) { | 1356 | if (zhdr->mapped_count != 0) { |
1356 | z3fold_page_unlock(zhdr); | 1357 | z3fold_page_unlock(zhdr); |
1357 | unlock_page(page); | ||
1358 | return -EBUSY; | 1358 | return -EBUSY; |
1359 | } | 1359 | } |
1360 | if (work_pending(&zhdr->work)) { | ||
1361 | z3fold_page_unlock(zhdr); | ||
1362 | return -EAGAIN; | ||
1363 | } | ||
1360 | new_zhdr = page_address(newpage); | 1364 | new_zhdr = page_address(newpage); |
1361 | memcpy(new_zhdr, zhdr, PAGE_SIZE); | 1365 | memcpy(new_zhdr, zhdr, PAGE_SIZE); |
1362 | newpage->private = page->private; | 1366 | newpage->private = page->private; |
1363 | page->private = 0; | 1367 | page->private = 0; |
1364 | z3fold_page_unlock(zhdr); | 1368 | z3fold_page_unlock(zhdr); |
1365 | spin_lock_init(&new_zhdr->page_lock); | 1369 | spin_lock_init(&new_zhdr->page_lock); |
1370 | INIT_WORK(&new_zhdr->work, compact_page_work); | ||
1371 | /* | ||
1372 | * z3fold_page_isolate() ensures that new_zhdr->buddy is empty, | ||
1373 | * so we only have to reinitialize it. | ||
1374 | */ | ||
1375 | INIT_LIST_HEAD(&new_zhdr->buddy); | ||
1366 | new_mapping = page_mapping(page); | 1376 | new_mapping = page_mapping(page); |
1367 | __ClearPageMovable(page); | 1377 | __ClearPageMovable(page); |
1368 | ClearPagePrivate(page); | 1378 | ClearPagePrivate(page); |
@@ -1386,7 +1396,6 @@ static int z3fold_page_migrate(struct address_space *mapping, struct page *newpa | |||
1386 | queue_work_on(new_zhdr->cpu, pool->compact_wq, &new_zhdr->work); | 1396 | queue_work_on(new_zhdr->cpu, pool->compact_wq, &new_zhdr->work); |
1387 | 1397 | ||
1388 | page_mapcount_reset(page); | 1398 | page_mapcount_reset(page); |
1389 | unlock_page(page); | ||
1390 | put_page(page); | 1399 | put_page(page); |
1391 | return 0; | 1400 | return 0; |
1392 | } | 1401 | } |