Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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