Blob Blame History Raw
.\" Automatically generated by Pandoc 2.1.3
.\"
.TH "PMEM_FLUSH" "3" "2018-07-18" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual"
.hy
.\" Copyright 2014-2018, Intel Corporation
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\"     * Redistributions of source code must retain the above copyright
.\"       notice, this list of conditions and the following disclaimer.
.\"
.\"     * Redistributions in binary form must reproduce the above copyright
.\"       notice, this list of conditions and the following disclaimer in
.\"       the documentation and/or other materials provided with the
.\"       distribution.
.\"
.\"     * Neither the name of the copyright holder nor the names of its
.\"       contributors may be used to endorse or promote products derived
.\"       from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
.\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.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\ <libpmem.h>

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 varsions 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]<http://pmem.io>\f[]