diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-06 23:49:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-06 23:49:49 -0400 |
commit | d34fc1adf01ff87026da85fb972dc259dc347540 (patch) | |
tree | 27356073d423187157b7cdb69da32b53102fb9e7 /drivers | |
parent | 1c9fe4409ce3e9c78b1ed96ee8ed699d4f03bf33 (diff) | |
parent | d2cd9ede6e193dd7d88b6d27399e96229a551b19 (diff) |
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton:
- various misc bits
- DAX updates
- OCFS2
- most of MM
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (119 commits)
mm,fork: introduce MADV_WIPEONFORK
x86,mpx: make mpx depend on x86-64 to free up VMA flag
mm: add /proc/pid/smaps_rollup
mm: hugetlb: clear target sub-page last when clearing huge page
mm: oom: let oom_reap_task and exit_mmap run concurrently
swap: choose swap device according to numa node
mm: replace TIF_MEMDIE checks by tsk_is_oom_victim
mm, oom: do not rely on TIF_MEMDIE for memory reserves access
z3fold: use per-cpu unbuddied lists
mm, swap: don't use VMA based swap readahead if HDD is used as swap
mm, swap: add sysfs interface for VMA based swap readahead
mm, swap: VMA based swap readahead
mm, swap: fix swap readahead marking
mm, swap: add swap readahead hit statistics
mm/vmalloc.c: don't reinvent the wheel but use existing llist API
mm/vmstat.c: fix wrong comment
selftests/memfd: add memfd_create hugetlbfs selftest
mm/shmem: add hugetlbfs support to memfd_create()
mm, devm_memremap_pages: use multi-order radix for ZONE_DEVICE lookups
mm/vmalloc.c: halve the number of comparisons performed in pcpu_get_vm_areas()
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/memory.c | 30 | ||||
-rw-r--r-- | drivers/block/brd.c | 6 | ||||
-rw-r--r-- | drivers/block/zram/Kconfig | 12 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.c | 540 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_shrinker.c | 24 | ||||
-rw-r--r-- | drivers/nvdimm/btt.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/pmem.c | 41 |
12 files changed, 563 insertions, 116 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index c7c4e0325cdb..4e3b61cda520 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -388,6 +388,19 @@ static ssize_t show_phys_device(struct device *dev, | |||
388 | } | 388 | } |
389 | 389 | ||
390 | #ifdef CONFIG_MEMORY_HOTREMOVE | 390 | #ifdef CONFIG_MEMORY_HOTREMOVE |
391 | static void print_allowed_zone(char *buf, int nid, unsigned long start_pfn, | ||
392 | unsigned long nr_pages, int online_type, | ||
393 | struct zone *default_zone) | ||
394 | { | ||
395 | struct zone *zone; | ||
396 | |||
397 | zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages); | ||
398 | if (zone != default_zone) { | ||
399 | strcat(buf, " "); | ||
400 | strcat(buf, zone->name); | ||
401 | } | ||
402 | } | ||
403 | |||
391 | static ssize_t show_valid_zones(struct device *dev, | 404 | static ssize_t show_valid_zones(struct device *dev, |
392 | struct device_attribute *attr, char *buf) | 405 | struct device_attribute *attr, char *buf) |
393 | { | 406 | { |
@@ -395,7 +408,7 @@ static ssize_t show_valid_zones(struct device *dev, | |||
395 | unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); | 408 | unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); |
396 | unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; | 409 | unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; |
397 | unsigned long valid_start_pfn, valid_end_pfn; | 410 | unsigned long valid_start_pfn, valid_end_pfn; |
398 | bool append = false; | 411 | struct zone *default_zone; |
399 | int nid; | 412 | int nid; |
400 | 413 | ||
401 | /* | 414 | /* |
@@ -418,16 +431,13 @@ static ssize_t show_valid_zones(struct device *dev, | |||
418 | } | 431 | } |
419 | 432 | ||
420 | nid = pfn_to_nid(start_pfn); | 433 | nid = pfn_to_nid(start_pfn); |
421 | if (allow_online_pfn_range(nid, start_pfn, nr_pages, MMOP_ONLINE_KERNEL)) { | 434 | default_zone = zone_for_pfn_range(MMOP_ONLINE_KEEP, nid, start_pfn, nr_pages); |
422 | strcat(buf, default_zone_for_pfn(nid, start_pfn, nr_pages)->name); | 435 | strcat(buf, default_zone->name); |
423 | append = true; | ||
424 | } | ||
425 | 436 | ||
426 | if (allow_online_pfn_range(nid, start_pfn, nr_pages, MMOP_ONLINE_MOVABLE)) { | 437 | print_allowed_zone(buf, nid, start_pfn, nr_pages, MMOP_ONLINE_KERNEL, |
427 | if (append) | 438 | default_zone); |
428 | strcat(buf, " "); | 439 | print_allowed_zone(buf, nid, start_pfn, nr_pages, MMOP_ONLINE_MOVABLE, |
429 | strcat(buf, NODE_DATA(nid)->node_zones[ZONE_MOVABLE].name); | 440 | default_zone); |
430 | } | ||
431 | out: | 441 | out: |
432 | strcat(buf, "\n"); | 442 | strcat(buf, "\n"); |
433 | 443 | ||
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 104b71c0490d..5d9ed0616413 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
@@ -326,7 +326,11 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector, | |||
326 | struct page *page, bool is_write) | 326 | struct page *page, bool is_write) |
327 | { | 327 | { |
328 | struct brd_device *brd = bdev->bd_disk->private_data; | 328 | struct brd_device *brd = bdev->bd_disk->private_data; |
329 | int err = brd_do_bvec(brd, page, PAGE_SIZE, 0, is_write, sector); | 329 | int err; |
330 | |||
331 | if (PageTransHuge(page)) | ||
332 | return -ENOTSUPP; | ||
333 | err = brd_do_bvec(brd, page, PAGE_SIZE, 0, is_write, sector); | ||
330 | page_endio(page, is_write, err); | 334 | page_endio(page, is_write, err); |
331 | return err; | 335 | return err; |
332 | } | 336 | } |
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index b8ecba6dcd3b..7cd4a8ec3c8f 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig | |||
@@ -13,3 +13,15 @@ config ZRAM | |||
13 | disks and maybe many more. | 13 | disks and maybe many more. |
14 | 14 | ||
15 | See zram.txt for more information. | 15 | See zram.txt for more information. |
16 | |||
17 | config ZRAM_WRITEBACK | ||
18 | bool "Write back incompressible page to backing device" | ||
19 | depends on ZRAM | ||
20 | default n | ||
21 | help | ||
22 | With incompressible page, there is no memory saving to keep it | ||
23 | in memory. Instead, write it out to backing device. | ||
24 | For this feature, admin should set up backing device via | ||
25 | /sys/block/zramX/backing_dev. | ||
26 | |||
27 | See zram.txt for more infomration. | ||
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 3b1b6340ba13..4a0438c4ef2a 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
@@ -270,6 +270,349 @@ static ssize_t mem_used_max_store(struct device *dev, | |||
270 | return len; | 270 | return len; |
271 | } | 271 | } |
272 | 272 | ||
273 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
274 | static bool zram_wb_enabled(struct zram *zram) | ||
275 | { | ||
276 | return zram->backing_dev; | ||
277 | } | ||
278 | |||
279 | static void reset_bdev(struct zram *zram) | ||
280 | { | ||
281 | struct block_device *bdev; | ||
282 | |||
283 | if (!zram_wb_enabled(zram)) | ||
284 | return; | ||
285 | |||
286 | bdev = zram->bdev; | ||
287 | if (zram->old_block_size) | ||
288 | set_blocksize(bdev, zram->old_block_size); | ||
289 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | ||
290 | /* hope filp_close flush all of IO */ | ||
291 | filp_close(zram->backing_dev, NULL); | ||
292 | zram->backing_dev = NULL; | ||
293 | zram->old_block_size = 0; | ||
294 | zram->bdev = NULL; | ||
295 | |||
296 | kvfree(zram->bitmap); | ||
297 | zram->bitmap = NULL; | ||
298 | } | ||
299 | |||
300 | static ssize_t backing_dev_show(struct device *dev, | ||
301 | struct device_attribute *attr, char *buf) | ||
302 | { | ||
303 | struct zram *zram = dev_to_zram(dev); | ||
304 | struct file *file = zram->backing_dev; | ||
305 | char *p; | ||
306 | ssize_t ret; | ||
307 | |||
308 | down_read(&zram->init_lock); | ||
309 | if (!zram_wb_enabled(zram)) { | ||
310 | memcpy(buf, "none\n", 5); | ||
311 | up_read(&zram->init_lock); | ||
312 | return 5; | ||
313 | } | ||
314 | |||
315 | p = file_path(file, buf, PAGE_SIZE - 1); | ||
316 | if (IS_ERR(p)) { | ||
317 | ret = PTR_ERR(p); | ||
318 | goto out; | ||
319 | } | ||
320 | |||
321 | ret = strlen(p); | ||
322 | memmove(buf, p, ret); | ||
323 | buf[ret++] = '\n'; | ||
324 | out: | ||
325 | up_read(&zram->init_lock); | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | static ssize_t backing_dev_store(struct device *dev, | ||
330 | struct device_attribute *attr, const char *buf, size_t len) | ||
331 | { | ||
332 | char *file_name; | ||
333 | struct file *backing_dev = NULL; | ||
334 | struct inode *inode; | ||
335 | struct address_space *mapping; | ||
336 | unsigned int bitmap_sz, old_block_size = 0; | ||
337 | unsigned long nr_pages, *bitmap = NULL; | ||
338 | struct block_device *bdev = NULL; | ||
339 | int err; | ||
340 | struct zram *zram = dev_to_zram(dev); | ||
341 | |||
342 | file_name = kmalloc(PATH_MAX, GFP_KERNEL); | ||
343 | if (!file_name) | ||
344 | return -ENOMEM; | ||
345 | |||
346 | down_write(&zram->init_lock); | ||
347 | if (init_done(zram)) { | ||
348 | pr_info("Can't setup backing device for initialized device\n"); | ||
349 | err = -EBUSY; | ||
350 | goto out; | ||
351 | } | ||
352 | |||
353 | strlcpy(file_name, buf, len); | ||
354 | |||
355 | backing_dev = filp_open(file_name, O_RDWR|O_LARGEFILE, 0); | ||
356 | if (IS_ERR(backing_dev)) { | ||
357 | err = PTR_ERR(backing_dev); | ||
358 | backing_dev = NULL; | ||
359 | goto out; | ||
360 | } | ||
361 | |||
362 | mapping = backing_dev->f_mapping; | ||
363 | inode = mapping->host; | ||
364 | |||
365 | /* Support only block device in this moment */ | ||
366 | if (!S_ISBLK(inode->i_mode)) { | ||
367 | err = -ENOTBLK; | ||
368 | goto out; | ||
369 | } | ||
370 | |||
371 | bdev = bdgrab(I_BDEV(inode)); | ||
372 | err = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, zram); | ||
373 | if (err < 0) | ||
374 | goto out; | ||
375 | |||
376 | nr_pages = i_size_read(inode) >> PAGE_SHIFT; | ||
377 | bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long); | ||
378 | bitmap = kvzalloc(bitmap_sz, GFP_KERNEL); | ||
379 | if (!bitmap) { | ||
380 | err = -ENOMEM; | ||
381 | goto out; | ||
382 | } | ||
383 | |||
384 | old_block_size = block_size(bdev); | ||
385 | err = set_blocksize(bdev, PAGE_SIZE); | ||
386 | if (err) | ||
387 | goto out; | ||
388 | |||
389 | reset_bdev(zram); | ||
390 | spin_lock_init(&zram->bitmap_lock); | ||
391 | |||
392 | zram->old_block_size = old_block_size; | ||
393 | zram->bdev = bdev; | ||
394 | zram->backing_dev = backing_dev; | ||
395 | zram->bitmap = bitmap; | ||
396 | zram->nr_pages = nr_pages; | ||
397 | up_write(&zram->init_lock); | ||
398 | |||
399 | pr_info("setup backing device %s\n", file_name); | ||
400 | kfree(file_name); | ||
401 | |||
402 | return len; | ||
403 | out: | ||
404 | if (bitmap) | ||
405 | kvfree(bitmap); | ||
406 | |||
407 | if (bdev) | ||
408 | blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); | ||
409 | |||
410 | if (backing_dev) | ||
411 | filp_close(backing_dev, NULL); | ||
412 | |||
413 | up_write(&zram->init_lock); | ||
414 | |||
415 | kfree(file_name); | ||
416 | |||
417 | return err; | ||
418 | } | ||
419 | |||
420 | static unsigned long get_entry_bdev(struct zram *zram) | ||
421 | { | ||
422 | unsigned long entry; | ||
423 | |||
424 | spin_lock(&zram->bitmap_lock); | ||
425 | /* skip 0 bit to confuse zram.handle = 0 */ | ||
426 | entry = find_next_zero_bit(zram->bitmap, zram->nr_pages, 1); | ||
427 | if (entry == zram->nr_pages) { | ||
428 | spin_unlock(&zram->bitmap_lock); | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | set_bit(entry, zram->bitmap); | ||
433 | spin_unlock(&zram->bitmap_lock); | ||
434 | |||
435 | return entry; | ||
436 | } | ||
437 | |||
438 | static void put_entry_bdev(struct zram *zram, unsigned long entry) | ||
439 | { | ||
440 | int was_set; | ||
441 | |||
442 | spin_lock(&zram->bitmap_lock); | ||
443 | was_set = test_and_clear_bit(entry, zram->bitmap); | ||
444 | spin_unlock(&zram->bitmap_lock); | ||
445 | WARN_ON_ONCE(!was_set); | ||
446 | } | ||
447 | |||
448 | void zram_page_end_io(struct bio *bio) | ||
449 | { | ||
450 | struct page *page = bio->bi_io_vec[0].bv_page; | ||
451 | |||
452 | page_endio(page, op_is_write(bio_op(bio)), | ||
453 | blk_status_to_errno(bio->bi_status)); | ||
454 | bio_put(bio); | ||
455 | } | ||
456 | |||
457 | /* | ||
458 | * Returns 1 if the submission is successful. | ||
459 | */ | ||
460 | static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec, | ||
461 | unsigned long entry, struct bio *parent) | ||
462 | { | ||
463 | struct bio *bio; | ||
464 | |||
465 | bio = bio_alloc(GFP_ATOMIC, 1); | ||
466 | if (!bio) | ||
467 | return -ENOMEM; | ||
468 | |||
469 | bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9); | ||
470 | bio->bi_bdev = zram->bdev; | ||
471 | if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, bvec->bv_offset)) { | ||
472 | bio_put(bio); | ||
473 | return -EIO; | ||
474 | } | ||
475 | |||
476 | if (!parent) { | ||
477 | bio->bi_opf = REQ_OP_READ; | ||
478 | bio->bi_end_io = zram_page_end_io; | ||
479 | } else { | ||
480 | bio->bi_opf = parent->bi_opf; | ||
481 | bio_chain(bio, parent); | ||
482 | } | ||
483 | |||
484 | submit_bio(bio); | ||
485 | return 1; | ||
486 | } | ||
487 | |||
488 | struct zram_work { | ||
489 | struct work_struct work; | ||
490 | struct zram *zram; | ||
491 | unsigned long entry; | ||
492 | struct bio *bio; | ||
493 | }; | ||
494 | |||
495 | #if PAGE_SIZE != 4096 | ||
496 | static void zram_sync_read(struct work_struct *work) | ||
497 | { | ||
498 | struct bio_vec bvec; | ||
499 | struct zram_work *zw = container_of(work, struct zram_work, work); | ||
500 | struct zram *zram = zw->zram; | ||
501 | unsigned long entry = zw->entry; | ||
502 | struct bio *bio = zw->bio; | ||
503 | |||
504 | read_from_bdev_async(zram, &bvec, entry, bio); | ||
505 | } | ||
506 | |||
507 | /* | ||
508 | * Block layer want one ->make_request_fn to be active at a time | ||
509 | * so if we use chained IO with parent IO in same context, | ||
510 | * it's a deadlock. To avoid, it, it uses worker thread context. | ||
511 | */ | ||
512 | static int read_from_bdev_sync(struct zram *zram, struct bio_vec *bvec, | ||
513 | unsigned long entry, struct bio *bio) | ||
514 | { | ||
515 | struct zram_work work; | ||
516 | |||
517 | work.zram = zram; | ||
518 | work.entry = entry; | ||
519 | work.bio = bio; | ||
520 | |||
521 | INIT_WORK_ONSTACK(&work.work, zram_sync_read); | ||
522 | queue_work(system_unbound_wq, &work.work); | ||
523 | flush_work(&work.work); | ||
524 | destroy_work_on_stack(&work.work); | ||
525 | |||
526 | return 1; | ||
527 | } | ||
528 | #else | ||
529 | static int read_from_bdev_sync(struct zram *zram, struct bio_vec *bvec, | ||
530 | unsigned long entry, struct bio *bio) | ||
531 | { | ||
532 | WARN_ON(1); | ||
533 | return -EIO; | ||
534 | } | ||
535 | #endif | ||
536 | |||
537 | static int read_from_bdev(struct zram *zram, struct bio_vec *bvec, | ||
538 | unsigned long entry, struct bio *parent, bool sync) | ||
539 | { | ||
540 | if (sync) | ||
541 | return read_from_bdev_sync(zram, bvec, entry, parent); | ||
542 | else | ||
543 | return read_from_bdev_async(zram, bvec, entry, parent); | ||
544 | } | ||
545 | |||
546 | static int write_to_bdev(struct zram *zram, struct bio_vec *bvec, | ||
547 | u32 index, struct bio *parent, | ||
548 | unsigned long *pentry) | ||
549 | { | ||
550 | struct bio *bio; | ||
551 | unsigned long entry; | ||
552 | |||
553 | bio = bio_alloc(GFP_ATOMIC, 1); | ||
554 | if (!bio) | ||
555 | return -ENOMEM; | ||
556 | |||
557 | entry = get_entry_bdev(zram); | ||
558 | if (!entry) { | ||
559 | bio_put(bio); | ||
560 | return -ENOSPC; | ||
561 | } | ||
562 | |||
563 | bio->bi_iter.bi_sector = entry * (PAGE_SIZE >> 9); | ||
564 | bio->bi_bdev = zram->bdev; | ||
565 | if (!bio_add_page(bio, bvec->bv_page, bvec->bv_len, | ||
566 | bvec->bv_offset)) { | ||
567 | bio_put(bio); | ||
568 | put_entry_bdev(zram, entry); | ||
569 | return -EIO; | ||
570 | } | ||
571 | |||
572 | if (!parent) { | ||
573 | bio->bi_opf = REQ_OP_WRITE | REQ_SYNC; | ||
574 | bio->bi_end_io = zram_page_end_io; | ||
575 | } else { | ||
576 | bio->bi_opf = parent->bi_opf; | ||
577 | bio_chain(bio, parent); | ||
578 | } | ||
579 | |||
580 | submit_bio(bio); | ||
581 | *pentry = entry; | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static void zram_wb_clear(struct zram *zram, u32 index) | ||
587 | { | ||
588 | unsigned long entry; | ||
589 | |||
590 | zram_clear_flag(zram, index, ZRAM_WB); | ||
591 | entry = zram_get_element(zram, index); | ||
592 | zram_set_element(zram, index, 0); | ||
593 | put_entry_bdev(zram, entry); | ||
594 | } | ||
595 | |||
596 | #else | ||
597 | static bool zram_wb_enabled(struct zram *zram) { return false; } | ||
598 | static inline void reset_bdev(struct zram *zram) {}; | ||
599 | static int write_to_bdev(struct zram *zram, struct bio_vec *bvec, | ||
600 | u32 index, struct bio *parent, | ||
601 | unsigned long *pentry) | ||
602 | |||
603 | { | ||
604 | return -EIO; | ||
605 | } | ||
606 | |||
607 | static int read_from_bdev(struct zram *zram, struct bio_vec *bvec, | ||
608 | unsigned long entry, struct bio *parent, bool sync) | ||
609 | { | ||
610 | return -EIO; | ||
611 | } | ||
612 | static void zram_wb_clear(struct zram *zram, u32 index) {} | ||
613 | #endif | ||
614 | |||
615 | |||
273 | /* | 616 | /* |
274 | * We switched to per-cpu streams and this attr is not needed anymore. | 617 | * We switched to per-cpu streams and this attr is not needed anymore. |
275 | * However, we will keep it around for some time, because: | 618 | * However, we will keep it around for some time, because: |
@@ -453,30 +796,6 @@ static bool zram_same_page_read(struct zram *zram, u32 index, | |||
453 | return false; | 796 | return false; |
454 | } | 797 | } |
455 | 798 | ||
456 | static bool zram_same_page_write(struct zram *zram, u32 index, | ||
457 | struct page *page) | ||
458 | { | ||
459 | unsigned long element; | ||
460 | void *mem = kmap_atomic(page); | ||
461 | |||
462 | if (page_same_filled(mem, &element)) { | ||
463 | kunmap_atomic(mem); | ||
464 | /* Free memory associated with this sector now. */ | ||
465 | zram_slot_lock(zram, index); | ||
466 | zram_free_page(zram, index); | ||
467 | zram_set_flag(zram, index, ZRAM_SAME); | ||
468 | zram_set_element(zram, index, element); | ||
469 | zram_slot_unlock(zram, index); | ||
470 | |||
471 | atomic64_inc(&zram->stats.same_pages); | ||
472 | atomic64_inc(&zram->stats.pages_stored); | ||
473 | return true; | ||
474 | } | ||
475 | kunmap_atomic(mem); | ||
476 | |||
477 | return false; | ||
478 | } | ||
479 | |||
480 | static void zram_meta_free(struct zram *zram, u64 disksize) | 799 | static void zram_meta_free(struct zram *zram, u64 disksize) |
481 | { | 800 | { |
482 | size_t num_pages = disksize >> PAGE_SHIFT; | 801 | size_t num_pages = disksize >> PAGE_SHIFT; |
@@ -515,7 +834,13 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) | |||
515 | */ | 834 | */ |
516 | static void zram_free_page(struct zram *zram, size_t index) | 835 | static void zram_free_page(struct zram *zram, size_t index) |
517 | { | 836 | { |
518 | unsigned long handle = zram_get_handle(zram, index); | 837 | unsigned long handle; |
838 | |||
839 | if (zram_wb_enabled(zram) && zram_test_flag(zram, index, ZRAM_WB)) { | ||
840 | zram_wb_clear(zram, index); | ||
841 | atomic64_dec(&zram->stats.pages_stored); | ||
842 | return; | ||
843 | } | ||
519 | 844 | ||
520 | /* | 845 | /* |
521 | * No memory is allocated for same element filled pages. | 846 | * No memory is allocated for same element filled pages. |
@@ -529,6 +854,7 @@ static void zram_free_page(struct zram *zram, size_t index) | |||
529 | return; | 854 | return; |
530 | } | 855 | } |
531 | 856 | ||
857 | handle = zram_get_handle(zram, index); | ||
532 | if (!handle) | 858 | if (!handle) |
533 | return; | 859 | return; |
534 | 860 | ||
@@ -542,13 +868,31 @@ static void zram_free_page(struct zram *zram, size_t index) | |||
542 | zram_set_obj_size(zram, index, 0); | 868 | zram_set_obj_size(zram, index, 0); |
543 | } | 869 | } |
544 | 870 | ||
545 | static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) | 871 | static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, |
872 | struct bio *bio, bool partial_io) | ||
546 | { | 873 | { |
547 | int ret; | 874 | int ret; |
548 | unsigned long handle; | 875 | unsigned long handle; |
549 | unsigned int size; | 876 | unsigned int size; |
550 | void *src, *dst; | 877 | void *src, *dst; |
551 | 878 | ||
879 | if (zram_wb_enabled(zram)) { | ||
880 | zram_slot_lock(zram, index); | ||
881 | if (zram_test_flag(zram, index, ZRAM_WB)) { | ||
882 | struct bio_vec bvec; | ||
883 | |||
884 | zram_slot_unlock(zram, index); | ||
885 | |||
886 | bvec.bv_page = page; | ||
887 | bvec.bv_len = PAGE_SIZE; | ||
888 | bvec.bv_offset = 0; | ||
889 | return read_from_bdev(zram, &bvec, | ||
890 | zram_get_element(zram, index), | ||
891 | bio, partial_io); | ||
892 | } | ||
893 | zram_slot_unlock(zram, index); | ||
894 | } | ||
895 | |||
552 | if (zram_same_page_read(zram, index, page, 0, PAGE_SIZE)) | 896 | if (zram_same_page_read(zram, index, page, 0, PAGE_SIZE)) |
553 | return 0; | 897 | return 0; |
554 | 898 | ||
@@ -581,7 +925,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) | |||
581 | } | 925 | } |
582 | 926 | ||
583 | static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, | 927 | static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, |
584 | u32 index, int offset) | 928 | u32 index, int offset, struct bio *bio) |
585 | { | 929 | { |
586 | int ret; | 930 | int ret; |
587 | struct page *page; | 931 | struct page *page; |
@@ -594,7 +938,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, | |||
594 | return -ENOMEM; | 938 | return -ENOMEM; |
595 | } | 939 | } |
596 | 940 | ||
597 | ret = zram_decompress_page(zram, page, index); | 941 | ret = __zram_bvec_read(zram, page, index, bio, is_partial_io(bvec)); |
598 | if (unlikely(ret)) | 942 | if (unlikely(ret)) |
599 | goto out; | 943 | goto out; |
600 | 944 | ||
@@ -613,30 +957,57 @@ out: | |||
613 | return ret; | 957 | return ret; |
614 | } | 958 | } |
615 | 959 | ||
616 | static int zram_compress(struct zram *zram, struct zcomp_strm **zstrm, | 960 | static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, |
617 | struct page *page, | 961 | u32 index, struct bio *bio) |
618 | unsigned long *out_handle, unsigned int *out_comp_len) | ||
619 | { | 962 | { |
620 | int ret; | 963 | int ret = 0; |
621 | unsigned int comp_len; | ||
622 | void *src; | ||
623 | unsigned long alloced_pages; | 964 | unsigned long alloced_pages; |
624 | unsigned long handle = 0; | 965 | unsigned long handle = 0; |
966 | unsigned int comp_len = 0; | ||
967 | void *src, *dst, *mem; | ||
968 | struct zcomp_strm *zstrm; | ||
969 | struct page *page = bvec->bv_page; | ||
970 | unsigned long element = 0; | ||
971 | enum zram_pageflags flags = 0; | ||
972 | bool allow_wb = true; | ||
973 | |||
974 | mem = kmap_atomic(page); | ||
975 | if (page_same_filled(mem, &element)) { | ||
976 | kunmap_atomic(mem); | ||
977 | /* Free memory associated with this sector now. */ | ||
978 | flags = ZRAM_SAME; | ||
979 | atomic64_inc(&zram->stats.same_pages); | ||
980 | goto out; | ||
981 | } | ||
982 | kunmap_atomic(mem); | ||
625 | 983 | ||
626 | compress_again: | 984 | compress_again: |
985 | zstrm = zcomp_stream_get(zram->comp); | ||
627 | src = kmap_atomic(page); | 986 | src = kmap_atomic(page); |
628 | ret = zcomp_compress(*zstrm, src, &comp_len); | 987 | ret = zcomp_compress(zstrm, src, &comp_len); |
629 | kunmap_atomic(src); | 988 | kunmap_atomic(src); |
630 | 989 | ||
631 | if (unlikely(ret)) { | 990 | if (unlikely(ret)) { |
991 | zcomp_stream_put(zram->comp); | ||
632 | pr_err("Compression failed! err=%d\n", ret); | 992 | pr_err("Compression failed! err=%d\n", ret); |
633 | if (handle) | 993 | zs_free(zram->mem_pool, handle); |
634 | zs_free(zram->mem_pool, handle); | ||
635 | return ret; | 994 | return ret; |
636 | } | 995 | } |
637 | 996 | ||
638 | if (unlikely(comp_len > max_zpage_size)) | 997 | if (unlikely(comp_len > max_zpage_size)) { |
998 | if (zram_wb_enabled(zram) && allow_wb) { | ||
999 | zcomp_stream_put(zram->comp); | ||
1000 | ret = write_to_bdev(zram, bvec, index, bio, &element); | ||
1001 | if (!ret) { | ||
1002 | flags = ZRAM_WB; | ||
1003 | ret = 1; | ||
1004 | goto out; | ||
1005 | } | ||
1006 | allow_wb = false; | ||
1007 | goto compress_again; | ||
1008 | } | ||
639 | comp_len = PAGE_SIZE; | 1009 | comp_len = PAGE_SIZE; |
1010 | } | ||
640 | 1011 | ||
641 | /* | 1012 | /* |
642 | * handle allocation has 2 paths: | 1013 | * handle allocation has 2 paths: |
@@ -663,7 +1034,6 @@ compress_again: | |||
663 | handle = zs_malloc(zram->mem_pool, comp_len, | 1034 | handle = zs_malloc(zram->mem_pool, comp_len, |
664 | GFP_NOIO | __GFP_HIGHMEM | | 1035 | GFP_NOIO | __GFP_HIGHMEM | |
665 | __GFP_MOVABLE); | 1036 | __GFP_MOVABLE); |
666 | *zstrm = zcomp_stream_get(zram->comp); | ||
667 | if (handle) | 1037 | if (handle) |
668 | goto compress_again; | 1038 | goto compress_again; |
669 | return -ENOMEM; | 1039 | return -ENOMEM; |
@@ -673,34 +1043,11 @@ compress_again: | |||
673 | update_used_max(zram, alloced_pages); | 1043 | update_used_max(zram, alloced_pages); |
674 | 1044 | ||
675 | if (zram->limit_pages && alloced_pages > zram->limit_pages) { | 1045 | if (zram->limit_pages && alloced_pages > zram->limit_pages) { |
1046 | zcomp_stream_put(zram->comp); | ||
676 | zs_free(zram->mem_pool, handle); | 1047 | zs_free(zram->mem_pool, handle); |
677 | return -ENOMEM; | 1048 | return -ENOMEM; |
678 | } | 1049 | } |
679 | 1050 | ||
680 | *out_handle = handle; | ||
681 | *out_comp_len = comp_len; | ||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index) | ||
686 | { | ||
687 | int ret; | ||
688 | unsigned long handle; | ||
689 | unsigned int comp_len; | ||
690 | void *src, *dst; | ||
691 | struct zcomp_strm *zstrm; | ||
692 | struct page *page = bvec->bv_page; | ||
693 | |||
694 | if (zram_same_page_write(zram, index, page)) | ||
695 | return 0; | ||
696 | |||
697 | zstrm = zcomp_stream_get(zram->comp); | ||
698 | ret = zram_compress(zram, &zstrm, page, &handle, &comp_len); | ||
699 | if (ret) { | ||
700 | zcomp_stream_put(zram->comp); | ||
701 | return ret; | ||
702 | } | ||
703 | |||
704 | dst = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); | 1051 | dst = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); |
705 | 1052 | ||
706 | src = zstrm->buffer; | 1053 | src = zstrm->buffer; |
@@ -712,25 +1059,31 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index) | |||
712 | 1059 | ||
713 | zcomp_stream_put(zram->comp); | 1060 | zcomp_stream_put(zram->comp); |
714 | zs_unmap_object(zram->mem_pool, handle); | 1061 | zs_unmap_object(zram->mem_pool, handle); |
715 | 1062 | atomic64_add(comp_len, &zram->stats.compr_data_size); | |
1063 | out: | ||
716 | /* | 1064 | /* |
717 | * Free memory associated with this sector | 1065 | * Free memory associated with this sector |
718 | * before overwriting unused sectors. | 1066 | * before overwriting unused sectors. |
719 | */ | 1067 | */ |
720 | zram_slot_lock(zram, index); | 1068 | zram_slot_lock(zram, index); |
721 | zram_free_page(zram, index); | 1069 | zram_free_page(zram, index); |
722 | zram_set_handle(zram, index, handle); | 1070 | |
723 | zram_set_obj_size(zram, index, comp_len); | 1071 | if (flags) { |
1072 | zram_set_flag(zram, index, flags); | ||
1073 | zram_set_element(zram, index, element); | ||
1074 | } else { | ||
1075 | zram_set_handle(zram, index, handle); | ||
1076 | zram_set_obj_size(zram, index, comp_len); | ||
1077 | } | ||
724 | zram_slot_unlock(zram, index); | 1078 | zram_slot_unlock(zram, index); |
725 | 1079 | ||
726 | /* Update stats */ | 1080 | /* Update stats */ |
727 | atomic64_add(comp_len, &zram->stats.compr_data_size); | ||
728 | atomic64_inc(&zram->stats.pages_stored); | 1081 | atomic64_inc(&zram->stats.pages_stored); |
729 | return 0; | 1082 | return ret; |
730 | } | 1083 | } |
731 | 1084 | ||
732 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, | 1085 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, |
733 | u32 index, int offset) | 1086 | u32 index, int offset, struct bio *bio) |
734 | { | 1087 | { |
735 | int ret; | 1088 | int ret; |
736 | struct page *page = NULL; | 1089 | struct page *page = NULL; |
@@ -748,7 +1101,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, | |||
748 | if (!page) | 1101 | if (!page) |
749 | return -ENOMEM; | 1102 | return -ENOMEM; |
750 | 1103 | ||
751 | ret = zram_decompress_page(zram, page, index); | 1104 | ret = __zram_bvec_read(zram, page, index, bio, true); |
752 | if (ret) | 1105 | if (ret) |
753 | goto out; | 1106 | goto out; |
754 | 1107 | ||
@@ -763,7 +1116,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, | |||
763 | vec.bv_offset = 0; | 1116 | vec.bv_offset = 0; |
764 | } | 1117 | } |
765 | 1118 | ||
766 | ret = __zram_bvec_write(zram, &vec, index); | 1119 | ret = __zram_bvec_write(zram, &vec, index, bio); |
767 | out: | 1120 | out: |
768 | if (is_partial_io(bvec)) | 1121 | if (is_partial_io(bvec)) |
769 | __free_page(page); | 1122 | __free_page(page); |
@@ -808,8 +1161,13 @@ static void zram_bio_discard(struct zram *zram, u32 index, | |||
808 | } | 1161 | } |
809 | } | 1162 | } |
810 | 1163 | ||
1164 | /* | ||
1165 | * Returns errno if it has some problem. Otherwise return 0 or 1. | ||
1166 | * Returns 0 if IO request was done synchronously | ||
1167 | * Returns 1 if IO request was successfully submitted. | ||
1168 | */ | ||
811 | static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, | 1169 | static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, |
812 | int offset, bool is_write) | 1170 | int offset, bool is_write, struct bio *bio) |
813 | { | 1171 | { |
814 | unsigned long start_time = jiffies; | 1172 | unsigned long start_time = jiffies; |
815 | int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ; | 1173 | int rw_acct = is_write ? REQ_OP_WRITE : REQ_OP_READ; |
@@ -820,16 +1178,16 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
820 | 1178 | ||
821 | if (!is_write) { | 1179 | if (!is_write) { |
822 | atomic64_inc(&zram->stats.num_reads); | 1180 | atomic64_inc(&zram->stats.num_reads); |
823 | ret = zram_bvec_read(zram, bvec, index, offset); | 1181 | ret = zram_bvec_read(zram, bvec, index, offset, bio); |
824 | flush_dcache_page(bvec->bv_page); | 1182 | flush_dcache_page(bvec->bv_page); |
825 | } else { | 1183 | } else { |
826 | atomic64_inc(&zram->stats.num_writes); | 1184 | atomic64_inc(&zram->stats.num_writes); |
827 | ret = zram_bvec_write(zram, bvec, index, offset); | 1185 | ret = zram_bvec_write(zram, bvec, index, offset, bio); |
828 | } | 1186 | } |
829 | 1187 | ||
830 | generic_end_io_acct(rw_acct, &zram->disk->part0, start_time); | 1188 | generic_end_io_acct(rw_acct, &zram->disk->part0, start_time); |
831 | 1189 | ||
832 | if (unlikely(ret)) { | 1190 | if (unlikely(ret < 0)) { |
833 | if (!is_write) | 1191 | if (!is_write) |
834 | atomic64_inc(&zram->stats.failed_reads); | 1192 | atomic64_inc(&zram->stats.failed_reads); |
835 | else | 1193 | else |
@@ -868,7 +1226,7 @@ static void __zram_make_request(struct zram *zram, struct bio *bio) | |||
868 | bv.bv_len = min_t(unsigned int, PAGE_SIZE - offset, | 1226 | bv.bv_len = min_t(unsigned int, PAGE_SIZE - offset, |
869 | unwritten); | 1227 | unwritten); |
870 | if (zram_bvec_rw(zram, &bv, index, offset, | 1228 | if (zram_bvec_rw(zram, &bv, index, offset, |
871 | op_is_write(bio_op(bio))) < 0) | 1229 | op_is_write(bio_op(bio)), bio) < 0) |
872 | goto out; | 1230 | goto out; |
873 | 1231 | ||
874 | bv.bv_offset += bv.bv_len; | 1232 | bv.bv_offset += bv.bv_len; |
@@ -922,16 +1280,18 @@ static void zram_slot_free_notify(struct block_device *bdev, | |||
922 | static int zram_rw_page(struct block_device *bdev, sector_t sector, | 1280 | static int zram_rw_page(struct block_device *bdev, sector_t sector, |
923 | struct page *page, bool is_write) | 1281 | struct page *page, bool is_write) |
924 | { | 1282 | { |
925 | int offset, err = -EIO; | 1283 | int offset, ret; |
926 | u32 index; | 1284 | u32 index; |
927 | struct zram *zram; | 1285 | struct zram *zram; |
928 | struct bio_vec bv; | 1286 | struct bio_vec bv; |
929 | 1287 | ||
1288 | if (PageTransHuge(page)) | ||
1289 | return -ENOTSUPP; | ||
930 | zram = bdev->bd_disk->private_data; | 1290 | zram = bdev->bd_disk->private_data; |
931 | 1291 | ||
932 | if (!valid_io_request(zram, sector, PAGE_SIZE)) { | 1292 | if (!valid_io_request(zram, sector, PAGE_SIZE)) { |
933 | atomic64_inc(&zram->stats.invalid_io); | 1293 | atomic64_inc(&zram->stats.invalid_io); |
934 | err = -EINVAL; | 1294 | ret = -EINVAL; |
935 | goto out; | 1295 | goto out; |
936 | } | 1296 | } |
937 | 1297 | ||
@@ -942,7 +1302,7 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, | |||
942 | bv.bv_len = PAGE_SIZE; | 1302 | bv.bv_len = PAGE_SIZE; |
943 | bv.bv_offset = 0; | 1303 | bv.bv_offset = 0; |
944 | 1304 | ||
945 | err = zram_bvec_rw(zram, &bv, index, offset, is_write); | 1305 | ret = zram_bvec_rw(zram, &bv, index, offset, is_write, NULL); |
946 | out: | 1306 | out: |
947 | /* | 1307 | /* |
948 | * If I/O fails, just return error(ie, non-zero) without | 1308 | * If I/O fails, just return error(ie, non-zero) without |
@@ -952,9 +1312,20 @@ out: | |||
952 | * bio->bi_end_io does things to handle the error | 1312 | * bio->bi_end_io does things to handle the error |
953 | * (e.g., SetPageError, set_page_dirty and extra works). | 1313 | * (e.g., SetPageError, set_page_dirty and extra works). |
954 | */ | 1314 | */ |
955 | if (err == 0) | 1315 | if (unlikely(ret < 0)) |
1316 | return ret; | ||
1317 | |||
1318 | switch (ret) { | ||
1319 | case 0: | ||
956 | page_endio(page, is_write, 0); | 1320 | page_endio(page, is_write, 0); |
957 | return err; | 1321 | break; |
1322 | case 1: | ||
1323 | ret = 0; | ||
1324 | break; | ||
1325 | default: | ||
1326 | WARN_ON(1); | ||
1327 | } | ||
1328 | return ret; | ||
958 | } | 1329 | } |
959 | 1330 | ||
960 | static void zram_reset_device(struct zram *zram) | 1331 | static void zram_reset_device(struct zram *zram) |
@@ -983,6 +1354,7 @@ static void zram_reset_device(struct zram *zram) | |||
983 | zram_meta_free(zram, disksize); | 1354 | zram_meta_free(zram, disksize); |
984 | memset(&zram->stats, 0, sizeof(zram->stats)); | 1355 | memset(&zram->stats, 0, sizeof(zram->stats)); |
985 | zcomp_destroy(comp); | 1356 | zcomp_destroy(comp); |
1357 | reset_bdev(zram); | ||
986 | } | 1358 | } |
987 | 1359 | ||
988 | static ssize_t disksize_store(struct device *dev, | 1360 | static ssize_t disksize_store(struct device *dev, |
@@ -1108,6 +1480,9 @@ static DEVICE_ATTR_WO(mem_limit); | |||
1108 | static DEVICE_ATTR_WO(mem_used_max); | 1480 | static DEVICE_ATTR_WO(mem_used_max); |
1109 | static DEVICE_ATTR_RW(max_comp_streams); | 1481 | static DEVICE_ATTR_RW(max_comp_streams); |
1110 | static DEVICE_ATTR_RW(comp_algorithm); | 1482 | static DEVICE_ATTR_RW(comp_algorithm); |
1483 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
1484 | static DEVICE_ATTR_RW(backing_dev); | ||
1485 | #endif | ||
1111 | 1486 | ||
1112 | static struct attribute *zram_disk_attrs[] = { | 1487 | static struct attribute *zram_disk_attrs[] = { |
1113 | &dev_attr_disksize.attr, | 1488 | &dev_attr_disksize.attr, |
@@ -1118,6 +1493,9 @@ static struct attribute *zram_disk_attrs[] = { | |||
1118 | &dev_attr_mem_used_max.attr, | 1493 | &dev_attr_mem_used_max.attr, |
1119 | &dev_attr_max_comp_streams.attr, | 1494 | &dev_attr_max_comp_streams.attr, |
1120 | &dev_attr_comp_algorithm.attr, | 1495 | &dev_attr_comp_algorithm.attr, |
1496 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
1497 | &dev_attr_backing_dev.attr, | ||
1498 | #endif | ||
1121 | &dev_attr_io_stat.attr, | 1499 | &dev_attr_io_stat.attr, |
1122 | &dev_attr_mm_stat.attr, | 1500 | &dev_attr_mm_stat.attr, |
1123 | &dev_attr_debug_stat.attr, | 1501 | &dev_attr_debug_stat.attr, |
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index e34e44d02e3e..31762db861e3 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h | |||
@@ -60,9 +60,10 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3; | |||
60 | 60 | ||
61 | /* Flags for zram pages (table[page_no].value) */ | 61 | /* Flags for zram pages (table[page_no].value) */ |
62 | enum zram_pageflags { | 62 | enum zram_pageflags { |
63 | /* Page consists entirely of zeros */ | 63 | /* Page consists the same element */ |
64 | ZRAM_SAME = ZRAM_FLAG_SHIFT, | 64 | ZRAM_SAME = ZRAM_FLAG_SHIFT, |
65 | ZRAM_ACCESS, /* page is now accessed */ | 65 | ZRAM_ACCESS, /* page is now accessed */ |
66 | ZRAM_WB, /* page is stored on backing_device */ | ||
66 | 67 | ||
67 | __NR_ZRAM_PAGEFLAGS, | 68 | __NR_ZRAM_PAGEFLAGS, |
68 | }; | 69 | }; |
@@ -115,5 +116,13 @@ struct zram { | |||
115 | * zram is claimed so open request will be failed | 116 | * zram is claimed so open request will be failed |
116 | */ | 117 | */ |
117 | bool claim; /* Protected by bdev->bd_mutex */ | 118 | bool claim; /* Protected by bdev->bd_mutex */ |
119 | #ifdef CONFIG_ZRAM_WRITEBACK | ||
120 | struct file *backing_dev; | ||
121 | struct block_device *bdev; | ||
122 | unsigned int old_block_size; | ||
123 | unsigned long *bitmap; | ||
124 | unsigned long nr_pages; | ||
125 | spinlock_t bitmap_lock; | ||
126 | #endif | ||
118 | }; | 127 | }; |
119 | #endif | 128 | #endif |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a36216bd2a84..e4d4b6b41e26 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -4308,10 +4308,10 @@ i915_drop_caches_set(void *data, u64 val) | |||
4308 | 4308 | ||
4309 | fs_reclaim_acquire(GFP_KERNEL); | 4309 | fs_reclaim_acquire(GFP_KERNEL); |
4310 | if (val & DROP_BOUND) | 4310 | if (val & DROP_BOUND) |
4311 | i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND); | 4311 | i915_gem_shrink(dev_priv, LONG_MAX, NULL, I915_SHRINK_BOUND); |
4312 | 4312 | ||
4313 | if (val & DROP_UNBOUND) | 4313 | if (val & DROP_UNBOUND) |
4314 | i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_UNBOUND); | 4314 | i915_gem_shrink(dev_priv, LONG_MAX, NULL, I915_SHRINK_UNBOUND); |
4315 | 4315 | ||
4316 | if (val & DROP_SHRINK_ALL) | 4316 | if (val & DROP_SHRINK_ALL) |
4317 | i915_gem_shrink_all(dev_priv); | 4317 | i915_gem_shrink_all(dev_priv); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 60267e375e88..bd74641ab7f6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -3742,6 +3742,7 @@ i915_gem_object_create_internal(struct drm_i915_private *dev_priv, | |||
3742 | /* i915_gem_shrinker.c */ | 3742 | /* i915_gem_shrinker.c */ |
3743 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, | 3743 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, |
3744 | unsigned long target, | 3744 | unsigned long target, |
3745 | unsigned long *nr_scanned, | ||
3745 | unsigned flags); | 3746 | unsigned flags); |
3746 | #define I915_SHRINK_PURGEABLE 0x1 | 3747 | #define I915_SHRINK_PURGEABLE 0x1 |
3747 | #define I915_SHRINK_UNBOUND 0x2 | 3748 | #define I915_SHRINK_UNBOUND 0x2 |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b9e8e0d6e97b..287c6ead95b3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2354,7 +2354,7 @@ rebuild_st: | |||
2354 | goto err_sg; | 2354 | goto err_sg; |
2355 | } | 2355 | } |
2356 | 2356 | ||
2357 | i915_gem_shrink(dev_priv, 2 * page_count, *s++); | 2357 | i915_gem_shrink(dev_priv, 2 * page_count, NULL, *s++); |
2358 | cond_resched(); | 2358 | cond_resched(); |
2359 | 2359 | ||
2360 | /* We've tried hard to allocate the memory by reaping | 2360 | /* We've tried hard to allocate the memory by reaping |
@@ -5015,7 +5015,7 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv) | |||
5015 | * the objects as well, see i915_gem_freeze() | 5015 | * the objects as well, see i915_gem_freeze() |
5016 | */ | 5016 | */ |
5017 | 5017 | ||
5018 | i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND); | 5018 | i915_gem_shrink(dev_priv, -1UL, NULL, I915_SHRINK_UNBOUND); |
5019 | i915_gem_drain_freed_objects(dev_priv); | 5019 | i915_gem_drain_freed_objects(dev_priv); |
5020 | 5020 | ||
5021 | mutex_lock(&dev_priv->drm.struct_mutex); | 5021 | mutex_lock(&dev_priv->drm.struct_mutex); |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d60f38adc4c4..6c6b8e8592aa 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -2062,7 +2062,7 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, | |||
2062 | */ | 2062 | */ |
2063 | GEM_BUG_ON(obj->mm.pages == pages); | 2063 | GEM_BUG_ON(obj->mm.pages == pages); |
2064 | } while (i915_gem_shrink(to_i915(obj->base.dev), | 2064 | } while (i915_gem_shrink(to_i915(obj->base.dev), |
2065 | obj->base.size >> PAGE_SHIFT, | 2065 | obj->base.size >> PAGE_SHIFT, NULL, |
2066 | I915_SHRINK_BOUND | | 2066 | I915_SHRINK_BOUND | |
2067 | I915_SHRINK_UNBOUND | | 2067 | I915_SHRINK_UNBOUND | |
2068 | I915_SHRINK_ACTIVE)); | 2068 | I915_SHRINK_ACTIVE)); |
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 77fb39808131..74002b2d1b6f 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c | |||
@@ -136,6 +136,7 @@ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj) | |||
136 | * i915_gem_shrink - Shrink buffer object caches | 136 | * i915_gem_shrink - Shrink buffer object caches |
137 | * @dev_priv: i915 device | 137 | * @dev_priv: i915 device |
138 | * @target: amount of memory to make available, in pages | 138 | * @target: amount of memory to make available, in pages |
139 | * @nr_scanned: optional output for number of pages scanned (incremental) | ||
139 | * @flags: control flags for selecting cache types | 140 | * @flags: control flags for selecting cache types |
140 | * | 141 | * |
141 | * This function is the main interface to the shrinker. It will try to release | 142 | * This function is the main interface to the shrinker. It will try to release |
@@ -158,7 +159,9 @@ static bool unsafe_drop_pages(struct drm_i915_gem_object *obj) | |||
158 | */ | 159 | */ |
159 | unsigned long | 160 | unsigned long |
160 | i915_gem_shrink(struct drm_i915_private *dev_priv, | 161 | i915_gem_shrink(struct drm_i915_private *dev_priv, |
161 | unsigned long target, unsigned flags) | 162 | unsigned long target, |
163 | unsigned long *nr_scanned, | ||
164 | unsigned flags) | ||
162 | { | 165 | { |
163 | const struct { | 166 | const struct { |
164 | struct list_head *list; | 167 | struct list_head *list; |
@@ -169,6 +172,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
169 | { NULL, 0 }, | 172 | { NULL, 0 }, |
170 | }, *phase; | 173 | }, *phase; |
171 | unsigned long count = 0; | 174 | unsigned long count = 0; |
175 | unsigned long scanned = 0; | ||
172 | bool unlock; | 176 | bool unlock; |
173 | 177 | ||
174 | if (!shrinker_lock(dev_priv, &unlock)) | 178 | if (!shrinker_lock(dev_priv, &unlock)) |
@@ -249,6 +253,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
249 | count += obj->base.size >> PAGE_SHIFT; | 253 | count += obj->base.size >> PAGE_SHIFT; |
250 | } | 254 | } |
251 | mutex_unlock(&obj->mm.lock); | 255 | mutex_unlock(&obj->mm.lock); |
256 | scanned += obj->base.size >> PAGE_SHIFT; | ||
252 | } | 257 | } |
253 | } | 258 | } |
254 | list_splice_tail(&still_in_list, phase->list); | 259 | list_splice_tail(&still_in_list, phase->list); |
@@ -261,6 +266,8 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, | |||
261 | 266 | ||
262 | shrinker_unlock(dev_priv, unlock); | 267 | shrinker_unlock(dev_priv, unlock); |
263 | 268 | ||
269 | if (nr_scanned) | ||
270 | *nr_scanned += scanned; | ||
264 | return count; | 271 | return count; |
265 | } | 272 | } |
266 | 273 | ||
@@ -283,7 +290,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv) | |||
283 | unsigned long freed; | 290 | unsigned long freed; |
284 | 291 | ||
285 | intel_runtime_pm_get(dev_priv); | 292 | intel_runtime_pm_get(dev_priv); |
286 | freed = i915_gem_shrink(dev_priv, -1UL, | 293 | freed = i915_gem_shrink(dev_priv, -1UL, NULL, |
287 | I915_SHRINK_BOUND | | 294 | I915_SHRINK_BOUND | |
288 | I915_SHRINK_UNBOUND | | 295 | I915_SHRINK_UNBOUND | |
289 | I915_SHRINK_ACTIVE); | 296 | I915_SHRINK_ACTIVE); |
@@ -329,23 +336,28 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) | |||
329 | unsigned long freed; | 336 | unsigned long freed; |
330 | bool unlock; | 337 | bool unlock; |
331 | 338 | ||
339 | sc->nr_scanned = 0; | ||
340 | |||
332 | if (!shrinker_lock(dev_priv, &unlock)) | 341 | if (!shrinker_lock(dev_priv, &unlock)) |
333 | return SHRINK_STOP; | 342 | return SHRINK_STOP; |
334 | 343 | ||
335 | freed = i915_gem_shrink(dev_priv, | 344 | freed = i915_gem_shrink(dev_priv, |
336 | sc->nr_to_scan, | 345 | sc->nr_to_scan, |
346 | &sc->nr_scanned, | ||
337 | I915_SHRINK_BOUND | | 347 | I915_SHRINK_BOUND | |
338 | I915_SHRINK_UNBOUND | | 348 | I915_SHRINK_UNBOUND | |
339 | I915_SHRINK_PURGEABLE); | 349 | I915_SHRINK_PURGEABLE); |
340 | if (freed < sc->nr_to_scan) | 350 | if (freed < sc->nr_to_scan) |
341 | freed += i915_gem_shrink(dev_priv, | 351 | freed += i915_gem_shrink(dev_priv, |
342 | sc->nr_to_scan - freed, | 352 | sc->nr_to_scan - sc->nr_scanned, |
353 | &sc->nr_scanned, | ||
343 | I915_SHRINK_BOUND | | 354 | I915_SHRINK_BOUND | |
344 | I915_SHRINK_UNBOUND); | 355 | I915_SHRINK_UNBOUND); |
345 | if (freed < sc->nr_to_scan && current_is_kswapd()) { | 356 | if (freed < sc->nr_to_scan && current_is_kswapd()) { |
346 | intel_runtime_pm_get(dev_priv); | 357 | intel_runtime_pm_get(dev_priv); |
347 | freed += i915_gem_shrink(dev_priv, | 358 | freed += i915_gem_shrink(dev_priv, |
348 | sc->nr_to_scan - freed, | 359 | sc->nr_to_scan - sc->nr_scanned, |
360 | &sc->nr_scanned, | ||
349 | I915_SHRINK_ACTIVE | | 361 | I915_SHRINK_ACTIVE | |
350 | I915_SHRINK_BOUND | | 362 | I915_SHRINK_BOUND | |
351 | I915_SHRINK_UNBOUND); | 363 | I915_SHRINK_UNBOUND); |
@@ -354,7 +366,7 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) | |||
354 | 366 | ||
355 | shrinker_unlock(dev_priv, unlock); | 367 | shrinker_unlock(dev_priv, unlock); |
356 | 368 | ||
357 | return freed; | 369 | return sc->nr_scanned ? freed : SHRINK_STOP; |
358 | } | 370 | } |
359 | 371 | ||
360 | static bool | 372 | static bool |
@@ -453,7 +465,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr | |||
453 | goto out; | 465 | goto out; |
454 | 466 | ||
455 | intel_runtime_pm_get(dev_priv); | 467 | intel_runtime_pm_get(dev_priv); |
456 | freed_pages += i915_gem_shrink(dev_priv, -1UL, | 468 | freed_pages += i915_gem_shrink(dev_priv, -1UL, NULL, |
457 | I915_SHRINK_BOUND | | 469 | I915_SHRINK_BOUND | |
458 | I915_SHRINK_UNBOUND | | 470 | I915_SHRINK_UNBOUND | |
459 | I915_SHRINK_ACTIVE | | 471 | I915_SHRINK_ACTIVE | |
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index 14323faf8bd9..60491641a8d6 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c | |||
@@ -1241,8 +1241,10 @@ static int btt_rw_page(struct block_device *bdev, sector_t sector, | |||
1241 | { | 1241 | { |
1242 | struct btt *btt = bdev->bd_disk->private_data; | 1242 | struct btt *btt = bdev->bd_disk->private_data; |
1243 | int rc; | 1243 | int rc; |
1244 | unsigned int len; | ||
1244 | 1245 | ||
1245 | rc = btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector); | 1246 | len = hpage_nr_pages(page) * PAGE_SIZE; |
1247 | rc = btt_do_bvec(btt, NULL, page, len, 0, is_write, sector); | ||
1246 | if (rc == 0) | 1248 | if (rc == 0) |
1247 | page_endio(page, is_write, 0); | 1249 | page_endio(page, is_write, 0); |
1248 | 1250 | ||
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index f7099adaabc0..e9aa453da50c 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c | |||
@@ -80,22 +80,40 @@ static blk_status_t pmem_clear_poison(struct pmem_device *pmem, | |||
80 | static void write_pmem(void *pmem_addr, struct page *page, | 80 | static void write_pmem(void *pmem_addr, struct page *page, |
81 | unsigned int off, unsigned int len) | 81 | unsigned int off, unsigned int len) |
82 | { | 82 | { |
83 | void *mem = kmap_atomic(page); | 83 | unsigned int chunk; |
84 | 84 | void *mem; | |
85 | memcpy_flushcache(pmem_addr, mem + off, len); | 85 | |
86 | kunmap_atomic(mem); | 86 | while (len) { |
87 | mem = kmap_atomic(page); | ||
88 | chunk = min_t(unsigned int, len, PAGE_SIZE); | ||
89 | memcpy_flushcache(pmem_addr, mem + off, chunk); | ||
90 | kunmap_atomic(mem); | ||
91 | len -= chunk; | ||
92 | off = 0; | ||
93 | page++; | ||
94 | pmem_addr += PAGE_SIZE; | ||
95 | } | ||
87 | } | 96 | } |
88 | 97 | ||
89 | static blk_status_t read_pmem(struct page *page, unsigned int off, | 98 | static blk_status_t read_pmem(struct page *page, unsigned int off, |
90 | void *pmem_addr, unsigned int len) | 99 | void *pmem_addr, unsigned int len) |
91 | { | 100 | { |
101 | unsigned int chunk; | ||
92 | int rc; | 102 | int rc; |
93 | void *mem = kmap_atomic(page); | 103 | void *mem; |
94 | 104 | ||
95 | rc = memcpy_mcsafe(mem + off, pmem_addr, len); | 105 | while (len) { |
96 | kunmap_atomic(mem); | 106 | mem = kmap_atomic(page); |
97 | if (rc) | 107 | chunk = min_t(unsigned int, len, PAGE_SIZE); |
98 | return BLK_STS_IOERR; | 108 | rc = memcpy_mcsafe(mem + off, pmem_addr, chunk); |
109 | kunmap_atomic(mem); | ||
110 | if (rc) | ||
111 | return BLK_STS_IOERR; | ||
112 | len -= chunk; | ||
113 | off = 0; | ||
114 | page++; | ||
115 | pmem_addr += PAGE_SIZE; | ||
116 | } | ||
99 | return BLK_STS_OK; | 117 | return BLK_STS_OK; |
100 | } | 118 | } |
101 | 119 | ||
@@ -188,7 +206,8 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, | |||
188 | struct pmem_device *pmem = bdev->bd_queue->queuedata; | 206 | struct pmem_device *pmem = bdev->bd_queue->queuedata; |
189 | blk_status_t rc; | 207 | blk_status_t rc; |
190 | 208 | ||
191 | rc = pmem_do_bvec(pmem, page, PAGE_SIZE, 0, is_write, sector); | 209 | rc = pmem_do_bvec(pmem, page, hpage_nr_pages(page) * PAGE_SIZE, |
210 | 0, is_write, sector); | ||
192 | 211 | ||
193 | /* | 212 | /* |
194 | * The ->rw_page interface is subtle and tricky. The core | 213 | * The ->rw_page interface is subtle and tricky. The core |