rsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget7/translations/zh_CN/admin-guide/device-mapper/dm-pcachemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget7/translations/zh_TW/admin-guide/device-mapper/dm-pcachemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget7/translations/it_IT/admin-guide/device-mapper/dm-pcachemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget7/translations/ja_JP/admin-guide/device-mapper/dm-pcachemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget7/translations/ko_KR/admin-guide/device-mapper/dm-pcachemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget7/translations/sp_SP/admin-guide/device-mapper/dm-pcachemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhQ/var/lib/git/docbuild/linux/Documentation/admin-guide/device-mapper/dm-pcache.rsthKubhsection)}(hhh](htitle)}(hdm-pcache — Persistent Cacheh]hdm-pcache — Persistent Cache}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(h3*Author: Dongsheng Yang *h]hemphasis)}(hhh]h1Author: Dongsheng Yang }(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXThis document describes *dm-pcache*, a Device-Mapper target that lets a byte-addressable *DAX* (persistent-memory, “pmem”) region act as a high-performance, crash-persistent cache in front of a slower block device. The code lives in `drivers/md/dm-pcache/`.h](hThis document describes }(hhhhhNhNubh)}(h *dm-pcache*h]h dm-pcache}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh6, a Device-Mapper target that lets a byte-addressable }(hhhhhNhNubh)}(h*DAX*h]hDAX}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh (persistent-memory, “pmem”) region act as a high-performance, crash-persistent cache in front of a slower block device. The code lives in }(hhhhhNhNubhtitle_reference)}(h`drivers/md/dm-pcache/`h]hdrivers/md/dm-pcache/}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhubh.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hhh](h)}(hQuick feature summaryh]hQuick feature summary}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj*hhhhhKubh bullet_list)}(hhh](h list_item)}(h5*Write-back* caching (only mode currently supported).h]h)}(hjDh](h)}(h *Write-back*h]h Write-back}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjFubh) caching (only mode currently supported).}(hjFhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjBubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubjA)}(h/*16 MiB segments* allocated on the pmem device.h]h)}(hjih](h)}(h*16 MiB segments*h]h16 MiB segments}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjkubh allocated on the pmem device.}(hjkhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjgubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubjA)}(h0*Data CRC32* verification (optional, per cache).h]h)}(hjh](h)}(h *Data CRC32*h]h Data CRC32}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh$ verification (optional, per cache).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubjA)}(hzCrash-safe: every metadata structure is duplicated (`PCACHE_META_INDEX_MAX == 2`) and protected with CRC+sequence numbers.h]h)}(hzCrash-safe: every metadata structure is duplicated (`PCACHE_META_INDEX_MAX == 2`) and protected with CRC+sequence numbers.h](h4Crash-safe: every metadata structure is duplicated (}(hjhhhNhNubj)}(h`PCACHE_META_INDEX_MAX == 2`h]hPCACHE_META_INDEX_MAX == 2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh*) and protected with CRC+sequence numbers.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubjA)}(h[*Multi-tree indexing* (indexing trees sharded by logical address) for high PMem parallelismh]h)}(hjh](h)}(h*Multi-tree indexing*h]hMulti-tree indexing}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhF (indexing trees sharded by logical address) for high PMem parallelism}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubjA)}(h0Pure *DAX path* I/O – no extra BIO round-tripsh]h)}(hjh](hPure }(hjhhhNhNubh)}(h *DAX path*h]hDAX path}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh! I/O – no extra BIO round-trips}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubjA)}(hF*Log-structured write-back* that preserves backend crash-consistency h]h)}(hD*Log-structured write-back* that preserves backend crash-consistencyh](h)}(h*Log-structured write-back*h]hLog-structured write-back}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj-ubh) that preserves backend crash-consistency}(hj-hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj)ubah}(h]h ]h"]h$]h&]uh1j@hj=hhhhhNubeh}(h]h ]h"]h$]h&]bullet*uh1j;hhhKhj*hhubeh}(h]quick-feature-summaryah ]h"]quick feature summaryah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Constructorh]h Constructor}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj_hhhhhKubh literal_block)}(hnpcache [ ]h]hnpcache [ ]}hjrsbah}(h]h ]h"]h$]h&]hhuh1jphhhK hj_hhubhtable)}(hhh]htgroup)}(hhh](hcolspec)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthK4uh1jhjubhtbody)}(hhh](hrow)}(hhh](hentry)}(hhh]h)}(h ``cache_dev``h]hliteral)}(hjh]h cache_dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hcAny DAX-capable block device (``/dev/pmem0``…). All metadata *and* cached blocks are stored here.h](hAny DAX-capable block device (}(hjhhhNhNubj)}(h``/dev/pmem0``h]h /dev/pmem0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh…). All metadata }(hjhhhNhNubh)}(h*and*h]hand}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh cached blocks are stored here.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``backing_dev``h]j)}(hjh]h backing_dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhK&hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h#The slow block device to be cached.h]h#The slow block device to be cached.}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK&hj2ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``cache_mode``h]j)}(hjWh]h cache_mode}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjUubah}(h]h ]h"]h$]h&]uh1hhhhK(hjRubah}(h]h ]h"]h$]h&]uh1jhjOubj)}(hhh]h)}(h7Optional, Only ``writeback`` is accepted at the moment.h](hOptional, Only }(hjuhhhNhNubj)}(h ``writeback``h]h writeback}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjuubh is accepted at the moment.}(hjuhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK(hjrubah}(h]h ]h"]h$]h&]uh1jhjOubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h ``data_crc``h]j)}(hjh]hdata_crc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhK+hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](h)}(hOptional, default to ``false``h](hOptional, default to }(hjhhhNhNubj)}(h ``false``h]hfalse}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1hhhhK+hjubj<)}(hhh](jA)}(hD``true`` – store CRC32 for every cached entry and verify on readsh]h)}(hD``true`` – store CRC32 for every cached entry and verify on readsh](j)}(h``true``h]htrue}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh< – store CRC32 for every cached entry and verify on reads}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK-hjubah}(h]h ]h"]h$]h&]uh1j@hjubjA)}(h``false`` – skip CRC (faster)h]h)}(hjh](j)}(h ``false``h]hfalse}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh – skip CRC (faster)}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK/hj ubah}(h]h ]h"]h$]h&]uh1j@hjubeh}(h]h ]h"]h$]h&]jUjVuh1j;hhhK-hjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jhjubah}(h]h ]h"]h$]h&]uh1jhj_hhhNhNubh)}(hhh](h)}(hExampleh]hExample}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjVhhhhhK3ubjq)}(hdmsetup create pcache_sdb --table \ "0 $(blockdev --getsz /dev/sdb) pcache /dev/pmem0 /dev/sdb 4 cache_mode writeback data_crc true"h]hdmsetup create pcache_sdb --table \ "0 $(blockdev --getsz /dev/sdb) pcache /dev/pmem0 /dev/sdb 4 cache_mode writeback data_crc true"}hjgsbah}(h]h ]h"]h$]h&]hhforcelanguageshellhighlight_args}uh1jphhhK5hjVhhubh)}(hiThe first time a pmem device is used, dm-pcache formats it automatically (super-block, cache_info, etc.).h]hiThe first time a pmem device is used, dm-pcache formats it automatically (super-block, cache_info, etc.).}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjVhhubeh}(h]exampleah ]h"]exampleah$]h&]uh1hhj_hhhhhK3ubeh}(h] constructorah ]h"] constructorah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Status lineh]h Status line}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK?ubh)}(h9``dmsetup status `` (``STATUSTYPE_INFO``) prints:h](j)}(h``dmsetup status ``h]hdmsetup status }(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh (}(hjhhhNhNubj)}(h``STATUSTYPE_INFO``h]hSTATUSTYPE_INFO}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh ) prints:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKAhjhhubjq)}(h \ \ : \ : \ :h]h \ \ : \ : \ :}hjsbah}(h]h ]h"]h$]h&]hhuh1jphhhKEhjhhubh)}(hhh](h)}(hField meaningsh]hField meanings}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKLubj)}(hhh]j)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthK-uh1jhjubj)}(hhh](j)}(hhh](j)}(hhh]h)}(h ``sb_flags``h]j)}(hjh]hsb_flags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKOhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h'Super-block flags (e.g. endian marker).h]h'Super-block flags (e.g. endian marker).}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhj6ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h ``seg_total``h]j)}(hj[h]h seg_total}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjYubah}(h]h ]h"]h$]h&]uh1hhhhKQhjVubah}(h]h ]h"]h$]h&]uh1jhjSubj)}(hhh]h)}(h#Number of physical *pmem* segments.h](hNumber of physical }(hjyhhhNhNubh)}(h*pmem*h]hpmem}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh segments.}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKQhjvubah}(h]h ]h"]h$]h&]uh1jhjSubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``cache_segs``h]j)}(hjh]h cache_segs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKShjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h"Number of segments used for cache.h]h"Number of segments used for cache.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKShjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h ``segs_used``h]j)}(hjh]h segs_used}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKUhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h-Segments currently allocated (bitmap weight).h]h-Segments currently allocated (bitmap weight).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKUhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``gc_percent``h]j)}(hj-h]h gc_percent}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj+ubah}(h]h ]h"]h$]h&]uh1hhhhKWhj(ubah}(h]h ]h"]h$]h&]uh1jhj%ubj)}(hhh]h)}(h"Current GC high-water mark (0-90).h]h"Current GC high-water mark (0-90).}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKWhjHubah}(h]h ]h"]h$]h&]uh1jhj%ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``cache_flags``h]j)}(hjmh]h cache_flags}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1jhjkubah}(h]h ]h"]h$]h&]uh1hhhhKYhjhubah}(h]h ]h"]h$]h&]uh1jhjeubj)}(hhh]h)}(heBit 0 – DATA_CRC enabled Bit 1 – INIT_DONE (cache initialised) Bits 2-5 – cache mode (0 == WB).h]heBit 0 – DATA_CRC enabled Bit 1 – INIT_DONE (cache initialised) Bits 2-5 – cache mode (0 == WB).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKYhjubah}(h]h ]h"]h$]h&]uh1jhjeubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h ``key_head``h]j)}(hjh]hkey_head}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhK]hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h%Where new key-sets are being written.h]h%Where new key-sets are being written.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK]hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``dirty_tail``h]j)}(hjh]h dirty_tail}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhK_hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(hFFirst dirty key-set that still needs write-back to the backing device.h]hFFirst dirty key-set that still needs write-back to the backing device.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK_hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h ``key_tail``h]j)}(hj-h]hkey_tail}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj+ubah}(h]h ]h"]h$]h&]uh1hhhhKbhj(ubah}(h]h ]h"]h$]h&]uh1jhj%ubj)}(hhh]h)}(h*First key-set that may be reclaimed by GC.h]h*First key-set that may be reclaimed by GC.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhjHubah}(h]h ]h"]h$]h&]uh1jhj%ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]field-meaningsah ]h"]field meaningsah$]h&]uh1hhjhhhhhKLubeh}(h] status-lineah ]h"] status lineah$]h&]uh1hhhhhhhhK?ubh)}(hhh](h)}(hMessagesh]hMessages}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKgubh)}(h*Change GC trigger*h]h)}(hjh]hChange GC trigger}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]uh1hhhhKihjhhubjq)}(h)dmsetup message 0 gc_percent <0-90>h]h)dmsetup message 0 gc_percent <0-90>}hjsbah}(h]h ]h"]h$]h&]hhuh1jphhhKmhjhhubeh}(h]messagesah ]h"]messagesah$]h&]uh1hhhhhhhhKgubh)}(hhh](h)}(hTheory of operationh]hTheory of operation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKqubh)}(hhh](h)}(h Sub-devicesh]h Sub-devices}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKtubj)}(hhh]j)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthK9uh1jhjubj)}(hhh](j)}(hhh](j)}(hhh]h)}(h backing_devh]h backing_dev}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h*Any block device (SSD/HDD/loop/LVM, etc.).h]h*Any block device (SSD/HDD/loop/LVM, etc.).}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h cache_devh]h cache_dev}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhj?ubah}(h]h ]h"]h$]h&]uh1jhj<ubj)}(hhh]h)}(h-DAX device; must expose direct-access memory.h]h-DAX device; must expose direct-access memory.}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjVubah}(h]h ]h"]h$]h&]uh1jhj<ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h] sub-devicesah ]h"] sub-devicesah$]h&]uh1hhjhhhhhKtubh)}(hhh](h)}(hSegments and key-setsh]hSegments and key-sets}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK|ubj<)}(hhh](jA)}(h1The pmem space is divided into *16 MiB segments*.h]h)}(hjh](hThe pmem space is divided into }(hjhhhNhNubh)}(h*16 MiB segments*h]h16 MiB segments}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK~hjubah}(h]h ]h"]h$]h&]uh1j@hjhhhhhNubjA)}(hGEach write allocates space from a per-CPU *data_head* inside a segment.h]h)}(hjh](h*Each write allocates space from a per-CPU }(hjhhhNhNubh)}(h *data_head*h]h data_head}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh inside a segment.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j@hjhhhhhNubjA)}(hsA *cache-key* records a logical range on the origin and where it lives inside pmem (segment + offset + generation).h]h)}(hsA *cache-key* records a logical range on the origin and where it lives inside pmem (segment + offset + generation).h](hA }(hjhhhNhNubh)}(h *cache-key*h]h cache-key}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhf records a logical range on the origin and where it lives inside pmem (segment + offset + generation).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j@hjhhhhhNubjA)}(hm128 keys form a *key-set* (kset); ksets are written sequentially in pmem and are themselves crash-safe (CRC).h]h)}(hm128 keys form a *key-set* (kset); ksets are written sequentially in pmem and are themselves crash-safe (CRC).h](h128 keys form a }(hj" hhhNhNubh)}(h *key-set*h]hkey-set}(hj* hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj" ubhT (kset); ksets are written sequentially in pmem and are themselves crash-safe (CRC).}(hj" hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1j@hjhhhhhNubjA)}(hKThe pair *(key_tail, dirty_tail)* delimit clean/dirty and live/dead ksets. h]h)}(hJThe pair *(key_tail, dirty_tail)* delimit clean/dirty and live/dead ksets.h](h The pair }(hjL hhhNhNubh)}(h*(key_tail, dirty_tail)*h]h(key_tail, dirty_tail)}(hjT hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjL ubh) delimit clean/dirty and live/dead ksets.}(hjL hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjH ubah}(h]h ]h"]h$]h&]uh1j@hjhhhhhNubeh}(h]h ]h"]h$]h&]jUjVuh1j;hhhK~hjhhubeh}(h]segments-and-key-setsah ]h"]segments and key-setsah$]h&]uh1hhjhhhhhK|ubh)}(hhh](h)}(h Write-backh]h Write-back}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hDirty keys are queued into a tree; a background worker copies data back to the backing_dev and advances *dirty_tail*. A FLUSH/FUA bio from the upper layers forces an immediate metadata commit.h](hhDirty keys are queued into a tree; a background worker copies data back to the backing_dev and advances }(hj hhhNhNubh)}(h *dirty_tail*h]h dirty_tail}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhM. A FLUSH/FUA bio from the upper layers forces an immediate metadata commit.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h] write-backah ]h"] write-backah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hGarbage collectionh]hGarbage collection}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hGC starts when ``segs_used >= seg_total * gc_percent / 100``. It walks from *key_tail*, frees segments whose every key has been invalidated, and advances *key_tail*.h](hGC starts when }(hj hhhNhNubj)}(h-``segs_used >= seg_total * gc_percent / 100``h]h)segs_used >= seg_total * gc_percent / 100}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. It walks from }(hj hhhNhNubh)}(h *key_tail*h]hkey_tail}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhD, frees segments whose every key has been invalidated, and advances }(hj hhhNhNubh)}(h *key_tail*h]hkey_tail}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h]garbage-collectionah ]h"]garbage collectionah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(hCRC verificationh]hCRC verification}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hIf ``data_crc is enabled`` dm-pcache computes a CRC32 over every cached data range when it is inserted and stores it in the on-media key. Reads validate the CRC before copying to the caller.h](hIf }(hj' hhhNhNubj)}(h``data_crc is enabled``h]hdata_crc is enabled}(hj/ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj' ubh dm-pcache computes a CRC32 over every cached data range when it is inserted and stores it in the on-media key. Reads validate the CRC before copying to the caller.}(hj' hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h]crc-verificationah ]h"]crc verificationah$]h&]uh1hhjhhhhhKubeh}(h]theory-of-operationah ]h"]theory of operationah$]h&]uh1hhhhhhhhKqubh)}(hhh](h)}(hFailure handlingh]hFailure handling}(hjZ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjW hhhhhKubj<)}(hhh](jA)}(h*pmem media errors* – all metadata copies are read with ``copy_mc_to_kernel``; an uncorrectable error logs and aborts initialisation.h]h)}(h*pmem media errors* – all metadata copies are read with ``copy_mc_to_kernel``; an uncorrectable error logs and aborts initialisation.h](h)}(h*pmem media errors*h]hpmem media errors}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjo ubh' – all metadata copies are read with }(hjo hhhNhNubj)}(h``copy_mc_to_kernel``h]hcopy_mc_to_kernel}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjo ubh8; an uncorrectable error logs and aborts initialisation.}(hjo hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjk ubah}(h]h ]h"]h$]h&]uh1j@hjh hhhhhNubjA)}(h|*Cache full* – if no free segment can be found, writes return ``-EBUSY``; dm-pcache retries internally (request deferral).h]h)}(h|*Cache full* – if no free segment can be found, writes return ``-EBUSY``; dm-pcache retries internally (request deferral).h](h)}(h *Cache full*h]h Cache full}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh4 – if no free segment can be found, writes return }(hj hhhNhNubj)}(h ``-EBUSY``h]h-EBUSY}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh2; dm-pcache retries internally (request deferral).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1j@hjh hhhhhNubjA)}(h*System crash* – on attach, the driver replays ksets from *key_tail* to rebuild the in-core trees; every segment’s generation guards against use-after-free keys. h]h)}(h*System crash* – on attach, the driver replays ksets from *key_tail* to rebuild the in-core trees; every segment’s generation guards against use-after-free keys.h](h)}(h*System crash*h]h System crash}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh. – on attach, the driver replays ksets from }(hj hhhNhNubh)}(h *key_tail*h]hkey_tail}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh_ to rebuild the in-core trees; every segment’s generation guards against use-after-free keys.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1j@hjh hhhhhNubeh}(h]h ]h"]h$]h&]jUjVuh1j;hhhKhjW hhubeh}(h]failure-handlingah ]h"]failure handlingah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hLimitations & TODOh]hLimitations & TODO}(hj$ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj! hhhhhKubj<)}(hhh](jA)}(h,Only *write-back* mode; other modes planned.h]h)}(hj7 h](hOnly }(hj9 hhhNhNubh)}(h *write-back*h]h write-back}(hj@ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj9 ubh mode; other modes planned.}(hj9 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj5 ubah}(h]h ]h"]h$]h&]uh1j@hj2 hhhhhNubjA)}(h8Only FIFO cache invalidate; other (LRU, ARC...) planned.h]h)}(hj` h]h8Only FIFO cache invalidate; other (LRU, ARC...) planned.}(hjb hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj^ ubah}(h]h ]h"]h$]h&]uh1j@hj2 hhhhhNubjA)}(h(Table reload is not supported currently.h]h)}(hjw h]h(Table reload is not supported currently.}(hjy hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhju ubah}(h]h ]h"]h$]h&]uh1j@hj2 hhhhhNubjA)}(hDiscard planned. h]h)}(hDiscard planned.h]hDiscard planned.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1j@hj2 hhhhhNubeh}(h]h ]h"]h$]h&]jUjVuh1j;hhhKhj! hhubeh}(h]limitations-todoah ]h"]limitations & todoah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hExample workflowh]hExample workflow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubjq)}(hX# 1. Create devices dmsetup create pcache_sdb --table \ "0 $(blockdev --getsz /dev/sdb) pcache /dev/pmem0 /dev/sdb 4 cache_mode writeback data_crc true" # 2. Put a filesystem on top mkfs.ext4 /dev/mapper/pcache_sdb mount /dev/mapper/pcache_sdb /mnt # 3. Tune GC threshold to 80 % dmsetup message pcache_sdb 0 gc_percent 80 # 4. Observe status watch -n1 'dmsetup status pcache_sdb' # 5. Shutdown umount /mnt dmsetup remove pcache_sdbh]hX# 1. Create devices dmsetup create pcache_sdb --table \ "0 $(blockdev --getsz /dev/sdb) pcache /dev/pmem0 /dev/sdb 4 cache_mode writeback data_crc true" # 2. Put a filesystem on top mkfs.ext4 /dev/mapper/pcache_sdb mount /dev/mapper/pcache_sdb /mnt # 3. Tune GC threshold to 80 % dmsetup message pcache_sdb 0 gc_percent 80 # 4. Observe status watch -n1 'dmsetup status pcache_sdb' # 5. Shutdown umount /mnt dmsetup remove pcache_sdb}hj sbah}(h]h ]h"]h$]h&]hhjujvshelljx}uh1jphhhKhj hhubh)}(h^``dm-pcache`` is under active development; feedback, bug reports and patches are very welcome!h](j)}(h ``dm-pcache``h]h dm-pcache}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhQ is under active development; feedback, bug reports and patches are very welcome!}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h]example-workflowah ]h"]example workflowah$]h&]uh1hhhhhhhhKubeh}(h]dm-pcache-persistent-cacheah ]h"]dm-pcache — persistent cacheah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksjfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj! error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j j j\jYjjjjjjj}jzjjjT jQ jjj} jz j j j j jL jI j j j j j j u nametypes}(j j\jjjj}jjT jj} j j jL j j j uh}(j hjYj*jj_jjVjjjzjjjjQ jjjjz jj j j j jI j j jW j j! j j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.