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

Commit 53ecfde4 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

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