diff options
Diffstat (limited to 'drivers/staging/zram/zram_drv.c')
-rw-r--r-- | drivers/staging/zram/zram_drv.c | 104 |
1 files changed, 12 insertions, 92 deletions
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 0cdc303..2036a90 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -136,6 +136,7 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes) static void zram_free_page(struct zram *zram, size_t index) { unsigned long handle = zram->table[index].handle; + u16 size = zram->table[index].size; if (unlikely(!handle)) { /* @@ -149,19 +150,14 @@ static void zram_free_page(struct zram *zram, size_t index) return; } - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - __free_page((struct page *)handle); - zram_clear_flag(zram, index, ZRAM_UNCOMPRESSED); - zram_stat_dec(&zram->stats.pages_expand); - goto out; - } + if (unlikely(size > max_zpage_size)) + zram_stat_dec(&zram->stats.bad_compress); zs_free(zram->mem_pool, handle); - if (zram->table[index].size <= PAGE_SIZE / 2) + if (size <= PAGE_SIZE / 2) zram_stat_dec(&zram->stats.good_compress); -out: zram_stat64_sub(zram, &zram->stats.compr_size, zram->table[index].size); zram_stat_dec(&zram->stats.pages_stored); @@ -182,22 +178,6 @@ static void handle_zero_page(struct bio_vec *bvec) flush_dcache_page(page); } -static void handle_uncompressed_page(struct zram *zram, struct bio_vec *bvec, - u32 index, int offset) -{ - struct page *page = bvec->bv_page; - unsigned char *user_mem, *cmem; - - user_mem = kmap_atomic(page); - cmem = kmap_atomic((struct page *)zram->table[index].handle); - - memcpy(user_mem + bvec->bv_offset, cmem + offset, bvec->bv_len); - kunmap_atomic(cmem); - kunmap_atomic(user_mem); - - flush_dcache_page(page); -} - static inline int is_partial_io(struct bio_vec *bvec) { return bvec->bv_len != PAGE_SIZE; @@ -209,7 +189,6 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, int ret; size_t clen; struct page *page; - struct zobj_header *zheader; unsigned char *user_mem, *cmem, *uncmem = NULL; page = bvec->bv_page; @@ -227,12 +206,6 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, return 0; } - /* Page is stored uncompressed since it's incompressible */ - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - handle_uncompressed_page(zram, bvec, index, offset); - return 0; - } - if (is_partial_io(bvec)) { /* Use a temporary buffer to decompress the page */ uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); @@ -249,8 +222,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, cmem = zs_map_object(zram->mem_pool, zram->table[index].handle); - ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), - zram->table[index].size, + ret = lzo1x_decompress_safe(cmem, zram->table[index].size, uncmem, &clen); if (is_partial_io(bvec)) { @@ -278,7 +250,6 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) { int ret; size_t clen = PAGE_SIZE; - struct zobj_header *zheader; unsigned char *cmem; unsigned long handle = zram->table[index].handle; @@ -287,18 +258,8 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index) return 0; } - /* Page is stored uncompressed since it's incompressible */ - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - char *src = kmap_atomic((struct page *)handle); - memcpy(mem, src, PAGE_SIZE); - kunmap_atomic(src); - return 0; - } - cmem = zs_map_object(zram->mem_pool, handle); - - ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), - zram->table[index].size, + ret = lzo1x_decompress_safe(cmem, zram->table[index].size, mem, &clen); zs_unmap_object(zram->mem_pool, handle); @@ -316,11 +277,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, int offset) { int ret; - u32 store_offset; size_t clen; unsigned long handle; - struct zobj_header *zheader; - struct page *page, *page_store; + struct page *page; unsigned char *user_mem, *cmem, *src, *uncmem = NULL; page = bvec->bv_page; @@ -382,31 +341,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, goto out; } - /* - * Page is incompressible. Store it as-is (uncompressed) - * since we do not want to return too many disk write - * errors which has side effect of hanging the system. - */ - if (unlikely(clen > max_zpage_size)) { - clen = PAGE_SIZE; - page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM); - if (unlikely(!page_store)) { - pr_info("Error allocating memory for " - "incompressible page: %u\n", index); - ret = -ENOMEM; - goto out; - } + if (unlikely(clen > max_zpage_size)) + zram_stat_inc(&zram->stats.bad_compress); - store_offset = 0; - zram_set_flag(zram, index, ZRAM_UNCOMPRESSED); - zram_stat_inc(&zram->stats.pages_expand); - handle = (unsigned long)page_store; - src = kmap_atomic(page); - cmem = kmap_atomic(page_store); - goto memstore; - } - - handle = zs_malloc(zram->mem_pool, clen + sizeof(*zheader)); + handle = zs_malloc(zram->mem_pool, clen); if (!handle) { pr_info("Error allocating memory for compressed " "page: %u, size=%zu\n", index, clen); @@ -415,24 +353,9 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, } cmem = zs_map_object(zram->mem_pool, handle); -memstore: -#if 0 - /* Back-reference needed for memory defragmentation */ - if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) { - zheader = (struct zobj_header *)cmem; - zheader->table_idx = index; - cmem += sizeof(*zheader); - } -#endif - memcpy(cmem, src, clen); - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - kunmap_atomic(cmem); - kunmap_atomic(src); - } else { - zs_unmap_object(zram->mem_pool, handle); - } + zs_unmap_object(zram->mem_pool, handle); zram->table[index].handle = handle; zram->table[index].size = clen; @@ -597,10 +520,7 @@ void __zram_reset_device(struct zram *zram) if (!handle) continue; - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) - __free_page((struct page *)handle); - else - zs_free(zram->mem_pool, handle); + zs_free(zram->mem_pool, handle); } vfree(zram->table); |