Skip to content

Commit

Permalink
delayacct: Add sysctl to enable at runtime
Browse files Browse the repository at this point in the history
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: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YJkhebGJAywaZowX@hirez.programming.kicks-ass.net
  • Loading branch information
Peter Zijlstra committed May 12, 2021
1 parent e4042ad commit 0cd7c74
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
6 changes: 4 additions & 2 deletions Documentation/accounting/delay-accounting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ To enable, add::

delayacct

to the kernel boot options. The rest of the instructions
below assume this has been done.
to the kernel boot options. The rest of the instructions below assume this has
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
similar to getdelays.c to access the delays
Expand Down
4 changes: 4 additions & 0 deletions include/linux/delayacct.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ DECLARE_STATIC_KEY_FALSE(delayacct_key);
extern int delayacct_on; /* Delay accounting turned on/off */
extern struct kmem_cache *delayacct_cache;
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_exit(struct task_struct *);
extern void __delayacct_blkio_start(void);
Expand Down
36 changes: 34 additions & 2 deletions kernel/delayacct.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ DEFINE_STATIC_KEY_FALSE(delayacct_key);
int delayacct_on __read_mostly; /* Delay accounting turned on/off */
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)
{
delayacct_on = 1;
Expand All @@ -29,9 +40,30 @@ void delayacct_init(void)
{
delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC|SLAB_ACCOUNT);
delayacct_tsk_init(&init_task);
if (delayacct_on)
static_branch_enable(&delayacct_key);
set_delayacct(delayacct_on);
}

#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)
{
Expand Down
12 changes: 12 additions & 0 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <linux/coredump.h>
#include <linux/latencytop.h>
#include <linux/pid.h>
#include <linux/delayacct.h>

#include "../lib/kstrtox.h"

Expand Down Expand Up @@ -1727,6 +1728,17 @@ static struct ctl_table kern_table[] = {
.extra2 = SYSCTL_ONE,
},
#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
{
.procname = "numa_balancing",
Expand Down

0 comments on commit 0cd7c74

Please sign in to comment.