Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 1 | /* |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 2 | * Compressed RAM block device |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 3 | * |
Nitin Gupta | 1130ebb | 2010-01-28 21:21:35 +0530 | [diff] [blame] | 4 | * Copyright (C) 2008, 2009, 2010 Nitin Gupta |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 5 | * |
| 6 | * This code is released using a dual license strategy: BSD/GPL |
| 7 | * You can choose the licence that better fits your requirements. |
| 8 | * |
| 9 | * Released under the terms of 3-clause BSD License |
| 10 | * Released under the terms of GNU General Public License Version 2.0 |
| 11 | * |
| 12 | * Project home: http://compcache.googlecode.com |
| 13 | */ |
| 14 | |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 15 | #ifndef _ZRAM_DRV_H_ |
| 16 | #define _ZRAM_DRV_H_ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 17 | |
Nitin Gupta | 6a90772 | 2010-01-28 21:13:37 +0530 | [diff] [blame] | 18 | #include <linux/spinlock.h> |
| 19 | #include <linux/mutex.h> |
| 20 | |
Nitin Gupta | fd1a30d | 2012-01-09 16:51:59 -0600 | [diff] [blame] | 21 | #include "../zsmalloc/zsmalloc.h" |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 22 | |
| 23 | /* |
| 24 | * Some arbitrary value. This is just to catch |
| 25 | * invalid value for num_devices module parameter. |
| 26 | */ |
| 27 | static const unsigned max_num_devices = 32; |
| 28 | |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 29 | /*-- Configurable parameters */ |
| 30 | |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 31 | /* |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 32 | * Pages that compress to size greater than this are stored |
| 33 | * uncompressed in memory. |
| 34 | */ |
Nitin Gupta | 2ccbec0 | 2011-09-09 19:01:00 -0400 | [diff] [blame] | 35 | static const size_t max_zpage_size = PAGE_SIZE / 4 * 3; |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 36 | |
| 37 | /* |
Nitin Gupta | 97a0638 | 2010-05-13 14:24:21 +0530 | [diff] [blame] | 38 | * NOTE: max_zpage_size must be less than or equal to: |
Minchan Kim | 55dcbbb | 2012-10-10 08:49:52 +0900 | [diff] [blame] | 39 | * ZS_MAX_ALLOC_SIZE. Otherwise, zs_malloc() would |
| 40 | * always return failure. |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 41 | */ |
| 42 | |
| 43 | /*-- End of configurable params */ |
| 44 | |
| 45 | #define SECTOR_SHIFT 9 |
| 46 | #define SECTOR_SIZE (1 << SECTOR_SHIFT) |
| 47 | #define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) |
| 48 | #define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) |
Jerome Marchand | 924bd88 | 2011-06-10 15:28:48 +0200 | [diff] [blame] | 49 | #define ZRAM_LOGICAL_BLOCK_SHIFT 12 |
| 50 | #define ZRAM_LOGICAL_BLOCK_SIZE (1 << ZRAM_LOGICAL_BLOCK_SHIFT) |
| 51 | #define ZRAM_SECTOR_PER_LOGICAL_BLOCK \ |
| 52 | (1 << (ZRAM_LOGICAL_BLOCK_SHIFT - SECTOR_SHIFT)) |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 53 | |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 54 | /* Flags for zram pages (table[page_no].flags) */ |
| 55 | enum zram_pageflags { |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 56 | /* Page consists entirely of zeros */ |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 57 | ZRAM_ZERO, |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 58 | |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 59 | __NR_ZRAM_PAGEFLAGS, |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 60 | }; |
| 61 | |
| 62 | /*-- Data structures */ |
| 63 | |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 64 | /* Allocated for each disk page */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 65 | struct table { |
Minchan Kim | c234434 | 2012-06-08 15:39:25 +0900 | [diff] [blame] | 66 | unsigned long handle; |
Nitin Gupta | fd1a30d | 2012-01-09 16:51:59 -0600 | [diff] [blame] | 67 | u16 size; /* object size (excluding header) */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 68 | u8 count; /* object ref count (not yet used) */ |
| 69 | u8 flags; |
Sam Hansen | 80677c2 | 2012-06-07 16:03:48 -0700 | [diff] [blame] | 70 | } __aligned(4); |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 71 | |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 72 | struct zram_stats { |
Nitin Gupta | 33863c2 | 2010-08-09 22:56:47 +0530 | [diff] [blame] | 73 | u64 compr_size; /* compressed size of pages stored */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 74 | u64 num_reads; /* failed + successful */ |
| 75 | u64 num_writes; /* --do-- */ |
C yp | ef4ffb7 | 2010-01-06 13:42:00 +0100 | [diff] [blame] | 76 | u64 failed_reads; /* should NEVER! happen */ |
| 77 | u64 failed_writes; /* can happen when memory is too low */ |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 78 | u64 invalid_io; /* non-page-aligned I/O requests */ |
Nitin Gupta | 6a90772 | 2010-01-28 21:13:37 +0530 | [diff] [blame] | 79 | u64 notify_free; /* no. of swap slot free notifications */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 80 | u32 pages_zero; /* no. of zero filled pages */ |
| 81 | u32 pages_stored; /* no. of pages currently stored */ |
| 82 | u32 good_compress; /* % of pages with compression ratio<=50% */ |
Minchan Kim | 130f315 | 2012-06-08 15:39:27 +0900 | [diff] [blame] | 83 | u32 bad_compress; /* % of pages with compression ratio>=75% */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 84 | }; |
| 85 | |
Minchan Kim | 8b3cc3e | 2013-02-06 08:48:53 +0900 | [diff] [blame] | 86 | struct zram_meta { |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 87 | void *compress_workmem; |
| 88 | void *compress_buffer; |
| 89 | struct table *table; |
Minchan Kim | 8b3cc3e | 2013-02-06 08:48:53 +0900 | [diff] [blame] | 90 | struct zs_pool *mem_pool; |
| 91 | }; |
| 92 | |
| 93 | struct zram { |
| 94 | struct zram_meta *meta; |
Nitin Gupta | 6a90772 | 2010-01-28 21:13:37 +0530 | [diff] [blame] | 95 | spinlock_t stat64_lock; /* protect 64-bit stats */ |
Jiang Liu | 57ab048 | 2013-06-07 00:07:23 +0800 | [diff] [blame^] | 96 | struct rw_semaphore lock; /* protect compression buffers, table, |
| 97 | * 32bit stat counters against concurrent |
| 98 | * notifications, reads and writes */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 99 | struct request_queue *queue; |
| 100 | struct gendisk *disk; |
| 101 | int init_done; |
Jerome Marchand | 0900bea | 2011-09-06 15:02:11 +0200 | [diff] [blame] | 102 | /* Prevent concurrent execution of device init, reset and R/W request */ |
| 103 | struct rw_semaphore init_lock; |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 104 | /* |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 105 | * This is the limit on amount of *uncompressed* worth of data |
| 106 | * we can store in a disk. |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 107 | */ |
Nitin Gupta | 33863c2 | 2010-08-09 22:56:47 +0530 | [diff] [blame] | 108 | u64 disksize; /* bytes */ |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 109 | |
Nitin Gupta | f1e3cff | 2010-06-01 13:31:25 +0530 | [diff] [blame] | 110 | struct zram_stats stats; |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 111 | }; |
| 112 | |
Noah Watkins | 43801f6 | 2011-07-20 17:05:57 -0600 | [diff] [blame] | 113 | extern struct zram *zram_devices; |
Nitin Gupta | 5fa5a90 | 2012-02-12 23:04:45 -0500 | [diff] [blame] | 114 | unsigned int zram_get_num_devices(void); |
Nitin Gupta | 33863c2 | 2010-08-09 22:56:47 +0530 | [diff] [blame] | 115 | #ifdef CONFIG_SYSFS |
| 116 | extern struct attribute_group zram_disk_attr_group; |
| 117 | #endif |
Nitin Gupta | 306b0c9 | 2009-09-22 10:26:53 +0530 | [diff] [blame] | 118 | |
Minchan Kim | 0231c40 | 2013-01-30 11:41:40 +0900 | [diff] [blame] | 119 | extern void zram_reset_device(struct zram *zram); |
Minchan Kim | 8b3cc3e | 2013-02-06 08:48:53 +0900 | [diff] [blame] | 120 | extern struct zram_meta *zram_meta_alloc(u64 disksize); |
| 121 | extern void zram_meta_free(struct zram_meta *meta); |
| 122 | extern void zram_init_device(struct zram *zram, struct zram_meta *meta); |
Nitin Gupta | 6a90772 | 2010-01-28 21:13:37 +0530 | [diff] [blame] | 123 | |
| 124 | #endif |