mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
oom: make memory pressure duration configurable through oomd.conf
This commit is contained in:
parent
664e54b1bb
commit
c20aa7b171
@ -65,13 +65,23 @@
|
||||
will take action. A unit can override this value with <varname>ManagedOOMMemoryPressureLimitPercent=</varname>.
|
||||
The memory pressure for this property represents the fraction of time in a 10 second window in which all tasks
|
||||
in the cgroup were delayed. For each monitored cgroup, if the memory pressure on that cgroup exceeds the
|
||||
limit set for more than 30 seconds, <command>systemd-oomd</command> will act on eligible descendant cgroups,
|
||||
limit set for longer than the duration set by <varname>DefaultMemoryPressureDurationSec=</varname>,
|
||||
<command>systemd-oomd</command> will act on eligible descendant cgroups,
|
||||
starting from the ones with the most reclaim activity to the least reclaim activity. Which cgroups are
|
||||
monitored and what action gets taken depends on what the unit has configured for
|
||||
<varname>ManagedOOMMemoryPressure=</varname>. Takes a percentage value between 0% and 100%, inclusive.
|
||||
Defaults to 60%.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DefaultMemoryPressureDurationSec=</varname></term>
|
||||
|
||||
<listitem><para>Sets the amount of time a unit's cgroup needs to have exceeded memory pressure limits before
|
||||
<command>systemd-oomd</command> will take action. Memory pressure limits are defined by
|
||||
<varname>DefaultMemoryPressureLimitPercent=</varname> and <varname>ManagedOOMMemoryPressureLimitPercent=</varname>.
|
||||
Defaults to 30 seconds when this property is unset or set to 0.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -306,7 +306,7 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
|
||||
m->post_action_delay_start = 0;
|
||||
}
|
||||
|
||||
r = oomd_pressure_above(m->monitored_mem_pressure_cgroup_contexts, PRESSURE_DURATION_USEC, &targets);
|
||||
r = oomd_pressure_above(m->monitored_mem_pressure_cgroup_contexts, m->default_mem_pressure_duration_usec, &targets);
|
||||
if (r == -ENOMEM)
|
||||
return log_error_errno(r, "Failed to check if memory pressure exceeded limits");
|
||||
else if (r == 1) {
|
||||
@ -325,7 +325,7 @@ static int monitor_cgroup_contexts_handler(sd_event_source *s, uint64_t usec, vo
|
||||
|
||||
SET_FOREACH(t, targets) {
|
||||
log_notice("Memory pressure for %s is greater than %lu for more than %"PRIu64" seconds and there was reclaim activity",
|
||||
t->path, LOAD_INT(t->mem_pressure_limit), PRESSURE_DURATION_USEC / USEC_PER_SEC);
|
||||
t->path, LOAD_INT(t->mem_pressure_limit), m->default_mem_pressure_duration_usec / USEC_PER_SEC);
|
||||
|
||||
r = oomd_kill_by_pgscan(candidates, t->path, m->dry_run);
|
||||
if (r == -ENOMEM)
|
||||
@ -471,7 +471,7 @@ static int manager_connect_bus(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit) {
|
||||
int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit, usec_t mem_pressure_usec) {
|
||||
unsigned long l;
|
||||
int r;
|
||||
|
||||
@ -487,6 +487,8 @@ int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressur
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m->default_mem_pressure_duration_usec = mem_pressure_usec ?: DEFAULT_MEM_PRESSURE_DURATION_USEC;
|
||||
|
||||
r = manager_connect_bus(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -505,6 +507,7 @@ int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressur
|
||||
int manager_get_dump_string(Manager *m, char **ret) {
|
||||
_cleanup_free_ char *dump = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
char buf[FORMAT_TIMESPAN_MAX];
|
||||
OomdCGroupContext *c;
|
||||
size_t size;
|
||||
char *key;
|
||||
@ -521,10 +524,12 @@ int manager_get_dump_string(Manager *m, char **ret) {
|
||||
"Dry Run: %s\n"
|
||||
"Swap Used Limit: %u%%\n"
|
||||
"Default Memory Pressure Limit: %lu%%\n"
|
||||
"Default Memory Pressure Duration: %s\n"
|
||||
"System Context:\n",
|
||||
yes_no(m->dry_run),
|
||||
m->swap_used_limit,
|
||||
LOAD_INT(m->default_mem_pressure_limit));
|
||||
LOAD_INT(m->default_mem_pressure_limit),
|
||||
format_timespan(buf, sizeof(buf), m->default_mem_pressure_duration_usec, USEC_PER_SEC));
|
||||
oomd_dump_system_context(&m->system_context, f, "\t");
|
||||
|
||||
fprintf(f, "Swap Monitored CGroups:\n");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* percentage of time all tasks were delayed (i.e. unproductive).
|
||||
* Generally 60 or higher might be acceptable for something like system.slice with no memory.high set; processes in
|
||||
* system.slice are assumed to be less latency sensitive. */
|
||||
#define PRESSURE_DURATION_USEC (30 * USEC_PER_SEC)
|
||||
#define DEFAULT_MEM_PRESSURE_DURATION_USEC (30 * USEC_PER_SEC)
|
||||
#define DEFAULT_MEM_PRESSURE_LIMIT 60
|
||||
#define DEFAULT_SWAP_USED_LIMIT 90
|
||||
|
||||
@ -33,6 +33,7 @@ struct Manager {
|
||||
bool dry_run;
|
||||
unsigned swap_used_limit;
|
||||
loadavg_t default_mem_pressure_limit;
|
||||
usec_t default_mem_pressure_duration_usec;
|
||||
|
||||
/* k: cgroup paths -> v: OomdCGroupContext
|
||||
* Used to detect when to take action. */
|
||||
@ -53,7 +54,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
|
||||
int manager_new(Manager **ret);
|
||||
|
||||
int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit);
|
||||
int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit, usec_t mem_pressure_usec);
|
||||
|
||||
int manager_get_dump_string(Manager *m, char **ret);
|
||||
|
||||
|
@ -31,6 +31,7 @@ struct OomdCGroupContext {
|
||||
|
||||
/* These are only used by oomd_pressure_above for acting on high memory pressure. */
|
||||
loadavg_t mem_pressure_limit;
|
||||
usec_t mem_pressure_duration_usec;
|
||||
usec_t last_hit_mem_pressure_limit;
|
||||
};
|
||||
|
||||
|
@ -19,11 +19,13 @@
|
||||
static bool arg_dry_run = false;
|
||||
static int arg_swap_used_limit = -1;
|
||||
static int arg_mem_pressure_limit = -1;
|
||||
static usec_t arg_mem_pressure_usec = 0;
|
||||
|
||||
static int parse_config(void) {
|
||||
static const ConfigTableItem items[] = {
|
||||
{ "OOM", "SwapUsedLimitPercent", config_parse_percent, 0, &arg_swap_used_limit },
|
||||
{ "OOM", "DefaultMemoryPressureLimitPercent", config_parse_percent, 0, &arg_mem_pressure_limit },
|
||||
{ "OOM", "DefaultMemoryPressureDurationSec", config_parse_sec, 0, &arg_mem_pressure_usec },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -160,7 +162,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create manager: %m");
|
||||
|
||||
r = manager_start(m, arg_dry_run, arg_swap_used_limit, arg_mem_pressure_limit);
|
||||
r = manager_start(m, arg_dry_run, arg_swap_used_limit, arg_mem_pressure_limit, arg_mem_pressure_usec);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to start up daemon: %m");
|
||||
|
||||
|
@ -14,3 +14,4 @@
|
||||
[OOM]
|
||||
#SwapUsedLimitPercent=90%
|
||||
#DefaultMemoryPressureLimitPercent=60%
|
||||
#DefaultMemoryPressureDurationSec=30s
|
||||
|
@ -14,12 +14,15 @@ if [[ "$cgroup_type" != *"cgroup2"* ]] && [[ "$cgroup_type" != *"0x63677270"* ]]
|
||||
fi
|
||||
[[ -e /skipped ]] && exit 0 || true
|
||||
|
||||
echo "DefaultMemoryPressureDurationSec=5s" >> /etc/systemd/oomd.conf
|
||||
|
||||
systemctl start testsuite-56-testbloat.service
|
||||
systemctl start testsuite-56-testchill.service
|
||||
|
||||
# Verify systemd-oomd is monitoring the expected units
|
||||
oomctl | grep "/testsuite-56-workload.slice"
|
||||
oomctl | grep "1%"
|
||||
oomctl | grep "Default Memory Pressure Duration: 5s"
|
||||
|
||||
# systemd-oomd watches for elevated pressure for 30 seconds before acting.
|
||||
# It can take time to build up pressure so either wait 5 minutes or for the service to fail.
|
||||
|
Loading…
Reference in New Issue
Block a user