aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/zram
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/zram')
-rw-r--r--drivers/block/zram/zram_drv.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 15e7b8e64cbb..9849b5233bf4 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -551,6 +551,47 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
551 return ret; 551 return ret;
552} 552}
553 553
554/*
555 * zram_bio_discard - handler on discard request
556 * @index: physical block index in PAGE_SIZE units
557 * @offset: byte offset within physical block
558 */
559static void zram_bio_discard(struct zram *zram, u32 index,
560 int offset, struct bio *bio)
561{
562 size_t n = bio->bi_iter.bi_size;
563
564 /*
565 * zram manages data in physical block size units. Because logical block
566 * size isn't identical with physical block size on some arch, we
567 * could get a discard request pointing to a specific offset within a
568 * certain physical block. Although we can handle this request by
569 * reading that physiclal block and decompressing and partially zeroing
570 * and re-compressing and then re-storing it, this isn't reasonable
571 * because our intent with a discard request is to save memory. So
572 * skipping this logical block is appropriate here.
573 */
574 if (offset) {
575 if (n < offset)
576 return;
577
578 n -= offset;
579 index++;
580 }
581
582 while (n >= PAGE_SIZE) {
583 /*
584 * Discard request can be large so the lock hold times could be
585 * lengthy. So take the lock once per page.
586 */
587 write_lock(&zram->meta->tb_lock);
588 zram_free_page(zram, index);
589 write_unlock(&zram->meta->tb_lock);
590 index++;
591 n -= PAGE_SIZE;
592 }
593}
594
554static void zram_reset_device(struct zram *zram, bool reset_capacity) 595static void zram_reset_device(struct zram *zram, bool reset_capacity)
555{ 596{
556 size_t index; 597 size_t index;
@@ -686,6 +727,12 @@ static void __zram_make_request(struct zram *zram, struct bio *bio)
686 offset = (bio->bi_iter.bi_sector & 727 offset = (bio->bi_iter.bi_sector &
687 (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT; 728 (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT;
688 729
730 if (unlikely(bio->bi_rw & REQ_DISCARD)) {
731 zram_bio_discard(zram, index, offset, bio);
732 bio_endio(bio, 0);
733 return;
734 }
735
689 bio_for_each_segment(bvec, bio, iter) { 736 bio_for_each_segment(bvec, bio, iter) {
690 int max_transfer_size = PAGE_SIZE - offset; 737 int max_transfer_size = PAGE_SIZE - offset;
691 738
@@ -855,6 +902,21 @@ static int create_device(struct zram *zram, int device_id)
855 ZRAM_LOGICAL_BLOCK_SIZE); 902 ZRAM_LOGICAL_BLOCK_SIZE);
856 blk_queue_io_min(zram->disk->queue, PAGE_SIZE); 903 blk_queue_io_min(zram->disk->queue, PAGE_SIZE);
857 blk_queue_io_opt(zram->disk->queue, PAGE_SIZE); 904 blk_queue_io_opt(zram->disk->queue, PAGE_SIZE);
905 zram->disk->queue->limits.discard_granularity = PAGE_SIZE;
906 zram->disk->queue->limits.max_discard_sectors = UINT_MAX;
907 /*
908 * zram_bio_discard() will clear all logical blocks if logical block
909 * size is identical with physical block size(PAGE_SIZE). But if it is
910 * different, we will skip discarding some parts of logical blocks in
911 * the part of the request range which isn't aligned to physical block
912 * size. So we can't ensure that all discarded logical blocks are
913 * zeroed.
914 */
915 if (ZRAM_LOGICAL_BLOCK_SIZE == PAGE_SIZE)
916 zram->disk->queue->limits.discard_zeroes_data = 1;
917 else
918 zram->disk->queue->limits.discard_zeroes_data = 0;
919 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zram->disk->queue);
858 920
859 add_disk(zram->disk); 921 add_disk(zram->disk);
860 922