Merge "arm64: defconfig: Enable hung tasks detection"

This commit is contained in:
qctecmdr 2020-03-28 07:28:14 -07:00 • committed by Gerrit - the friendly Code Review server
commit d711937055
6 changed files with 84 additions and 3 deletions

View file

@ -18,6 +18,7 @@ CONFIG_EDAC_KRYO_ARM64_PANIC_ON_CE=y
CONFIG_QMP_DEBUGFS_CLIENT=y
CONFIG_LKDTM=m
CONFIG_ATOMIC64_SELFTEST=m
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_TEST_USER_COPY=m
CONFIG_OF_RESERVED_MEM_CHECK=y

View file

@ -2505,7 +2505,7 @@ static struct dentry *proc_pident_instantiate(struct dentry *dentry,
return d_splice_alias(inode, dentry);
}
static struct dentry *proc_pident_lookup(struct inode *dir,
static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *dentry,
const struct pid_entry *p,
const struct pid_entry *end)
@ -2692,7 +2692,7 @@ static const struct pid_entry attr_dir_stuff[] = {
static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
{
return proc_pident_readdir(file, ctx,
return proc_pident_readdir(file, ctx,
attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
}
@ -2855,6 +2855,53 @@ 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 = scnprintf(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_SCHED_WALT
static ssize_t proc_sched_task_boost_read(struct file *file,
char __user *buf, size_t count, loff_t *ppos)
@ -3234,6 +3281,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),
@ -3634,6 +3685,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),

View file

@ -1076,8 +1076,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;

View file

@ -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);

View file

@ -23,12 +23,21 @@
#include <linux/sched/sysctl.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.
*
@ -195,7 +204,10 @@ 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_hung_task(t, timeout);
/* Check for selective monitoring */
if (!sysctl_hung_task_selective_monitoring ||
t->hang_detection_enabled)
check_hung_task(t, timeout);
}
unlock:
rcu_read_unlock();

View file

@ -1435,6 +1435,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 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
#endif
#ifdef CONFIG_RT_MUTEXES
{