.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM_FLUSH" "3" "2022-08-25" "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[](), \f[B]pmem_drain\f[](), \f[B]pmem_persist\f[](), \f[B]pmem_msync\f[](), \f[B]pmem_deep_flush\f[](), \f[B]pmem_deep_drain\f[](), \f[B]pmem_deep_persist\f[](), \f[B]pmem_has_hw_drain\f[](), \f[B]pmem_has_auto_flush\f[]() \- 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[] .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[]() function. .RS .PP WARNING: Using \f[B]pmem_persist\f[]() on a range where \f[B]pmem_is_pmem\f[](3) returns false may not do anything useful \[en] use \f[B]msync\f[](2) instead. .RE .PP The \f[B]pmem_persist\f[]() function force any changes in the range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) to be stored durably in persistent memory. This is equivalent to calling \f[B]msync\f[](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[] and \f[I]len\f[], but \f[B]pmem_persist\f[]() may expand the range as necessary to meet platform alignment requirements. .RS .PP WARNING: Like \f[B]msync\f[](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[]() is called to become persistent \[en] they can become persistent at any time before \f[B]pmem_persist\f[]() is called. .RE .PP The \f[B]pmem_msync\f[]() function is like \f[B]pmem_persist\f[]() in that it forces any changes in the range [\f[I]addr\f[], \f[I]addr\f[]+\f[I]len\f[]) to be stored durably. Since it calls \f[B]msync\f[](), this function works on either persistent memory or a memory mapped file on traditional storage. \f[B]pmem_msync\f[]() takes steps to ensure the alignment of addresses and lengths passed to \f[B]msync\f[]() meet the requirements of that system call. It calls \f[B]msync\f[]() with the \f[B]MS_SYNC\f[] flag as described in \f[B]msync\f[](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[] .fi .RS .PP WARNING: On Linux, \f[B]pmem_msync\f[]() and \f[B]msync\f[](2) have no effect on memory ranges mapped from Device DAX. In case of memory ranges where \f[B]pmem_is_pmem\f[](3) returns true use \f[B]pmem_persist\f[]() to force the changes to be stored durably in persistent memory. .RE .PP The \f[B]pmem_flush\f[]() and \f[B]pmem_drain\f[]() functions provide partial versions of the \f[B]pmem_persist\f[]() function. \f[B]pmem_persist\f[]() 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[] .fi .PP These functions allow advanced programs to create their own variations of \f[B]pmem_persist\f[](). For example, a program that needs to flush several discontiguous ranges can call \f[B]pmem_flush\f[]() for each range and then follow up by calling \f[B]pmem_drain\f[]() once. .PP The semantics of \f[B]pmem_deep_flush\f[]() function is the same as \f[B]pmem_flush\f[]() function except that \f[B]pmem_deep_flush\f[]() is indifferent to \f[B]PMEM_NO_FLUSH\f[] environment variable (see \f[B]ENVIRONMENT\f[] section in \f[B]libpmem\f[](7)) and always flushes processor caches. .PP The behavior of \f[B]pmem_deep_persist\f[]() function is the same as \f[B]pmem_persist\f[](), 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[]() and \f[B]pmem_deep_drain\f[]() functions provide partial versions of \f[B]pmem_deep_persist\f[]() function. \f[B]pmem_deep_persist\f[]() 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[] .fi .PP Since this operation is usually much more expensive than \f[B]pmem_persist\f[](), 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[]() 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[]() function checks if the machine supports an explicit \f[I]hardware drain\f[] instruction for persistent memory. .SH RETURN VALUE .PP The \f[B]pmem_persist\f[]() function returns no value. .PP The \f[B]pmem_msync\f[]() return value is the return value of \f[B]msync\f[](), which can return \-1 and set \f[I]errno\f[] to indicate an error. .PP The \f[B]pmem_flush\f[](), \f[B]pmem_drain\f[]() and \f[B]pmem_deep_flush\f[]() functions return no value. .PP The \f[B]pmem_deep_persist\f[]() and \f[B]pmem_deep_drain\f[]() return 0 on success. Otherwise it returns \-1 and sets \f[I]errno\f[] appropriately. If \f[I]len\f[] is equal zero \f[B]pmem_deep_persist\f[]() and \f[B]pmem_deep_drain\f[]() return 0 but no flushing take place. .PP The \f[B]pmem_has_auto_flush\f[]() 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[] appropriately. .PP The \f[B]pmem_has_hw_drain\f[]() function returns true if the machine supports an explicit \f[I]hardware drain\f[] 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[]() to flush ranges of memory should still follow up by calling \f[B]pmem_drain\f[]() once to ensure the flushes are complete. As mentioned above, \f[B]pmem_persist\f[]() handles calling both \f[B]pmem_flush\f[]() and \f[B]pmem_drain\f[](). .SH SEE ALSO .PP \f[B]msync\f[](2), \f[B]pmem_is_pmem\f[](3), \f[B]libpmem\f[](7) and \f[B]\f[]