Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0c491f1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hung task: check specific tasks for long uninterruptible sleep state"

parents 4921041e a9788f4c
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -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)
@@ -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),
@@ -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),
+1 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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);
+13 −1
Original line number Diff line number Diff line
@@ -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.
 *
@@ -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:
+10 −0
Original line number Diff line number Diff line
@@ -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
	{