~ubuntu-branches/ubuntu/trusty/linux-ti-omap/trusty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * Compressed RAM based swap device
 *
 * Copyright (C) 2008, 2009  Nitin Gupta
 *
 * This RAM based block device acts as swap disk.
 * Pages swapped to this device are compressed and
 * stored in memory.
 *
 * Released under the terms of GNU General Public License Version 2.0
 *
 * Project home: http://compcache.googlecode.com
 */

#ifndef _RAMZSWAP_H_
#define _RAMZSWAP_H_

#include "xvmalloc.h"

/*
 * Stored at beginning of each compressed object.
 *
 * It stores back-reference to table entry which points to this
 * object. This is required to support memory defragmentation or
 * migrating compressed pages to backing swap disk.
 */
struct zobj_header {
#if 0
	u32 table_idx;
#endif
};

/*-- Configurable parameters */

/* Default ramzswap disk size: 25% of total RAM */
#define DEFAULT_DISKSIZE_PERC_RAM	25
#define DEFAULT_MEMLIMIT_PERC_RAM	15

/*
 * Max compressed page size when backing device is provided.
 * Pages that compress to size greater than this are sent to
 * physical swap disk.
 */
#define MAX_CPAGE_SIZE_BDEV	(PAGE_SIZE / 2)

/*
 * Max compressed page size when there is no backing dev.
 * Pages that compress to size greater than this are stored
 * uncompressed in memory.
 */
#define MAX_CPAGE_SIZE_NOBDEV	(PAGE_SIZE / 4 * 3)

/*
 * NOTE: MAX_CPAGE_SIZE_{BDEV,NOBDEV} sizes must be
 * less than or equal to:
 *   XV_MAX_ALLOC_SIZE - sizeof(struct zobj_header)
 * since otherwise xvMalloc would always return failure.
 */

/*-- End of configurable params */

#define SECTOR_SHIFT		9
#define SECTOR_SIZE		(1 << SECTOR_SHIFT)
#define SECTORS_PER_PAGE_SHIFT	(PAGE_SHIFT - SECTOR_SHIFT)
#define SECTORS_PER_PAGE	(1 << SECTORS_PER_PAGE_SHIFT)

/* Message prefix */
#define C "ramzswap: "

/* Debugging and Stats */
#define NOP	do { } while (0)

#if defined(CONFIG_BLK_DEV_RAMZSWAP_STATS)
#define STATS
#endif

#if defined(STATS)
#define stat_inc(stat)			((stat)++)
#define stat_dec(stat)			((stat)--)
#define stat_inc_if_less(stat, val1, val2) \
				((stat) += ((val1) < (val2) ? 1 : 0))
#define stat_dec_if_less(stat, val1, val2) \
				((stat) -= ((val1) < (val2) ? 1 : 0))
#else	/* STATS */
#define stat_inc(x)			NOP
#define stat_dec(x)			NOP
#define stat_inc_if_less(x, v1, v2)	NOP
#define stat_dec_if_less(x, v1, v2)	NOP
#endif	/* STATS */

/* Flags for ramzswap pages (table[page_no].flags) */
enum rzs_pageflags {
	/* Page is stored uncompressed */
	RZS_UNCOMPRESSED,

	/* Page consists entirely of zeros */
	RZS_ZERO,

	__NR_RZS_PAGEFLAGS,
};

/*-- Data structures */

/* Indexed by page no. */
struct table {
	u32 pagenum;
	u16 offset;
	u8 count;	/* object ref count (not yet used) */
	u8 flags;
};

struct ramzswap {
	struct xv_pool *mem_pool;
	void *compress_workmem;
	void *compress_buffer;
	struct table *table;
	struct mutex lock;
	struct gendisk *disk;
	/*
	 * This is limit on compressed data size (stats.compr_size)
	 * Its applicable only when backing swap device is present.
	 */
	size_t memlimit;	/* bytes */
	/*
	 * This is limit on amount of *uncompressed* worth of data
	 * we can hold. When backing swap device is provided, it is
	 * set equal to device size.
	 */
	size_t disksize;	/* bytes */

	/* backing swap device info */
	struct block_device *backing_swap;
	struct file *swap_file;
	int old_block_size;
};

struct ramzswap_stats {
	/* basic stats */
	size_t compr_size;	/* compressed size of pages stored -
				 * needed to enforce memlimit */
	/* more stats */
#if defined(STATS)
	u64 num_reads;		/* failed + successful */
	u64 num_writes;		/* --do-- */
	u64 failed_reads;	/* can happen when memory is too low */
	u64 failed_writes;	/* should NEVER! happen */
	u64 invalid_io;		/* non-swap I/O requests */
	u64 pages_discard;	/* no. of pages freed by discard callback */
	u32 pages_zero;		/* no. of zero filled pages */
	u32 pages_stored;	/* no. of pages currently stored */
	u32 good_compress;	/* no. of pages with compression ratio<=50% */
	u32 pages_expand;	/* no. of incompressible pages */
	u64 bdev_num_reads;	/* no. of reads on backing dev */
	u64 bdev_num_writes;	/* no. of writes on backing dev */
#endif
};
/*-- */

#endif