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

Configure Feed

Select the types of activity you want to include in your feed.

rseq: Provide static branch for runtime debugging

Config based debug is rarely turned on and is not available easily when
things go wrong.

Provide a static branch to allow permanent integration of debug mechanisms
along with the usual toggles in Kconfig, command line and debugfs.

Requested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027084307.089270547@linutronix.de

authored by

Thomas Gleixner and committed by
Ingo Molnar
9c37cb6e 54129104

+90 -4
+4
Documentation/admin-guide/kernel-parameters.txt
··· 6500 6500 Memory area to be used by remote processor image, 6501 6501 managed by CMA. 6502 6502 6503 + rseq_debug= [KNL] Enable or disable restartable sequence 6504 + debug mode. Defaults to CONFIG_RSEQ_DEBUG_DEFAULT_ENABLE. 6505 + Format: <bool> 6506 + 6503 6507 rt_group_sched= [KNL] Enable or disable SCHED_RR/FIFO group scheduling 6504 6508 when CONFIG_RT_GROUP_SCHED=y. Defaults to 6505 6509 !CONFIG_RT_GROUP_SCHED_DEFAULT_DISABLED.
+3
include/linux/rseq_entry.h
··· 34 34 #endif /* !CONFIG_RSEQ_STATS */ 35 35 36 36 #ifdef CONFIG_RSEQ 37 + #include <linux/jump_label.h> 37 38 #include <linux/rseq.h> 38 39 39 40 #include <linux/tracepoint-defs.h> ··· 64 63 static inline void rseq_trace_ip_fixup(unsigned long ip, unsigned long start_ip, 65 64 unsigned long offset, unsigned long abort_ip) { } 66 65 #endif /* !CONFIG_TRACEPOINT */ 66 + 67 + DECLARE_STATIC_KEY_MAYBE(CONFIG_RSEQ_DEBUG_DEFAULT_ENABLE, rseq_debug_enabled); 67 68 68 69 static __always_inline void rseq_note_user_irq_entry(void) 69 70 {
+14
init/Kconfig
··· 1925 1925 1926 1926 If unsure, say N. 1927 1927 1928 + config RSEQ_DEBUG_DEFAULT_ENABLE 1929 + default n 1930 + bool "Enable restartable sequences debug mode by default" if EXPERT 1931 + depends on RSEQ 1932 + help 1933 + This enables the static branch for debug mode of restartable 1934 + sequences. 1935 + 1936 + This also can be controlled on the kernel command line via the 1937 + command line parameter "rseq_debug=0/1" and through debugfs. 1938 + 1939 + If unsure, say N. 1940 + 1928 1941 config DEBUG_RSEQ 1929 1942 default n 1930 1943 bool "Enable debugging of rseq() system call" if EXPERT 1931 1944 depends on RSEQ && DEBUG_KERNEL 1945 + select RSEQ_DEBUG_DEFAULT_ENABLE 1932 1946 help 1933 1947 Enable extra debugging checks for the rseq system call. 1934 1948
+69 -4
kernel/rseq.c
··· 95 95 RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL | \ 96 96 RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE) 97 97 98 + DEFINE_STATIC_KEY_MAYBE(CONFIG_RSEQ_DEBUG_DEFAULT_ENABLE, rseq_debug_enabled); 99 + 100 + static inline void rseq_control_debug(bool on) 101 + { 102 + if (on) 103 + static_branch_enable(&rseq_debug_enabled); 104 + else 105 + static_branch_disable(&rseq_debug_enabled); 106 + } 107 + 108 + static int __init rseq_setup_debug(char *str) 109 + { 110 + bool on; 111 + 112 + if (kstrtobool(str, &on)) 113 + return -EINVAL; 114 + rseq_control_debug(on); 115 + return 1; 116 + } 117 + __setup("rseq_debug=", rseq_setup_debug); 118 + 98 119 #ifdef CONFIG_TRACEPOINTS 99 120 /* 100 121 * Out of line, so the actual update functions can be in a header to be ··· 133 112 } 134 113 #endif /* CONFIG_TRACEPOINTS */ 135 114 115 + #ifdef CONFIG_DEBUG_FS 136 116 #ifdef CONFIG_RSEQ_STATS 137 117 DEFINE_PER_CPU(struct rseq_stats, rseq_stats); 138 118 139 - static int rseq_debug_show(struct seq_file *m, void *p) 119 + static int rseq_stats_show(struct seq_file *m, void *p) 140 120 { 141 121 struct rseq_stats stats = { }; 142 122 unsigned int cpu; ··· 162 140 return 0; 163 141 } 164 142 143 + static int rseq_stats_open(struct inode *inode, struct file *file) 144 + { 145 + return single_open(file, rseq_stats_show, inode->i_private); 146 + } 147 + 148 + static const struct file_operations stat_ops = { 149 + .open = rseq_stats_open, 150 + .read = seq_read, 151 + .llseek = seq_lseek, 152 + .release = single_release, 153 + }; 154 + 155 + static int __init rseq_stats_init(struct dentry *root_dir) 156 + { 157 + debugfs_create_file("stats", 0444, root_dir, NULL, &stat_ops); 158 + return 0; 159 + } 160 + #else 161 + static inline void rseq_stats_init(struct dentry *root_dir) { } 162 + #endif /* CONFIG_RSEQ_STATS */ 163 + 164 + static int rseq_debug_show(struct seq_file *m, void *p) 165 + { 166 + bool on = static_branch_unlikely(&rseq_debug_enabled); 167 + 168 + seq_printf(m, "%d\n", on); 169 + return 0; 170 + } 171 + 172 + static ssize_t rseq_debug_write(struct file *file, const char __user *ubuf, 173 + size_t count, loff_t *ppos) 174 + { 175 + bool on; 176 + 177 + if (kstrtobool_from_user(ubuf, count, &on)) 178 + return -EINVAL; 179 + 180 + rseq_control_debug(on); 181 + return count; 182 + } 183 + 165 184 static int rseq_debug_open(struct inode *inode, struct file *file) 166 185 { 167 186 return single_open(file, rseq_debug_show, inode->i_private); 168 187 } 169 188 170 - static const struct file_operations dfs_ops = { 189 + static const struct file_operations debug_ops = { 171 190 .open = rseq_debug_open, 172 191 .read = seq_read, 192 + .write = rseq_debug_write, 173 193 .llseek = seq_lseek, 174 194 .release = single_release, 175 195 }; ··· 220 156 { 221 157 struct dentry *root_dir = debugfs_create_dir("rseq", NULL); 222 158 223 - debugfs_create_file("stats", 0444, root_dir, NULL, &dfs_ops); 159 + debugfs_create_file("debug", 0644, root_dir, NULL, &debug_ops); 160 + rseq_stats_init(root_dir); 224 161 return 0; 225 162 } 226 163 __initcall(rseq_debugfs_init); 227 - #endif /* CONFIG_RSEQ_STATS */ 164 + #endif /* CONFIG_DEBUG_FS */ 228 165 229 166 #ifdef CONFIG_DEBUG_RSEQ 230 167 static struct rseq *rseq_kernel_fields(struct task_struct *t)