Skip to content

Commit

Permalink
Remove option to use kernel oom-killer (-k)
Browse files Browse the repository at this point in the history
The kernel oom-killer has many problems, has no
features, and is probably used by nobody at all.

Quoting from the (remove) function comment:

 * Invoke the kernel oom killer by writing "f" into /proc/sysrq-trigger
 *
 * This approach has a few problems:
 * 1) It is disallowed by default (even for root) on Fedora 20.
 *    You have to first write "1" into /proc/sys/kernel/sysrq to enable the "f"
 *    trigger.
 * 2) The Chrome web browser assigns a penalty of 300 onto its own tab renderer
 *    processes. On an 8GB RAM machine, this means 2400MB, and will lead to every
 *    tab being killed before the actual memory hog
 *    See https://code.google.com/p/chromium/issues/detail?id=333617 for more info
 * 3) It is broken in 4.0.5 - see
 *    f7e2ced

#80
  • Loading branch information
rfjakob committed Jul 16, 2018
1 parent ff1c7df commit 368c172
Show file tree
Hide file tree
Showing 5 changed files with 8 additions and 66 deletions.
2 changes: 1 addition & 1 deletion MANPAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ set available memory minimum to SIZE KiB
set free swap minimum to SIZE KiB

#### -k
use kernel oom killer instead of own user-space implementation
removed in earlyoom v1.2, ignored for compatibility

#### -i
user-space oom killer should ignore positive oom_score_adj values
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ accept

Changelog
---------
* v1.2, in progress
* Remove option to use kernel oom-killer (`-k`) ([issue #80](https://github.com/rfjakob/earlyoom/issues/80))
* v1.1, 2018-07-07
* Fix possible shell code injection through GUI notifications
([commit](https://github.com/rfjakob/earlyoom/commit/ab79aa3895077676f50120f15e2bb22915446db9))
Expand Down
48 changes: 1 addition & 47 deletions kill.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static struct procinfo get_process_stats(int pid)
* Find the process with the largest oom_score and kill it.
* See trigger_kernel_oom() for the reason why this is done in userspace.
*/
static void userspace_kill(poll_loop_args_t args, int sig)
void userspace_kill(poll_loop_args_t args, int sig)
{
struct dirent* d;
char buf[256];
Expand Down Expand Up @@ -243,49 +243,3 @@ static void userspace_kill(poll_loop_args_t args, int sig)
sleep(1);
}
}

/*
* Invoke the kernel oom killer by writing "f" into /proc/sysrq-trigger
*
* This approach has a few problems:
* 1) It is disallowed by default (even for root) on Fedora 20.
* You have to first write "1" into /proc/sys/kernel/sysrq to enable the "f"
* trigger.
* 2) The Chrome web browser assigns a penalty of 300 onto its own tab renderer
* processes. On an 8GB RAM machine, this means 2400MB, and will lead to every
* tab being killed before the actual memory hog
* See https://code.google.com/p/chromium/issues/detail?id=333617 for more info
* 3) It is broken in 4.0.5 - see
* https://github.com/rfjakob/earlyoom/commit/f7e2cedce8e9605c688d0c6d7dc26b7e81817f02
* Because of these issues, kill_by_rss() is used instead by default.
*/
void trigger_kernel_oom(int sig, char* notif_command)
{
FILE* trig_fd;
trig_fd = fopen("sysrq-trigger", "w");
if (trig_fd == NULL) {
perror("Could not open /proc/sysrq-trigger");
exit(7);
}
if (sig == 9) {
fprintf(stderr, "Invoking oom killer: ");
maybe_notify(notif_command,
"-i dialog-warning 'earlyoom' 'Invoking OOM killer'");

if (fprintf(trig_fd, "f\n") != 2) {
perror("failed");
maybe_notify(notif_command,
"-i dialog-error 'earlyoom' 'Error: Failed to invoke OOM killer'");
} else
fprintf(stderr, "done\n");
}
fclose(trig_fd);
}

void handle_oom(poll_loop_args_t args, int sig)
{
if (args.kernel_oom_killer)
trigger_kernel_oom(sig, args.notif_command);
else
userspace_kill(args, sig);
}
4 changes: 1 addition & 3 deletions kill.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ typedef struct {
* we start killing processes */
int mem_min_percent;
int swap_min_percent;
/* use the kernel oom killer? */
bool kernel_oom_killer;
/* ignore /proc/PID/oom_score_adj? */
bool ignore_oom_score_adj;
/* notifcation command to launch when killing something. NULL = no-op. */
Expand All @@ -22,4 +20,4 @@ typedef struct {
int report_interval_ms;
} poll_loop_args_t;

void handle_oom(poll_loop_args_t args, int sig);
void userspace_kill(poll_loop_args_t args, int sig);
18 changes: 3 additions & 15 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ int main(int argc, char* argv[])
}
break;
case 'k':
args.kernel_oom_killer = 1;
fprintf(stderr, "Using kernel oom killer\n");
fprintf(stderr, "Option -k is ignored since earlyoom v1.2\n");
break;
case 'i':
args.ignore_oom_score_adj = 1;
Expand Down Expand Up @@ -155,7 +154,6 @@ int main(int argc, char* argv[])
" -s PERCENT set free swap minimum to PERCENT of total (default 10 %%)\n"
" -M SIZE set available memory minimum to SIZE KiB\n"
" -S SIZE set free swap minimum to SIZE KiB\n"
" -k use kernel oom killer instead of own user-space implementation\n"
" -i user-space oom killer should ignore positive oom_score_adj values\n"
" -n enable notifications using \"notify-send\"\n"
" -N COMMAND enable notifications using COMMAND\n"
Expand Down Expand Up @@ -184,16 +182,6 @@ int main(int argc, char* argv[])
exit(2);
}

if (args.kernel_oom_killer && args.ignore_oom_score_adj) {
fprintf(stderr, "Kernel oom killer does not support -i\n");
exit(2);
}

if (args.kernel_oom_killer && (prefer_cmds || avoid_cmds)) {
fprintf(stderr, "Kernel oom killer does not support --prefer/--avoid\n");
exit(2);
}

if (prefer_cmds) {
args.prefer_regex = &_prefer_regex;
if (regcomp(args.prefer_regex, prefer_cmds, REG_EXTENDED | REG_NOSUB) != 0) {
Expand Down Expand Up @@ -250,7 +238,7 @@ int main(int argc, char* argv[])
/* Dry-run oom kill to make sure stack grows to maximum size before
* calling mlockall()
*/
handle_oom(args, 0);
userspace_kill(args, 0);

if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
perror("Could not lock memory - continuing anyway");
Expand Down Expand Up @@ -321,7 +309,7 @@ static void poll_loop(const poll_loop_args_t args)
m.SwapTotalMiB,
m.SwapFreePercent,
args.swap_min_percent);
handle_oom(args, 9);
userspace_kill(args, 9);
// With swap enabled, the kernel seems to need more than 100ms to free the memory
// of the killed process. This means that earlyoom would immediately kill another
// process. Sleep a little extra to give the kernel time to free the memory.
Expand Down

0 comments on commit 368c172

Please sign in to comment.