• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _frontswap:
2
3=========
4Frontswap
5=========
6
7Frontswap provides a "transcendent memory" interface for swap pages.
8In some environments, dramatic performance savings may be obtained because
9swapped pages are saved in RAM (or a RAM-like device) instead of a swap disk.
10
11(Note, frontswap -- and :ref:`cleancache` (merged at 3.0) -- are the "frontends"
12and the only necessary changes to the core kernel for transcendent memory;
13all other supporting code -- the "backends" -- is implemented as drivers.
14See the LWN.net article `Transcendent memory in a nutshell`_
15for a detailed overview of frontswap and related kernel parts)
16
17.. _Transcendent memory in a nutshell: https://lwn.net/Articles/454795/
18
19Frontswap is so named because it can be thought of as the opposite of
20a "backing" store for a swap device.  The storage is assumed to be
21a synchronous concurrency-safe page-oriented "pseudo-RAM device" conforming
22to the requirements of transcendent memory (such as Xen's "tmem", or
23in-kernel compressed memory, aka "zcache", or future RAM-like devices);
24this pseudo-RAM device is not directly accessible or addressable by the
25kernel and is of unknown and possibly time-varying size.  The driver
26links itself to frontswap by calling frontswap_register_ops to set the
27frontswap_ops funcs appropriately and the functions it provides must
28conform to certain policies as follows:
29
30An "init" prepares the device to receive frontswap pages associated
31with the specified swap device number (aka "type").  A "store" will
32copy the page to transcendent memory and associate it with the type and
33offset associated with the page. A "load" will copy the page, if found,
34from transcendent memory into kernel memory, but will NOT remove the page
35from transcendent memory.  An "invalidate_page" will remove the page
36from transcendent memory and an "invalidate_area" will remove ALL pages
37associated with the swap type (e.g., like swapoff) and notify the "device"
38to refuse further stores with that swap type.
39
40Once a page is successfully stored, a matching load on the page will normally
41succeed.  So when the kernel finds itself in a situation where it needs
42to swap out a page, it first attempts to use frontswap.  If the store returns
43success, the data has been successfully saved to transcendent memory and
44a disk write and, if the data is later read back, a disk read are avoided.
45If a store returns failure, transcendent memory has rejected the data, and the
46page can be written to swap as usual.
47
48Note that if a page is stored and the page already exists in transcendent memory
49(a "duplicate" store), either the store succeeds and the data is overwritten,
50or the store fails AND the page is invalidated.  This ensures stale data may
51never be obtained from frontswap.
52
53If properly configured, monitoring of frontswap is done via debugfs in
54the `/sys/kernel/debug/frontswap` directory.  The effectiveness of
55frontswap can be measured (across all swap devices) with:
56
57``failed_stores``
58	how many store attempts have failed
59
60``loads``
61	how many loads were attempted (all should succeed)
62
63``succ_stores``
64	how many store attempts have succeeded
65
66``invalidates``
67	how many invalidates were attempted
68
69A backend implementation may provide additional metrics.
70
71FAQ
72===
73
74* Where's the value?
75
76When a workload starts swapping, performance falls through the floor.
77Frontswap significantly increases performance in many such workloads by
78providing a clean, dynamic interface to read and write swap pages to
79"transcendent memory" that is otherwise not directly addressable to the kernel.
80This interface is ideal when data is transformed to a different form
81and size (such as with compression) or secretly moved (as might be
82useful for write-balancing for some RAM-like devices).  Swap pages (and
83evicted page-cache pages) are a great use for this kind of slower-than-RAM-
84but-much-faster-than-disk "pseudo-RAM device" and the frontswap (and
85cleancache) interface to transcendent memory provides a nice way to read
86and write -- and indirectly "name" -- the pages.
87
88Frontswap -- and cleancache -- with a fairly small impact on the kernel,
89provides a huge amount of flexibility for more dynamic, flexible RAM
90utilization in various system configurations:
91
92In the single kernel case, aka "zcache", pages are compressed and
93stored in local memory, thus increasing the total anonymous pages
94that can be safely kept in RAM.  Zcache essentially trades off CPU
95cycles used in compression/decompression for better memory utilization.
96Benchmarks have shown little or no impact when memory pressure is
97low while providing a significant performance improvement (25%+)
98on some workloads under high memory pressure.
99
100"RAMster" builds on zcache by adding "peer-to-peer" transcendent memory
101support for clustered systems.  Frontswap pages are locally compressed
102as in zcache, but then "remotified" to another system's RAM.  This
103allows RAM to be dynamically load-balanced back-and-forth as needed,
104i.e. when system A is overcommitted, it can swap to system B, and
105vice versa.  RAMster can also be configured as a memory server so
106many servers in a cluster can swap, dynamically as needed, to a single
107server configured with a large amount of RAM... without pre-configuring
108how much of the RAM is available for each of the clients!
109
110In the virtual case, the whole point of virtualization is to statistically
111multiplex physical resources across the varying demands of multiple
112virtual machines.  This is really hard to do with RAM and efforts to do
113it well with no kernel changes have essentially failed (except in some
114well-publicized special-case workloads).
115Specifically, the Xen Transcendent Memory backend allows otherwise
116"fallow" hypervisor-owned RAM to not only be "time-shared" between multiple
117virtual machines, but the pages can be compressed and deduplicated to
118optimize RAM utilization.  And when guest OS's are induced to surrender
119underutilized RAM (e.g. with "selfballooning"), sudden unexpected
120memory pressure may result in swapping; frontswap allows those pages
121to be swapped to and from hypervisor RAM (if overall host system memory
122conditions allow), thus mitigating the potentially awful performance impact
123of unplanned swapping.
124
125A KVM implementation is underway and has been RFC'ed to lkml.  And,
126using frontswap, investigation is also underway on the use of NVM as
127a memory extension technology.
128
129* Sure there may be performance advantages in some situations, but
130  what's the space/time overhead of frontswap?
131
132If CONFIG_FRONTSWAP is disabled, every frontswap hook compiles into
133nothingness and the only overhead is a few extra bytes per swapon'ed
134swap device.  If CONFIG_FRONTSWAP is enabled but no frontswap "backend"
135registers, there is one extra global variable compared to zero for
136every swap page read or written.  If CONFIG_FRONTSWAP is enabled
137AND a frontswap backend registers AND the backend fails every "store"
138request (i.e. provides no memory despite claiming it might),
139CPU overhead is still negligible -- and since every frontswap fail
140precedes a swap page write-to-disk, the system is highly likely
141to be I/O bound and using a small fraction of a percent of a CPU
142will be irrelevant anyway.
143
144As for space, if CONFIG_FRONTSWAP is enabled AND a frontswap backend
145registers, one bit is allocated for every swap page for every swap
146device that is swapon'd.  This is added to the EIGHT bits (which
147was sixteen until about 2.6.34) that the kernel already allocates
148for every swap page for every swap device that is swapon'd.  (Hugh
149Dickins has observed that frontswap could probably steal one of
150the existing eight bits, but let's worry about that minor optimization
151later.)  For very large swap disks (which are rare) on a standard
1524K pagesize, this is 1MB per 32GB swap.
153
154When swap pages are stored in transcendent memory instead of written
155out to disk, there is a side effect that this may create more memory
156pressure that can potentially outweigh the other advantages.  A
157backend, such as zcache, must implement policies to carefully (but
158dynamically) manage memory limits to ensure this doesn't happen.
159
160* OK, how about a quick overview of what this frontswap patch does
161  in terms that a kernel hacker can grok?
162
163Let's assume that a frontswap "backend" has registered during
164kernel initialization; this registration indicates that this
165frontswap backend has access to some "memory" that is not directly
166accessible by the kernel.  Exactly how much memory it provides is
167entirely dynamic and random.
168
169Whenever a swap-device is swapon'd frontswap_init() is called,
170passing the swap device number (aka "type") as a parameter.
171This notifies frontswap to expect attempts to "store" swap pages
172associated with that number.
173
174Whenever the swap subsystem is readying a page to write to a swap
175device (c.f swap_writepage()), frontswap_store is called.  Frontswap
176consults with the frontswap backend and if the backend says it does NOT
177have room, frontswap_store returns -1 and the kernel swaps the page
178to the swap device as normal.  Note that the response from the frontswap
179backend is unpredictable to the kernel; it may choose to never accept a
180page, it could accept every ninth page, or it might accept every
181page.  But if the backend does accept a page, the data from the page
182has already been copied and associated with the type and offset,
183and the backend guarantees the persistence of the data.  In this case,
184frontswap sets a bit in the "frontswap_map" for the swap device
185corresponding to the page offset on the swap device to which it would
186otherwise have written the data.
187
188When the swap subsystem needs to swap-in a page (swap_readpage()),
189it first calls frontswap_load() which checks the frontswap_map to
190see if the page was earlier accepted by the frontswap backend.  If
191it was, the page of data is filled from the frontswap backend and
192the swap-in is complete.  If not, the normal swap-in code is
193executed to obtain the page of data from the real swap device.
194
195So every time the frontswap backend accepts a page, a swap device read
196and (potentially) a swap device write are replaced by a "frontswap backend
197store" and (possibly) a "frontswap backend loads", which are presumably much
198faster.
199
200* Can't frontswap be configured as a "special" swap device that is
201  just higher priority than any real swap device (e.g. like zswap,
202  or maybe swap-over-nbd/NFS)?
203
204No.  First, the existing swap subsystem doesn't allow for any kind of
205swap hierarchy.  Perhaps it could be rewritten to accommodate a hierarchy,
206but this would require fairly drastic changes.  Even if it were
207rewritten, the existing swap subsystem uses the block I/O layer which
208assumes a swap device is fixed size and any page in it is linearly
209addressable.  Frontswap barely touches the existing swap subsystem,
210and works around the constraints of the block I/O subsystem to provide
211a great deal of flexibility and dynamicity.
212
213For example, the acceptance of any swap page by the frontswap backend is
214entirely unpredictable. This is critical to the definition of frontswap
215backends because it grants completely dynamic discretion to the
216backend.  In zcache, one cannot know a priori how compressible a page is.
217"Poorly" compressible pages can be rejected, and "poorly" can itself be
218defined dynamically depending on current memory constraints.
219
220Further, frontswap is entirely synchronous whereas a real swap
221device is, by definition, asynchronous and uses block I/O.  The
222block I/O layer is not only unnecessary, but may perform "optimizations"
223that are inappropriate for a RAM-oriented device including delaying
224the write of some pages for a significant amount of time.  Synchrony is
225required to ensure the dynamicity of the backend and to avoid thorny race
226conditions that would unnecessarily and greatly complicate frontswap
227and/or the block I/O subsystem.  That said, only the initial "store"
228and "load" operations need be synchronous.  A separate asynchronous thread
229is free to manipulate the pages stored by frontswap.  For example,
230the "remotification" thread in RAMster uses standard asynchronous
231kernel sockets to move compressed frontswap pages to a remote machine.
232Similarly, a KVM guest-side implementation could do in-guest compression
233and use "batched" hypercalls.
234
235In a virtualized environment, the dynamicity allows the hypervisor
236(or host OS) to do "intelligent overcommit".  For example, it can
237choose to accept pages only until host-swapping might be imminent,
238then force guests to do their own swapping.
239
240There is a downside to the transcendent memory specifications for
241frontswap:  Since any "store" might fail, there must always be a real
242slot on a real swap device to swap the page.  Thus frontswap must be
243implemented as a "shadow" to every swapon'd device with the potential
244capability of holding every page that the swap device might have held
245and the possibility that it might hold no pages at all.  This means
246that frontswap cannot contain more pages than the total of swapon'd
247swap devices.  For example, if NO swap device is configured on some
248installation, frontswap is useless.  Swapless portable devices
249can still use frontswap but a backend for such devices must configure
250some kind of "ghost" swap device and ensure that it is never used.
251
252* Why this weird definition about "duplicate stores"?  If a page
253  has been previously successfully stored, can't it always be
254  successfully overwritten?
255
256Nearly always it can, but no, sometimes it cannot.  Consider an example
257where data is compressed and the original 4K page has been compressed
258to 1K.  Now an attempt is made to overwrite the page with data that
259is non-compressible and so would take the entire 4K.  But the backend
260has no more space.  In this case, the store must be rejected.  Whenever
261frontswap rejects a store that would overwrite, it also must invalidate
262the old data and ensure that it is no longer accessible.  Since the
263swap subsystem then writes the new data to the read swap device,
264this is the correct course of action to ensure coherency.
265
266* Why does the frontswap patch create the new include file swapfile.h?
267
268The frontswap code depends on some swap-subsystem-internal data
269structures that have, over the years, moved back and forth between
270static and global.  This seemed a reasonable compromise:  Define
271them as global but declare them in a new include file that isn't
272included by the large number of source files that include swap.h.
273
274Dan Magenheimer, last updated April 9, 2012
275