1PMEM_FLUSH(3)              PMDK Programmer's Manual              PMEM_FLUSH(3)
2
3
4

NAME

6       pmem_flush(),      pmem_drain(),      pmem_persist(),     pmem_msync(),
7       pmem_deep_flush(),       pmem_deep_drain(),        pmem_deep_persist(),
8       pmem_has_hw_drain(),  pmem_has_auto_flush() -- check persistency, store
9       persistent data and delete mappings
10

SYNOPSIS

12              #include <libpmem.h>
13
14              void pmem_persist(const void *addr, size_t len);
15              int pmem_msync(const void *addr, size_t len);
16              void pmem_flush(const void *addr, size_t len);
17              void pmem_deep_flush(const void *addr, size_t len);
18              int pmem_deep_drain(const void *addr, size_t len);
19              int pmem_deep_persist(const void *addr, size_t len);
20              void pmem_drain(void);
21              int pmem_has_auto_flush(void);
22              int pmem_has_hw_drain(void);
23

DESCRIPTION

25       The functions in this section provide access to the stages of  flushing
26       to  persistence,  for  the less common cases where an application needs
27       more control of the flushing operations than the  pmem_persist()  func‐
28       tion.
29
30              WARNING:  Using  pmem_persist() on a range where pmem_is_pmem(3)
31              returns false may not do anything useful  --  use  msync(2)  in‐
32              stead.
33
34       The  pmem_persist()  function force any changes in the range [addr, ad‐
35       dr+len) to be stored durably in persistent memory.  This is  equivalent
36       to calling msync(2) but may be more optimal and will avoid calling into
37       the kernel if possible.  There are no  alignment  restrictions  on  the
38       range  described  by  addr  and  len, but pmem_persist() may expand the
39       range as necessary to meet platform alignment requirements.
40
41              WARNING: Like msync(2), there is nothing atomic or transactional
42              about  this  call.  Any unwritten stores in the given range will
43              be written, but some stores may have  already  been  written  by
44              virtue of normal cache eviction/replacement policies.  Correctly
45              written code must not depend on stores waiting  until  pmem_per‐
46              sist() is called to become persistent -- they can become persis‐
47              tent at any time before pmem_persist() is called.
48
49       The pmem_msync() function is like pmem_persist() in that it forces  any
50       changes  in  the range [addr, addr+len) to be stored durably.  Since it
51       calls msync(), this function works on either  persistent  memory  or  a
52       memory mapped file on traditional storage.  pmem_msync() takes steps to
53       ensure the alignment of addresses and lengths passed  to  msync()  meet
54       the  requirements  of  that  system  call.   It  calls msync() with the
55       MS_SYNC flag as described in msync(2).  Typically the application  only
56       checks  for the existence of persistent memory once, and then uses that
57       result throughout the program, for example:
58
59              /* do this call once, after the pmem is memory mapped */
60              int is_pmem = pmem_is_pmem(rangeaddr, rangelen);
61
62              /* ... make changes to a range of pmem ... */
63
64              /* make the changes durable */
65              if (is_pmem)
66                  pmem_persist(subrangeaddr, subrangelen);
67              else
68                  pmem_msync(subrangeaddr, subrangelen);
69
70              /* ... */
71
72              WARNING: On Linux, pmem_msync() and msync(2) have no  effect  on
73              memory  ranges mapped from Device DAX.  In case of memory ranges
74              where pmem_is_pmem(3) returns true use pmem_persist()  to  force
75              the changes to be stored durably in persistent memory.
76
77       The pmem_flush() and pmem_drain() functions provide partial versions of
78       the pmem_persist() function.  pmem_persist() can be thought of as this:
79
80              void
81              pmem_persist(const void *addr, size_t len)
82              {
83                  /* flush the processor caches */
84                  pmem_flush(addr, len);
85
86                  /* wait for any pmem stores to drain from HW buffers */
87                  pmem_drain();
88              }
89
90       These functions allow advanced programs to create their own  variations
91       of  pmem_persist().  For example, a program that needs to flush several
92       discontiguous ranges can call pmem_flush() for each range and then fol‐
93       low up by calling pmem_drain() once.
94
95       The semantics of pmem_deep_flush() function is the same as pmem_flush()
96       function except that pmem_deep_flush() is indifferent to  PMEM_NO_FLUSH
97       environment variable (see ENVIRONMENT section in libpmem(7)) and always
98       flushes processor caches.
99
100       The behavior of pmem_deep_persist() function is the same  as  pmem_per‐
101       sist(),  except that it provides higher reliability by flushing persis‐
102       tent memory stores to the most reliable persistence domain available to
103       software  rather  than depending on automatic WPQ (write pending queue)
104       flush on power failure (ADR).
105
106       The pmem_deep_flush() and pmem_deep_drain() functions  provide  partial
107       varsions  of  pmem_deep_persist() function.  pmem_deep_persist() can be
108       thought of as this:
109
110              int pmem_deep_persist(const void *addr, size_t len)
111              {
112                  /* flush the processor caches */
113                  pmem_deep_flush(addr, len);
114
115                  /* wait for any pmem stores to drain from HW buffers */
116                  return pmem_deep_drain(addr, len);
117              }
118
119       Since this operation is usually  much  more  expensive  than  pmem_per‐
120       sist(), it should be used rarely.  Typically the application should use
121       this function only to flush the most critical data, which are  required
122       to recover after the power failure.
123
124       The pmem_has_auto_flush() function checks if the machine supports auto‐
125       matic CPU cache flush on power failure.   Function  returns  true  only
126       when each NVDIMM supports eADR.
127
128       The  pmem_has_hw_drain() function checks if the machine supports an ex‐
129       plicit hardware drain instruction for persistent memory.
130

RETURN VALUE

132       The pmem_persist() function returns no value.
133
134       The pmem_msync() return value is the return value of msync(), which can
135       return -1 and set errno to indicate an error.
136
137       The  pmem_flush(),  pmem_drain() and pmem_deep_flush() functions return
138       no value.
139
140       The pmem_deep_persist() and  pmem_deep_drain()  return  0  on  success.
141       Otherwise  it returns -1 and sets errno appropriately.  If len is equal
142       zero pmem_deep_persist() and pmem_deep_drain() return 0 but no flushing
143       take place.
144
145       The pmem_has_auto_flush() function returns 1 if eADR is supported and 0
146       if eADR is not supported.  On error it returns -1 and sets errno appro‐
147       priately.
148
149       The  pmem_has_hw_drain()  function returns true if the machine supports
150       an explicit hardware drain instruction for persistent memory.  On Intel
151       processors with persistent memory, stores to persistent memory are con‐
152       sidered persistent once they are flushed from the CPU caches,  so  this
153       function   always   returns   false.    Despite  that,  programs  using
154       pmem_flush() to flush ranges of memory should still follow up by  call‐
155       ing pmem_drain() once to ensure the flushes are complete.  As mentioned
156       above,   pmem_persist()   handles   calling   both   pmem_flush()   and
157       pmem_drain().
158

SEE ALSO

160       msync(2), pmem_is_pmem(3), libpmem(7) and <http://pmem.io>
161
162
163
164PMDK - pmem API version 1.1       2018-03-13                     PMEM_FLUSH(3)
Impressum