[sphinx.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]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget7/translations/pt_BR/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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh6, a Device-Mapper target that lets a byte-addressable }(hhhhhNhNubh)}(h*DAX*h]hDAX}(hjhhhNhNubah}(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/}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j$hhubh.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hhh](h)}(hQuick feature summaryh]hQuick feature summary}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj>hhhhhKubh bullet_list)}(hhh](h list_item)}(h5*Write-back* caching (only mode currently supported).h]h)}(hjXh](h)}(h *Write-back*h]h Write-back}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjZubh) caching (only mode currently supported).}(hjZhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjVubah}(h]h ]h"]h$]h&]uh1jThjQhhhhhNubjU)}(h/*16 MiB segments* allocated on the pmem device.h]h)}(hj}h](h)}(h*16 MiB segments*h]h16 MiB segments}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh allocated on the pmem device.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj{ubah}(h]h ]h"]h$]h&]uh1jThjQhhhhhNubjU)}(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&]uh1jThjQhhhhhNubjU)}(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&]uh1j$hjubh*) and protected with CRC+sequence numbers.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jThjQhhhhhNubjU)}(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&]uh1jThjQhhhhhNubjU)}(h0Pure *DAX path* I/O – no extra BIO round-tripsh]h)}(hjh](hPure }(hjhhhNhNubh)}(h *DAX path*h]hDAX path}(hjhhhNhNubah}(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&]uh1jThjQhhhhhNubjU)}(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}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjAubh) that preserves backend crash-consistency}(hjAhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj=ubah}(h]h ]h"]h$]h&]uh1jThjQhhhhhNubeh}(h]h ]h"]h$]h&]bullet*uh1jOhhhKhj>hhubeh}(h]quick-feature-summaryah ]h"]quick feature summaryah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Constructorh]h Constructor}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjshhhhhKubh literal_block)}(hnpcache [ ]h]hnpcache [ ]}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhK hjshhubhtable)}(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)}(hj+h]h backing_dev}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj)ubah}(h]h ]h"]h$]h&]uh1hhhhK&hj&ubah}(h]h ]h"]h$]h&]uh1jhj#ubj)}(hhh]h)}(h#The slow block device to be cached.h]h#The slow block device to be cached.}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK&hjFubah}(h]h ]h"]h$]h&]uh1jhj#ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h``cache_mode``h]j)}(hjkh]h cache_mode}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjiubah}(h]h ]h"]h$]h&]uh1hhhhK(hjfubah}(h]h ]h"]h$]h&]uh1jhjcubj)}(hhh]h)}(h7Optional, Only ``writeback`` is accepted at the moment.h](hOptional, Only }(hjhhhNhNubj)}(h ``writeback``h]h writeback}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is accepted at the moment.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK(hjubah}(h]h ]h"]h$]h&]uh1jhjcubeh}(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+hjubjP)}(hhh](jU)}(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&]uh1jThjubjU)}(h``false`` – skip CRC (faster)h]h)}(hj"h](j)}(h ``false``h]hfalse}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ubh – skip CRC (faster)}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK/hj ubah}(h]h ]h"]h$]h&]uh1jThjubeh}(h]h ]h"]h$]h&]jijjuh1jOhhhK-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&]uh1jhjshhhNhNubh)}(hhh](h)}(hExampleh]hExample}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjjhhhhhK3ubj)}(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"}hj{sbah}(h]h ]h"]h$]h&]hhƌforcelanguageshellhighlight_args}uh1jhhhK5hjjhhubh)}(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.).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjjhhubeh}(h]exampleah ]h"]exampleah$]h&]uh1hhjshhhhhK3ubeh}(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&]uh1hhhhKAhjhhubj)}(h \ \ : \ : \ :h]h \ \ : \ : \ :}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKEhjhhubh)}(hhh](h)}(hField meaningsh]hField meanings}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKLubj)}(hhh]j)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhj ubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthK-uh1jhj ubj)}(hhh](j)}(hhh](j)}(hhh]h)}(h ``sb_flags``h]j)}(hj/h]hsb_flags}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj-ubah}(h]h ]h"]h$]h&]uh1hhhhKOhj*ubah}(h]h ]h"]h$]h&]uh1jhj'ubj)}(hhh]h)}(h'Super-block flags (e.g. endian marker).h]h'Super-block flags (e.g. endian marker).}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhjJubah}(h]h ]h"]h$]h&]uh1jhj'ubeh}(h]h ]h"]h$]h&]uh1jhj$ubj)}(hhh](j)}(hhh]h)}(h ``seg_total``h]j)}(hjoh]h seg_total}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjmubah}(h]h ]h"]h$]h&]uh1hhhhKQhjjubah}(h]h ]h"]h$]h&]uh1jhjgubj)}(hhh]h)}(h#Number of physical *pmem* segments.h](hNumber of physical }(hjhhhNhNubh)}(h*pmem*h]hpmem}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh segments.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKQhjubah}(h]h ]h"]h$]h&]uh1jhjgubeh}(h]h ]h"]h$]h&]uh1jhj$ubj)}(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&]uh1jhj$ubj)}(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).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKUhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj$ubj)}(hhh](j)}(hhh]h)}(h``gc_percent``h]j)}(hjAh]h gc_percent}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubah}(h]h ]h"]h$]h&]uh1hhhhKWhj<ubah}(h]h ]h"]h$]h&]uh1jhj9ubj)}(hhh]h)}(h"Current GC high-water mark (0-90).h]h"Current GC high-water mark (0-90).}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKWhj\ubah}(h]h ]h"]h$]h&]uh1jhj9ubeh}(h]h ]h"]h$]h&]uh1jhj$ubj)}(hhh](j)}(hhh]h)}(h``cache_flags``h]j)}(hjh]h cache_flags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKYhj|ubah}(h]h ]h"]h$]h&]uh1jhjyubj)}(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&]uh1jhjyubeh}(h]h ]h"]h$]h&]uh1jhj$ubj)}(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&]uh1jhj$ubj)}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK_hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj$ubj)}(hhh](j)}(hhh]h)}(h ``key_tail``h]j)}(hjAh]hkey_tail}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubah}(h]h ]h"]h$]h&]uh1hhhhKbhj<ubah}(h]h ]h"]h$]h&]uh1jhj9ubj)}(hhh]h)}(h*First key-set that may be reclaimed by GC.h]h*First key-set that may be reclaimed by GC.}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhj\ubah}(h]h ]h"]h$]h&]uh1jhj9ubeh}(h]h ]h"]h$]h&]uh1jhj$ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]colsKuh1jhj ubah}(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&]uh1hhhhKihjhhubj)}(h)dmsetup message 0 gc_percent <0-90>h]h)dmsetup message 0 gc_percent <0-90>}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKmhjhhubeh}(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}(hjhhhNhNubah}(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.).}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhj3ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h cache_devh]h cache_dev}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjSubah}(h]h ]h"]h$]h&]uh1jhjPubj)}(hhh]h)}(h-DAX device; must expose direct-access memory.h]h-DAX device; must expose direct-access memory.}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjjubah}(h]h ]h"]h$]h&]uh1jhjPubeh}(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|ubjP)}(hhh](jU)}(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&]uh1jThjhhhhhNubjU)}(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&]uh1jThjhhhhhNubjU)}(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 }(hj hhhNhNubh)}(h *cache-key*h]h cache-key}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhf records a logical range on the origin and where it lives inside pmem (segment + offset + generation).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jThjhhhhhNubjU)}(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 }(hj6 hhhNhNubh)}(h *key-set*h]hkey-set}(hj> hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj6 ubhT (kset); ksets are written sequentially in pmem and are themselves crash-safe (CRC).}(hj6 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj2 ubah}(h]h ]h"]h$]h&]uh1jThjhhhhhNubjU)}(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 }(hj` hhhNhNubh)}(h*(key_tail, dirty_tail)*h]h(key_tail, dirty_tail)}(hjh hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj` ubh) delimit clean/dirty and live/dead ksets.}(hj` hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj\ ubah}(h]h ]h"]h$]h&]uh1jThjhhhhhNubeh}(h]h ]h"]h$]h&]jijjuh1jOhhhK~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}(hjC 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}(hjn hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjk hhhhhKubjP)}(hhh](jU)}(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}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh' – all metadata copies are read with }(hj hhhNhNubj)}(h``copy_mc_to_kernel``h]hcopy_mc_to_kernel}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh8; an uncorrectable error logs and aborts initialisation.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jThj| hhhhhNubjU)}(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&]uh1jThj| hhhhhNubjU)}(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&]uh1jThj| hhhhhNubeh}(h]h ]h"]h$]h&]jijjuh1jOhhhKhjk hhubeh}(h]failure-handlingah ]h"]failure handlingah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hLimitations & TODOh]hLimitations & TODO}(hj8 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj5 hhhhhKubjP)}(hhh](jU)}(h,Only *write-back* mode; other modes planned.h]h)}(hjK h](hOnly }(hjM hhhNhNubh)}(h *write-back*h]h write-back}(hjT hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjM ubh mode; other modes planned.}(hjM hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjI ubah}(h]h ]h"]h$]h&]uh1jThjF hhhhhNubjU)}(h8Only FIFO cache invalidate; other (LRU, ARC...) planned.h]h)}(hjt h]h8Only FIFO cache invalidate; other (LRU, ARC...) planned.}(hjv hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjr ubah}(h]h ]h"]h$]h&]uh1jThjF hhhhhNubjU)}(h(Table reload is not supported currently.h]h)}(hj h]h(Table reload is not supported currently.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jThjF hhhhhNubjU)}(hDiscard planned. h]h)}(hDiscard planned.h]hDiscard planned.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jThjF hhhhhNubeh}(h]h ]h"]h$]h&]jijjuh1jOhhhKhj5 hhubeh}(h]limitations-todoah ]h"]limitations & todoah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hExample workflowh]hExample workflow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubj)}(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&]hhjjshellj}uh1jhhhKhj 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_handlerj5 error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _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 jpjmjjjjjjjjjjjh je jjj j j j j' j$ j` j] j2 j/ j j j j u nametypes}(j jpjjjjjjh jj j j' j` j2 j j uh}(j hjmj>jjsjjjjjjjjjje jjjj jj j j$ j j] j* j/ jk j j5 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.