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 /drivers | |
| 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 'drivers')
31 files changed, 478 insertions, 301 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 0e5985682642..fb75a6fd4bd9 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -207,15 +207,15 @@ static bool pages_correctly_probed(unsigned long start_pfn) | |||
| 207 | return false; | 207 | return false; |
| 208 | 208 | ||
| 209 | if (!present_section_nr(section_nr)) { | 209 | if (!present_section_nr(section_nr)) { |
| 210 | pr_warn("section %ld pfn[%lx, %lx) not present", | 210 | pr_warn("section %ld pfn[%lx, %lx) not present\n", |
| 211 | section_nr, pfn, pfn + PAGES_PER_SECTION); | 211 | section_nr, pfn, pfn + PAGES_PER_SECTION); |
| 212 | return false; | 212 | return false; |
| 213 | } else if (!valid_section_nr(section_nr)) { | 213 | } else if (!valid_section_nr(section_nr)) { |
| 214 | pr_warn("section %ld pfn[%lx, %lx) no valid memmap", | 214 | pr_warn("section %ld pfn[%lx, %lx) no valid memmap\n", |
| 215 | section_nr, pfn, pfn + PAGES_PER_SECTION); | 215 | section_nr, pfn, pfn + PAGES_PER_SECTION); |
| 216 | return false; | 216 | return false; |
| 217 | } else if (online_section_nr(section_nr)) { | 217 | } else if (online_section_nr(section_nr)) { |
| 218 | pr_warn("section %ld pfn[%lx, %lx) is already online", | 218 | pr_warn("section %ld pfn[%lx, %lx) is already online\n", |
| 219 | section_nr, pfn, pfn + PAGES_PER_SECTION); | 219 | section_nr, pfn, pfn + PAGES_PER_SECTION); |
| 220 | return false; | 220 | return false; |
| 221 | } | 221 | } |
| @@ -688,7 +688,7 @@ static int add_memory_block(int base_section_nr) | |||
| 688 | int i, ret, section_count = 0, section_nr; | 688 | int i, ret, section_count = 0, section_nr; |
| 689 | 689 | ||
| 690 | for (i = base_section_nr; | 690 | for (i = base_section_nr; |
| 691 | (i < base_section_nr + sections_per_block) && i < NR_MEM_SECTIONS; | 691 | i < base_section_nr + sections_per_block; |
| 692 | i++) { | 692 | i++) { |
| 693 | if (!present_section_nr(i)) | 693 | if (!present_section_nr(i)) |
| 694 | continue; | 694 | continue; |
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index fcd055457364..1ffc64770643 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig | |||
| @@ -15,7 +15,7 @@ config ZRAM | |||
| 15 | See Documentation/blockdev/zram.txt for more information. | 15 | See Documentation/blockdev/zram.txt for more information. |
| 16 | 16 | ||
| 17 | config ZRAM_WRITEBACK | 17 | config ZRAM_WRITEBACK |
| 18 | bool "Write back incompressible page to backing device" | 18 | bool "Write back incompressible or idle page to backing device" |
| 19 | depends on ZRAM | 19 | depends on ZRAM |
| 20 | help | 20 | help |
| 21 | With incompressible page, there is no memory saving to keep it | 21 | With incompressible page, there is no memory saving to keep it |
| @@ -23,6 +23,9 @@ config ZRAM_WRITEBACK | |||
| 23 | For this feature, admin should set up backing device via | 23 | For this feature, admin should set up backing device via |
| 24 | /sys/block/zramX/backing_dev. | 24 | /sys/block/zramX/backing_dev. |
| 25 | 25 | ||
| 26 | With /sys/block/zramX/{idle,writeback}, application could ask | ||
| 27 | idle page's writeback to the backing device to save in memory. | ||
| 28 | |||
| 26 | See Documentation/blockdev/zram.txt for more information. | 29 | See Documentation/blockdev/zram.txt for more information. |
| 27 | 30 | ||
| 28 | config ZRAM_MEMORY_TRACKING | 31 | config ZRAM_MEMORY_TRACKING |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 4879595200e1..33c5cc879f24 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
| @@ -52,15 +52,23 @@ static unsigned int num_devices = 1; | |||
| 52 | static size_t huge_class_size; | 52 | static size_t huge_class_size; |
| 53 | 53 | ||
| 54 | static void zram_free_page(struct zram *zram, size_t index); | 54 | static void zram_free_page(struct zram *zram, size_t index); |
| 55 | static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, | ||
| 56 | u32 index, int offset, struct bio *bio); | ||
| 57 | |||
| 58 | |||
| 59 | static int zram_slot_trylock(struct zram *zram, u32 index) | ||
| 60 | { | ||
| 61 | return bit_spin_trylock(ZRAM_LOCK, &zram->table[index].flags); | ||
| 62 | } | ||
| 55 | 63 | ||
| 56 | static void zram_slot_lock(struct zram *zram, u32 index) | 64 | static void zram_slot_lock(struct zram *zram, u32 index) |
| 57 | { | 65 | { |
| 58 | bit_spin_lock(ZRAM_LOCK, &zram->table[index].value); | 66 | bit_spin_lock(ZRAM_LOCK, &zram->table[index].flags); |
| 59 | } | 67 | } |
| 60 | 68 | ||
| 61 | static void zram_slot_unlock(struct zram *zram, u32 index) | 69 | static void zram_slot_unlock(struct zram *zram, u32 index) |
| 62 | { | 70 | { |
| 63 | bit_spin_unlock(ZRAM_LOCK, &zram->table[index].value); | 71 | bit_spin_unlock(ZRAM_LOCK, &zram->table[index].flags); |
| 64 | } | 72 | } |
| 65 | 73 | ||
| 66 | static inline bool init_done(struct zram *zram) | 74 | static inline bool init_done(struct zram *zram) |
| @@ -68,13 +76,6 @@ static inline bool init_done(struct zram *zram) | |||
| 68 | return zram->disksize; | 76 | return zram->disksize; |
| 69 | } | 77 | } |
| 70 | 78 | ||
| 71 | static inline bool zram_allocated(struct zram *zram, u32 index) | ||
| 72 | { | ||
| 73 | |||
| 74 | return (zram->table[index].value >> (ZRAM_FLAG_SHIFT + 1)) || | ||
| 75 | zram->table[index].handle; | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline struct zram *dev_to_zram(struct device *dev) | 79 | static inline struct zram *dev_to_zram(struct device *dev) |
| 79 | { | 80 | { |
| 80 | return (struct zram *)dev_to_disk(dev)->private_data; | 81 | return (struct zram *)dev_to_disk(dev)->private_data; |
| @@ -94,19 +95,19 @@ static void zram_set_handle(struct zram *zram, u32 index, unsigned long handle) | |||
| 94 | static bool zram_test_flag(struct zram *zram, u32 index, | 95 | static bool zram_test_flag(struct zram *zram, u32 index, |
| 95 | enum zram_pageflags flag) | 96 | enum zram_pageflags flag) |
| 96 | { | 97 | { |
| 97 | return zram->table[index].value & BIT(flag); | 98 | return zram->table[index].flags & BIT(flag); |
| 98 | } | 99 | } |
| 99 | 100 | ||
| 100 | static void zram_set_flag(struct zram *zram, u32 index, | 101 | static void zram_set_flag(struct zram *zram, u32 index, |
| 101 | enum zram_pageflags flag) | 102 | enum zram_pageflags flag) |
| 102 | { | 103 | { |
| 103 | zram->table[index].value |= BIT(flag); | 104 | zram->table[index].flags |= BIT(flag); |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | static void zram_clear_flag(struct zram *zram, u32 index, | 107 | static void zram_clear_flag(struct zram *zram, u32 index, |
| 107 | enum zram_pageflags flag) | 108 | enum zram_pageflags flag) |
| 108 | { | 109 | { |
| 109 | zram->table[index].value &= ~BIT(flag); | 110 | zram->table[index].flags &= ~BIT(flag); |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | static inline void zram_set_element(struct zram *zram, u32 index, | 113 | static inline void zram_set_element(struct zram *zram, u32 index, |
| @@ -122,15 +123,22 @@ static unsigned long zram_get_element(struct zram *zram, u32 index) | |||
| 122 | 123 | ||
| 123 | static size_t zram_get_obj_size(struct zram *zram, u32 index) | 124 | static size_t zram_get_obj_size(struct zram *zram, u32 index) |
| 124 | { | 125 | { |
| 125 | return zram->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); | 126 | return zram->table[index].flags & (BIT(ZRAM_FLAG_SHIFT) - 1); |
| 126 | } | 127 | } |
| 127 | 128 | ||
| 128 | static void zram_set_obj_size(struct zram *zram, | 129 | static void zram_set_obj_size(struct zram *zram, |
| 129 | u32 index, size_t size) | 130 | u32 index, size_t size) |
| 130 | { | 131 | { |
| 131 | unsigned long flags = zram->table[index].value >> ZRAM_FLAG_SHIFT; | 132 | unsigned long flags = zram->table[index].flags >> ZRAM_FLAG_SHIFT; |
| 132 | 133 | ||
| 133 | zram->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; | 134 | zram->table[index].flags = (flags << ZRAM_FLAG_SHIFT) | size; |
| 135 | } | ||
| 136 | |||
| 137 | static inline bool zram_allocated(struct zram *zram, u32 index) | ||
| 138 | { | ||
| 139 | return zram_get_obj_size(zram, index) || | ||
| 140 | zram_test_flag(zram, index, ZRAM_SAME) || | ||
| 141 | zram_test_flag(zram, index, ZRAM_WB); | ||
| 134 | } | 142 | } |
| 135 | 143 | ||
| 136 | #if PAGE_SIZE != 4096 | 144 | #if PAGE_SIZE != 4096 |
| @@ -276,17 +284,90 @@ static ssize_t mem_used_max_store(struct device *dev, | |||
| 276 | return len; | 284 | return len; |
| 277 | } | 285 | } |
| 278 | 286 | ||
| 287 | static ssize_t idle_store(struct device *dev, | ||
| 288 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 289 | { | ||
| 290 | struct zram *zram = dev_to_zram(dev); | ||
| 291 | unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; | ||
| 292 | int index; | ||
| 293 | char mode_buf[8]; | ||
| 294 | ssize_t sz; | ||
| 295 | |||
| 296 | sz = strscpy(mode_buf, buf, sizeof(mode_buf)); | ||
| 297 | if (sz <= 0) | ||
| 298 | return -EINVAL; | ||
| 299 | |||
| 300 | /* ignore trailing new line */ | ||
| 301 | if (mode_buf[sz - 1] == '\n') | ||
| 302 | mode_buf[sz - 1] = 0x00; | ||
| 303 | |||
| 304 | if (strcmp(mode_buf, "all")) | ||
| 305 | return -EINVAL; | ||
| 306 | |||
| 307 | down_read(&zram->init_lock); | ||
| 308 | if (!init_done(zram)) { | ||
| 309 | up_read(&zram->init_lock); | ||
| 310 | return -EINVAL; | ||
| 311 | } | ||
| 312 | |||
| 313 | for (index = 0; index < nr_pages; index++) { | ||
| 314 | /* | ||
| 315 | * Do not mark ZRAM_UNDER_WB slot as ZRAM_IDLE to close race. | ||
| 316 | * See the comment in writeback_store. | ||
| 317 | */ | ||
| 318 | zram_slot_lock(zram, index); | ||
| 319 | if (!zram_allocated(zram, index) || | ||
| 320 | zram_test_flag(zram, index, ZRAM_UNDER_WB)) | ||
| 321 | goto next; | ||
| 322 | zram_set_flag(zram, index, ZRAM_IDLE); | ||
| 323 | next: | ||
| 324 | zram_slot_unlock(zram, index); | ||
| 325 | } | ||
| 326 | |||
| 327 | up_read(&zram->init_lock); | ||
| 328 | |||
| 329 | return len; | ||
| 330 | } | ||
| 331 | |||
| 279 | #ifdef CONFIG_ZRAM_WRITEBACK | 332 | #ifdef CONFIG_ZRAM_WRITEBACK |
| 280 | static bool zram_wb_enabled(struct zram *zram) | 333 | static ssize_t writeback_limit_store(struct device *dev, |
| 334 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 335 | { | ||
| 336 | struct zram *zram = dev_to_zram(dev); | ||
| 337 | u64 val; | ||
| 338 | ssize_t ret = -EINVAL; | ||
| 339 | |||
| 340 | if (kstrtoull(buf, 10, &val)) | ||
| 341 | return ret; | ||
| 342 | |||
| 343 | down_read(&zram->init_lock); | ||
| 344 | atomic64_set(&zram->stats.bd_wb_limit, val); | ||
| 345 | if (val == 0) | ||
| 346 | zram->stop_writeback = false; | ||
| 347 | up_read(&zram->init_lock); | ||
| 348 | ret = len; | ||
| 349 | |||
| 350 | return ret; | ||
| 351 | } | ||
| 352 | |||
| 353 | static ssize_t writeback_limit_show(struct device *dev, | ||
| 354 | struct device_attribute *attr, char *buf) | ||
| 281 | { | 355 | { |
| 282 | return zram->backing_dev; | 356 | u64 val; |
| 357 | struct zram *zram = dev_to_zram(dev); | ||
| 358 | |||
| 359 | down_read(&zram->init_lock); | ||
| 360 | val = atomic64_read(&zram->stats.bd_wb_limit); | ||
| 361 | up_read(&zram->init_lock); | ||
| 362 | |||
| 363 | return scnprintf(buf, PAGE_SIZE, "%llu\n", val); | ||
| 283 | } | 364 | } |
| 284 | 365 | ||
| 285 | static void reset_bdev(struct zram *zram) | 366 | static void reset_bdev(struct zram *zram) |
| 286 | { | 367 | { |
| 287 | struct block_device *bdev; | 368 | struct block_device *bdev; |
| 288 | 369 | ||
| 289 | if (!zram_wb_enabled(zram)) | 370 | if (!zram->backing_dev) |
| 290 | return; | 371 | return; |
| 291 | 372 | ||
| 292 | bdev = zram->bdev; | 373 | bdev = zram->bdev; |
| @@ -313,7 +394,7 @@ static ssize_t backing_dev_show(struct device *dev, | |||
| 313 | ssize_t ret; | 394 | ssize_t ret; |
| 314 | 395 | ||
| 315 | down_read(&zram->init_lock); | 396 | down_read(&zram->init_lock); |
| 316 | if (!zram_wb_enabled(zram)) { | 397 | if (!zram->backing_dev) { |
| 317 | memcpy(buf, "none\n", 5); | 398 | memcpy(buf, "none\n", 5); |
| 318 | up_read(&zram->init_lock); | 399 | up_read(&zram->init_lock); |
| 319 | return 5; | 400 | return 5; |
| @@ -382,8 +463,10 @@ static ssize_t backing_dev_store(struct device *dev, | |||
| 382 | 463 | ||
| 383 | bdev = bdgrab(I_BDEV(inode)); | 464 | bdev = bdgrab(I_BDEV(inode)); |
| 384 | err = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, zram); | 465 | err = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, zram); |
| 385 | if (err < 0) | 466 | if (err < 0) { |
| 467 | bdev = NULL; | ||
| 386 | goto out; | 468 | goto out; |
| 469 | } | ||
| 387 | 470 | ||
| 388 | nr_pages = i_size_read(inode) >> PAGE_SHIFT; | 471 | nr_pages = i_size_read(inode) >> PAGE_SHIFT; |
| 389 | bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long); | 472 | bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long); |
| @@ -399,7 +482,6 @@ static ssize_t backing_dev_store(struct device *dev, | |||
| 399 | goto out; | 482 | goto out; |
| 400 | 483 | ||
| 401 | reset_bdev(zram); | 484 | reset_bdev(zram); |
| 402 | spin_lock_init(&zram->bitmap_lock); | ||
| 403 | 485 | ||
| 404 | zram->old_block_size = old_block_size; | 486 | zram->old_block_size = old_block_size; |
| 405 | zram->bdev = bdev; | 487 | zram->bdev = bdev; |
| @@ -441,32 +523,29 @@ out: | |||
| 441 | return err; | 523 | return err; |
| 442 | } | 524 | } |
| 443 | 525 | ||
| 444 | static unsigned long get_entry_bdev(struct zram *zram) | 526 | static unsigned long alloc_block_bdev(struct zram *zram) |
| 445 | { | 527 | { |
| 446 | unsigned long entry; | 528 | unsigned long blk_idx = 1; |
| 447 | 529 | retry: | |
| 448 | spin_lock(&zram->bitmap_lock); | ||
| 449 | /* skip 0 bit to confuse zram.handle = 0 */ | 530 | /* skip 0 bit to confuse zram.handle = 0 */ |
| 450 | entry = find_next_zero_bit(zram->bitmap, zram->nr_pages, 1); | 531 | blk_idx = find_next_zero_bit(zram->bitmap, zram->nr_pages, blk_idx); |
| 451 | if (entry == zram->nr_pages) { | 532 | if (blk_idx == zram->nr_pages) |
| 452 | spin_unlock(&zram->bitmap_lock); | ||
| 453 | return 0; | 533 | return 0; |
| 454 | } | ||
| 455 | 534 | ||
| 456 | set_bit(entry, zram->bitmap); | 535 | if (test_and_set_bit(blk_idx, zram->bitmap)) |
| 457 | spin_unlock(&zram->bitmap_lock); | 536 | goto retry; |
| 458 | 537 | ||
| 459 | return entry; | 538 | atomic64_inc(&zram->stats.bd_count); |
| 539 | return blk_idx; | ||
| 460 | } | 540 | } |
| 461 | 541 | ||
| 462 | static void put_entry_bdev(struct zram *zram, unsigned long entry) | 542 | static void free_block_bdev(struct zram *zram, unsigned long blk_idx) |
| 463 | { | 543 | { |
| 464 | int was_set; | 544 | int was_set; |
| 465 | 545 | ||
| 466 | spin_lock(&zram->bitmap_lock); | 546 | was_set = test_and_clear_bit(blk_idx, zram->bitmap); |
| 467 | was_set = test_and_clear_bit(entry, zram->bitmap); | ||
| 468 | spin_unlock(&zram->bitmap_lock); | ||
| 469 | WARN_ON_ONCE(!was_set); | 547 | WARN_ON_ONCE(!was_set); |
| 548 | atomic64_dec(&zram->stats.bd_count); | ||
| 470 | } | 549 | } |
| 471 | 550 | ||
| 472 | static void zram_page_end_io(struct bio *bio) | 551 | static void zram_page_end_io(struct bio *bio) |
| @@ -509,6 +588,169 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec, | |||
| 509 | return 1; | 588 | return 1; |
| 510 | } | 589 | } |
| 511 | 590 | ||
| 591 | #define HUGE_WRITEBACK 0x1 | ||
| 592 | #define IDLE_WRITEBACK 0x2 | ||
| 593 | |||
| 594 | static ssize_t writeback_store(struct device *dev, | ||
| 595 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 596 | { | ||
| 597 | struct zram *zram = dev_to_zram(dev); | ||
| 598 | unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; | ||
| 599 | unsigned long index; | ||
| 600 | struct bio bio; | ||
| 601 | struct bio_vec bio_vec; | ||
| 602 | struct page *page; | ||
| 603 | ssize_t ret, sz; | ||
| 604 | char mode_buf[8]; | ||
| 605 | unsigned long mode = -1UL; | ||
| 606 | unsigned long blk_idx = 0; | ||
| 607 | |||
| 608 | sz = strscpy(mode_buf, buf, sizeof(mode_buf)); | ||
| 609 | if (sz <= 0) | ||
| 610 | return -EINVAL; | ||
| 611 | |||
| 612 | /* ignore trailing newline */ | ||
| 613 | if (mode_buf[sz - 1] == '\n') | ||
| 614 | mode_buf[sz - 1] = 0x00; | ||
| 615 | |||
| 616 | if (!strcmp(mode_buf, "idle")) | ||
| 617 | mode = IDLE_WRITEBACK; | ||
| 618 | else if (!strcmp(mode_buf, "huge")) | ||
| 619 | mode = HUGE_WRITEBACK; | ||
| 620 | |||
| 621 | if (mode == -1UL) | ||
| 622 | return -EINVAL; | ||
| 623 | |||
| 624 | down_read(&zram->init_lock); | ||
| 625 | if (!init_done(zram)) { | ||
| 626 | ret = -EINVAL; | ||
| 627 | goto release_init_lock; | ||
| 628 | } | ||
| 629 | |||
| 630 | if (!zram->backing_dev) { | ||
| 631 | ret = -ENODEV; | ||
| 632 | goto release_init_lock; | ||
| 633 | } | ||
| 634 | |||
| 635 | page = alloc_page(GFP_KERNEL); | ||
| 636 | if (!page) { | ||
| 637 | ret = -ENOMEM; | ||
| 638 | goto release_init_lock; | ||
| 639 | } | ||
| 640 | |||
| 641 | for (index = 0; index < nr_pages; index++) { | ||
| 642 | struct bio_vec bvec; | ||
| 643 | |||
| 644 | bvec.bv_page = page; | ||
| 645 | bvec.bv_len = PAGE_SIZE; | ||
| 646 | bvec.bv_offset = 0; | ||
| 647 | |||
| 648 | if (zram->stop_writeback) { | ||
| 649 | ret = -EIO; | ||
| 650 | break; | ||
| 651 | } | ||
| 652 | |||
| 653 | if (!blk_idx) { | ||
| 654 | blk_idx = alloc_block_bdev(zram); | ||
| 655 | if (!blk_idx) { | ||
| 656 | ret = -ENOSPC; | ||
| 657 | break; | ||
| 658 | } | ||
| 659 | } | ||
| 660 | |||
| 661 | zram_slot_lock(zram, index); | ||
| 662 | if (!zram_allocated(zram, index)) | ||
| 663 | goto next; | ||
| 664 | |||
| 665 | if (zram_test_flag(zram, index, ZRAM_WB) || | ||
| 666 | zram_test_flag(zram, index, ZRAM_SAME) || | ||
| 667 | zram_test_flag(zram, index, ZRAM_UNDER_WB)) | ||
| 668 | goto next; | ||
| 669 | |||
| 670 | if ((mode & IDLE_WRITEBACK && | ||
| 671 | !zram_test_flag(zram, index, ZRAM_IDLE)) && | ||
| 672 | (mode & HUGE_WRITEBACK && | ||
| 673 | !zram_test_flag(zram, index, ZRAM_HUGE))) | ||
| 674 | goto next; | ||
| 675 | /* | ||
| 676 | * Clearing ZRAM_UNDER_WB is duty of caller. | ||
| 677 | * IOW, zram_free_page never clear it. | ||
| 678 | */ | ||
| 679 | zram_set_flag(zram, index, ZRAM_UNDER_WB); | ||
| 680 | /* Need for hugepage writeback racing */ | ||
| 681 | zram_set_flag(zram, index, ZRAM_IDLE); | ||
| 682 | zram_slot_unlock(zram, index); | ||
| 683 | if (zram_bvec_read(zram, &bvec, index, 0, NULL)) { | ||
| 684 | zram_slot_lock(zram, index); | ||
| 685 | zram_clear_flag(zram, index, ZRAM_UNDER_WB); | ||
| 686 | zram_clear_flag(zram, index, ZRAM_IDLE); | ||
| 687 | zram_slot_unlock(zram, index); | ||
| 688 | continue; | ||
| 689 | } | ||
| 690 | |||
| 691 | bio_init(&bio, &bio_vec, 1); | ||
| 692 | bio_set_dev(&bio, zram->bdev); | ||
| 693 | bio.bi_iter.bi_sector = blk_idx * (PAGE_SIZE >> 9); | ||
| 694 | bio.bi_opf = REQ_OP_WRITE | REQ_SYNC; | ||
| 695 | |||
| 696 | bio_add_page(&bio, bvec.bv_page, bvec.bv_len, | ||
| 697 | bvec.bv_offset); | ||
| 698 | /* | ||
| 699 | * XXX: A single page IO would be inefficient for write | ||
| 700 | * but it would be not bad as starter. | ||
| 701 | */ | ||
| 702 | ret = submit_bio_wait(&bio); | ||
| 703 | if (ret) { | ||
| 704 | zram_slot_lock(zram, index); | ||
| 705 | zram_clear_flag(zram, index, ZRAM_UNDER_WB); | ||
| 706 | zram_clear_flag(zram, index, ZRAM_IDLE); | ||
| 707 | zram_slot_unlock(zram, index); | ||
| 708 | continue; | ||
| 709 | } | ||
| 710 | |||
| 711 | atomic64_inc(&zram->stats.bd_writes); | ||
| 712 | /* | ||
| 713 | * We released zram_slot_lock so need to check if the slot was | ||
| 714 | * changed. If there is freeing for the slot, we can catch it | ||
| 715 | * easily by zram_allocated. | ||
| 716 | * A subtle case is the slot is freed/reallocated/marked as | ||
| 717 | * ZRAM_IDLE again. To close the race, idle_store doesn't | ||
| 718 | * mark ZRAM_IDLE once it found the slot was ZRAM_UNDER_WB. | ||
| 719 | * Thus, we could close the race by checking ZRAM_IDLE bit. | ||
| 720 | */ | ||
| 721 | zram_slot_lock(zram, index); | ||
| 722 | if (!zram_allocated(zram, index) || | ||
| 723 | !zram_test_flag(zram, index, ZRAM_IDLE)) { | ||
| 724 | zram_clear_flag(zram, index, ZRAM_UNDER_WB); | ||
| 725 | zram_clear_flag(zram, index, ZRAM_IDLE); | ||
| 726 | goto next; | ||
| 727 | } | ||
| 728 | |||
| 729 | zram_free_page(zram, index); | ||
| 730 | zram_clear_flag(zram, index, ZRAM_UNDER_WB); | ||
| 731 | zram_set_flag(zram, index, ZRAM_WB); | ||
| 732 | zram_set_element(zram, index, blk_idx); | ||
| 733 | blk_idx = 0; | ||
| 734 | atomic64_inc(&zram->stats.pages_stored); | ||
| 735 | if (atomic64_add_unless(&zram->stats.bd_wb_limit, | ||
| 736 | -1 << (PAGE_SHIFT - 12), 0)) { | ||
| 737 | if (atomic64_read(&zram->stats.bd_wb_limit) == 0) | ||
| 738 | zram->stop_writeback = true; | ||
| 739 | } | ||
| 740 | next: | ||
| 741 | zram_slot_unlock(zram, index); | ||
| 742 | } | ||
| 743 | |||
| 744 | if (blk_idx) | ||
| 745 | free_block_bdev(zram, blk_idx); | ||
| 746 | ret = len; | ||
| 747 | __free_page(page); | ||
| 748 | release_init_lock: | ||
| 749 | up_read(&zram->init_lock); | ||
| 750 | |||
| 751 | return ret; | ||
| 752 | } | ||
| 753 | |||
| 512 | struct zram_work { | 754 | struct zram_work { |
| 513 | struct work_struct work; | 755 | struct work_struct work; |
| 514 | struct zram *zram; | 756 | struct zram *zram; |
| @@ -561,79 +803,21 @@ static int read_from_bdev_sync(struct zram *zram, struct bio_vec *bvec, | |||
| 561 | static int read_from_bdev(struct zram *zram, struct bio_vec *bvec, | 803 | static int read_from_bdev(struct zram *zram, struct bio_vec *bvec, |
| 562 | unsigned long entry, struct bio *parent, bool sync) | 804 | unsigned long entry, struct bio *parent, bool sync) |
| 563 | { | 805 | { |
| 806 | atomic64_inc(&zram->stats.bd_reads); | ||
| 564 | if (sync) | 807 | if (sync) |
| 565 | return read_from_bdev_sync(zram, bvec, entry, parent); | 808 | return read_from_bdev_sync(zram, bvec, entry, parent); |
| 566 | else | 809 | else |
| 567 | return read_from_bdev_async(zram, bvec, entry, parent); | 810 | return read_from_bdev_async(zram, bvec, entry, parent); |
| 568 | } | 811 | } |
| 569 | |||
| 570 | static int write_to_bdev(struct zram *zram, struct bio_vec *bvec, | ||
| 571 | u32 index, struct bio *parent, | ||
| 572 | unsigned long *pentry) | ||
| 573 | { | ||
| 574 | struct bio *bio; | ||
| 575 | unsigned long entry; | ||
| 576 | |||
| 577 | bio = bio_alloc(GFP_ATOMIC, 1); | ||
| 578 | if (!bio) | ||
| 579 | return -ENOMEM; | ||
| 580 | |||
| 581 | entry = get_entry_bdev(zram); | ||
| 582 | if (!entry) { | ||
| 583 | bio_put(bio); | ||
| 584 | return -ENOSPC; | ||
| 585 | } | ||
| 586 | |||
| 587 | bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9); | ||
| 588 | bio_set_dev(bio, zram->bdev); | ||
| 589 | if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, | ||
| 590 | bvec->bv_offset)) { | ||
| 591 | bio_put(bio); | ||
| 592 | put_entry_bdev(zram, entry); | ||
| 593 | return -EIO; | ||
| 594 | } | ||
| 595 | |||
| 596 | if (!parent) { | ||
| 597 | bio->bi_opf = REQ_OP_WRITE | REQ_SYNC; | ||
| 598 | bio->bi_end_io = zram_page_end_io; | ||
| 599 | } else { | ||
| 600 | bio->bi_opf = parent->bi_opf; | ||
| 601 | bio_chain(bio, parent); | ||
| 602 | } | ||
| 603 | |||
| 604 | submit_bio(bio); | ||
| 605 | *pentry = entry; | ||
| 606 | |||
| 607 | return 0; | ||
| 608 | } | ||
| 609 | |||
| 610 | static void zram_wb_clear(struct zram *zram, u32 index) | ||
| 611 | { | ||
| 612 | unsigned long entry; | ||
| 613 | |||
| 614 | zram_clear_flag(zram, index, ZRAM_WB); | ||
| 615 | entry = zram_get_element(zram, index); | ||
| 616 | zram_set_element(zram, index, 0); | ||
| 617 | put_entry_bdev(zram, entry); | ||
| 618 | } | ||
| 619 | |||
| 620 | #else | 812 | #else |
| 621 | static bool zram_wb_enabled(struct zram *zram) { return false; } | ||
| 622 | static inline void reset_bdev(struct zram *zram) {}; | 813 | static inline void reset_bdev(struct zram *zram) {}; |
| 623 | static int write_to_bdev(struct zram *zram, struct bio_vec *bvec, | ||
| 624 | u32 index, struct bio *parent, | ||
| 625 | unsigned long *pentry) | ||
| 626 | |||
| 627 | { | ||
| 628 | return -EIO; | ||
| 629 | } | ||
| 630 | |||
| 631 | static int read_from_bdev(struct zram *zram, struct bio_vec *bvec, | 814 | static int read_from_bdev(struct zram *zram, struct bio_vec *bvec, |
| 632 | unsigned long entry, struct bio *parent, bool sync) | 815 | unsigned long entry, struct bio *parent, bool sync) |
| 633 | { | 816 | { |
| 634 | return -EIO; | 817 | return -EIO; |
| 635 | } | 818 | } |
| 636 | static void zram_wb_clear(struct zram *zram, u32 index) {} | 819 | |
| 820 | static void free_block_bdev(struct zram *zram, unsigned long blk_idx) {}; | ||
| 637 | #endif | 821 | #endif |
| 638 | 822 | ||
| 639 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING | 823 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING |
| @@ -652,14 +836,10 @@ static void zram_debugfs_destroy(void) | |||
| 652 | 836 | ||
| 653 | static void zram_accessed(struct zram *zram, u32 index) | 837 | static void zram_accessed(struct zram *zram, u32 index) |
| 654 | { | 838 | { |
| 839 | zram_clear_flag(zram, index, ZRAM_IDLE); | ||
| 655 | zram->table[index].ac_time = ktime_get_boottime(); | 840 | zram->table[index].ac_time = ktime_get_boottime(); |
| 656 | } | 841 | } |
| 657 | 842 | ||
| 658 | static void zram_reset_access(struct zram *zram, u32 index) | ||
| 659 | { | ||
| 660 | zram->table[index].ac_time = 0; | ||
| 661 | } | ||
| 662 | |||
| 663 | static ssize_t read_block_state(struct file *file, char __user *buf, | 843 | static ssize_t read_block_state(struct file *file, char __user *buf, |
| 664 | size_t count, loff_t *ppos) | 844 | size_t count, loff_t *ppos) |
| 665 | { | 845 | { |
| @@ -689,12 +869,13 @@ static ssize_t read_block_state(struct file *file, char __user *buf, | |||
| 689 | 869 | ||
| 690 | ts = ktime_to_timespec64(zram->table[index].ac_time); | 870 | ts = ktime_to_timespec64(zram->table[index].ac_time); |
| 691 | copied = snprintf(kbuf + written, count, | 871 | copied = snprintf(kbuf + written, count, |
| 692 | "%12zd %12lld.%06lu %c%c%c\n", | 872 | "%12zd %12lld.%06lu %c%c%c%c\n", |
| 693 | index, (s64)ts.tv_sec, | 873 | index, (s64)ts.tv_sec, |
| 694 | ts.tv_nsec / NSEC_PER_USEC, | 874 | ts.tv_nsec / NSEC_PER_USEC, |
| 695 | zram_test_flag(zram, index, ZRAM_SAME) ? 's' : '.', | 875 | zram_test_flag(zram, index, ZRAM_SAME) ? 's' : '.', |
| 696 | zram_test_flag(zram, index, ZRAM_WB) ? 'w' : '.', | 876 | zram_test_flag(zram, index, ZRAM_WB) ? 'w' : '.', |
| 697 | zram_test_flag(zram, index, ZRAM_HUGE) ? 'h' : '.'); | 877 | zram_test_flag(zram, index, ZRAM_HUGE) ? 'h' : '.', |
| 878 | zram_test_flag(zram, index, ZRAM_IDLE) ? 'i' : '.'); | ||
| 698 | 879 | ||
| 699 | if (count < copied) { | 880 | if (count < copied) { |
| 700 | zram_slot_unlock(zram, index); | 881 | zram_slot_unlock(zram, index); |
| @@ -739,8 +920,10 @@ static void zram_debugfs_unregister(struct zram *zram) | |||
| 739 | #else | 920 | #else |
| 740 | static void zram_debugfs_create(void) {}; | 921 | static void zram_debugfs_create(void) {}; |
| 741 | static void zram_debugfs_destroy(void) {}; | 922 | static void zram_debugfs_destroy(void) {}; |
| 742 | static void zram_accessed(struct zram *zram, u32 index) {}; | 923 | static void zram_accessed(struct zram *zram, u32 index) |
| 743 | static void zram_reset_access(struct zram *zram, u32 index) {}; | 924 | { |
| 925 | zram_clear_flag(zram, index, ZRAM_IDLE); | ||
| 926 | }; | ||
| 744 | static void zram_debugfs_register(struct zram *zram) {}; | 927 | static void zram_debugfs_register(struct zram *zram) {}; |
| 745 | static void zram_debugfs_unregister(struct zram *zram) {}; | 928 | static void zram_debugfs_unregister(struct zram *zram) {}; |
| 746 | #endif | 929 | #endif |
| @@ -877,6 +1060,26 @@ static ssize_t mm_stat_show(struct device *dev, | |||
| 877 | return ret; | 1060 | return ret; |
| 878 | } | 1061 | } |
| 879 | 1062 | ||
| 1063 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
| 1064 | #define FOUR_K(x) ((x) * (1 << (PAGE_SHIFT - 12))) | ||
| 1065 | static ssize_t bd_stat_show(struct device *dev, | ||
| 1066 | struct device_attribute *attr, char *buf) | ||
| 1067 | { | ||
| 1068 | struct zram *zram = dev_to_zram(dev); | ||
| 1069 | ssize_t ret; | ||
| 1070 | |||
| 1071 | down_read(&zram->init_lock); | ||
| 1072 | ret = scnprintf(buf, PAGE_SIZE, | ||
| 1073 | "%8llu %8llu %8llu\n", | ||
| 1074 | FOUR_K((u64)atomic64_read(&zram->stats.bd_count)), | ||
| 1075 | FOUR_K((u64)atomic64_read(&zram->stats.bd_reads)), | ||
| 1076 | FOUR_K((u64)atomic64_read(&zram->stats.bd_writes))); | ||
| 1077 | up_read(&zram->init_lock); | ||
| 1078 | |||
| 1079 | return ret; | ||
| 1080 | } | ||
| 1081 | #endif | ||
| 1082 | |||
| 880 | static ssize_t debug_stat_show(struct device *dev, | 1083 | static ssize_t debug_stat_show(struct device *dev, |
| 881 | struct device_attribute *attr, char *buf) | 1084 | struct device_attribute *attr, char *buf) |
| 882 | { | 1085 | { |
| @@ -886,9 +1089,10 @@ static ssize_t debug_stat_show(struct device *dev, | |||
| 886 | 1089 | ||
| 887 | down_read(&zram->init_lock); | 1090 | down_read(&zram->init_lock); |
| 888 | ret = scnprintf(buf, PAGE_SIZE, | 1091 | ret = scnprintf(buf, PAGE_SIZE, |
| 889 | "version: %d\n%8llu\n", | 1092 | "version: %d\n%8llu %8llu\n", |
| 890 | version, | 1093 | version, |
| 891 | (u64)atomic64_read(&zram->stats.writestall)); | 1094 | (u64)atomic64_read(&zram->stats.writestall), |
| 1095 | (u64)atomic64_read(&zram->stats.miss_free)); | ||
| 892 | up_read(&zram->init_lock); | 1096 | up_read(&zram->init_lock); |
| 893 | 1097 | ||
| 894 | return ret; | 1098 | return ret; |
| @@ -896,6 +1100,9 @@ static ssize_t debug_stat_show(struct device *dev, | |||
| 896 | 1100 | ||
| 897 | static DEVICE_ATTR_RO(io_stat); | 1101 | static DEVICE_ATTR_RO(io_stat); |
| 898 | static DEVICE_ATTR_RO(mm_stat); | 1102 | static DEVICE_ATTR_RO(mm_stat); |
| 1103 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
| 1104 | static DEVICE_ATTR_RO(bd_stat); | ||
| 1105 | #endif | ||
| 899 | static DEVICE_ATTR_RO(debug_stat); | 1106 | static DEVICE_ATTR_RO(debug_stat); |
| 900 | 1107 | ||
| 901 | static void zram_meta_free(struct zram *zram, u64 disksize) | 1108 | static void zram_meta_free(struct zram *zram, u64 disksize) |
| @@ -940,17 +1147,21 @@ static void zram_free_page(struct zram *zram, size_t index) | |||
| 940 | { | 1147 | { |
| 941 | unsigned long handle; | 1148 | unsigned long handle; |
| 942 | 1149 | ||
| 943 | zram_reset_access(zram, index); | 1150 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING |
| 1151 | zram->table[index].ac_time = 0; | ||
| 1152 | #endif | ||
| 1153 | if (zram_test_flag(zram, index, ZRAM_IDLE)) | ||
| 1154 | zram_clear_flag(zram, index, ZRAM_IDLE); | ||
| 944 | 1155 | ||
| 945 | if (zram_test_flag(zram, index, ZRAM_HUGE)) { | 1156 | if (zram_test_flag(zram, index, ZRAM_HUGE)) { |
| 946 | zram_clear_flag(zram, index, ZRAM_HUGE); | 1157 | zram_clear_flag(zram, index, ZRAM_HUGE); |
| 947 | atomic64_dec(&zram->stats.huge_pages); | 1158 | atomic64_dec(&zram->stats.huge_pages); |
| 948 | } | 1159 | } |
| 949 | 1160 | ||
| 950 | if (zram_wb_enabled(zram) && zram_test_flag(zram, index, ZRAM_WB)) { | 1161 | if (zram_test_flag(zram, index, ZRAM_WB)) { |
| 951 | zram_wb_clear(zram, index); | 1162 | zram_clear_flag(zram, index, ZRAM_WB); |
| 952 | atomic64_dec(&zram->stats.pages_stored); | 1163 | free_block_bdev(zram, zram_get_element(zram, index)); |
| 953 | return; | 1164 | goto out; |
| 954 | } | 1165 | } |
| 955 | 1166 | ||
| 956 | /* | 1167 | /* |
| @@ -959,10 +1170,8 @@ static void zram_free_page(struct zram *zram, size_t index) | |||
| 959 | */ | 1170 | */ |
| 960 | if (zram_test_flag(zram, index, ZRAM_SAME)) { | 1171 | if (zram_test_flag(zram, index, ZRAM_SAME)) { |
| 961 | zram_clear_flag(zram, index, ZRAM_SAME); | 1172 | zram_clear_flag(zram, index, ZRAM_SAME); |
| 962 | zram_set_element(zram, index, 0); | ||
| 963 | atomic64_dec(&zram->stats.same_pages); | 1173 | atomic64_dec(&zram->stats.same_pages); |
| 964 | atomic64_dec(&zram->stats.pages_stored); | 1174 | goto out; |
| 965 | return; | ||
| 966 | } | 1175 | } |
| 967 | 1176 | ||
| 968 | handle = zram_get_handle(zram, index); | 1177 | handle = zram_get_handle(zram, index); |
| @@ -973,10 +1182,12 @@ static void zram_free_page(struct zram *zram, size_t index) | |||
| 973 | 1182 | ||
| 974 | atomic64_sub(zram_get_obj_size(zram, index), | 1183 | atomic64_sub(zram_get_obj_size(zram, index), |
| 975 | &zram->stats.compr_data_size); | 1184 | &zram->stats.compr_data_size); |
| 1185 | out: | ||
| 976 | atomic64_dec(&zram->stats.pages_stored); | 1186 | atomic64_dec(&zram->stats.pages_stored); |
| 977 | |||
| 978 | zram_set_handle(zram, index, 0); | 1187 | zram_set_handle(zram, index, 0); |
| 979 | zram_set_obj_size(zram, index, 0); | 1188 | zram_set_obj_size(zram, index, 0); |
| 1189 | WARN_ON_ONCE(zram->table[index].flags & | ||
| 1190 | ~(1UL << ZRAM_LOCK | 1UL << ZRAM_UNDER_WB)); | ||
| 980 | } | 1191 | } |
| 981 | 1192 | ||
| 982 | static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, | 1193 | static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, |
| @@ -987,24 +1198,20 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, | |||
| 987 | unsigned int size; | 1198 | unsigned int size; |
| 988 | void *src, *dst; | 1199 | void *src, *dst; |
| 989 | 1200 | ||
| 990 | if (zram_wb_enabled(zram)) { | 1201 | zram_slot_lock(zram, index); |
| 991 | zram_slot_lock(zram, index); | 1202 | if (zram_test_flag(zram, index, ZRAM_WB)) { |
| 992 | if (zram_test_flag(zram, index, ZRAM_WB)) { | 1203 | struct bio_vec bvec; |
| 993 | struct bio_vec bvec; | ||
| 994 | |||
| 995 | zram_slot_unlock(zram, index); | ||
| 996 | 1204 | ||
| 997 | bvec.bv_page = page; | ||
| 998 | bvec.bv_len = PAGE_SIZE; | ||
| 999 | bvec.bv_offset = 0; | ||
| 1000 | return read_from_bdev(zram, &bvec, | ||
| 1001 | zram_get_element(zram, index), | ||
| 1002 | bio, partial_io); | ||
| 1003 | } | ||
| 1004 | zram_slot_unlock(zram, index); | 1205 | zram_slot_unlock(zram, index); |
| 1206 | |||
| 1207 | bvec.bv_page = page; | ||
| 1208 | bvec.bv_len = PAGE_SIZE; | ||
| 1209 | bvec.bv_offset = 0; | ||
| 1210 | return read_from_bdev(zram, &bvec, | ||
| 1211 | zram_get_element(zram, index), | ||
| 1212 | bio, partial_io); | ||
| 1005 | } | 1213 | } |
| 1006 | 1214 | ||
| 1007 | zram_slot_lock(zram, index); | ||
| 1008 | handle = zram_get_handle(zram, index); | 1215 | handle = zram_get_handle(zram, index); |
| 1009 | if (!handle || zram_test_flag(zram, index, ZRAM_SAME)) { | 1216 | if (!handle || zram_test_flag(zram, index, ZRAM_SAME)) { |
| 1010 | unsigned long value; | 1217 | unsigned long value; |
| @@ -1089,7 +1296,6 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, | |||
| 1089 | struct page *page = bvec->bv_page; | 1296 | struct page *page = bvec->bv_page; |
| 1090 | unsigned long element = 0; | 1297 | unsigned long element = 0; |
| 1091 | enum zram_pageflags flags = 0; | 1298 | enum zram_pageflags flags = 0; |
| 1092 | bool allow_wb = true; | ||
| 1093 | 1299 | ||
| 1094 | mem = kmap_atomic(page); | 1300 | mem = kmap_atomic(page); |
| 1095 | if (page_same_filled(mem, &element)) { | 1301 | if (page_same_filled(mem, &element)) { |
| @@ -1114,21 +1320,8 @@ compress_again: | |||
| 1114 | return ret; | 1320 | return ret; |
| 1115 | } | 1321 | } |
| 1116 | 1322 | ||
| 1117 | if (unlikely(comp_len >= huge_class_size)) { | 1323 | if (comp_len >= huge_class_size) |
| 1118 | comp_len = PAGE_SIZE; | 1324 | comp_len = PAGE_SIZE; |
| 1119 | if (zram_wb_enabled(zram) && allow_wb) { | ||
| 1120 | zcomp_stream_put(zram->comp); | ||
| 1121 | ret = write_to_bdev(zram, bvec, index, bio, &element); | ||
| 1122 | if (!ret) { | ||
| 1123 | flags = ZRAM_WB; | ||
| 1124 | ret = 1; | ||
| 1125 | goto out; | ||
| 1126 | } | ||
| 1127 | allow_wb = false; | ||
| 1128 | goto compress_again; | ||
| 1129 | } | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | /* | 1325 | /* |
| 1133 | * handle allocation has 2 paths: | 1326 | * handle allocation has 2 paths: |
| 1134 | * a) fast path is executed with preemption disabled (for | 1327 | * a) fast path is executed with preemption disabled (for |
| @@ -1400,10 +1593,14 @@ static void zram_slot_free_notify(struct block_device *bdev, | |||
| 1400 | 1593 | ||
| 1401 | zram = bdev->bd_disk->private_data; | 1594 | zram = bdev->bd_disk->private_data; |
| 1402 | 1595 | ||
| 1403 | zram_slot_lock(zram, index); | 1596 | atomic64_inc(&zram->stats.notify_free); |
| 1597 | if (!zram_slot_trylock(zram, index)) { | ||
| 1598 | atomic64_inc(&zram->stats.miss_free); | ||
| 1599 | return; | ||
| 1600 | } | ||
| 1601 | |||
| 1404 | zram_free_page(zram, index); | 1602 | zram_free_page(zram, index); |
| 1405 | zram_slot_unlock(zram, index); | 1603 | zram_slot_unlock(zram, index); |
| 1406 | atomic64_inc(&zram->stats.notify_free); | ||
| 1407 | } | 1604 | } |
| 1408 | 1605 | ||
| 1409 | static int zram_rw_page(struct block_device *bdev, sector_t sector, | 1606 | static int zram_rw_page(struct block_device *bdev, sector_t sector, |
| @@ -1608,10 +1805,13 @@ static DEVICE_ATTR_RO(initstate); | |||
| 1608 | static DEVICE_ATTR_WO(reset); | 1805 | static DEVICE_ATTR_WO(reset); |
| 1609 | static DEVICE_ATTR_WO(mem_limit); | 1806 | static DEVICE_ATTR_WO(mem_limit); |
| 1610 | static DEVICE_ATTR_WO(mem_used_max); | 1807 | static DEVICE_ATTR_WO(mem_used_max); |
| 1808 | static DEVICE_ATTR_WO(idle); | ||
| 1611 | static DEVICE_ATTR_RW(max_comp_streams); | 1809 | static DEVICE_ATTR_RW(max_comp_streams); |
| 1612 | static DEVICE_ATTR_RW(comp_algorithm); | 1810 | static DEVICE_ATTR_RW(comp_algorithm); |
| 1613 | #ifdef CONFIG_ZRAM_WRITEBACK | 1811 | #ifdef CONFIG_ZRAM_WRITEBACK |
| 1614 | static DEVICE_ATTR_RW(backing_dev); | 1812 | static DEVICE_ATTR_RW(backing_dev); |
| 1813 | static DEVICE_ATTR_WO(writeback); | ||
| 1814 | static DEVICE_ATTR_RW(writeback_limit); | ||
| 1615 | #endif | 1815 | #endif |
| 1616 | 1816 | ||
| 1617 | static struct attribute *zram_disk_attrs[] = { | 1817 | static struct attribute *zram_disk_attrs[] = { |
| @@ -1621,13 +1821,19 @@ static struct attribute *zram_disk_attrs[] = { | |||
| 1621 | &dev_attr_compact.attr, | 1821 | &dev_attr_compact.attr, |
| 1622 | &dev_attr_mem_limit.attr, | 1822 | &dev_attr_mem_limit.attr, |
| 1623 | &dev_attr_mem_used_max.attr, | 1823 | &dev_attr_mem_used_max.attr, |
| 1824 | &dev_attr_idle.attr, | ||
| 1624 | &dev_attr_max_comp_streams.attr, | 1825 | &dev_attr_max_comp_streams.attr, |
| 1625 | &dev_attr_comp_algorithm.attr, | 1826 | &dev_attr_comp_algorithm.attr, |
| 1626 | #ifdef CONFIG_ZRAM_WRITEBACK | 1827 | #ifdef CONFIG_ZRAM_WRITEBACK |
| 1627 | &dev_attr_backing_dev.attr, | 1828 | &dev_attr_backing_dev.attr, |
| 1829 | &dev_attr_writeback.attr, | ||
| 1830 | &dev_attr_writeback_limit.attr, | ||
| 1628 | #endif | 1831 | #endif |
| 1629 | &dev_attr_io_stat.attr, | 1832 | &dev_attr_io_stat.attr, |
| 1630 | &dev_attr_mm_stat.attr, | 1833 | &dev_attr_mm_stat.attr, |
| 1834 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
| 1835 | &dev_attr_bd_stat.attr, | ||
| 1836 | #endif | ||
| 1631 | &dev_attr_debug_stat.attr, | 1837 | &dev_attr_debug_stat.attr, |
| 1632 | NULL, | 1838 | NULL, |
| 1633 | }; | 1839 | }; |
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 72c8584b6dff..4bd3afd15e83 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | * The lower ZRAM_FLAG_SHIFT bits of table.value is for | 33 | * The lower ZRAM_FLAG_SHIFT bits of table.flags is for |
| 34 | * object size (excluding header), the higher bits is for | 34 | * object size (excluding header), the higher bits is for |
| 35 | * zram_pageflags. | 35 | * zram_pageflags. |
| 36 | * | 36 | * |
| @@ -41,13 +41,15 @@ | |||
| 41 | */ | 41 | */ |
| 42 | #define ZRAM_FLAG_SHIFT 24 | 42 | #define ZRAM_FLAG_SHIFT 24 |
| 43 | 43 | ||
| 44 | /* Flags for zram pages (table[page_no].value) */ | 44 | /* Flags for zram pages (table[page_no].flags) */ |
| 45 | enum zram_pageflags { | 45 | enum zram_pageflags { |
| 46 | /* zram slot is locked */ | 46 | /* zram slot is locked */ |
| 47 | ZRAM_LOCK = ZRAM_FLAG_SHIFT, | 47 | ZRAM_LOCK = ZRAM_FLAG_SHIFT, |
| 48 | ZRAM_SAME, /* Page consists the same element */ | 48 | ZRAM_SAME, /* Page consists the same element */ |
| 49 | ZRAM_WB, /* page is stored on backing_device */ | 49 | ZRAM_WB, /* page is stored on backing_device */ |
| 50 | ZRAM_UNDER_WB, /* page is under writeback */ | ||
| 50 | ZRAM_HUGE, /* Incompressible page */ | 51 | ZRAM_HUGE, /* Incompressible page */ |
| 52 | ZRAM_IDLE, /* not accessed page since last idle marking */ | ||
| 51 | 53 | ||
| 52 | __NR_ZRAM_PAGEFLAGS, | 54 | __NR_ZRAM_PAGEFLAGS, |
| 53 | }; | 55 | }; |
| @@ -60,7 +62,7 @@ struct zram_table_entry { | |||
| 60 | unsigned long handle; | 62 | unsigned long handle; |
| 61 | unsigned long element; | 63 | unsigned long element; |
| 62 | }; | 64 | }; |
| 63 | unsigned long value; | 65 | unsigned long flags; |
| 64 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING | 66 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING |
| 65 | ktime_t ac_time; | 67 | ktime_t ac_time; |
| 66 | #endif | 68 | #endif |
| @@ -79,6 +81,13 @@ struct zram_stats { | |||
| 79 | atomic64_t pages_stored; /* no. of pages currently stored */ | 81 | atomic64_t pages_stored; /* no. of pages currently stored */ |
| 80 | atomic_long_t max_used_pages; /* no. of maximum pages stored */ | 82 | atomic_long_t max_used_pages; /* no. of maximum pages stored */ |
| 81 | atomic64_t writestall; /* no. of write slow paths */ | 83 | atomic64_t writestall; /* no. of write slow paths */ |
| 84 | atomic64_t miss_free; /* no. of missed free */ | ||
| 85 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
| 86 | atomic64_t bd_count; /* no. of pages in backing device */ | ||
| 87 | atomic64_t bd_reads; /* no. of reads from backing device */ | ||
| 88 | atomic64_t bd_writes; /* no. of writes from backing device */ | ||
| 89 | atomic64_t bd_wb_limit; /* writeback limit of backing device */ | ||
| 90 | #endif | ||
| 82 | }; | 91 | }; |
| 83 | 92 | ||
| 84 | struct zram { | 93 | struct zram { |
| @@ -104,13 +113,13 @@ struct zram { | |||
| 104 | * zram is claimed so open request will be failed | 113 | * zram is claimed so open request will be failed |
| 105 | */ | 114 | */ |
| 106 | bool claim; /* Protected by bdev->bd_mutex */ | 115 | bool claim; /* Protected by bdev->bd_mutex */ |
| 107 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
| 108 | struct file *backing_dev; | 116 | struct file *backing_dev; |
| 117 | bool stop_writeback; | ||
| 118 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
| 109 | struct block_device *bdev; | 119 | struct block_device *bdev; |
| 110 | unsigned int old_block_size; | 120 | unsigned int old_block_size; |
| 111 | unsigned long *bitmap; | 121 | unsigned long *bitmap; |
| 112 | unsigned long nr_pages; | 122 | unsigned long nr_pages; |
| 113 | spinlock_t bitmap_lock; | ||
| 114 | #endif | 123 | #endif |
| 115 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING | 124 | #ifdef CONFIG_ZRAM_MEMORY_TRACKING |
| 116 | struct dentry *debugfs_dir; | 125 | struct dentry *debugfs_dir; |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 38ffb281df97..004a3ce8ba72 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
| @@ -115,9 +115,9 @@ static int agp_find_max(void) | |||
| 115 | long memory, index, result; | 115 | long memory, index, result; |
| 116 | 116 | ||
| 117 | #if PAGE_SHIFT < 20 | 117 | #if PAGE_SHIFT < 20 |
| 118 | memory = totalram_pages >> (20 - PAGE_SHIFT); | 118 | memory = totalram_pages() >> (20 - PAGE_SHIFT); |
| 119 | #else | 119 | #else |
| 120 | memory = totalram_pages << (PAGE_SHIFT - 20); | 120 | memory = totalram_pages() << (PAGE_SHIFT - 20); |
| 121 | #endif | 121 | #endif |
| 122 | index = 1; | 122 | index = 1; |
| 123 | 123 | ||
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c index 99e2aace8078..2c1f459c0c63 100644 --- a/drivers/dax/pmem.c +++ b/drivers/dax/pmem.c | |||
| @@ -48,9 +48,8 @@ static void dax_pmem_percpu_exit(void *data) | |||
| 48 | percpu_ref_exit(ref); | 48 | percpu_ref_exit(ref); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | static void dax_pmem_percpu_kill(void *data) | 51 | static void dax_pmem_percpu_kill(struct percpu_ref *ref) |
| 52 | { | 52 | { |
| 53 | struct percpu_ref *ref = data; | ||
| 54 | struct dax_pmem *dax_pmem = to_dax_pmem(ref); | 53 | struct dax_pmem *dax_pmem = to_dax_pmem(ref); |
| 55 | 54 | ||
| 56 | dev_dbg(dax_pmem->dev, "trace\n"); | 55 | dev_dbg(dax_pmem->dev, "trace\n"); |
| @@ -112,17 +111,10 @@ static int dax_pmem_probe(struct device *dev) | |||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | dax_pmem->pgmap.ref = &dax_pmem->ref; | 113 | dax_pmem->pgmap.ref = &dax_pmem->ref; |
| 114 | dax_pmem->pgmap.kill = dax_pmem_percpu_kill; | ||
| 115 | addr = devm_memremap_pages(dev, &dax_pmem->pgmap); | 115 | addr = devm_memremap_pages(dev, &dax_pmem->pgmap); |
| 116 | if (IS_ERR(addr)) { | 116 | if (IS_ERR(addr)) |
| 117 | devm_remove_action(dev, dax_pmem_percpu_exit, &dax_pmem->ref); | ||
| 118 | percpu_ref_exit(&dax_pmem->ref); | ||
| 119 | return PTR_ERR(addr); | 117 | return PTR_ERR(addr); |
| 120 | } | ||
| 121 | |||
| 122 | rc = devm_add_action_or_reset(dev, dax_pmem_percpu_kill, | ||
| 123 | &dax_pmem->ref); | ||
| 124 | if (rc) | ||
| 125 | return rc; | ||
| 126 | 118 | ||
| 127 | /* adjust the dax_region resource to the start of data */ | 119 | /* adjust the dax_region resource to the start of data */ |
| 128 | memcpy(&res, &dax_pmem->pgmap.res, sizeof(res)); | 120 | memcpy(&res, &dax_pmem->pgmap.res, sizeof(res)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index e55508b39496..3e6823fdd939 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | |||
| @@ -238,44 +238,40 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node, | |||
| 238 | * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change | 238 | * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change |
| 239 | * | 239 | * |
| 240 | * @mn: our notifier | 240 | * @mn: our notifier |
| 241 | * @mm: the mm this callback is about | 241 | * @range: mmu notifier context |
| 242 | * @start: start of updated range | ||
| 243 | * @end: end of updated range | ||
| 244 | * | 242 | * |
| 245 | * Block for operations on BOs to finish and mark pages as accessed and | 243 | * Block for operations on BOs to finish and mark pages as accessed and |
| 246 | * potentially dirty. | 244 | * potentially dirty. |
| 247 | */ | 245 | */ |
| 248 | static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn, | 246 | static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn, |
| 249 | struct mm_struct *mm, | 247 | const struct mmu_notifier_range *range) |
| 250 | unsigned long start, | ||
| 251 | unsigned long end, | ||
| 252 | bool blockable) | ||
| 253 | { | 248 | { |
| 254 | struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); | 249 | struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); |
| 255 | struct interval_tree_node *it; | 250 | struct interval_tree_node *it; |
| 251 | unsigned long end; | ||
| 256 | 252 | ||
| 257 | /* notification is exclusive, but interval is inclusive */ | 253 | /* notification is exclusive, but interval is inclusive */ |
| 258 | end -= 1; | 254 | end = range->end - 1; |
| 259 | 255 | ||
| 260 | /* TODO we should be able to split locking for interval tree and | 256 | /* TODO we should be able to split locking for interval tree and |
| 261 | * amdgpu_mn_invalidate_node | 257 | * amdgpu_mn_invalidate_node |
| 262 | */ | 258 | */ |
| 263 | if (amdgpu_mn_read_lock(amn, blockable)) | 259 | if (amdgpu_mn_read_lock(amn, range->blockable)) |
| 264 | return -EAGAIN; | 260 | return -EAGAIN; |
| 265 | 261 | ||
| 266 | it = interval_tree_iter_first(&amn->objects, start, end); | 262 | it = interval_tree_iter_first(&amn->objects, range->start, end); |
| 267 | while (it) { | 263 | while (it) { |
| 268 | struct amdgpu_mn_node *node; | 264 | struct amdgpu_mn_node *node; |
| 269 | 265 | ||
| 270 | if (!blockable) { | 266 | if (!range->blockable) { |
| 271 | amdgpu_mn_read_unlock(amn); | 267 | amdgpu_mn_read_unlock(amn); |
| 272 | return -EAGAIN; | 268 | return -EAGAIN; |
| 273 | } | 269 | } |
| 274 | 270 | ||
| 275 | node = container_of(it, struct amdgpu_mn_node, it); | 271 | node = container_of(it, struct amdgpu_mn_node, it); |
| 276 | it = interval_tree_iter_next(it, start, end); | 272 | it = interval_tree_iter_next(it, range->start, end); |
| 277 | 273 | ||
| 278 | amdgpu_mn_invalidate_node(node, start, end); | 274 | amdgpu_mn_invalidate_node(node, range->start, end); |
| 279 | } | 275 | } |
| 280 | 276 | ||
| 281 | return 0; | 277 | return 0; |
| @@ -294,39 +290,38 @@ static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn, | |||
| 294 | * are restorted in amdgpu_mn_invalidate_range_end_hsa. | 290 | * are restorted in amdgpu_mn_invalidate_range_end_hsa. |
| 295 | */ | 291 | */ |
| 296 | static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn, | 292 | static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn, |
| 297 | struct mm_struct *mm, | 293 | const struct mmu_notifier_range *range) |
| 298 | unsigned long start, | ||
| 299 | unsigned long end, | ||
| 300 | bool blockable) | ||
| 301 | { | 294 | { |
| 302 | struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); | 295 | struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); |
| 303 | struct interval_tree_node *it; | 296 | struct interval_tree_node *it; |
| 297 | unsigned long end; | ||
| 304 | 298 | ||
| 305 | /* notification is exclusive, but interval is inclusive */ | 299 | /* notification is exclusive, but interval is inclusive */ |
| 306 | end -= 1; | 300 | end = range->end - 1; |
| 307 | 301 | ||
| 308 | if (amdgpu_mn_read_lock(amn, blockable)) | 302 | if (amdgpu_mn_read_lock(amn, range->blockable)) |
| 309 | return -EAGAIN; | 303 | return -EAGAIN; |
| 310 | 304 | ||
| 311 | it = interval_tree_iter_first(&amn->objects, start, end); | 305 | it = interval_tree_iter_first(&amn->objects, range->start, end); |
| 312 | while (it) { | 306 | while (it) { |
| 313 | struct amdgpu_mn_node *node; | 307 | struct amdgpu_mn_node *node; |
| 314 | struct amdgpu_bo *bo; | 308 | struct amdgpu_bo *bo; |
| 315 | 309 | ||
| 316 | if (!blockable) { | 310 | if (!range->blockable) { |
| 317 | amdgpu_mn_read_unlock(amn); | 311 | amdgpu_mn_read_unlock(amn); |
| 318 | return -EAGAIN; | 312 | return -EAGAIN; |
| 319 | } | 313 | } |
| 320 | 314 | ||
| 321 | node = container_of(it, struct amdgpu_mn_node, it); | 315 | node = container_of(it, struct amdgpu_mn_node, it); |
| 322 | it = interval_tree_iter_next(it, start, end); | 316 | it = interval_tree_iter_next(it, range->start, end); |
| 323 | 317 | ||
| 324 | list_for_each_entry(bo, &node->bos, mn_list) { | 318 | list_for_each_entry(bo, &node->bos, mn_list) { |
| 325 | struct kgd_mem *mem = bo->kfd_bo; | 319 | struct kgd_mem *mem = bo->kfd_bo; |
| 326 | 320 | ||
| 327 | if (amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, | 321 | if (amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, |
| 328 | start, end)) | 322 | range->start, |
| 329 | amdgpu_amdkfd_evict_userptr(mem, mm); | 323 | end)) |
| 324 | amdgpu_amdkfd_evict_userptr(mem, range->mm); | ||
| 330 | } | 325 | } |
| 331 | } | 326 | } |
| 332 | 327 | ||
| @@ -344,9 +339,7 @@ static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn, | |||
| 344 | * Release the lock again to allow new command submissions. | 339 | * Release the lock again to allow new command submissions. |
| 345 | */ | 340 | */ |
| 346 | static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn, | 341 | static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn, |
| 347 | struct mm_struct *mm, | 342 | const struct mmu_notifier_range *range) |
| 348 | unsigned long start, | ||
| 349 | unsigned long end) | ||
| 350 | { | 343 | { |
| 351 | struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); | 344 | struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn); |
| 352 | 345 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index c02adbbeef2a..b7bc7d7d048f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c | |||
| @@ -853,7 +853,7 @@ static int kfd_fill_mem_info_for_cpu(int numa_node_id, int *avail_size, | |||
| 853 | */ | 853 | */ |
| 854 | pgdat = NODE_DATA(numa_node_id); | 854 | pgdat = NODE_DATA(numa_node_id); |
| 855 | for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) | 855 | for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) |
| 856 | mem_in_bytes += pgdat->node_zones[zone_type].managed_pages; | 856 | mem_in_bytes += zone_managed_pages(&pgdat->node_zones[zone_type]); |
| 857 | mem_in_bytes <<= PAGE_SHIFT; | 857 | mem_in_bytes <<= PAGE_SHIFT; |
| 858 | 858 | ||
| 859 | sub_type_hdr->length_low = lower_32_bits(mem_in_bytes); | 859 | sub_type_hdr->length_low = lower_32_bits(mem_in_bytes); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d36a9755ad91..a9de07bb72c8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -2559,7 +2559,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
| 2559 | * If there's no chance of allocating enough pages for the whole | 2559 | * If there's no chance of allocating enough pages for the whole |
| 2560 | * object, bail early. | 2560 | * object, bail early. |
| 2561 | */ | 2561 | */ |
| 2562 | if (page_count > totalram_pages) | 2562 | if (page_count > totalram_pages()) |
| 2563 | return -ENOMEM; | 2563 | return -ENOMEM; |
| 2564 | 2564 | ||
| 2565 | st = kmalloc(sizeof(*st), GFP_KERNEL); | 2565 | st = kmalloc(sizeof(*st), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 2c9b284036d1..3df77020aada 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
| @@ -113,27 +113,25 @@ static void del_object(struct i915_mmu_object *mo) | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, | 115 | static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, |
| 116 | struct mm_struct *mm, | 116 | const struct mmu_notifier_range *range) |
| 117 | unsigned long start, | ||
| 118 | unsigned long end, | ||
| 119 | bool blockable) | ||
| 120 | { | 117 | { |
| 121 | struct i915_mmu_notifier *mn = | 118 | struct i915_mmu_notifier *mn = |
| 122 | container_of(_mn, struct i915_mmu_notifier, mn); | 119 | container_of(_mn, struct i915_mmu_notifier, mn); |
| 123 | struct i915_mmu_object *mo; | 120 | struct i915_mmu_object *mo; |
| 124 | struct interval_tree_node *it; | 121 | struct interval_tree_node *it; |
| 125 | LIST_HEAD(cancelled); | 122 | LIST_HEAD(cancelled); |
| 123 | unsigned long end; | ||
| 126 | 124 | ||
| 127 | if (RB_EMPTY_ROOT(&mn->objects.rb_root)) | 125 | if (RB_EMPTY_ROOT(&mn->objects.rb_root)) |
| 128 | return 0; | 126 | return 0; |
| 129 | 127 | ||
| 130 | /* interval ranges are inclusive, but invalidate range is exclusive */ | 128 | /* interval ranges are inclusive, but invalidate range is exclusive */ |
| 131 | end--; | 129 | end = range->end - 1; |
| 132 | 130 | ||
| 133 | spin_lock(&mn->lock); | 131 | spin_lock(&mn->lock); |
| 134 | it = interval_tree_iter_first(&mn->objects, start, end); | 132 | it = interval_tree_iter_first(&mn->objects, range->start, end); |
| 135 | while (it) { | 133 | while (it) { |
| 136 | if (!blockable) { | 134 | if (!range->blockable) { |
| 137 | spin_unlock(&mn->lock); | 135 | spin_unlock(&mn->lock); |
| 138 | return -EAGAIN; | 136 | return -EAGAIN; |
| 139 | } | 137 | } |
| @@ -151,7 +149,7 @@ static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn, | |||
| 151 | queue_work(mn->wq, &mo->work); | 149 | queue_work(mn->wq, &mo->work); |
| 152 | 150 | ||
| 153 | list_add(&mo->link, &cancelled); | 151 | list_add(&mo->link, &cancelled); |
| 154 | it = interval_tree_iter_next(it, start, end); | 152 | it = interval_tree_iter_next(it, range->start, end); |
| 155 | } | 153 | } |
| 156 | list_for_each_entry(mo, &cancelled, link) | 154 | list_for_each_entry(mo, &cancelled, link) |
| 157 | del_object(mo); | 155 | del_object(mo); |
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 69fe86b30fbb..a9ed0ecc94e2 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | |||
| @@ -170,7 +170,7 @@ static int igt_ppgtt_alloc(void *arg) | |||
| 170 | * This should ensure that we do not run into the oomkiller during | 170 | * This should ensure that we do not run into the oomkiller during |
| 171 | * the test and take down the machine wilfully. | 171 | * the test and take down the machine wilfully. |
| 172 | */ | 172 | */ |
| 173 | limit = totalram_pages << PAGE_SHIFT; | 173 | limit = totalram_pages() << PAGE_SHIFT; |
| 174 | limit = min(ppgtt->vm.total, limit); | 174 | limit = min(ppgtt->vm.total, limit); |
| 175 | 175 | ||
| 176 | /* Check we can allocate the entire range */ | 176 | /* Check we can allocate the entire range */ |
| @@ -1244,7 +1244,7 @@ static int exercise_mock(struct drm_i915_private *i915, | |||
| 1244 | u64 hole_start, u64 hole_end, | 1244 | u64 hole_start, u64 hole_end, |
| 1245 | unsigned long end_time)) | 1245 | unsigned long end_time)) |
| 1246 | { | 1246 | { |
| 1247 | const u64 limit = totalram_pages << PAGE_SHIFT; | 1247 | const u64 limit = totalram_pages() << PAGE_SHIFT; |
| 1248 | struct i915_gem_context *ctx; | 1248 | struct i915_gem_context *ctx; |
| 1249 | struct i915_hw_ppgtt *ppgtt; | 1249 | struct i915_hw_ppgtt *ppgtt; |
| 1250 | IGT_TIMEOUT(end_time); | 1250 | IGT_TIMEOUT(end_time); |
diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c index f8b35df44c60..b3019505065a 100644 --- a/drivers/gpu/drm/radeon/radeon_mn.c +++ b/drivers/gpu/drm/radeon/radeon_mn.c | |||
| @@ -119,40 +119,38 @@ static void radeon_mn_release(struct mmu_notifier *mn, | |||
| 119 | * unmap them by move them into system domain again. | 119 | * unmap them by move them into system domain again. |
| 120 | */ | 120 | */ |
| 121 | static int radeon_mn_invalidate_range_start(struct mmu_notifier *mn, | 121 | static int radeon_mn_invalidate_range_start(struct mmu_notifier *mn, |
| 122 | struct mm_struct *mm, | 122 | const struct mmu_notifier_range *range) |
| 123 | unsigned long start, | ||
| 124 | unsigned long end, | ||
| 125 | bool blockable) | ||
| 126 | { | 123 | { |
| 127 | struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn); | 124 | struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn); |
| 128 | struct ttm_operation_ctx ctx = { false, false }; | 125 | struct ttm_operation_ctx ctx = { false, false }; |
| 129 | struct interval_tree_node *it; | 126 | struct interval_tree_node *it; |
| 127 | unsigned long end; | ||
| 130 | int ret = 0; | 128 | int ret = 0; |
| 131 | 129 | ||
| 132 | /* notification is exclusive, but interval is inclusive */ | 130 | /* notification is exclusive, but interval is inclusive */ |
| 133 | end -= 1; | 131 | end = range->end - 1; |
| 134 | 132 | ||
| 135 | /* TODO we should be able to split locking for interval tree and | 133 | /* TODO we should be able to split locking for interval tree and |
| 136 | * the tear down. | 134 | * the tear down. |
| 137 | */ | 135 | */ |
| 138 | if (blockable) | 136 | if (range->blockable) |
| 139 | mutex_lock(&rmn->lock); | 137 | mutex_lock(&rmn->lock); |
| 140 | else if (!mutex_trylock(&rmn->lock)) | 138 | else if (!mutex_trylock(&rmn->lock)) |
| 141 | return -EAGAIN; | 139 | return -EAGAIN; |
| 142 | 140 | ||
| 143 | it = interval_tree_iter_first(&rmn->objects, start, end); | 141 | it = interval_tree_iter_first(&rmn->objects, range->start, end); |
| 144 | while (it) { | 142 | while (it) { |
| 145 | struct radeon_mn_node *node; | 143 | struct radeon_mn_node *node; |
| 146 | struct radeon_bo *bo; | 144 | struct radeon_bo *bo; |
| 147 | long r; | 145 | long r; |
| 148 | 146 | ||
| 149 | if (!blockable) { | 147 | if (!range->blockable) { |
| 150 | ret = -EAGAIN; | 148 | ret = -EAGAIN; |
| 151 | goto out_unlock; | 149 | goto out_unlock; |
| 152 | } | 150 | } |
| 153 | 151 | ||
| 154 | node = container_of(it, struct radeon_mn_node, it); | 152 | node = container_of(it, struct radeon_mn_node, it); |
| 155 | it = interval_tree_iter_next(it, start, end); | 153 | it = interval_tree_iter_next(it, range->start, end); |
| 156 | 154 | ||
| 157 | list_for_each_entry(bo, &node->bos, mn_list) { | 155 | list_for_each_entry(bo, &node->bos, mn_list) { |
| 158 | 156 | ||
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 41631512ae97..5301fef16c31 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c | |||
| @@ -1090,6 +1090,7 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg) | |||
| 1090 | static unsigned long compute_balloon_floor(void) | 1090 | static unsigned long compute_balloon_floor(void) |
| 1091 | { | 1091 | { |
| 1092 | unsigned long min_pages; | 1092 | unsigned long min_pages; |
| 1093 | unsigned long nr_pages = totalram_pages(); | ||
| 1093 | #define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) | 1094 | #define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) |
| 1094 | /* Simple continuous piecewiese linear function: | 1095 | /* Simple continuous piecewiese linear function: |
| 1095 | * max MiB -> min MiB gradient | 1096 | * max MiB -> min MiB gradient |
| @@ -1102,16 +1103,16 @@ static unsigned long compute_balloon_floor(void) | |||
| 1102 | * 8192 744 (1/16) | 1103 | * 8192 744 (1/16) |
| 1103 | * 32768 1512 (1/32) | 1104 | * 32768 1512 (1/32) |
| 1104 | */ | 1105 | */ |
| 1105 | if (totalram_pages < MB2PAGES(128)) | 1106 | if (nr_pages < MB2PAGES(128)) |
| 1106 | min_pages = MB2PAGES(8) + (totalram_pages >> 1); | 1107 | min_pages = MB2PAGES(8) + (nr_pages >> 1); |
| 1107 | else if (totalram_pages < MB2PAGES(512)) | 1108 | else if (nr_pages < MB2PAGES(512)) |
| 1108 | min_pages = MB2PAGES(40) + (totalram_pages >> 2); | 1109 | min_pages = MB2PAGES(40) + (nr_pages >> 2); |
| 1109 | else if (totalram_pages < MB2PAGES(2048)) | 1110 | else if (nr_pages < MB2PAGES(2048)) |
| 1110 | min_pages = MB2PAGES(104) + (totalram_pages >> 3); | 1111 | min_pages = MB2PAGES(104) + (nr_pages >> 3); |
| 1111 | else if (totalram_pages < MB2PAGES(8192)) | 1112 | else if (nr_pages < MB2PAGES(8192)) |
| 1112 | min_pages = MB2PAGES(232) + (totalram_pages >> 4); | 1113 | min_pages = MB2PAGES(232) + (nr_pages >> 4); |
| 1113 | else | 1114 | else |
| 1114 | min_pages = MB2PAGES(488) + (totalram_pages >> 5); | 1115 | min_pages = MB2PAGES(488) + (nr_pages >> 5); |
| 1115 | #undef MB2PAGES | 1116 | #undef MB2PAGES |
| 1116 | return min_pages; | 1117 | return min_pages; |
| 1117 | } | 1118 | } |
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 9608681224e6..a4ec43093cb3 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c | |||
| @@ -146,15 +146,12 @@ static int invalidate_range_start_trampoline(struct ib_umem_odp *item, | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn, | 148 | static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn, |
| 149 | struct mm_struct *mm, | 149 | const struct mmu_notifier_range *range) |
| 150 | unsigned long start, | ||
| 151 | unsigned long end, | ||
| 152 | bool blockable) | ||
| 153 | { | 150 | { |
| 154 | struct ib_ucontext_per_mm *per_mm = | 151 | struct ib_ucontext_per_mm *per_mm = |
| 155 | container_of(mn, struct ib_ucontext_per_mm, mn); | 152 | container_of(mn, struct ib_ucontext_per_mm, mn); |
| 156 | 153 | ||
| 157 | if (blockable) | 154 | if (range->blockable) |
| 158 | down_read(&per_mm->umem_rwsem); | 155 | down_read(&per_mm->umem_rwsem); |
| 159 | else if (!down_read_trylock(&per_mm->umem_rwsem)) | 156 | else if (!down_read_trylock(&per_mm->umem_rwsem)) |
| 160 | return -EAGAIN; | 157 | return -EAGAIN; |
| @@ -169,9 +166,10 @@ static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn, | |||
| 169 | return 0; | 166 | return 0; |
| 170 | } | 167 | } |
| 171 | 168 | ||
| 172 | return rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, start, end, | 169 | return rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, range->start, |
| 170 | range->end, | ||
| 173 | invalidate_range_start_trampoline, | 171 | invalidate_range_start_trampoline, |
| 174 | blockable, NULL); | 172 | range->blockable, NULL); |
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | static int invalidate_range_end_trampoline(struct ib_umem_odp *item, u64 start, | 175 | static int invalidate_range_end_trampoline(struct ib_umem_odp *item, u64 start, |
| @@ -182,9 +180,7 @@ static int invalidate_range_end_trampoline(struct ib_umem_odp *item, u64 start, | |||
| 182 | } | 180 | } |
| 183 | 181 | ||
| 184 | static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn, | 182 | static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn, |
| 185 | struct mm_struct *mm, | 183 | const struct mmu_notifier_range *range) |
| 186 | unsigned long start, | ||
| 187 | unsigned long end) | ||
| 188 | { | 184 | { |
| 189 | struct ib_ucontext_per_mm *per_mm = | 185 | struct ib_ucontext_per_mm *per_mm = |
| 190 | container_of(mn, struct ib_ucontext_per_mm, mn); | 186 | container_of(mn, struct ib_ucontext_per_mm, mn); |
| @@ -192,8 +188,8 @@ static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn, | |||
| 192 | if (unlikely(!per_mm->active)) | 188 | if (unlikely(!per_mm->active)) |
| 193 | return; | 189 | return; |
| 194 | 190 | ||
| 195 | rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, start, | 191 | rbt_ib_umem_for_each_in_range(&per_mm->umem_tree, range->start, |
| 196 | end, | 192 | range->end, |
| 197 | invalidate_range_end_trampoline, true, NULL); | 193 | invalidate_range_end_trampoline, true, NULL); |
| 198 | up_read(&per_mm->umem_rwsem); | 194 | up_read(&per_mm->umem_rwsem); |
| 199 | } | 195 | } |
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index 475b769e120c..14d2a90964c3 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c | |||
| @@ -68,8 +68,7 @@ struct mmu_rb_handler { | |||
| 68 | static unsigned long mmu_node_start(struct mmu_rb_node *); | 68 | static unsigned long mmu_node_start(struct mmu_rb_node *); |
| 69 | static unsigned long mmu_node_last(struct mmu_rb_node *); | 69 | static unsigned long mmu_node_last(struct mmu_rb_node *); |
| 70 | static int mmu_notifier_range_start(struct mmu_notifier *, | 70 | static int mmu_notifier_range_start(struct mmu_notifier *, |
| 71 | struct mm_struct *, | 71 | const struct mmu_notifier_range *); |
| 72 | unsigned long, unsigned long, bool); | ||
| 73 | static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, | 72 | static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *, |
| 74 | unsigned long, unsigned long); | 73 | unsigned long, unsigned long); |
| 75 | static void do_remove(struct mmu_rb_handler *handler, | 74 | static void do_remove(struct mmu_rb_handler *handler, |
| @@ -284,10 +283,7 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler, | |||
| 284 | } | 283 | } |
| 285 | 284 | ||
| 286 | static int mmu_notifier_range_start(struct mmu_notifier *mn, | 285 | static int mmu_notifier_range_start(struct mmu_notifier *mn, |
| 287 | struct mm_struct *mm, | 286 | const struct mmu_notifier_range *range) |
| 288 | unsigned long start, | ||
| 289 | unsigned long end, | ||
| 290 | bool blockable) | ||
| 291 | { | 287 | { |
| 292 | struct mmu_rb_handler *handler = | 288 | struct mmu_rb_handler *handler = |
| 293 | container_of(mn, struct mmu_rb_handler, mn); | 289 | container_of(mn, struct mmu_rb_handler, mn); |
| @@ -297,10 +293,11 @@ static int mmu_notifier_range_start(struct mmu_notifier *mn, | |||
| 297 | bool added = false; | 293 | bool added = false; |
| 298 | 294 | ||
| 299 | spin_lock_irqsave(&handler->lock, flags); | 295 | spin_lock_irqsave(&handler->lock, flags); |
| 300 | for (node = __mmu_int_rb_iter_first(root, start, end - 1); | 296 | for (node = __mmu_int_rb_iter_first(root, range->start, range->end-1); |
| 301 | node; node = ptr) { | 297 | node; node = ptr) { |
| 302 | /* Guard against node removal. */ | 298 | /* Guard against node removal. */ |
| 303 | ptr = __mmu_int_rb_iter_next(node, start, end - 1); | 299 | ptr = __mmu_int_rb_iter_next(node, range->start, |
| 300 | range->end - 1); | ||
| 304 | trace_hfi1_mmu_mem_invalidate(node->addr, node->len); | 301 | trace_hfi1_mmu_mem_invalidate(node->addr, node->len); |
| 305 | if (handler->ops->invalidate(handler->ops_arg, node)) { | 302 | if (handler->ops->invalidate(handler->ops_arg, node)) { |
| 306 | __mmu_int_rb_remove(node, root); | 303 | __mmu_int_rb_remove(node, root); |
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 0e9fcceaefd2..1ecef76225a1 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c | |||
| @@ -1887,7 +1887,7 @@ static int __init dm_bufio_init(void) | |||
| 1887 | dm_bufio_allocated_vmalloc = 0; | 1887 | dm_bufio_allocated_vmalloc = 0; |
| 1888 | dm_bufio_current_allocated = 0; | 1888 | dm_bufio_current_allocated = 0; |
| 1889 | 1889 | ||
| 1890 | mem = (__u64)mult_frac(totalram_pages - totalhigh_pages, | 1890 | mem = (__u64)mult_frac(totalram_pages() - totalhigh_pages(), |
| 1891 | DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT; | 1891 | DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT; |
| 1892 | 1892 | ||
| 1893 | if (mem > ULONG_MAX) | 1893 | if (mem > ULONG_MAX) |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 1ea73ace9b9e..0ff22159a0ca 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
| @@ -2167,7 +2167,7 @@ static int crypt_wipe_key(struct crypt_config *cc) | |||
| 2167 | 2167 | ||
| 2168 | static void crypt_calculate_pages_per_client(void) | 2168 | static void crypt_calculate_pages_per_client(void) |
| 2169 | { | 2169 | { |
| 2170 | unsigned long pages = (totalram_pages - totalhigh_pages) * DM_CRYPT_MEMORY_PERCENT / 100; | 2170 | unsigned long pages = (totalram_pages() - totalhigh_pages()) * DM_CRYPT_MEMORY_PERCENT / 100; |
| 2171 | 2171 | ||
| 2172 | if (!dm_crypt_clients_n) | 2172 | if (!dm_crypt_clients_n) |
| 2173 | return; | 2173 | return; |
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 2b27abfa428d..457200ca6287 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c | |||
| @@ -2843,7 +2843,7 @@ static int create_journal(struct dm_integrity_c *ic, char **error) | |||
| 2843 | journal_pages = roundup((__u64)ic->journal_sections * ic->journal_section_sectors, | 2843 | journal_pages = roundup((__u64)ic->journal_sections * ic->journal_section_sectors, |
| 2844 | PAGE_SIZE >> SECTOR_SHIFT) >> (PAGE_SHIFT - SECTOR_SHIFT); | 2844 | PAGE_SIZE >> SECTOR_SHIFT) >> (PAGE_SHIFT - SECTOR_SHIFT); |
| 2845 | journal_desc_size = journal_pages * sizeof(struct page_list); | 2845 | journal_desc_size = journal_pages * sizeof(struct page_list); |
| 2846 | if (journal_pages >= totalram_pages - totalhigh_pages || journal_desc_size > ULONG_MAX) { | 2846 | if (journal_pages >= totalram_pages() - totalhigh_pages() || journal_desc_size > ULONG_MAX) { |
| 2847 | *error = "Journal doesn't fit into memory"; | 2847 | *error = "Journal doesn't fit into memory"; |
| 2848 | r = -ENOMEM; | 2848 | r = -ENOMEM; |
| 2849 | goto bad; | 2849 | goto bad; |
diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index 21de30b4e2a1..45b92a3d9d8e 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c | |||
| @@ -85,7 +85,7 @@ static bool __check_shared_memory(size_t alloc_size) | |||
| 85 | a = shared_memory_amount + alloc_size; | 85 | a = shared_memory_amount + alloc_size; |
| 86 | if (a < shared_memory_amount) | 86 | if (a < shared_memory_amount) |
| 87 | return false; | 87 | return false; |
| 88 | if (a >> PAGE_SHIFT > totalram_pages / DM_STATS_MEMORY_FACTOR) | 88 | if (a >> PAGE_SHIFT > totalram_pages() / DM_STATS_MEMORY_FACTOR) |
| 89 | return false; | 89 | return false; |
| 90 | #ifdef CONFIG_MMU | 90 | #ifdef CONFIG_MMU |
| 91 | if (a > (VMALLOC_END - VMALLOC_START) / DM_STATS_VMALLOC_FACTOR) | 91 | if (a > (VMALLOC_END - VMALLOC_START) / DM_STATS_VMALLOC_FACTOR) |
diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index 616f78b24a79..b6602490a247 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c | |||
| @@ -855,7 +855,7 @@ static int mtk_vpu_probe(struct platform_device *pdev) | |||
| 855 | /* Set PTCM to 96K and DTCM to 32K */ | 855 | /* Set PTCM to 96K and DTCM to 32K */ |
| 856 | vpu_cfg_writel(vpu, 0x2, VPU_TCM_CFG); | 856 | vpu_cfg_writel(vpu, 0x2, VPU_TCM_CFG); |
| 857 | 857 | ||
| 858 | vpu->enable_4GB = !!(totalram_pages > (SZ_2G >> PAGE_SHIFT)); | 858 | vpu->enable_4GB = !!(totalram_pages() > (SZ_2G >> PAGE_SHIFT)); |
| 859 | dev_info(dev, "4GB mode %u\n", vpu->enable_4GB); | 859 | dev_info(dev, "4GB mode %u\n", vpu->enable_4GB); |
| 860 | 860 | ||
| 861 | if (vpu->enable_4GB) { | 861 | if (vpu->enable_4GB) { |
diff --git a/drivers/misc/mic/scif/scif_dma.c b/drivers/misc/mic/scif/scif_dma.c index 18b8ed57c4ac..e0d97044d0e9 100644 --- a/drivers/misc/mic/scif/scif_dma.c +++ b/drivers/misc/mic/scif/scif_dma.c | |||
| @@ -201,23 +201,18 @@ static void scif_mmu_notifier_release(struct mmu_notifier *mn, | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, | 203 | static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, |
| 204 | struct mm_struct *mm, | 204 | const struct mmu_notifier_range *range) |
| 205 | unsigned long start, | ||
| 206 | unsigned long end, | ||
| 207 | bool blockable) | ||
| 208 | { | 205 | { |
| 209 | struct scif_mmu_notif *mmn; | 206 | struct scif_mmu_notif *mmn; |
| 210 | 207 | ||
| 211 | mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier); | 208 | mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier); |
| 212 | scif_rma_destroy_tcw(mmn, start, end - start); | 209 | scif_rma_destroy_tcw(mmn, range->start, range->end - range->start); |
| 213 | 210 | ||
| 214 | return 0; | 211 | return 0; |
| 215 | } | 212 | } |
| 216 | 213 | ||
| 217 | static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn, | 214 | static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn, |
| 218 | struct mm_struct *mm, | 215 | const struct mmu_notifier_range *range) |
| 219 | unsigned long start, | ||
| 220 | unsigned long end) | ||
| 221 | { | 216 | { |
| 222 | /* | 217 | /* |
| 223 | * Nothing to do here, everything needed was done in | 218 | * Nothing to do here, everything needed was done in |
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c index 03b49d52092e..ca2032afe035 100644 --- a/drivers/misc/sgi-gru/grutlbpurge.c +++ b/drivers/misc/sgi-gru/grutlbpurge.c | |||
| @@ -220,9 +220,7 @@ void gru_flush_all_tlb(struct gru_state *gru) | |||
| 220 | * MMUOPS notifier callout functions | 220 | * MMUOPS notifier callout functions |
| 221 | */ | 221 | */ |
| 222 | static int gru_invalidate_range_start(struct mmu_notifier *mn, | 222 | static int gru_invalidate_range_start(struct mmu_notifier *mn, |
| 223 | struct mm_struct *mm, | 223 | const struct mmu_notifier_range *range) |
| 224 | unsigned long start, unsigned long end, | ||
| 225 | bool blockable) | ||
| 226 | { | 224 | { |
| 227 | struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct, | 225 | struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct, |
| 228 | ms_notifier); | 226 | ms_notifier); |
| @@ -230,15 +228,14 @@ static int gru_invalidate_range_start(struct mmu_notifier *mn, | |||
| 230 | STAT(mmu_invalidate_range); | 228 | STAT(mmu_invalidate_range); |
| 231 | atomic_inc(&gms->ms_range_active); | 229 | atomic_inc(&gms->ms_range_active); |
| 232 | gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx, act %d\n", gms, | 230 | gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx, act %d\n", gms, |
| 233 | start, end, atomic_read(&gms->ms_range_active)); | 231 | range->start, range->end, atomic_read(&gms->ms_range_active)); |
| 234 | gru_flush_tlb_range(gms, start, end - start); | 232 | gru_flush_tlb_range(gms, range->start, range->end - range->start); |
| 235 | 233 | ||
| 236 | return 0; | 234 | return 0; |
| 237 | } | 235 | } |
| 238 | 236 | ||
| 239 | static void gru_invalidate_range_end(struct mmu_notifier *mn, | 237 | static void gru_invalidate_range_end(struct mmu_notifier *mn, |
| 240 | struct mm_struct *mm, unsigned long start, | 238 | const struct mmu_notifier_range *range) |
| 241 | unsigned long end) | ||
| 242 | { | 239 | { |
| 243 | struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct, | 240 | struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct, |
| 244 | ms_notifier); | 241 | ms_notifier); |
| @@ -247,7 +244,8 @@ static void gru_invalidate_range_end(struct mmu_notifier *mn, | |||
| 247 | (void)atomic_dec_and_test(&gms->ms_range_active); | 244 | (void)atomic_dec_and_test(&gms->ms_range_active); |
| 248 | 245 | ||
| 249 | wake_up_all(&gms->ms_wait_queue); | 246 | wake_up_all(&gms->ms_wait_queue); |
| 250 | gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx\n", gms, start, end); | 247 | gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx\n", |
| 248 | gms, range->start, range->end); | ||
| 251 | } | 249 | } |
| 252 | 250 | ||
| 253 | static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm) | 251 | static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm) |
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 9b0b3fa4f836..e6126a4b95d3 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c | |||
| @@ -570,7 +570,7 @@ static int vmballoon_send_get_target(struct vmballoon *b) | |||
| 570 | unsigned long status; | 570 | unsigned long status; |
| 571 | unsigned long limit; | 571 | unsigned long limit; |
| 572 | 572 | ||
| 573 | limit = totalram_pages; | 573 | limit = totalram_pages(); |
| 574 | 574 | ||
| 575 | /* Ensure limit fits in 32-bits */ | 575 | /* Ensure limit fits in 32-bits */ |
| 576 | if (limit != (u32)limit) | 576 | if (limit != (u32)limit) |
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index f7019294740c..bc2f700feef8 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c | |||
| @@ -309,8 +309,11 @@ static void pmem_release_queue(void *q) | |||
| 309 | blk_cleanup_queue(q); | 309 | blk_cleanup_queue(q); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | static void pmem_freeze_queue(void *q) | 312 | static void pmem_freeze_queue(struct percpu_ref *ref) |
| 313 | { | 313 | { |
| 314 | struct request_queue *q; | ||
| 315 | |||
| 316 | q = container_of(ref, typeof(*q), q_usage_counter); | ||
| 314 | blk_freeze_queue_start(q); | 317 | blk_freeze_queue_start(q); |
| 315 | } | 318 | } |
| 316 | 319 | ||
| @@ -402,6 +405,7 @@ static int pmem_attach_disk(struct device *dev, | |||
| 402 | 405 | ||
| 403 | pmem->pfn_flags = PFN_DEV; | 406 | pmem->pfn_flags = PFN_DEV; |
| 404 | pmem->pgmap.ref = &q->q_usage_counter; | 407 | pmem->pgmap.ref = &q->q_usage_counter; |
| 408 | pmem->pgmap.kill = pmem_freeze_queue; | ||
| 405 | if (is_nd_pfn(dev)) { | 409 | if (is_nd_pfn(dev)) { |
| 406 | if (setup_pagemap_fsdax(dev, &pmem->pgmap)) | 410 | if (setup_pagemap_fsdax(dev, &pmem->pgmap)) |
| 407 | return -ENOMEM; | 411 | return -ENOMEM; |
| @@ -427,13 +431,6 @@ static int pmem_attach_disk(struct device *dev, | |||
| 427 | memcpy(&bb_res, &nsio->res, sizeof(bb_res)); | 431 | memcpy(&bb_res, &nsio->res, sizeof(bb_res)); |
| 428 | } | 432 | } |
| 429 | 433 | ||
| 430 | /* | ||
| 431 | * At release time the queue must be frozen before | ||
| 432 | * devm_memremap_pages is unwound | ||
| 433 | */ | ||
| 434 | if (devm_add_action_or_reset(dev, pmem_freeze_queue, q)) | ||
| 435 | return -ENOMEM; | ||
| 436 | |||
| 437 | if (IS_ERR(addr)) | 434 | if (IS_ERR(addr)) |
| 438 | return PTR_ERR(addr); | 435 | return PTR_ERR(addr); |
| 439 | pmem->virt_addr = addr; | 436 | pmem->virt_addr = addr; |
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 714aac72df0e..8d2fc84119c6 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
| @@ -1243,7 +1243,7 @@ ccio_ioc_init(struct ioc *ioc) | |||
| 1243 | ** Hot-Plug/Removal of PCI cards. (aka PCI OLARD). | 1243 | ** Hot-Plug/Removal of PCI cards. (aka PCI OLARD). |
| 1244 | */ | 1244 | */ |
| 1245 | 1245 | ||
| 1246 | iova_space_size = (u32) (totalram_pages / count_parisc_driver(&ccio_driver)); | 1246 | iova_space_size = (u32) (totalram_pages() / count_parisc_driver(&ccio_driver)); |
| 1247 | 1247 | ||
| 1248 | /* limit IOVA space size to 1MB-1GB */ | 1248 | /* limit IOVA space size to 1MB-1GB */ |
| 1249 | 1249 | ||
| @@ -1282,7 +1282,7 @@ ccio_ioc_init(struct ioc *ioc) | |||
| 1282 | 1282 | ||
| 1283 | DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n", | 1283 | DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n", |
| 1284 | __func__, ioc->ioc_regs, | 1284 | __func__, ioc->ioc_regs, |
| 1285 | (unsigned long) totalram_pages >> (20 - PAGE_SHIFT), | 1285 | (unsigned long) totalram_pages() >> (20 - PAGE_SHIFT), |
| 1286 | iova_space_size>>20, | 1286 | iova_space_size>>20, |
| 1287 | iov_order + PAGE_SHIFT); | 1287 | iov_order + PAGE_SHIFT); |
| 1288 | 1288 | ||
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 452d306ce5cb..42172eb32235 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
| @@ -1406,7 +1406,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
| 1406 | ** for DMA hints - ergo only 30 bits max. | 1406 | ** for DMA hints - ergo only 30 bits max. |
| 1407 | */ | 1407 | */ |
| 1408 | 1408 | ||
| 1409 | iova_space_size = (u32) (totalram_pages/global_ioc_cnt); | 1409 | iova_space_size = (u32) (totalram_pages()/global_ioc_cnt); |
| 1410 | 1410 | ||
| 1411 | /* limit IOVA space size to 1MB-1GB */ | 1411 | /* limit IOVA space size to 1MB-1GB */ |
| 1412 | if (iova_space_size < (1 << (20 - PAGE_SHIFT))) { | 1412 | if (iova_space_size < (1 << (20 - PAGE_SHIFT))) { |
| @@ -1431,7 +1431,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) | |||
| 1431 | DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n", | 1431 | DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n", |
| 1432 | __func__, | 1432 | __func__, |
| 1433 | ioc->ioc_hpa, | 1433 | ioc->ioc_hpa, |
| 1434 | (unsigned long) totalram_pages >> (20 - PAGE_SHIFT), | 1434 | (unsigned long) totalram_pages() >> (20 - PAGE_SHIFT), |
| 1435 | iova_space_size>>20, | 1435 | iova_space_size>>20, |
| 1436 | iov_order + PAGE_SHIFT); | 1436 | iov_order + PAGE_SHIFT); |
| 1437 | 1437 | ||
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index ae3c5b25dcc7..a2eb25271c96 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c | |||
| @@ -82,10 +82,8 @@ static void pci_p2pdma_percpu_release(struct percpu_ref *ref) | |||
| 82 | complete_all(&p2p->devmap_ref_done); | 82 | complete_all(&p2p->devmap_ref_done); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static void pci_p2pdma_percpu_kill(void *data) | 85 | static void pci_p2pdma_percpu_kill(struct percpu_ref *ref) |
| 86 | { | 86 | { |
| 87 | struct percpu_ref *ref = data; | ||
| 88 | |||
| 89 | /* | 87 | /* |
| 90 | * pci_p2pdma_add_resource() may be called multiple times | 88 | * pci_p2pdma_add_resource() may be called multiple times |
| 91 | * by a driver and may register the percpu_kill devm action multiple | 89 | * by a driver and may register the percpu_kill devm action multiple |
| @@ -198,6 +196,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size, | |||
| 198 | pgmap->type = MEMORY_DEVICE_PCI_P2PDMA; | 196 | pgmap->type = MEMORY_DEVICE_PCI_P2PDMA; |
| 199 | pgmap->pci_p2pdma_bus_offset = pci_bus_address(pdev, bar) - | 197 | pgmap->pci_p2pdma_bus_offset = pci_bus_address(pdev, bar) - |
| 200 | pci_resource_start(pdev, bar); | 198 | pci_resource_start(pdev, bar); |
| 199 | pgmap->kill = pci_p2pdma_percpu_kill; | ||
| 201 | 200 | ||
| 202 | addr = devm_memremap_pages(&pdev->dev, pgmap); | 201 | addr = devm_memremap_pages(&pdev->dev, pgmap); |
| 203 | if (IS_ERR(addr)) { | 202 | if (IS_ERR(addr)) { |
| @@ -211,11 +210,6 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size, | |||
| 211 | if (error) | 210 | if (error) |
| 212 | goto pgmap_free; | 211 | goto pgmap_free; |
| 213 | 212 | ||
| 214 | error = devm_add_action_or_reset(&pdev->dev, pci_p2pdma_percpu_kill, | ||
| 215 | &pdev->p2pdma->devmap_ref); | ||
| 216 | if (error) | ||
| 217 | goto pgmap_free; | ||
| 218 | |||
| 219 | pci_info(pdev, "added peer-to-peer DMA memory %pR\n", | 213 | pci_info(pdev, "added peer-to-peer DMA memory %pR\n", |
| 220 | &pgmap->res); | 214 | &pgmap->res); |
| 221 | 215 | ||
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 548bb02c0ca6..6cb0eebdff89 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c | |||
| @@ -110,7 +110,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, | |||
| 110 | unsigned long size_remaining = PAGE_ALIGN(size); | 110 | unsigned long size_remaining = PAGE_ALIGN(size); |
| 111 | unsigned int max_order = orders[0]; | 111 | unsigned int max_order = orders[0]; |
| 112 | 112 | ||
| 113 | if (size / PAGE_SIZE > totalram_pages / 2) | 113 | if (size / PAGE_SIZE > totalram_pages() / 2) |
| 114 | return -ENOMEM; | 114 | return -ENOMEM; |
| 115 | 115 | ||
| 116 | INIT_LIST_HEAD(&pages); | 116 | INIT_LIST_HEAD(&pages); |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 221b7333d067..ceb5048de9a7 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
| @@ -352,7 +352,7 @@ static enum bp_state reserve_additional_memory(void) | |||
| 352 | mutex_unlock(&balloon_mutex); | 352 | mutex_unlock(&balloon_mutex); |
| 353 | /* add_memory_resource() requires the device_hotplug lock */ | 353 | /* add_memory_resource() requires the device_hotplug lock */ |
| 354 | lock_device_hotplug(); | 354 | lock_device_hotplug(); |
| 355 | rc = add_memory_resource(nid, resource, memhp_auto_online); | 355 | rc = add_memory_resource(nid, resource); |
| 356 | unlock_device_hotplug(); | 356 | unlock_device_hotplug(); |
| 357 | mutex_lock(&balloon_mutex); | 357 | mutex_lock(&balloon_mutex); |
| 358 | 358 | ||
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index b0b02a501167..5efc5eee9544 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
| @@ -520,26 +520,26 @@ static int unmap_if_in_range(struct gntdev_grant_map *map, | |||
| 520 | } | 520 | } |
| 521 | 521 | ||
| 522 | static int mn_invl_range_start(struct mmu_notifier *mn, | 522 | static int mn_invl_range_start(struct mmu_notifier *mn, |
| 523 | struct mm_struct *mm, | 523 | const struct mmu_notifier_range *range) |
| 524 | unsigned long start, unsigned long end, | ||
| 525 | bool blockable) | ||
| 526 | { | 524 | { |
| 527 | struct gntdev_priv *priv = container_of(mn, struct gntdev_priv, mn); | 525 | struct gntdev_priv *priv = container_of(mn, struct gntdev_priv, mn); |
| 528 | struct gntdev_grant_map *map; | 526 | struct gntdev_grant_map *map; |
| 529 | int ret = 0; | 527 | int ret = 0; |
| 530 | 528 | ||
| 531 | if (blockable) | 529 | if (range->blockable) |
| 532 | mutex_lock(&priv->lock); | 530 | mutex_lock(&priv->lock); |
| 533 | else if (!mutex_trylock(&priv->lock)) | 531 | else if (!mutex_trylock(&priv->lock)) |
| 534 | return -EAGAIN; | 532 | return -EAGAIN; |
| 535 | 533 | ||
| 536 | list_for_each_entry(map, &priv->maps, next) { | 534 | list_for_each_entry(map, &priv->maps, next) { |
| 537 | ret = unmap_if_in_range(map, start, end, blockable); | 535 | ret = unmap_if_in_range(map, range->start, range->end, |
| 536 | range->blockable); | ||
| 538 | if (ret) | 537 | if (ret) |
| 539 | goto out_unlock; | 538 | goto out_unlock; |
| 540 | } | 539 | } |
| 541 | list_for_each_entry(map, &priv->freeable_maps, next) { | 540 | list_for_each_entry(map, &priv->freeable_maps, next) { |
| 542 | ret = unmap_if_in_range(map, start, end, blockable); | 541 | ret = unmap_if_in_range(map, range->start, range->end, |
| 542 | range->blockable); | ||
| 543 | if (ret) | 543 | if (ret) |
| 544 | goto out_unlock; | 544 | goto out_unlock; |
| 545 | } | 545 | } |
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 5165aa82bf7d..246f6122c9ee 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c | |||
| @@ -189,7 +189,7 @@ static void selfballoon_process(struct work_struct *work) | |||
| 189 | bool reset_timer = false; | 189 | bool reset_timer = false; |
| 190 | 190 | ||
| 191 | if (xen_selfballooning_enabled) { | 191 | if (xen_selfballooning_enabled) { |
| 192 | cur_pages = totalram_pages; | 192 | cur_pages = totalram_pages(); |
| 193 | tgt_pages = cur_pages; /* default is no change */ | 193 | tgt_pages = cur_pages; /* default is no change */ |
| 194 | goal_pages = vm_memory_committed() + | 194 | goal_pages = vm_memory_committed() + |
| 195 | totalreserve_pages + | 195 | totalreserve_pages + |
| @@ -227,7 +227,7 @@ static void selfballoon_process(struct work_struct *work) | |||
| 227 | if (tgt_pages < floor_pages) | 227 | if (tgt_pages < floor_pages) |
| 228 | tgt_pages = floor_pages; | 228 | tgt_pages = floor_pages; |
| 229 | balloon_set_new_target(tgt_pages + | 229 | balloon_set_new_target(tgt_pages + |
| 230 | balloon_stats.current_pages - totalram_pages); | 230 | balloon_stats.current_pages - totalram_pages()); |
| 231 | reset_timer = true; | 231 | reset_timer = true; |
| 232 | } | 232 | } |
| 233 | #ifdef CONFIG_FRONTSWAP | 233 | #ifdef CONFIG_FRONTSWAP |
| @@ -569,7 +569,7 @@ int xen_selfballoon_init(bool use_selfballooning, bool use_frontswap_selfshrink) | |||
| 569 | * much more reliably and response faster in some cases. | 569 | * much more reliably and response faster in some cases. |
| 570 | */ | 570 | */ |
| 571 | if (!selfballoon_reserved_mb) { | 571 | if (!selfballoon_reserved_mb) { |
| 572 | reserve_pages = totalram_pages / 10; | 572 | reserve_pages = totalram_pages() / 10; |
| 573 | selfballoon_reserved_mb = PAGES2MB(reserve_pages); | 573 | selfballoon_reserved_mb = PAGES2MB(reserve_pages); |
| 574 | } | 574 | } |
| 575 | schedule_delayed_work(&selfballoon_worker, selfballoon_interval * HZ); | 575 | schedule_delayed_work(&selfballoon_worker, selfballoon_interval * HZ); |
