Based on kernel version 3.4. Page generated on 2012-05-21 22:13 EST.
1 MOTIVATION 2 3 Cleancache is a new optional feature provided by the VFS layer that 4 potentially dramatically increases page cache effectiveness for 5 many workloads in many environments at a negligible cost. 6 7 Cleancache can be thought of as a page-granularity victim cache for clean 8 pages that the kernel's pageframe replacement algorithm (PFRA) would like 9 to keep around, but can't since there isn't enough memory. So when the 10 PFRA "evicts" a page, it first attempts to use cleancache code to 11 put the data contained in that page into "transcendent memory", memory 12 that is not directly accessible or addressable by the kernel and is 13 of unknown and possibly time-varying size. 14 15 Later, when a cleancache-enabled filesystem wishes to access a page 16 in a file on disk, it first checks cleancache to see if it already 17 contains it; if it does, the page of data is copied into the kernel 18 and a disk access is avoided. 19 20 Transcendent memory "drivers" for cleancache are currently implemented 21 in Xen (using hypervisor memory) and zcache (using in-kernel compressed 22 memory) and other implementations are in development. 23 24 FAQs are included below. 25 26 IMPLEMENTATION OVERVIEW 27 28 A cleancache "backend" that provides transcendent memory registers itself 29 to the kernel's cleancache "frontend" by calling cleancache_register_ops, 30 passing a pointer to a cleancache_ops structure with funcs set appropriately. 31 Note that cleancache_register_ops returns the previous settings so that 32 chaining can be performed if desired. The functions provided must conform to 33 certain semantics as follows: 34 35 Most important, cleancache is "ephemeral". Pages which are copied into 36 cleancache have an indefinite lifetime which is completely unknowable 37 by the kernel and so may or may not still be in cleancache at any later time. 38 Thus, as its name implies, cleancache is not suitable for dirty pages. 39 Cleancache has complete discretion over what pages to preserve and what 40 pages to discard and when. 41 42 Mounting a cleancache-enabled filesystem should call "init_fs" to obtain a 43 pool id which, if positive, must be saved in the filesystem's superblock; 44 a negative return value indicates failure. A "put_page" will copy a 45 (presumably about-to-be-evicted) page into cleancache and associate it with 46 the pool id, a file key, and a page index into the file. (The combination 47 of a pool id, a file key, and an index is sometimes called a "handle".) 48 A "get_page" will copy the page, if found, from cleancache into kernel memory. 49 An "invalidate_page" will ensure the page no longer is present in cleancache; 50 an "invalidate_inode" will invalidate all pages associated with the specified 51 file; and, when a filesystem is unmounted, an "invalidate_fs" will invalidate 52 all pages in all files specified by the given pool id and also surrender 53 the pool id. 54 55 An "init_shared_fs", like init_fs, obtains a pool id but tells cleancache 56 to treat the pool as shared using a 128-bit UUID as a key. On systems 57 that may run multiple kernels (such as hard partitioned or virtualized 58 systems) that may share a clustered filesystem, and where cleancache 59 may be shared among those kernels, calls to init_shared_fs that specify the 60 same UUID will receive the same pool id, thus allowing the pages to 61 be shared. Note that any security requirements must be imposed outside 62 of the kernel (e.g. by "tools" that control cleancache). Or a 63 cleancache implementation can simply disable shared_init by always 64 returning a negative value. 65 66 If a get_page is successful on a non-shared pool, the page is invalidated 67 (thus making cleancache an "exclusive" cache). On a shared pool, the page 68 is NOT invalidated on a successful get_page so that it remains accessible to 69 other sharers. The kernel is responsible for ensuring coherency between 70 cleancache (shared or not), the page cache, and the filesystem, using 71 cleancache invalidate operations as required. 72 73 Note that cleancache must enforce put-put-get coherency and get-get 74 coherency. For the former, if two puts are made to the same handle but 75 with different data, say AAA by the first put and BBB by the second, a 76 subsequent get can never return the stale data (AAA). For get-get coherency, 77 if a get for a given handle fails, subsequent gets for that handle will 78 never succeed unless preceded by a successful put with that handle. 79 80 Last, cleancache provides no SMP serialization guarantees; if two 81 different Linux threads are simultaneously putting and invalidating a page 82 with the same handle, the results are indeterminate. Callers must 83 lock the page to ensure serial behavior. 84 85 CLEANCACHE PERFORMANCE METRICS 86 87 If properly configured, monitoring of cleancache is done via debugfs in 88 the /sys/kernel/debug/mm/cleancache directory. The effectiveness of cleancache 89 can be measured (across all filesystems) with: 90 91 succ_gets - number of gets that were successful 92 failed_gets - number of gets that failed 93 puts - number of puts attempted (all "succeed") 94 invalidates - number of invalidates attempted 95 96 A backend implementation may provide additional metrics. 97 98 FAQ 99 100 1) Where's the value? (Andrew Morton) 101 102 Cleancache provides a significant performance benefit to many workloads 103 in many environments with negligible overhead by improving the 104 effectiveness of the pagecache. Clean pagecache pages are 105 saved in transcendent memory (RAM that is otherwise not directly 106 addressable to the kernel); fetching those pages later avoids "refaults" 107 and thus disk reads. 108 109 Cleancache (and its sister code "frontswap") provide interfaces for 110 this transcendent memory (aka "tmem"), which conceptually lies between 111 fast kernel-directly-addressable RAM and slower DMA/asynchronous devices. 112 Disallowing direct kernel or userland reads/writes to tmem 113 is ideal when data is transformed to a different form and size (such 114 as with compression) or secretly moved (as might be useful for write- 115 balancing for some RAM-like devices). Evicted page-cache pages (and 116 swap pages) are a great use for this kind of slower-than-RAM-but-much- 117 faster-than-disk transcendent memory, and the cleancache (and frontswap) 118 "page-object-oriented" specification provides a nice way to read and 119 write -- and indirectly "name" -- the pages. 120 121 In the virtual case, the whole point of virtualization is to statistically 122 multiplex physical resources across the varying demands of multiple 123 virtual machines. This is really hard to do with RAM and efforts to 124 do it well with no kernel change have essentially failed (except in some 125 well-publicized special-case workloads). Cleancache -- and frontswap -- 126 with a fairly small impact on the kernel, provide a huge amount 127 of flexibility for more dynamic, flexible RAM multiplexing. 128 Specifically, the Xen Transcendent Memory backend allows otherwise 129 "fallow" hypervisor-owned RAM to not only be "time-shared" between multiple 130 virtual machines, but the pages can be compressed and deduplicated to 131 optimize RAM utilization. And when guest OS's are induced to surrender 132 underutilized RAM (e.g. with "self-ballooning"), page cache pages 133 are the first to go, and cleancache allows those pages to be 134 saved and reclaimed if overall host system memory conditions allow. 135 136 And the identical interface used for cleancache can be used in 137 physical systems as well. The zcache driver acts as a memory-hungry 138 device that stores pages of data in a compressed state. And 139 the proposed "RAMster" driver shares RAM across multiple physical 140 systems. 141 142 2) Why does cleancache have its sticky fingers so deep inside the 143 filesystems and VFS? (Andrew Morton and Christoph Hellwig) 144 145 The core hooks for cleancache in VFS are in most cases a single line 146 and the minimum set are placed precisely where needed to maintain 147 coherency (via cleancache_invalidate operations) between cleancache, 148 the page cache, and disk. All hooks compile into nothingness if 149 cleancache is config'ed off and turn into a function-pointer- 150 compare-to-NULL if config'ed on but no backend claims the ops 151 functions, or to a compare-struct-element-to-negative if a 152 backend claims the ops functions but a filesystem doesn't enable 153 cleancache. 154 155 Some filesystems are built entirely on top of VFS and the hooks 156 in VFS are sufficient, so don't require an "init_fs" hook; the 157 initial implementation of cleancache didn't provide this hook. 158 But for some filesystems (such as btrfs), the VFS hooks are 159 incomplete and one or more hooks in fs-specific code are required. 160 And for some other filesystems, such as tmpfs, cleancache may 161 be counterproductive. So it seemed prudent to require a filesystem 162 to "opt in" to use cleancache, which requires adding a hook in 163 each filesystem. Not all filesystems are supported by cleancache 164 only because they haven't been tested. The existing set should 165 be sufficient to validate the concept, the opt-in approach means 166 that untested filesystems are not affected, and the hooks in the 167 existing filesystems should make it very easy to add more 168 filesystems in the future. 169 170 The total impact of the hooks to existing fs and mm files is only 171 about 40 lines added (not counting comments and blank lines). 172 173 3) Why not make cleancache asynchronous and batched so it can 174 more easily interface with real devices with DMA instead 175 of copying each individual page? (Minchan Kim) 176 177 The one-page-at-a-time copy semantics simplifies the implementation 178 on both the frontend and backend and also allows the backend to 179 do fancy things on-the-fly like page compression and 180 page deduplication. And since the data is "gone" (copied into/out 181 of the pageframe) before the cleancache get/put call returns, 182 a great deal of race conditions and potential coherency issues 183 are avoided. While the interface seems odd for a "real device" 184 or for real kernel-addressable RAM, it makes perfect sense for 185 transcendent memory. 186 187 4) Why is non-shared cleancache "exclusive"? And where is the 188 page "invalidated" after a "get"? (Minchan Kim) 189 190 The main reason is to free up space in transcendent memory and 191 to avoid unnecessary cleancache_invalidate calls. If you want inclusive, 192 the page can be "put" immediately following the "get". If 193 put-after-get for inclusive becomes common, the interface could 194 be easily extended to add a "get_no_invalidate" call. 195 196 The invalidate is done by the cleancache backend implementation. 197 198 5) What's the performance impact? 199 200 Performance analysis has been presented at OLS'09 and LCA'10. 201 Briefly, performance gains can be significant on most workloads, 202 especially when memory pressure is high (e.g. when RAM is 203 overcommitted in a virtual workload); and because the hooks are 204 invoked primarily in place of or in addition to a disk read/write, 205 overhead is negligible even in worst case workloads. Basically 206 cleancache replaces I/O with memory-copy-CPU-overhead; on older 207 single-core systems with slow memory-copy speeds, cleancache 208 has little value, but in newer multicore machines, especially 209 consolidated/virtualized machines, it has great value. 210 211 6) How do I add cleancache support for filesystem X? (Boaz Harrash) 212 213 Filesystems that are well-behaved and conform to certain 214 restrictions can utilize cleancache simply by making a call to 215 cleancache_init_fs at mount time. Unusual, misbehaving, or 216 poorly layered filesystems must either add additional hooks 217 and/or undergo extensive additional testing... or should just 218 not enable the optional cleancache. 219 220 Some points for a filesystem to consider: 221 222 - The FS should be block-device-based (e.g. a ram-based FS such 223 as tmpfs should not enable cleancache) 224 - To ensure coherency/correctness, the FS must ensure that all 225 file removal or truncation operations either go through VFS or 226 add hooks to do the equivalent cleancache "invalidate" operations 227 - To ensure coherency/correctness, either inode numbers must 228 be unique across the lifetime of the on-disk file OR the 229 FS must provide an "encode_fh" function. 230 - The FS must call the VFS superblock alloc and deactivate routines 231 or add hooks to do the equivalent cleancache calls done there. 232 - To maximize performance, all pages fetched from the FS should 233 go through the do_mpag_readpage routine or the FS should add 234 hooks to do the equivalent (cf. btrfs) 235 - Currently, the FS blocksize must be the same as PAGESIZE. This 236 is not an architectural restriction, but no backends currently 237 support anything different. 238 - A clustered FS should invoke the "shared_init_fs" cleancache 239 hook to get best performance for some backends. 240 241 7) Why not use the KVA of the inode as the key? (Christoph Hellwig) 242 243 If cleancache would use the inode virtual address instead of 244 inode/filehandle, the pool id could be eliminated. But, this 245 won't work because cleancache retains pagecache data pages 246 persistently even when the inode has been pruned from the 247 inode unused list, and only invalidates the data page if the file 248 gets removed/truncated. So if cleancache used the inode kva, 249 there would be potential coherency issues if/when the inode 250 kva is reused for a different file. Alternately, if cleancache 251 invalidated the pages when the inode kva was freed, much of the value 252 of cleancache would be lost because the cache of pages in cleanache 253 is potentially much larger than the kernel pagecache and is most 254 useful if the pages survive inode cache removal. 255 256 8) Why is a global variable required? 257 258 The cleancache_enabled flag is checked in all of the frequently-used 259 cleancache hooks. The alternative is a function call to check a static 260 variable. Since cleancache is enabled dynamically at runtime, systems 261 that don't enable cleancache would suffer thousands (possibly 262 tens-of-thousands) of unnecessary function calls per second. So the 263 global variable allows cleancache to be enabled by default at compile 264 time, but have insignificant performance impact when cleancache remains 265 disabled at runtime. 266 267 9) Does cleanache work with KVM? 268 269 The memory model of KVM is sufficiently different that a cleancache 270 backend may have less value for KVM. This remains to be tested, 271 especially in an overcommitted system. 272 273 10) Does cleancache work in userspace? It sounds useful for 274 memory hungry caches like web browsers. (Jamie Lokier) 275 276 No plans yet, though we agree it sounds useful, at least for 277 apps that bypass the page cache (e.g. O_DIRECT). 278 279 Last updated: Dan Magenheimer, April 13 2011