.\" Automatically generated by Pandoc 2.10.1 .\" .TH "PMEM_FLUSH" "3" "2020-10-28" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2018, Intel Corporation .SH NAME .PP \f[B]pmem_flush\f[R](), \f[B]pmem_drain\f[R](), \f[B]pmem_persist\f[R](), \f[B]pmem_msync\f[R](), \f[B]pmem_deep_flush\f[R](), \f[B]pmem_deep_drain\f[R](), \f[B]pmem_deep_persist\f[R](), \f[B]pmem_has_hw_drain\f[R](), \f[B]pmem_has_auto_flush\f[R]() - check persistency, store persistent data and delete mappings .SH SYNOPSIS .IP .nf \f[C] #include void pmem_persist(const void *addr, size_t len); int pmem_msync(const void *addr, size_t len); void pmem_flush(const void *addr, size_t len); void pmem_deep_flush(const void *addr, size_t len); (EXPERIMENTAL) int pmem_deep_drain(const void *addr, size_t len); (EXPERIMENTAL) int pmem_deep_persist(const void *addr, size_t len); (EXPERIMENTAL) void pmem_drain(void); int pmem_has_auto_flush(void); (EXPERIMENTAL) int pmem_has_hw_drain(void); \f[R] .fi .SH DESCRIPTION .PP The functions in this section provide access to the stages of flushing to persistence, for the less common cases where an application needs more control of the flushing operations than the \f[B]pmem_persist\f[R]() function. .RS .PP WARNING: Using \f[B]pmem_persist\f[R]() on a range where \f[B]pmem_is_pmem\f[R](3) returns false may not do anything useful \[en] use \f[B]msync\f[R](2) instead. .RE .PP The \f[B]pmem_persist\f[R]() function force any changes in the range [\f[I]addr\f[R], \f[I]addr\f[R]+\f[I]len\f[R]) to be stored durably in persistent memory. This is equivalent to calling \f[B]msync\f[R](2) but may be more optimal and will avoid calling into the kernel if possible. There are no alignment restrictions on the range described by \f[I]addr\f[R] and \f[I]len\f[R], but \f[B]pmem_persist\f[R]() may expand the range as necessary to meet platform alignment requirements. .RS .PP WARNING: Like \f[B]msync\f[R](2), there is nothing atomic or transactional about this call. Any unwritten stores in the given range will be written, but some stores may have already been written by virtue of normal cache eviction/replacement policies. Correctly written code must not depend on stores waiting until \f[B]pmem_persist\f[R]() is called to become persistent \[en] they can become persistent at any time before \f[B]pmem_persist\f[R]() is called. .RE .PP The \f[B]pmem_msync\f[R]() function is like \f[B]pmem_persist\f[R]() in that it forces any changes in the range [\f[I]addr\f[R], \f[I]addr\f[R]+\f[I]len\f[R]) to be stored durably. Since it calls \f[B]msync\f[R](), this function works on either persistent memory or a memory mapped file on traditional storage. \f[B]pmem_msync\f[R]() takes steps to ensure the alignment of addresses and lengths passed to \f[B]msync\f[R]() meet the requirements of that system call. It calls \f[B]msync\f[R]() with the \f[B]MS_SYNC\f[R] flag as described in \f[B]msync\f[R](2). Typically the application only checks for the existence of persistent memory once, and then uses that result throughout the program, for example: .IP .nf \f[C] /* do this call once, after the pmem is memory mapped */ int is_pmem = pmem_is_pmem(rangeaddr, rangelen); /* ... make changes to a range of pmem ... */ /* make the changes durable */ if (is_pmem) pmem_persist(subrangeaddr, subrangelen); else pmem_msync(subrangeaddr, subrangelen); /* ... */ \f[R] .fi .RS .PP WARNING: On Linux, \f[B]pmem_msync\f[R]() and \f[B]msync\f[R](2) have no effect on memory ranges mapped from Device DAX. In case of memory ranges where \f[B]pmem_is_pmem\f[R](3) returns true use \f[B]pmem_persist\f[R]() to force the changes to be stored durably in persistent memory. .RE .PP The \f[B]pmem_flush\f[R]() and \f[B]pmem_drain\f[R]() functions provide partial versions of the \f[B]pmem_persist\f[R]() function. \f[B]pmem_persist\f[R]() can be thought of as this: .IP .nf \f[C] void pmem_persist(const void *addr, size_t len) { /* flush the processor caches */ pmem_flush(addr, len); /* wait for any pmem stores to drain from HW buffers */ pmem_drain(); } \f[R] .fi .PP These functions allow advanced programs to create their own variations of \f[B]pmem_persist\f[R](). For example, a program that needs to flush several discontiguous ranges can call \f[B]pmem_flush\f[R]() for each range and then follow up by calling \f[B]pmem_drain\f[R]() once. .PP The semantics of \f[B]pmem_deep_flush\f[R]() function is the same as \f[B]pmem_flush\f[R]() function except that \f[B]pmem_deep_flush\f[R]() is indifferent to \f[B]PMEM_NO_FLUSH\f[R] environment variable (see \f[B]ENVIRONMENT\f[R] section in \f[B]libpmem\f[R](7)) and always flushes processor caches. .PP The behavior of \f[B]pmem_deep_persist\f[R]() function is the same as \f[B]pmem_persist\f[R](), except that it provides higher reliability by flushing persistent memory stores to the most reliable persistence domain available to software rather than depending on automatic WPQ (write pending queue) flush on power failure (ADR). .PP The \f[B]pmem_deep_flush\f[R]() and \f[B]pmem_deep_drain\f[R]() functions provide partial versions of \f[B]pmem_deep_persist\f[R]() function. \f[B]pmem_deep_persist\f[R]() can be thought of as this: .IP .nf \f[C] int pmem_deep_persist(const void *addr, size_t len) { /* flush the processor caches */ pmem_deep_flush(addr, len); /* wait for any pmem stores to drain from HW buffers */ return pmem_deep_drain(addr, len); } \f[R] .fi .PP Since this operation is usually much more expensive than \f[B]pmem_persist\f[R](), it should be used rarely. Typically the application should use this function only to flush the most critical data, which are required to recover after the power failure. .PP The \f[B]pmem_has_auto_flush\f[R]() function checks if the machine supports automatic CPU cache flush on power failure or system crash. Function returns true only when each NVDIMM in the system is covered by this mechanism. .PP The \f[B]pmem_has_hw_drain\f[R]() function checks if the machine supports an explicit \f[I]hardware drain\f[R] instruction for persistent memory. .SH RETURN VALUE .PP The \f[B]pmem_persist\f[R]() function returns no value. .PP The \f[B]pmem_msync\f[R]() return value is the return value of \f[B]msync\f[R](), which can return -1 and set \f[I]errno\f[R] to indicate an error. .PP The \f[B]pmem_flush\f[R](), \f[B]pmem_drain\f[R]() and \f[B]pmem_deep_flush\f[R]() functions return no value. .PP The \f[B]pmem_deep_persist\f[R]() and \f[B]pmem_deep_drain\f[R]() return 0 on success. Otherwise it returns -1 and sets \f[I]errno\f[R] appropriately. If \f[I]len\f[R] is equal zero \f[B]pmem_deep_persist\f[R]() and \f[B]pmem_deep_drain\f[R]() return 0 but no flushing take place. .PP The \f[B]pmem_has_auto_flush\f[R]() function returns 1 if given platform supports processor cache flushing on a power loss event. Otherwise it returns 0. On error it returns -1 and sets \f[I]errno\f[R] appropriately. .PP The \f[B]pmem_has_hw_drain\f[R]() function returns true if the machine supports an explicit \f[I]hardware drain\f[R] instruction for persistent memory. On Intel processors with persistent memory, stores to persistent memory are considered persistent once they are flushed from the CPU caches, so this function always returns false. Despite that, programs using \f[B]pmem_flush\f[R]() to flush ranges of memory should still follow up by calling \f[B]pmem_drain\f[R]() once to ensure the flushes are complete. As mentioned above, \f[B]pmem_persist\f[R]() handles calling both \f[B]pmem_flush\f[R]() and \f[B]pmem_drain\f[R](). .SH SEE ALSO .PP \f[B]msync\f[R](2), \f[B]pmem_is_pmem\f[R](3), \f[B]libpmem\f[R](7) and \f[B]\f[R]