// SPDX-License-Identifier: GPL-2.0/* * Linux Magic System Request Key Hacks * * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> * based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz> * * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com> * overhauled to use key registration * based upon discusions in irc://irc.openprojects.net/#kernelnewbies * * Copyright (c) 2010 Dmitry Torokhov * Input handler conversion */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/sched/signal.h>#include <linux/sched/rt.h>#include <linux/sched/debug.h>#include <linux/sched/task.h>#include <linux/ctype.h>#include <linux/interrupt.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/mount.h>#include <linux/kdev_t.h>#include <linux/major.h>#include <linux/reboot.h>#include <linux/sysrq.h>#include <linux/kbd_kern.h>#include <linux/proc_fs.h>#include <linux/nmi.h>#include <linux/quotaops.h>#include <linux/perf_event.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/suspend.h>#include <linux/writeback.h>#include <linux/swap.h>#include <linux/spinlock.h>#include <linux/vt_kern.h>#include <linux/workqueue.h>#include <linux/hrtimer.h>#include <linux/oom.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/uaccess.h>#include <linux/moduleparam.h>#include <linux/jiffies.h>#include <linux/syscalls.h>#include <linux/of.h>#include <linux/rcupdate.h> #include <asm/ptrace.h>#include <asm/irq_regs.h> /* Whether we react on sysrq keys or just ignore them */static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;static bool __read_mostly sysrq_always_enabled; static bool sysrq_on(void){ return sysrq_enabled || sysrq_always_enabled;} /** * sysrq_mask - Getter for sysrq_enabled mask. * * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise. */int sysrq_mask(void){ if (sysrq_always_enabled) return 1; return sysrq_enabled;}EXPORT_SYMBOL_GPL(sysrq_mask); /* * A value of 1 means 'all', other nonzero values are an op mask: */static bool sysrq_on_mask(int mask){ return sysrq_always_enabled || sysrq_enabled == 1 || (sysrq_enabled & mask);} static int __init sysrq_always_enabled_setup(char *str){ sysrq_always_enabled = true; pr_info("sysrq always enabled.\n"); return 1;} __setup("sysrq_always_enabled", sysrq_always_enabled_setup); static void sysrq_handle_loglevel(u8 key){ u8 loglevel = key - '0'; console_loglevel = CONSOLE_LOGLEVEL_DEFAULT; pr_info("Loglevel set to %u\n", loglevel); console_loglevel = loglevel;}static const struct sysrq_key_op sysrq_loglevel_op = { .handler = sysrq_handle_loglevel, .help_msg = "loglevel(0-9)", .action_msg = "Changing Loglevel", .enable_mask = SYSRQ_ENABLE_LOG,}; #ifdef CONFIG_VTstatic void sysrq_handle_SAK(u8 key){ struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; schedule_work(SAK_work);}static const struct sysrq_key_op sysrq_SAK_op = { .handler = sysrq_handle_SAK, .help_msg = "sak(k)", .action_msg = "SAK", .enable_mask = SYSRQ_ENABLE_KEYBOARD,};#else#define sysrq_SAK_op (*(const struct sysrq_key_op *)NULL)#endif #ifdef CONFIG_VTstatic void sysrq_handle_unraw(u8 key){ vt_reset_unicode(fg_console);} static const struct sysrq_key_op sysrq_unraw_op = { .handler = sysrq_handle_unraw, .help_msg = "unraw(r)", .action_msg = "Keyboard mode set to system default", .enable_mask = SYSRQ_ENABLE_KEYBOARD,};#else#define sysrq_unraw_op (*(const struct sysrq_key_op *)NULL)#endif /* CONFIG_VT */ static void sysrq_handle_crash(u8 key){ /* release the RCU read lock before crashing */ rcu_read_unlock(); panic("sysrq triggered crash\n");}static const struct sysrq_key_op sysrq_crash_op = { .handler = sysrq_handle_crash, .help_msg = "crash(c)", .action_msg = "Trigger a crash", .enable_mask = SYSRQ_ENABLE_DUMP,}; static void sysrq_handle_reboot(u8 key){ lockdep_off(); local_irq_enable(); emergency_restart();}static const struct sysrq_key_op sysrq_reboot_op = { .handler = sysrq_handle_reboot, .help_msg = "reboot(b)", .action_msg = "Resetting", .enable_mask = SYSRQ_ENABLE_BOOT,}; const struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; static void sysrq_handle_sync(u8 key){ emergency_sync();}static const struct sysrq_key_op sysrq_sync_op = { .handler = sysrq_handle_sync, .help_msg = "sync(s)", .action_msg = "Emergency Sync", .enable_mask = SYSRQ_ENABLE_SYNC,}; static void sysrq_handle_show_timers(u8 key){ sysrq_timer_list_show();} static const struct sysrq_key_op sysrq_show_timers_op = { .handler = sysrq_handle_show_timers, .help_msg = "show-all-timers(q)", .action_msg = "Show clockevent devices & pending hrtimers (no others)",}; static void sysrq_handle_mountro(u8 key){ emergency_remount();}static const struct sysrq_key_op sysrq_mountro_op = { .handler = sysrq_handle_mountro, .help_msg = "unmount(u)", .action_msg = "Emergency Remount R/O", .enable_mask = SYSRQ_ENABLE_REMOUNT,}; #ifdef CONFIG_LOCKDEPstatic void sysrq_handle_showlocks(u8 key){ debug_show_all_locks();} static const struct sysrq_key_op sysrq_showlocks_op = { .handler = sysrq_handle_showlocks, .help_msg = "show-all-locks(d)", .action_msg = "Show Locks Held",};#else#define sysrq_showlocks_op (*(const struct sysrq_key_op *)NULL)#endif #ifdef CONFIG_SMPstatic DEFINE_RAW_SPINLOCK(show_lock); static void showacpu(void *dummy){ unsigned long flags; /* Idle CPUs have no interesting backtrace. */ if (idle_cpu(smp_processor_id())) { pr_info("CPU%d: backtrace skipped as idling\n", smp_processor_id()); return; } raw_spin_lock_irqsave(&show_lock, flags); pr_info("CPU%d:\n", smp_processor_id()); show_stack(NULL, NULL, KERN_INFO); raw_spin_unlock_irqrestore(&show_lock, flags);} static void sysrq_showregs_othercpus(struct work_struct *dummy){ smp_call_function(showacpu, NULL, 0);} static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); static void sysrq_handle_showallcpus(u8 key){ /* * Fall back to the workqueue based printing if the * backtrace printing did not succeed or the * architecture has no support for it: */ if (!trigger_all_cpu_backtrace()) { struct pt_regs *regs = NULL; if (in_hardirq()) regs = get_irq_regs(); pr_info("CPU%d:\n", get_cpu()); if (regs) show_regs(regs); else show_stack(NULL, NULL, KERN_INFO); schedule_work(&sysrq_showallcpus); put_cpu(); }} static const struct sysrq_key_op sysrq_showallcpus_op = { .handler = sysrq_handle_showallcpus, .help_msg = "show-backtrace-all-active-cpus(l)", .action_msg = "Show backtrace of all active CPUs", .enable_mask = SYSRQ_ENABLE_DUMP,};#else#define sysrq_showallcpus_op (*(const struct sysrq_key_op *)NULL)#endif static void sysrq_handle_showregs(u8 key){ struct pt_regs *regs = NULL; if (in_hardirq()) regs = get_irq_regs(); if (regs) show_regs(regs); perf_event_print_debug();}static const struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, .help_msg = "show-registers(p)", .action_msg = "Show Regs", .enable_mask = SYSRQ_ENABLE_DUMP,}; static void sysrq_handle_showstate(u8 key){ show_state(); show_all_workqueues();}static const struct sysrq_key_op sysrq_showstate_op = { .handler = sysrq_handle_showstate, .help_msg = "show-task-states(t)", .action_msg = "Show State", .enable_mask = SYSRQ_ENABLE_DUMP,}; static void sysrq_handle_showstate_blocked(u8 key){ show_state_filter(TASK_UNINTERRUPTIBLE);}static const struct sysrq_key_op sysrq_showstate_blocked_op = { .handler = sysrq_handle_showstate_blocked, .help_msg = "show-blocked-tasks(w)", .action_msg = "Show Blocked State", .enable_mask = SYSRQ_ENABLE_DUMP,}; #ifdef CONFIG_TRACING#include <linux/ftrace.h> static void sysrq_ftrace_dump(u8 key){ ftrace_dump(DUMP_ALL);}static const struct sysrq_key_op sysrq_ftrace_dump_op = { .handler = sysrq_ftrace_dump, .help_msg = "dump-ftrace-buffer(z)", .action_msg = "Dump ftrace buffer", .enable_mask = SYSRQ_ENABLE_DUMP,};#else#define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL)#endif static void sysrq_handle_showmem(u8 key){ show_mem();}static const struct sysrq_key_op sysrq_showmem_op = { .handler = sysrq_handle_showmem, .help_msg = "show-memory-usage(m)", .action_msg = "Show Memory", .enable_mask = SYSRQ_ENABLE_DUMP,}; /* * Signal sysrq helper function. Sends a signal to all user processes. */static void send_sig_all(int sig){ struct task_struct *p; read_lock(&tasklist_lock); for_each_process(p) { if (p->flags & PF_KTHREAD) continue; if (is_global_init(p)) continue; do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); } read_unlock(&tasklist_lock);} static void sysrq_handle_term(u8 key){ send_sig_all(SIGTERM); console_loglevel = CONSOLE_LOGLEVEL_DEBUG;}static const struct sysrq_key_op sysrq_term_op = { .handler = sysrq_handle_term, .help_msg = "terminate-all-tasks(e)", .action_msg = "Terminate All Tasks", .enable_mask = SYSRQ_ENABLE_SIGNAL,}; static void moom_callback(struct work_struct *ignored){ const gfp_t gfp_mask = GFP_KERNEL; struct oom_control oc = { .zonelist = node_zonelist(first_memory_node, gfp_mask), .nodemask = NULL, .memcg = NULL, .gfp_mask = gfp_mask, .order = -1, }; mutex_lock(&oom_lock); if (!out_of_memory(&oc)) pr_info("OOM request ignored. No task eligible\n"); mutex_unlock(&oom_lock);} static DECLARE_WORK(moom_work, moom_callback); static void sysrq_handle_moom(u8 key){ schedule_work(&moom_work);}static const struct sysrq_key_op sysrq_moom_op = { .handler = sysrq_handle_moom, .help_msg = "memory-full-oom-kill(f)", .action_msg = "Manual OOM execution", .enable_mask = SYSRQ_ENABLE_SIGNAL,}; #ifdef CONFIG_BLOCKstatic void sysrq_handle_thaw(u8 key){ emergency_thaw_all();}static const struct sysrq_key_op sysrq_thaw_op = { .handler = sysrq_handle_thaw, .help_msg = "thaw-filesystems(j)", .action_msg = "Emergency Thaw of all frozen filesystems", .enable_mask = SYSRQ_ENABLE_SIGNAL,};#else#define sysrq_thaw_op (*(const struct sysrq_key_op *)NULL)#endif static void sysrq_handle_kill(u8 key){ send_sig_all(SIGKILL); console_loglevel = CONSOLE_LOGLEVEL_DEBUG;}static const struct sysrq_key_op sysrq_kill_op = { .handler = sysrq_handle_kill, .help_msg = "kill-all-tasks(i)", .action_msg = "Kill All Tasks", .enable_mask = SYSRQ_ENABLE_SIGNAL,}; static void sysrq_handle_unrt(u8 key){ normalize_rt_tasks();}static const struct sysrq_key_op sysrq_unrt_op = { .handler = sysrq_handle_unrt, .help_msg = "nice-all-RT-tasks(n)", .action_msg = "Nice All RT Tasks", .enable_mask = SYSRQ_ENABLE_RTNICE,}; static void sysrq_handle_replay_logs(u8 key){ console_try_replay_all();}static struct sysrq_key_op sysrq_replay_logs_op = { .handler = sysrq_handle_replay_logs, .help_msg = "replay-kernel-logs(R)", .action_msg = "Replay kernel logs on consoles", .enable_mask = SYSRQ_ENABLE_DUMP,}; /* Key Operations table and lock */static DEFINE_SPINLOCK(sysrq_key_table_lock); static const struct sysrq_key_op *sysrq_key_table[62] = { &sysrq_loglevel_op, /* 0 */ &sysrq_loglevel_op, /* 1 */ &sysrq_loglevel_op, /* 2 */ &sysrq_loglevel_op, /* 3 */ &sysrq_loglevel_op, /* 4 */ &sysrq_loglevel_op, /* 5 */ &sysrq_loglevel_op, /* 6 */ &sysrq_loglevel_op, /* 7 */ &sysrq_loglevel_op, /* 8 */ &sysrq_loglevel_op, /* 9 */ /* * a: Don't use for system provided sysrqs, it is handled specially on * sparc and will never arrive. */ NULL, /* a */ &sysrq_reboot_op, /* b */ &sysrq_crash_op, /* c */ &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ /* g: May be registered for the kernel debugger */ NULL, /* g */ NULL, /* h - reserved for help */ &sysrq_kill_op, /* i */ &sysrq_thaw_op, /* j */ &sysrq_SAK_op, /* k */ &sysrq_showallcpus_op, /* l */ &sysrq_showmem_op, /* m */ &sysrq_unrt_op, /* n */ /* o: This will often be registered as 'Off' at init time */ NULL, /* o */ &sysrq_showregs_op, /* p */Lines 1–500 of 1259. Load more
// SPDX-License-Identifier: GPL-2.0 /* * Linux Magic System Request Key Hacks * * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> * based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz> * * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com> * overhauled to use key registration * based upon discusions in irc://irc.openprojects.net/#kernelnewbies * * Copyright (c) 2010 Dmitry Torokhov * Input handler conversion */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/sched/signal.h> #include <linux/sched/rt.h> #include <linux/sched/debug.h> #include <linux/sched/task.h> #include <linux/ctype.h> #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/mount.h> #include <linux/kdev_t.h> #include <linux/major.h> #include <linux/reboot.h> #include <linux/sysrq.h> #include <linux/kbd_kern.h> #include <linux/proc_fs.h> #include <linux/nmi.h> #include <linux/quotaops.h> #include <linux/perf_event.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/suspend.h> #include <linux/writeback.h> #include <linux/swap.h> #include <linux/spinlock.h> #include <linux/vt_kern.h> #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/oom.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/uaccess.h> #include <linux/moduleparam.h> #include <linux/jiffies.h> #include <linux/syscalls.h> #include <linux/of.h> #include <linux/rcupdate.h> #include <asm/ptrace.h> #include <asm/irq_regs.h> /* Whether we react on sysrq keys or just ignore them */ static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE; static bool __read_mostly sysrq_always_enabled; static bool sysrq_on(void) { return sysrq_enabled || sysrq_always_enabled; } /** * sysrq_mask - Getter for sysrq_enabled mask. * * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise. */ int sysrq_mask(void) { if (sysrq_always_enabled) return 1; return sysrq_enabled; } EXPORT_SYMBOL_GPL(sysrq_mask); /* * A value of 1 means 'all', other nonzero values are an op mask: */ static bool sysrq_on_mask(int mask) { return sysrq_always_enabled || sysrq_enabled == 1 || (sysrq_enabled & mask); } static int __init sysrq_always_enabled_setup(char *str) { sysrq_always_enabled = true; pr_info("sysrq always enabled.\n"); return 1; } __setup("sysrq_always_enabled", sysrq_always_enabled_setup); static void sysrq_handle_loglevel(u8 key) { u8 loglevel = key - '0'; console_loglevel = CONSOLE_LOGLEVEL_DEFAULT; pr_info("Loglevel set to %u\n", loglevel); console_loglevel = loglevel; } static const struct sysrq_key_op sysrq_loglevel_op = { .handler = sysrq_handle_loglevel, .help_msg = "loglevel(0-9)", .action_msg = "Changing Loglevel", .enable_mask = SYSRQ_ENABLE_LOG, }; #ifdef CONFIG_VT static void sysrq_handle_SAK(u8 key) { struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; schedule_work(SAK_work); } static const struct sysrq_key_op sysrq_SAK_op = { .handler = sysrq_handle_SAK, .help_msg = "sak(k)", .action_msg = "SAK", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else #define sysrq_SAK_op (*(const struct sysrq_key_op *)NULL) #endif #ifdef CONFIG_VT static void sysrq_handle_unraw(u8 key) { vt_reset_unicode(fg_console); } static const struct sysrq_key_op sysrq_unraw_op = { .handler = sysrq_handle_unraw, .help_msg = "unraw(r)", .action_msg = "Keyboard mode set to system default", .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else #define sysrq_unraw_op (*(const struct sysrq_key_op *)NULL) #endif /* CONFIG_VT */ static void sysrq_handle_crash(u8 key) { /* release the RCU read lock before crashing */ rcu_read_unlock(); panic("sysrq triggered crash\n"); } static const struct sysrq_key_op sysrq_crash_op = { .handler = sysrq_handle_crash, .help_msg = "crash(c)", .action_msg = "Trigger a crash", .enable_mask = SYSRQ_ENABLE_DUMP, }; static void sysrq_handle_reboot(u8 key) { lockdep_off(); local_irq_enable(); emergency_restart(); } static const struct sysrq_key_op sysrq_reboot_op = { .handler = sysrq_handle_reboot, .help_msg = "reboot(b)", .action_msg = "Resetting", .enable_mask = SYSRQ_ENABLE_BOOT, }; const struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; static void sysrq_handle_sync(u8 key) { emergency_sync(); } static const struct sysrq_key_op sysrq_sync_op = { .handler = sysrq_handle_sync, .help_msg = "sync(s)", .action_msg = "Emergency Sync", .enable_mask = SYSRQ_ENABLE_SYNC, }; static void sysrq_handle_show_timers(u8 key) { sysrq_timer_list_show(); } static const struct sysrq_key_op sysrq_show_timers_op = { .handler = sysrq_handle_show_timers, .help_msg = "show-all-timers(q)", .action_msg = "Show clockevent devices & pending hrtimers (no others)", }; static void sysrq_handle_mountro(u8 key) { emergency_remount(); } static const struct sysrq_key_op sysrq_mountro_op = { .handler = sysrq_handle_mountro, .help_msg = "unmount(u)", .action_msg = "Emergency Remount R/O", .enable_mask = SYSRQ_ENABLE_REMOUNT, }; #ifdef CONFIG_LOCKDEP static void sysrq_handle_showlocks(u8 key) { debug_show_all_locks(); } static const struct sysrq_key_op sysrq_showlocks_op = { .handler = sysrq_handle_showlocks, .help_msg = "show-all-locks(d)", .action_msg = "Show Locks Held", }; #else #define sysrq_showlocks_op (*(const struct sysrq_key_op *)NULL) #endif #ifdef CONFIG_SMP static DEFINE_RAW_SPINLOCK(show_lock); static void showacpu(void *dummy) { unsigned long flags; /* Idle CPUs have no interesting backtrace. */ if (idle_cpu(smp_processor_id())) { pr_info("CPU%d: backtrace skipped as idling\n", smp_processor_id()); return; } raw_spin_lock_irqsave(&show_lock, flags); pr_info("CPU%d:\n", smp_processor_id()); show_stack(NULL, NULL, KERN_INFO); raw_spin_unlock_irqrestore(&show_lock, flags); } static void sysrq_showregs_othercpus(struct work_struct *dummy) { smp_call_function(showacpu, NULL, 0); } static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); static void sysrq_handle_showallcpus(u8 key) { /* * Fall back to the workqueue based printing if the * backtrace printing did not succeed or the * architecture has no support for it: */ if (!trigger_all_cpu_backtrace()) { struct pt_regs *regs = NULL; if (in_hardirq()) regs = get_irq_regs(); pr_info("CPU%d:\n", get_cpu()); if (regs) show_regs(regs); else show_stack(NULL, NULL, KERN_INFO); schedule_work(&sysrq_showallcpus); put_cpu(); } } static const struct sysrq_key_op sysrq_showallcpus_op = { .handler = sysrq_handle_showallcpus, .help_msg = "show-backtrace-all-active-cpus(l)", .action_msg = "Show backtrace of all active CPUs", .enable_mask = SYSRQ_ENABLE_DUMP, }; #else #define sysrq_showallcpus_op (*(const struct sysrq_key_op *)NULL) #endif static void sysrq_handle_showregs(u8 key) { struct pt_regs *regs = NULL; if (in_hardirq()) regs = get_irq_regs(); if (regs) show_regs(regs); perf_event_print_debug(); } static const struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, .help_msg = "show-registers(p)", .action_msg = "Show Regs", .enable_mask = SYSRQ_ENABLE_DUMP, }; static void sysrq_handle_showstate(u8 key) { show_state(); show_all_workqueues(); } static const struct sysrq_key_op sysrq_showstate_op = { .handler = sysrq_handle_showstate, .help_msg = "show-task-states(t)", .action_msg = "Show State", .enable_mask = SYSRQ_ENABLE_DUMP, }; static void sysrq_handle_showstate_blocked(u8 key) { show_state_filter(TASK_UNINTERRUPTIBLE); } static const struct sysrq_key_op sysrq_showstate_blocked_op = { .handler = sysrq_handle_showstate_blocked, .help_msg = "show-blocked-tasks(w)", .action_msg = "Show Blocked State", .enable_mask = SYSRQ_ENABLE_DUMP, }; #ifdef CONFIG_TRACING #include <linux/ftrace.h> static void sysrq_ftrace_dump(u8 key) { ftrace_dump(DUMP_ALL); } static const struct sysrq_key_op sysrq_ftrace_dump_op = { .handler = sysrq_ftrace_dump, .help_msg = "dump-ftrace-buffer(z)", .action_msg = "Dump ftrace buffer", .enable_mask = SYSRQ_ENABLE_DUMP, }; #else #define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL) #endif static void sysrq_handle_showmem(u8 key) { show_mem(); } static const struct sysrq_key_op sysrq_showmem_op = { .handler = sysrq_handle_showmem, .help_msg = "show-memory-usage(m)", .action_msg = "Show Memory", .enable_mask = SYSRQ_ENABLE_DUMP, }; /* * Signal sysrq helper function. Sends a signal to all user processes. */ static void send_sig_all(int sig) { struct task_struct *p; read_lock(&tasklist_lock); for_each_process(p) { if (p->flags & PF_KTHREAD) continue; if (is_global_init(p)) continue; do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); } read_unlock(&tasklist_lock); } static void sysrq_handle_term(u8 key) { send_sig_all(SIGTERM); console_loglevel = CONSOLE_LOGLEVEL_DEBUG; } static const struct sysrq_key_op sysrq_term_op = { .handler = sysrq_handle_term, .help_msg = "terminate-all-tasks(e)", .action_msg = "Terminate All Tasks", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; static void moom_callback(struct work_struct *ignored) { const gfp_t gfp_mask = GFP_KERNEL; struct oom_control oc = { .zonelist = node_zonelist(first_memory_node, gfp_mask), .nodemask = NULL, .memcg = NULL, .gfp_mask = gfp_mask, .order = -1, }; mutex_lock(&oom_lock); if (!out_of_memory(&oc)) pr_info("OOM request ignored. No task eligible\n"); mutex_unlock(&oom_lock); } static DECLARE_WORK(moom_work, moom_callback); static void sysrq_handle_moom(u8 key) { schedule_work(&moom_work); } static const struct sysrq_key_op sysrq_moom_op = { .handler = sysrq_handle_moom, .help_msg = "memory-full-oom-kill(f)", .action_msg = "Manual OOM execution", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; #ifdef CONFIG_BLOCK static void sysrq_handle_thaw(u8 key) { emergency_thaw_all(); } static const struct sysrq_key_op sysrq_thaw_op = { .handler = sysrq_handle_thaw, .help_msg = "thaw-filesystems(j)", .action_msg = "Emergency Thaw of all frozen filesystems", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; #else #define sysrq_thaw_op (*(const struct sysrq_key_op *)NULL) #endif static void sysrq_handle_kill(u8 key) { send_sig_all(SIGKILL); console_loglevel = CONSOLE_LOGLEVEL_DEBUG; } static const struct sysrq_key_op sysrq_kill_op = { .handler = sysrq_handle_kill, .help_msg = "kill-all-tasks(i)", .action_msg = "Kill All Tasks", .enable_mask = SYSRQ_ENABLE_SIGNAL, }; static void sysrq_handle_unrt(u8 key) { normalize_rt_tasks(); } static const struct sysrq_key_op sysrq_unrt_op = { .handler = sysrq_handle_unrt, .help_msg = "nice-all-RT-tasks(n)", .action_msg = "Nice All RT Tasks", .enable_mask = SYSRQ_ENABLE_RTNICE, }; static void sysrq_handle_replay_logs(u8 key) { console_try_replay_all(); } static struct sysrq_key_op sysrq_replay_logs_op = { .handler = sysrq_handle_replay_logs, .help_msg = "replay-kernel-logs(R)", .action_msg = "Replay kernel logs on consoles", .enable_mask = SYSRQ_ENABLE_DUMP, }; /* Key Operations table and lock */ static DEFINE_SPINLOCK(sysrq_key_table_lock); static const struct sysrq_key_op *sysrq_key_table[62] = { &sysrq_loglevel_op, /* 0 */ &sysrq_loglevel_op, /* 1 */ &sysrq_loglevel_op, /* 2 */ &sysrq_loglevel_op, /* 3 */ &sysrq_loglevel_op, /* 4 */ &sysrq_loglevel_op, /* 5 */ &sysrq_loglevel_op, /* 6 */ &sysrq_loglevel_op, /* 7 */ &sysrq_loglevel_op, /* 8 */ &sysrq_loglevel_op, /* 9 */ /* * a: Don't use for system provided sysrqs, it is handled specially on * sparc and will never arrive. */ NULL, /* a */ &sysrq_reboot_op, /* b */ &sysrq_crash_op, /* c */ &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ /* g: May be registered for the kernel debugger */ NULL, /* g */ NULL, /* h - reserved for help */ &sysrq_kill_op, /* i */ &sysrq_thaw_op, /* j */ &sysrq_SAK_op, /* k */ &sysrq_showallcpus_op, /* l */ &sysrq_showmem_op, /* m */ &sysrq_unrt_op, /* n */ /* o: This will often be registered as 'Off' at init time */ NULL, /* o */ &sysrq_showregs_op, /* p */