Skip to content

Commit

Permalink
Don't kill anything if there's not enough anon memory used
Browse files Browse the repository at this point in the history
When /dev/shm and /tmp (when on tmpfs) gets filled up, earlyoom
would start killing everything, without improving the situation.

Check if we *possibly* could kill enough processes (i.e. anon memory)
to get the available memory over the minimum. If not, do nothing.

Fixes: #274
Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1012870
  • Loading branch information
rfjakob committed Nov 12, 2022
1 parent 1e48625 commit 42860d6
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,30 @@ static unsigned sleep_time_ms(const poll_loop_args_t* args, const meminfo_t* m)
*/
static int lowmem_sig(const poll_loop_args_t* args, const meminfo_t* m)
{
int sig = 0;
if (m->MemAvailablePercent <= args->mem_kill_percent && m->SwapFreePercent <= args->swap_kill_percent)
return SIGKILL;
sig = SIGKILL;
else if (m->MemAvailablePercent <= args->mem_term_percent && m->SwapFreePercent <= args->swap_term_percent)
return SIGTERM;
return 0;
sig = SIGTERM;
else
return 0;

long long want_kib = (long long)((double)m->SwapTotalKiB * args->swap_term_percent / 100 + (double)m->MemTotalKiB * args->mem_term_percent / 100);
long long have_kib = m->MemAvailableKiB + m->SwapFreeMiB * 1024;
// how much do we have to free by killing processes?
long long to_free_kib = want_kib - have_kib;
debug("%s: want_kib=%lld have_kib=%lld to_free_kib=%lld\n", __func__, want_kib, have_kib, to_free_kib);

// Let's not kill *everything* when the user has filled up /dev/shm and /tmp (when on tmpfs).
if (to_free_kib >= m->AnonPagesKiB) {
warn("We need to free %lld MiB, but there's only %lld MiB of anon memory that we could free!\n",
to_free_kib / 1024, m->AnonPagesKiB / 1024);
warn("Nothing we can do here. Sleeping 1 second.\n");
sleep(1);
return 0;
}

return sig;
}

// poll_loop is the main event loop. Never returns.
Expand Down

0 comments on commit 42860d6

Please sign in to comment.