Commit 0cd7c741 authored by Peter Zijlstra's avatar Peter Zijlstra

delayacct: Add sysctl to enable at runtime

Just like sched_schedstats, allow runtime enabling (and disabling) of
delayacct. This is useful if one forgot to add the delayacct boot time
option.
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YJkhebGJAywaZowX@hirez.programming.kicks-ass.net
parent e4042ad4
...@@ -74,8 +74,10 @@ To enable, add:: ...@@ -74,8 +74,10 @@ To enable, add::
delayacct delayacct
to the kernel boot options. The rest of the instructions to the kernel boot options. The rest of the instructions below assume this has
below assume this has been done. been done. Alternatively, use sysctl kernel.task_delayacct to switch the state
at runtime. Note however that only tasks started after enabling it will have
delayacct information.
After the system has booted up, use a utility After the system has booted up, use a utility
similar to getdelays.c to access the delays similar to getdelays.c to access the delays
......
...@@ -65,6 +65,10 @@ DECLARE_STATIC_KEY_FALSE(delayacct_key); ...@@ -65,6 +65,10 @@ DECLARE_STATIC_KEY_FALSE(delayacct_key);
extern int delayacct_on; /* Delay accounting turned on/off */ extern int delayacct_on; /* Delay accounting turned on/off */
extern struct kmem_cache *delayacct_cache; extern struct kmem_cache *delayacct_cache;
extern void delayacct_init(void); extern void delayacct_init(void);
extern int sysctl_delayacct(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos);
extern void __delayacct_tsk_init(struct task_struct *); extern void __delayacct_tsk_init(struct task_struct *);
extern void __delayacct_tsk_exit(struct task_struct *); extern void __delayacct_tsk_exit(struct task_struct *);
extern void __delayacct_blkio_start(void); extern void __delayacct_blkio_start(void);
......
...@@ -18,6 +18,17 @@ DEFINE_STATIC_KEY_FALSE(delayacct_key); ...@@ -18,6 +18,17 @@ DEFINE_STATIC_KEY_FALSE(delayacct_key);
int delayacct_on __read_mostly; /* Delay accounting turned on/off */ int delayacct_on __read_mostly; /* Delay accounting turned on/off */
struct kmem_cache *delayacct_cache; struct kmem_cache *delayacct_cache;
static void set_delayacct(bool enabled)
{
if (enabled) {
static_branch_enable(&delayacct_key);
delayacct_on = 1;
} else {
delayacct_on = 0;
static_branch_disable(&delayacct_key);
}
}
static int __init delayacct_setup_enable(char *str) static int __init delayacct_setup_enable(char *str)
{ {
delayacct_on = 1; delayacct_on = 1;
...@@ -29,9 +40,30 @@ void delayacct_init(void) ...@@ -29,9 +40,30 @@ void delayacct_init(void)
{ {
delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC|SLAB_ACCOUNT); delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC|SLAB_ACCOUNT);
delayacct_tsk_init(&init_task); delayacct_tsk_init(&init_task);
if (delayacct_on) set_delayacct(delayacct_on);
static_branch_enable(&delayacct_key); }
#ifdef CONFIG_PROC_SYSCTL
int sysctl_delayacct(struct ctl_table *table, int write, void *buffer,
size_t *lenp, loff_t *ppos)
{
int state = delayacct_on;
struct ctl_table t;
int err;
if (write && !capable(CAP_SYS_ADMIN))
return -EPERM;
t = *table;
t.data = &state;
err = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
if (err < 0)
return err;
if (write)
set_delayacct(state);
return err;
} }
#endif
void __delayacct_tsk_init(struct task_struct *tsk) void __delayacct_tsk_init(struct task_struct *tsk)
{ {
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include <linux/coredump.h> #include <linux/coredump.h>
#include <linux/latencytop.h> #include <linux/latencytop.h>
#include <linux/pid.h> #include <linux/pid.h>
#include <linux/delayacct.h>
#include "../lib/kstrtox.h" #include "../lib/kstrtox.h"
...@@ -1727,6 +1728,17 @@ static struct ctl_table kern_table[] = { ...@@ -1727,6 +1728,17 @@ static struct ctl_table kern_table[] = {
.extra2 = SYSCTL_ONE, .extra2 = SYSCTL_ONE,
}, },
#endif /* CONFIG_SCHEDSTATS */ #endif /* CONFIG_SCHEDSTATS */
#ifdef CONFIG_TASK_DELAY_ACCT
{
.procname = "task_delayacct",
.data = NULL,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = sysctl_delayacct,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
#endif /* CONFIG_TASK_DELAY_ACCT */
#ifdef CONFIG_NUMA_BALANCING #ifdef CONFIG_NUMA_BALANCING
{ {
.procname = "numa_balancing", .procname = "numa_balancing",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment