]>
Commit | Line | Data |
---|---|---|
f8a32e67 LP |
1 | <?xml version='1.0'?> |
2 | <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
eea10b26 | 3 | "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> |
f8a32e67 LP |
4 | <!-- SPDX-License-Identifier: LGPL-2.1-or-later --> |
5 | ||
6 | <refentry id="sd_event_add_memory_pressure" xmlns:xi="http://www.w3.org/2001/XInclude"> | |
7 | ||
8 | <refentryinfo> | |
9 | <title>sd_event_add_memory_pressure</title> | |
10 | <productname>systemd</productname> | |
11 | </refentryinfo> | |
12 | ||
13 | <refmeta> | |
14 | <refentrytitle>sd_event_add_memory_pressure</refentrytitle> | |
15 | <manvolnum>3</manvolnum> | |
16 | </refmeta> | |
17 | ||
18 | <refnamediv> | |
19 | <refname>sd_event_add_memory_pressure</refname> | |
20 | <refname>sd_event_source_set_memory_pressure_type</refname> | |
21 | <refname>sd_event_source_set_memory_pressure_period</refname> | |
22 | <refname>sd_event_trim_memory</refname> | |
23 | ||
24 | <refpurpose>Add and configure an event source run as result of memory pressure</refpurpose> | |
25 | </refnamediv> | |
26 | ||
27 | <refsynopsisdiv> | |
28 | <funcsynopsis> | |
29 | <funcsynopsisinfo>#include <systemd/sd-event.h></funcsynopsisinfo> | |
30 | ||
31 | <funcsynopsisinfo><token>typedef</token> struct sd_event_source sd_event_source;</funcsynopsisinfo> | |
32 | ||
33 | <funcprototype> | |
34 | <funcdef>int <function>sd_event_add_memory_pressure</function></funcdef> | |
35 | <paramdef>sd_event *<parameter>event</parameter></paramdef> | |
36 | <paramdef>sd_event_source **<parameter>ret_source</parameter></paramdef> | |
37 | <paramdef>sd_event_handler_t <parameter>handler</parameter></paramdef> | |
38 | <paramdef>void *<parameter>userdata</parameter></paramdef> | |
39 | </funcprototype> | |
40 | ||
41 | <funcprototype> | |
42 | <funcdef>int <function>sd_event_source_set_memory_pressure_type</function></funcdef> | |
43 | <paramdef>sd_event_source *<parameter>source</parameter></paramdef> | |
44 | <paramdef>const char *<parameter>type</parameter></paramdef> | |
45 | </funcprototype> | |
46 | ||
47 | <funcprototype> | |
48 | <funcdef>int <function>sd_event_source_set_memory_pressure_period</function></funcdef> | |
49 | <paramdef>sd_event_source *<parameter>source</parameter></paramdef> | |
50 | <paramdef>uint64_t <parameter>threshold_usec</parameter></paramdef> | |
51 | <paramdef>uint64_t <parameter>window_usec</parameter></paramdef> | |
52 | </funcprototype> | |
53 | ||
54 | <funcprototype> | |
55 | <funcdef>int <function>sd_event_trim_memory</function></funcdef> | |
56 | <paramdef>void</paramdef> | |
57 | </funcprototype> | |
58 | </funcsynopsis> | |
59 | </refsynopsisdiv> | |
60 | ||
61 | <refsect1> | |
62 | <title>Description</title> | |
63 | ||
64 | <para><function>sd_event_add_memory_pressure()</function> adds a new event source that is triggered | |
65 | whenever memory pressure is seen. This functionality is built around the Linux kernel's <ulink | |
66 | url="https://docs.kernel.org/accounting/psi.html">Pressure Stall Information (PSI)</ulink> logic.</para> | |
67 | ||
68 | <para>Expects an event loop object as first parameter, and returns the allocated event source object in | |
69 | the second parameter, on success. The <parameter>handler</parameter> parameter is a function to call when | |
70 | memory pressure is seen, or <constant>NULL</constant>. The handler function will be passed the | |
71 | <parameter>userdata</parameter> pointer, which may be chosen freely by the caller. The handler may return | |
72 | negative to signal an error (see below), other return values are ignored. If | |
73 | <parameter>handler</parameter> is <constant>NULL</constant>, a default handler that compacts allocation | |
74 | caches maintained by <filename>libsystemd</filename> as well as glibc (via <citerefentry | |
75 | project='man-pages'><refentrytitle>malloc_trim</refentrytitle><manvolnum>3</manvolnum></citerefentry>) | |
76 | will be used.</para> | |
77 | ||
78 | <para>To destroy an event source object use | |
79 | <citerefentry><refentrytitle>sd_event_source_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>, | |
80 | but note that the event source is only removed from the event loop when all references to the event | |
81 | source are dropped. To make sure an event source does not fire anymore, even if it is still referenced, | |
82 | disable the event source using | |
83 | <citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry> | |
84 | with <constant>SD_EVENT_OFF</constant>.</para> | |
85 | ||
86 | <para>If the second parameter of <function>sd_event_add_memory_pressure()</function> is | |
87 | <constant>NULL</constant> no reference to the event source object is returned. In this case the event | |
88 | source is considered "floating", and will be destroyed implicitly when the event loop itself is | |
89 | destroyed.</para> | |
90 | ||
91 | <para>The event source will fire according to the following logic:</para> | |
92 | ||
93 | <orderedlist> | |
94 | <listitem><para>If the | |
95 | <varname>$MEMORY_PRESSURE_WATCH</varname>/<varname>$MEMORY_PRESSURE_WRITE</varname> environment | |
96 | variables are set at the time the event source is established, it will watch the file, FIFO or AF_UNIX | |
97 | socket specified via <varname>$MEMORY_PRESSURE_WATCH</varname> (which must contain an absolute path | |
98 | name) for <constant>POLLPRI</constant> (in case it is a regular file) or <constant>POLLIN</constant> | |
99 | events (otherwise). After opening the inode, it will write the (decoded) Base64 data provided via | |
100 | <varname>$MEMORY_PRESSURE_WRITE</varname> into it before it starts polling on it (the variable may be | |
101 | unset in which case this is skipped). Typically, if used, <varname>$MEMORY_PRESSURE_WATCH</varname> | |
102 | will contain a path such as <filename>/proc/pressure/memory</filename> or a path to a specific | |
103 | <filename>memory.pressure</filename> file in the control group file system | |
104 | (cgroupfs).</para></listitem> | |
105 | ||
106 | <listitem><para>If these environment variables are not set, the local PSI interface file | |
107 | <filename>memory.pressure</filename> of the control group the invoking process is running in is | |
108 | used.</para></listitem> | |
109 | ||
110 | <listitem><para>If that file does not exist, the system-wide PSI interface file | |
111 | <filename>/proc/pressure/memory</filename> is watched instead.</para></listitem> | |
112 | </orderedlist> | |
113 | ||
114 | <para>Or in other words: preferably any explicit configuration passed in by an invoking service manager | |
115 | (or similar) is used as notification source, before falling back to local notifications of the service, | |
116 | and finally to global notifications of the system.</para> | |
117 | ||
118 | <para>Well-behaving services and applications are recommended to react to memory pressure events by | |
119 | executing one or more of the following operations, in order to ensure optimal behaviour even on loaded | |
120 | and resource-constrained systems:</para> | |
121 | ||
122 | <itemizedlist> | |
123 | <listitem><para>Release allocation caches such as <function>malloc_trim()</function> or similar, both | |
124 | implemented in the libraries consumed by the program and in private allocation caches of the program | |
125 | itself.</para></listitem> | |
126 | ||
127 | <listitem><para>Release any other form of in-memory caches that can easily be recovered if | |
128 | needed (e.g. browser caches).</para></listitem> | |
129 | ||
130 | <listitem><para>Terminate idle worker threads or processes, or similar.</para></listitem> | |
131 | ||
132 | <listitem><para>Even exit entirely from the program if it is idle and can be automatically started when | |
133 | needed (for example via socket or bus activation).</para></listitem> | |
134 | </itemizedlist> | |
135 | ||
136 | <para>Any of the suggested operations should help easing memory pressure situations and allowing the | |
137 | system to make progress by reclaiming the memory for other purposes.</para> | |
138 | ||
139 | <para>This event source typically fires on memory pressure stalls, i.e. when operational latency above a | |
140 | configured threshold already has been seen. This should be taken into consideration when discussing | |
141 | whether later latency to re-aquire any released resources is acceptable: it's usually more important to | |
142 | think of the latencies that already happened than those coming up in future.</para> | |
143 | ||
144 | <para>The <function>sd_event_source_set_memory_pressure_type()</function> and | |
145 | <function>sd_event_source_set_memory_pressure_period()</function> functions can be used to fine-tune the | |
146 | PSI parameters for pressure notifications. The former takes either <literal>some</literal>, | |
147 | <literal>full</literal> as second parameter, the latter takes threshold and period times in microseconds | |
148 | as parameters. For details about these three parameters see the PSI documentation. Note that these two | |
149 | calls must be invoked immediately after allocating the event source, as they must be configured before | |
c73676dc | 150 | polling begins. Also note that these calls will fail if memory pressure parameterization has been passed |
f8a32e67 LP |
151 | in via the <varname>$MEMORY_PRESSURE_WATCH</varname>/<varname>$MEMORY_PRESSURE_WRITE</varname> |
152 | environment variables (or in other words: configuration supplied by a service manager wins over internal | |
153 | settings).</para> | |
154 | ||
155 | <para>The <function>sd_event_trim_memory()</function> function releases various internal allocation | |
156 | caches maintained by <filename>libsystemd</filename> and then invokes glibc's <citerefentry | |
157 | project='man-pages'><refentrytitle>malloc_trim</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This | |
158 | makes the operation executed when the handler function parameter of | |
159 | <function>sd_event_add_memory_pressure</function> is passed as <constant>NULL</constant> directly | |
160 | accessible for invocation at any time (see above). This function will log a structured log message at | |
161 | <constant>LOG_DEBUG</constant> level (with message ID f9b0be465ad540d0850ad32172d57c21) about the memory | |
162 | pressure operation.</para> | |
a4b13ae1 LP |
163 | |
164 | <para>For further details see <ulink url="https://systemd.io/MEMORY_PRESSURE">Memory Pressure Handling in | |
165 | systemd</ulink>.</para> | |
f8a32e67 LP |
166 | </refsect1> |
167 | ||
168 | <refsect1> | |
169 | <title>Return Value</title> | |
170 | ||
171 | <para>On success, these functions return 0 or a positive | |
172 | integer. On failure, they return a negative errno-style error | |
173 | code.</para> | |
174 | ||
175 | <refsect2> | |
176 | <title>Errors</title> | |
177 | ||
178 | <para>Returned errors may indicate the following problems:</para> | |
179 | ||
180 | <variablelist> | |
181 | <varlistentry> | |
182 | <term><constant>-ENOMEM</constant></term> | |
183 | ||
ec07c3c8 AK |
184 | <listitem><para>Not enough memory to allocate an object.</para> |
185 | ||
186 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
187 | </varlistentry> |
188 | ||
189 | <varlistentry> | |
190 | <term><constant>-EINVAL</constant></term> | |
191 | ||
ec07c3c8 AK |
192 | <listitem><para>An invalid argument has been passed.</para> |
193 | ||
194 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
195 | </varlistentry> |
196 | ||
197 | <varlistentry> | |
198 | <term><constant>-EHOSTDOWN</constant></term> | |
199 | ||
200 | <listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname> variable has been set to the literal | |
201 | string <filename>/dev/null</filename>, in order to explicitly disable memory pressure | |
ec07c3c8 AK |
202 | handling.</para> |
203 | ||
204 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
205 | </varlistentry> |
206 | ||
207 | <varlistentry> | |
208 | <term><constant>-EBADMSG</constant></term> | |
209 | ||
210 | <listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname> variable has been set to an invalid | |
ec07c3c8 AK |
211 | string, for example a relative rather than an absolute path.</para> |
212 | ||
213 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
214 | </varlistentry> |
215 | ||
216 | <varlistentry> | |
217 | <term><constant>-ENOTTY</constant></term> | |
218 | ||
219 | <listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname> variable points to a regular file | |
ec07c3c8 AK |
220 | outside of the procfs or cgroupfs file systems.</para> |
221 | ||
222 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
223 | </varlistentry> |
224 | ||
225 | <varlistentry> | |
226 | <term><constant>-EOPNOTSUPP</constant></term> | |
227 | ||
228 | <listitem><para>No configuration via <varname>$MEMORY_PRESSURE_WATCH</varname> has been specified | |
ec07c3c8 AK |
229 | and the local kernel does not support the PSI interface.</para> |
230 | ||
231 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
232 | </varlistentry> |
233 | ||
234 | <varlistentry> | |
235 | <term><constant>-EBUSY</constant></term> | |
236 | ||
237 | <listitem><para>This is returned by <function>sd_event_source_set_memory_pressure_type()</function> | |
238 | and <function>sd_event_source_set_memory_pressure_period()</function> if invoked on event sources | |
ec07c3c8 AK |
239 | at a time later than immediately after allocating them.</para> |
240 | ||
241 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
242 | </varlistentry> |
243 | ||
244 | <varlistentry> | |
245 | <term><constant>-ESTALE</constant></term> | |
246 | ||
ec07c3c8 AK |
247 | <listitem><para>The event loop is already terminated.</para> |
248 | ||
249 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
250 | </varlistentry> |
251 | ||
252 | <varlistentry> | |
253 | <term><constant>-ECHILD</constant></term> | |
254 | ||
ec07c3c8 AK |
255 | <listitem><para>The event loop has been created in a different process, library or module instance.</para> |
256 | ||
257 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
258 | </varlistentry> |
259 | ||
260 | <varlistentry> | |
261 | <term><constant>-EDOM</constant></term> | |
262 | ||
ec07c3c8 AK |
263 | <listitem><para>The passed event source is not a signal event source.</para> |
264 | ||
265 | <xi:include href="version-info.xml" xpointer="v254"/></listitem> | |
f8a32e67 LP |
266 | </varlistentry> |
267 | ||
268 | </variablelist> | |
269 | </refsect2> | |
270 | </refsect1> | |
271 | ||
272 | <xi:include href="libsystemd-pkgconfig.xml" /> | |
273 | ||
69106f47 AK |
274 | <refsect1> |
275 | <title>History</title> | |
00f95506 AK |
276 | <para><function>sd_event_add_memory_pressure()</function>, |
277 | <function>sd_event_source_set_memory_pressure_type()</function>, | |
278 | <function>sd_event_source_set_memory_pressure_period()</function>, and | |
279 | <function>sd_event_trim_memory()</function> were added in version 254.</para> | |
69106f47 AK |
280 | </refsect1> |
281 | ||
f8a32e67 LP |
282 | <refsect1> |
283 | <title>See Also</title> | |
284 | ||
13a69c12 DT |
285 | <para><simplelist type="inline"> |
286 | <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member> | |
287 | <member><citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
288 | <member><citerefentry><refentrytitle>sd_event_new</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
289 | <member><citerefentry><refentrytitle>sd_event_add_io</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
290 | <member><citerefentry><refentrytitle>sd_event_add_time</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
291 | <member><citerefentry><refentrytitle>sd_event_add_child</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
292 | <member><citerefentry><refentrytitle>sd_event_add_inotify</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
293 | <member><citerefentry><refentrytitle>sd_event_add_defer</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
294 | <member><citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
295 | <member><citerefentry><refentrytitle>sd_event_source_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
296 | <member><citerefentry><refentrytitle>sd_event_source_set_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
297 | <member><citerefentry><refentrytitle>sd_event_source_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> | |
298 | </simplelist></para> | |
f8a32e67 LP |
299 | </refsect1> |
300 | ||
301 | </refentry> |