1PMEM_FLUSH(3) PMDK Programmer's Manual PMEM_FLUSH(3)
2
3
4
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
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
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
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
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)