Loading fs/proc/base.c +56 −2 Original line number Diff line number Diff line Loading @@ -2953,6 +2953,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 static ssize_t proc_sched_task_boost_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { Loading Loading @@ -3318,6 +3364,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_TASK_IO_ACCOUNTING ONE("io", S_IRUSR, proc_tgid_io_accounting), #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 @@ -3703,6 +3753,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_TASK_IO_ACCOUNTING ONE("io", S_IRUSR, proc_tid_io_accounting), #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 +2 −0 Original line number Diff line number Diff line Loading @@ -1022,8 +1022,10 @@ struct task_struct { struct sysv_shm sysvshm; #endif #ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ unsigned long last_switch_count; unsigned long last_switch_time; 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 @@ -12,6 +12,7 @@ extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_timeout_secs; extern unsigned long sysctl_hung_task_check_interval_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 @@ -21,12 +21,21 @@ #include <linux/sched/debug.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 @@ -193,6 +202,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 @@ -1275,6 +1275,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 +56 −2 Original line number Diff line number Diff line Loading @@ -2953,6 +2953,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 static ssize_t proc_sched_task_boost_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { Loading Loading @@ -3318,6 +3364,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_TASK_IO_ACCOUNTING ONE("io", S_IRUSR, proc_tgid_io_accounting), #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 @@ -3703,6 +3753,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_TASK_IO_ACCOUNTING ONE("io", S_IRUSR, proc_tid_io_accounting), #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 +2 −0 Original line number Diff line number Diff line Loading @@ -1022,8 +1022,10 @@ struct task_struct { struct sysv_shm sysvshm; #endif #ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ unsigned long last_switch_count; unsigned long last_switch_time; 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 @@ -12,6 +12,7 @@ extern unsigned int sysctl_hung_task_panic; extern unsigned long sysctl_hung_task_timeout_secs; extern unsigned long sysctl_hung_task_check_interval_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 @@ -21,12 +21,21 @@ #include <linux/sched/debug.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 @@ -193,6 +202,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 @@ -1275,6 +1275,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