Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YJkhebGJAywaZowX@hirez.programming.kicks-ass.net

+54 -4
+4 -2
Documentation/accounting/delay-accounting.rst
··· 74 74 75 75 delayacct 76 76 77 - to the kernel boot options. The rest of the instructions 78 - below assume this has been done. 77 + to the kernel boot options. The rest of the instructions below assume this has 78 + been done. Alternatively, use sysctl kernel.task_delayacct to switch the state 79 + at runtime. Note however that only tasks started after enabling it will have 80 + delayacct information. 79 81 80 82 After the system has booted up, use a utility 81 83 similar to getdelays.c to access the delays
+4
include/linux/delayacct.h
··· 65 65 extern int delayacct_on; /* Delay accounting turned on/off */ 66 66 extern struct kmem_cache *delayacct_cache; 67 67 extern void delayacct_init(void); 68 + 69 + extern int sysctl_delayacct(struct ctl_table *table, int write, void *buffer, 70 + size_t *lenp, loff_t *ppos); 71 + 68 72 extern void __delayacct_tsk_init(struct task_struct *); 69 73 extern void __delayacct_tsk_exit(struct task_struct *); 70 74 extern void __delayacct_blkio_start(void);
+34 -2
kernel/delayacct.c
··· 18 18 int delayacct_on __read_mostly; /* Delay accounting turned on/off */ 19 19 struct kmem_cache *delayacct_cache; 20 20 21 + static void set_delayacct(bool enabled) 22 + { 23 + if (enabled) { 24 + static_branch_enable(&delayacct_key); 25 + delayacct_on = 1; 26 + } else { 27 + delayacct_on = 0; 28 + static_branch_disable(&delayacct_key); 29 + } 30 + } 31 + 21 32 static int __init delayacct_setup_enable(char *str) 22 33 { 23 34 delayacct_on = 1; ··· 40 29 { 41 30 delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC|SLAB_ACCOUNT); 42 31 delayacct_tsk_init(&init_task); 43 - if (delayacct_on) 44 - static_branch_enable(&delayacct_key); 32 + set_delayacct(delayacct_on); 45 33 } 34 + 35 + #ifdef CONFIG_PROC_SYSCTL 36 + int sysctl_delayacct(struct ctl_table *table, int write, void *buffer, 37 + size_t *lenp, loff_t *ppos) 38 + { 39 + int state = delayacct_on; 40 + struct ctl_table t; 41 + int err; 42 + 43 + if (write && !capable(CAP_SYS_ADMIN)) 44 + return -EPERM; 45 + 46 + t = *table; 47 + t.data = &state; 48 + err = proc_dointvec_minmax(&t, write, buffer, lenp, ppos); 49 + if (err < 0) 50 + return err; 51 + if (write) 52 + set_delayacct(state); 53 + return err; 54 + } 55 + #endif 46 56 47 57 void __delayacct_tsk_init(struct task_struct *tsk) 48 58 {
+12
kernel/sysctl.c
··· 71 71 #include <linux/coredump.h> 72 72 #include <linux/latencytop.h> 73 73 #include <linux/pid.h> 74 + #include <linux/delayacct.h> 74 75 75 76 #include "../lib/kstrtox.h" 76 77 ··· 1728 1727 .extra2 = SYSCTL_ONE, 1729 1728 }, 1730 1729 #endif /* CONFIG_SCHEDSTATS */ 1730 + #ifdef CONFIG_TASK_DELAY_ACCT 1731 + { 1732 + .procname = "task_delayacct", 1733 + .data = NULL, 1734 + .maxlen = sizeof(unsigned int), 1735 + .mode = 0644, 1736 + .proc_handler = sysctl_delayacct, 1737 + .extra1 = SYSCTL_ZERO, 1738 + .extra2 = SYSCTL_ONE, 1739 + }, 1740 + #endif /* CONFIG_TASK_DELAY_ACCT */ 1731 1741 #ifdef CONFIG_NUMA_BALANCING 1732 1742 { 1733 1743 .procname = "numa_balancing",