Loading fs/proc/base.c +54 −0 Original line number Original line Diff line number Diff line Loading @@ -2965,6 +2965,52 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns, } } #endif /* CONFIG_TASK_IO_ACCOUNTING */ #endif /* CONFIG_TASK_IO_ACCOUNTING */ #ifdef CONFIG_DETECT_HUNG_TASK static ssize_t proc_hung_task_detection_enabled_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; size_t len; bool hang_detection_enabled; if (!task) return -ESRCH; hang_detection_enabled = task->hang_detection_enabled; put_task_struct(task); len = snprintf(buffer, sizeof(buffer), "%d\n", hang_detection_enabled); return simple_read_from_buffer(buf, sizeof(buffer), ppos, buffer, len); } static ssize_t proc_hung_task_detection_enabled_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task; bool hang_detection_enabled; int rv; rv = kstrtobool_from_user(buf, count, &hang_detection_enabled); if (rv < 0) return rv; task = get_proc_task(file_inode(file)); if (!task) return -ESRCH; task->hang_detection_enabled = hang_detection_enabled; put_task_struct(task); return count; } static const struct file_operations proc_hung_task_detection_enabled_operations = { .read = proc_hung_task_detection_enabled_read, .write = proc_hung_task_detection_enabled_write, .llseek = generic_file_llseek, }; #endif #ifdef CONFIG_USER_NS #ifdef CONFIG_USER_NS static int proc_id_map_open(struct inode *inode, struct file *file, static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) const struct seq_operations *seq_ops) Loading Loading @@ -3218,6 +3264,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_HARDWALL #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading Loading @@ -3612,6 +3662,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_HARDWALL #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading include/linux/sched.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1001,7 +1001,9 @@ struct task_struct { struct sysv_shm sysvshm; struct sysv_shm sysvshm; #endif #endif #ifdef CONFIG_DETECT_HUNG_TASK #ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ unsigned long last_switch_count; unsigned long last_switch_count; bool hang_detection_enabled; #endif #endif /* Filesystem information: */ /* Filesystem information: */ struct fs_struct *fs; struct fs_struct *fs; Loading include/linux/sched/sysctl.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11,6 +11,7 @@ extern int sysctl_hung_task_check_count; extern unsigned int sysctl_hung_task_panic; extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_timeout_secs; extern unsigned long sysctl_hung_task_timeout_secs; extern int sysctl_hung_task_warnings; extern int sysctl_hung_task_warnings; extern int sysctl_hung_task_selective_monitoring; extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, void __user *buffer, void __user *buffer, size_t *lenp, loff_t *ppos); size_t *lenp, loff_t *ppos); Loading kernel/hung_task.c +13 −1 Original line number Original line Diff line number Diff line Loading @@ -20,12 +20,21 @@ #include <linux/sched/debug.h> #include <linux/sched/debug.h> #include <trace/events/sched.h> #include <trace/events/sched.h> #include <linux/sched/sysctl.h> /* /* * The number of tasks checked: * The number of tasks checked: */ */ int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; /* * Selective monitoring of hung tasks. * * if set to 1, khungtaskd skips monitoring tasks, which has * task_struct->hang_detection_enabled value not set, else monitors all tasks. */ int sysctl_hung_task_selective_monitoring = 1; /* /* * Limit number of tasks checked in a batch. * Limit number of tasks checked in a batch. * * Loading Loading @@ -186,6 +195,9 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) } } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) if (t->state == TASK_UNINTERRUPTIBLE) /* Check for selective monitoring */ if (!sysctl_hung_task_selective_monitoring || t->hang_detection_enabled) check_hung_task(t, timeout); check_hung_task(t, timeout); } } unlock: unlock: Loading kernel/sysctl.c +10 −0 Original line number Original line Diff line number Diff line Loading @@ -1232,6 +1232,16 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec_minmax, .proc_handler = proc_dointvec_minmax, .extra1 = &neg_one, .extra1 = &neg_one, }, }, { .procname = "hung_task_selective_monitoring", .data = &sysctl_hung_task_selective_monitoring, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &zero, .extra2 = &one, }, #endif #endif #ifdef CONFIG_RT_MUTEXES #ifdef CONFIG_RT_MUTEXES { { Loading Loading
fs/proc/base.c +54 −0 Original line number Original line Diff line number Diff line Loading @@ -2965,6 +2965,52 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns, } } #endif /* CONFIG_TASK_IO_ACCOUNTING */ #endif /* CONFIG_TASK_IO_ACCOUNTING */ #ifdef CONFIG_DETECT_HUNG_TASK static ssize_t proc_hung_task_detection_enabled_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task = get_proc_task(file_inode(file)); char buffer[PROC_NUMBUF]; size_t len; bool hang_detection_enabled; if (!task) return -ESRCH; hang_detection_enabled = task->hang_detection_enabled; put_task_struct(task); len = snprintf(buffer, sizeof(buffer), "%d\n", hang_detection_enabled); return simple_read_from_buffer(buf, sizeof(buffer), ppos, buffer, len); } static ssize_t proc_hung_task_detection_enabled_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct task_struct *task; bool hang_detection_enabled; int rv; rv = kstrtobool_from_user(buf, count, &hang_detection_enabled); if (rv < 0) return rv; task = get_proc_task(file_inode(file)); if (!task) return -ESRCH; task->hang_detection_enabled = hang_detection_enabled; put_task_struct(task); return count; } static const struct file_operations proc_hung_task_detection_enabled_operations = { .read = proc_hung_task_detection_enabled_read, .write = proc_hung_task_detection_enabled_write, .llseek = generic_file_llseek, }; #endif #ifdef CONFIG_USER_NS #ifdef CONFIG_USER_NS static int proc_id_map_open(struct inode *inode, struct file *file, static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) const struct seq_operations *seq_ops) Loading Loading @@ -3218,6 +3264,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_HARDWALL #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading Loading @@ -3612,6 +3662,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_HARDWALL #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading
include/linux/sched.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1001,7 +1001,9 @@ struct task_struct { struct sysv_shm sysvshm; struct sysv_shm sysvshm; #endif #endif #ifdef CONFIG_DETECT_HUNG_TASK #ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ unsigned long last_switch_count; unsigned long last_switch_count; bool hang_detection_enabled; #endif #endif /* Filesystem information: */ /* Filesystem information: */ struct fs_struct *fs; struct fs_struct *fs; Loading
include/linux/sched/sysctl.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11,6 +11,7 @@ extern int sysctl_hung_task_check_count; extern unsigned int sysctl_hung_task_panic; extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_timeout_secs; extern unsigned long sysctl_hung_task_timeout_secs; extern int sysctl_hung_task_warnings; extern int sysctl_hung_task_warnings; extern int sysctl_hung_task_selective_monitoring; extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, void __user *buffer, void __user *buffer, size_t *lenp, loff_t *ppos); size_t *lenp, loff_t *ppos); Loading
kernel/hung_task.c +13 −1 Original line number Original line Diff line number Diff line Loading @@ -20,12 +20,21 @@ #include <linux/sched/debug.h> #include <linux/sched/debug.h> #include <trace/events/sched.h> #include <trace/events/sched.h> #include <linux/sched/sysctl.h> /* /* * The number of tasks checked: * The number of tasks checked: */ */ int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT; /* * Selective monitoring of hung tasks. * * if set to 1, khungtaskd skips monitoring tasks, which has * task_struct->hang_detection_enabled value not set, else monitors all tasks. */ int sysctl_hung_task_selective_monitoring = 1; /* /* * Limit number of tasks checked in a batch. * Limit number of tasks checked in a batch. * * Loading Loading @@ -186,6 +195,9 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) } } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) if (t->state == TASK_UNINTERRUPTIBLE) /* Check for selective monitoring */ if (!sysctl_hung_task_selective_monitoring || t->hang_detection_enabled) check_hung_task(t, timeout); check_hung_task(t, timeout); } } unlock: unlock: Loading
kernel/sysctl.c +10 −0 Original line number Original line Diff line number Diff line Loading @@ -1232,6 +1232,16 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec_minmax, .proc_handler = proc_dointvec_minmax, .extra1 = &neg_one, .extra1 = &neg_one, }, }, { .procname = "hung_task_selective_monitoring", .data = &sysctl_hung_task_selective_monitoring, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &zero, .extra2 = &one, }, #endif #endif #ifdef CONFIG_RT_MUTEXES #ifdef CONFIG_RT_MUTEXES { { Loading