cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

frontswap.rst (13934B)


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