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

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
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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
+4 −0
Original line number Diff line number Diff line
@@ -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);
+34 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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)
{
+12 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@
#include <linux/coredump.h>
#include <linux/latencytop.h>
#include <linux/pid.h>
#include <linux/delayacct.h>

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

@@ -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",