Tejun Heo wrote: > If > the possibility of sysrq getting stuck behind concurrency management > is an issue, queueing them on an unbound or highpri workqueue should > be good enough. Regarding SysRq-f, we could do like below. Though I think that converting the OOM killer into a dedicated kernel thread would allow more things to do (e.g. Oleg's memory zapping code, my timeout based next victim selection). diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 5381a72..46b951aa 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -47,6 +47,7 @@ #include <linux/syscalls.h> #include <linux/of.h> #include <linux/rcupdate.h> +#include <linux/kthread.h> #include <asm/ptrace.h> #include <asm/irq_regs.h> @@ -351,27 +352,35 @@ static struct sysrq_key_op sysrq_term_op = { .enable_mask = SYSRQ_ENABLE_SIGNAL, }; -static void moom_callback(struct work_struct *ignored) +static DECLARE_WAIT_QUEUE_HEAD(moom_wait); + +static int moom_callback(void *unused) { const gfp_t gfp_mask = GFP_KERNEL; - struct oom_control oc = { - .zonelist = node_zonelist(first_memory_node, gfp_mask), - .nodemask = NULL, - .gfp_mask = gfp_mask, - .order = -1, - }; - - mutex_lock(&oom_lock); - if (!out_of_memory(&oc)) - pr_info("OOM request ignored because killer is disabled\n"); - mutex_unlock(&oom_lock); + DEFINE_WAIT(wait); + + while (1) { + struct oom_control oc = { + .zonelist = node_zonelist(first_memory_node, gfp_mask), + .nodemask = NULL, + .gfp_mask = gfp_mask, + .order = -1, + }; + + prepare_to_wait(&moom_wait, &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&moom_wait, &wait); + mutex_lock(&oom_lock); + if (!out_of_memory(&oc)) + pr_info("OOM request ignored because killer is disabled\n"); + mutex_unlock(&oom_lock); + } + return 0; } -static DECLARE_WORK(moom_work, moom_callback); - static void sysrq_handle_moom(int key) { - schedule_work(&moom_work); + wake_up(&moom_wait); } static struct sysrq_key_op sysrq_moom_op = { .handler = sysrq_handle_moom, @@ -1116,6 +1125,9 @@ static inline void sysrq_init_procfs(void) static int __init sysrq_init(void) { + struct task_struct *task = kthread_run(moom_callback, NULL, + "manual_oom"); + BUG_ON(IS_ERR(task)); sysrq_init_procfs(); if (sysrq_on()) -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>