Loading fs/proc/base.c +54 −0 Original line number Diff line number Diff line Loading @@ -2896,6 +2896,52 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns, } #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 static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) Loading Loading @@ -3138,6 +3184,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading Loading @@ -3526,6 +3576,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading include/linux/sched.h +1 −0 Original line number Diff line number Diff line Loading @@ -1946,6 +1946,7 @@ struct task_struct { #ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ unsigned long last_switch_count; bool hang_detection_enabled; #endif /* filesystem information */ struct fs_struct *fs; Loading include/linux/sched/sysctl.h +1 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ extern int sysctl_hung_task_check_count; extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_timeout_secs; 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, void __user *buffer, size_t *lenp, loff_t *ppos); Loading kernel/hung_task.c +13 −1 Original line number Diff line number Diff line Loading @@ -17,12 +17,21 @@ #include <linux/sysctl.h> #include <linux/utsname.h> #include <trace/events/sched.h> #include <linux/sched/sysctl.h> /* * The number of tasks checked: */ 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. * Loading Loading @@ -179,6 +188,9 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) /* Check for selective monitoring */ if (!sysctl_hung_task_selective_monitoring || t->hang_detection_enabled) check_hung_task(t, timeout); } unlock: Loading kernel/sysctl.c +10 −0 Original line number Diff line number Diff line Loading @@ -1186,6 +1186,16 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec_minmax, .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 #ifdef CONFIG_RT_MUTEXES { Loading Loading
fs/proc/base.c +54 −0 Original line number Diff line number Diff line Loading @@ -2896,6 +2896,52 @@ static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns, } #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 static int proc_id_map_open(struct inode *inode, struct file *file, const struct seq_operations *seq_ops) Loading Loading @@ -3138,6 +3184,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading Loading @@ -3526,6 +3576,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif #ifdef CONFIG_DETECT_HUNG_TASK REG("hang_detection_enabled", 0666, proc_hung_task_detection_enabled_operations), #endif #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), Loading
include/linux/sched.h +1 −0 Original line number Diff line number Diff line Loading @@ -1946,6 +1946,7 @@ struct task_struct { #ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ unsigned long last_switch_count; bool hang_detection_enabled; #endif /* filesystem information */ struct fs_struct *fs; Loading
include/linux/sched/sysctl.h +1 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ extern int sysctl_hung_task_check_count; extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_timeout_secs; 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, void __user *buffer, size_t *lenp, loff_t *ppos); Loading
kernel/hung_task.c +13 −1 Original line number Diff line number Diff line Loading @@ -17,12 +17,21 @@ #include <linux/sysctl.h> #include <linux/utsname.h> #include <trace/events/sched.h> #include <linux/sched/sysctl.h> /* * The number of tasks checked: */ 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. * Loading Loading @@ -179,6 +188,9 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) /* Check for selective monitoring */ if (!sysctl_hung_task_selective_monitoring || t->hang_detection_enabled) check_hung_task(t, timeout); } unlock: Loading
kernel/sysctl.c +10 −0 Original line number Diff line number Diff line Loading @@ -1186,6 +1186,16 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec_minmax, .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 #ifdef CONFIG_RT_MUTEXES { Loading