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