The kernel/sysctl.c is a kitchen sink where everyone leaves their dirty dishes, this makes it very difficult to maintain. To help with this maintenance let's start by moving sysctls to places where they actually belong. The proc sysctl maintainers do not want to know what sysctl knobs you wish to add for your own piece of code, we just care about the core logic. So move hung_task sysctl interface to hung_task.c and use register_sysctl() to register the sysctl interface. [mcgrof@kernel.org: commit log refresh and fixed 2-3 0day reported compile issues]
Unified · Split
| @@ -7,20 +7,8 @@ · 6 unmodified lines | |||
| 7 | struct ctl_table; | 7 | struct ctl_table; |
| 8 | 8 | ||
| 9 | #ifdef CONFIG_DETECT_HUNG_TASK | 9 | #ifdef CONFIG_DETECT_HUNG_TASK |
| 10 | 10 | /* used for hung_task and block/ */ | |
| 11 | #ifdef CONFIG_SMP | ||
| 12 | extern unsigned int sysctl_hung_task_all_cpu_backtrace; | ||
| 13 | #else | ||
| 14 | #define sysctl_hung_task_all_cpu_backtrace 0 | ||
| 15 | #endif /* CONFIG_SMP */ | ||
| 16 | |||
| 17 | extern int sysctl_hung_task_check_count; | ||
| 18 | extern unsigned int sysctl_hung_task_panic; | ||
| 19 | extern unsigned long sysctl_hung_task_timeout_secs; | 11 | extern unsigned long sysctl_hung_task_timeout_secs; |
| 20 | extern unsigned long sysctl_hung_task_check_interval_secs; | ||
| 21 | extern int sysctl_hung_task_warnings; | ||
| 22 | int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, | ||
| 23 | void *buffer, size_t *lenp, loff_t *ppos); | ||
| 24 | #else | 12 | #else |
| 25 | /* Avoid need for ifdefs elsewhere in the code */ | 13 | /* Avoid need for ifdefs elsewhere in the code */ |
| 26 | enum { sysctl_hung_task_timeout_secs = 0 }; | 14 | enum { sysctl_hung_task_timeout_secs = 0 }; |
| @@ -63,7 +63,9 @@ static struct task_struct *watchdog_task; · 62 unmodified lines | |||
| 63 | * Should we dump all CPUs backtraces in a hung task event? | 63 | * Should we dump all CPUs backtraces in a hung task event? |
| 64 | * Defaults to 0, can be changed via sysctl. | 64 | * Defaults to 0, can be changed via sysctl. |
| 65 | */ | 65 | */ |
| 66 | unsigned int __read_mostly sysctl_hung_task_all_cpu_backtrace; | 66 | static unsigned int __read_mostly sysctl_hung_task_all_cpu_backtrace; |
| 67 | #else | ||
| 68 | #define sysctl_hung_task_all_cpu_backtrace 0 | ||
| 67 | #endif /* CONFIG_SMP */ | 69 | #endif /* CONFIG_SMP */ |
| 68 | 70 | ||
| 69 | /* | 71 | /* |
| @@ -222,11 +224,13 @@ static long hung_timeout_jiffies(unsigned long last_checked, · 152 unmodified lines | |||
| 222 | MAX_SCHEDULE_TIMEOUT; | 224 | MAX_SCHEDULE_TIMEOUT; |
| 223 | } | 225 | } |
| 224 | 226 | ||
| 227 | #ifdef CONFIG_SYSCTL | ||
| 225 | /* | 228 | /* |
| 226 | * Process updating of timeout sysctl | 229 | * Process updating of timeout sysctl |
| 227 | */ | 230 | */ |
| 228 | int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, | 231 | static int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, |
| 229 | void *buffer, size_t *lenp, loff_t *ppos) | 232 | void __user *buffer, |
| 233 | size_t *lenp, loff_t *ppos) | ||
| 230 | { | 234 | { |
| 231 | int ret; | 235 | int ret; |
| 232 | 236 | ||
| @@ -241,6 +245,76 @@ int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, · 8 unmodified lines | |||
| 241 | return ret; | 245 | return ret; |
| 242 | } | 246 | } |
| 243 | 247 | ||
| 248 | /* | ||
| 249 | * This is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs | ||
| 250 | * and hung_task_check_interval_secs | ||
| 251 | */ | ||
| 252 | static const unsigned long hung_task_timeout_max = (LONG_MAX / HZ); | ||
| 253 | static struct ctl_table hung_task_sysctls[] = { | ||
| 254 | #ifdef CONFIG_SMP | ||
| 255 | { | ||
| 256 | .procname = "hung_task_all_cpu_backtrace", | ||
| 257 | .data = &sysctl_hung_task_all_cpu_backtrace, | ||
| 258 | .maxlen = sizeof(int), | ||
| 259 | .mode = 0644, | ||
| 260 | .proc_handler = proc_dointvec_minmax, | ||
| 261 | .extra1 = SYSCTL_ZERO, | ||
| 262 | .extra2 = SYSCTL_ONE, | ||
| 263 | }, | ||
| 264 | #endif /* CONFIG_SMP */ | ||
| 265 | { | ||
| 266 | .procname = "hung_task_panic", | ||
| 267 | .data = &sysctl_hung_task_panic, | ||
| 268 | .maxlen = sizeof(int), | ||
| 269 | .mode = 0644, | ||
| 270 | .proc_handler = proc_dointvec_minmax, | ||
| 271 | .extra1 = SYSCTL_ZERO, | ||
| 272 | .extra2 = SYSCTL_ONE, | ||
| 273 | }, | ||
| 274 | { | ||
| 275 | .procname = "hung_task_check_count", | ||
| 276 | .data = &sysctl_hung_task_check_count, | ||
| 277 | .maxlen = sizeof(int), | ||
| 278 | .mode = 0644, | ||
| 279 | .proc_handler = proc_dointvec_minmax, | ||
| 280 | .extra1 = SYSCTL_ZERO, | ||
| 281 | }, | ||
| 282 | { | ||
| 283 | .procname = "hung_task_timeout_secs", | ||
| 284 | .data = &sysctl_hung_task_timeout_secs, | ||
| 285 | .maxlen = sizeof(unsigned long), | ||
| 286 | .mode = 0644, | ||
| 287 | .proc_handler = proc_dohung_task_timeout_secs, | ||
| 288 | .extra2 = (void *)&hung_task_timeout_max, | ||
| 289 | }, | ||
| 290 | { | ||
| 291 | .procname = "hung_task_check_interval_secs", | ||
| 292 | .data = &sysctl_hung_task_check_interval_secs, | ||
| 293 | .maxlen = sizeof(unsigned long), | ||
| 294 | .mode = 0644, | ||
| 295 | .proc_handler = proc_dohung_task_timeout_secs, | ||
| 296 | .extra2 = (void *)&hung_task_timeout_max, | ||
| 297 | }, | ||
| 298 | { | ||
| 299 | .procname = "hung_task_warnings", | ||
| 300 | .data = &sysctl_hung_task_warnings, | ||
| 301 | .maxlen = sizeof(int), | ||
| 302 | .mode = 0644, | ||
| 303 | .proc_handler = proc_dointvec_minmax, | ||
| 304 | .extra1 = SYSCTL_NEG_ONE, | ||
| 305 | }, | ||
| 306 | {} | ||
| 307 | }; | ||
| 308 | |||
| 309 | static void __init hung_task_sysctl_init(void) | ||
| 310 | { | ||
| 311 | register_sysctl_init("kernel", hung_task_sysctls); | ||
| 312 | } | ||
| 313 | #else | ||
| 314 | #define hung_task_sysctl_init() do { } while (0) | ||
| 315 | #endif /* CONFIG_SYSCTL */ | ||
| 316 | |||
| 317 | |||
| 244 | static atomic_t reset_hung_task = ATOMIC_INIT(0); | 318 | static atomic_t reset_hung_task = ATOMIC_INIT(0); |
| 245 | 319 | ||
| 246 | void reset_hung_task_detector(void) | 320 | void reset_hung_task_detector(void) |
| @@ -310,6 +384,7 @@ static int __init hung_task_init(void) · 63 unmodified lines | |||
| 310 | pm_notifier(hungtask_pm_notify, 0); | 384 | pm_notifier(hungtask_pm_notify, 0); |
| 311 | 385 | ||
| 312 | watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); | 386 | watchdog_task = kthread_run(watchdog, NULL, "khungtaskd"); |
| 387 | hung_task_sysctl_init(); | ||
| 313 | 388 | ||
| 314 | return 0; | 389 | return 0; |
| 315 | } | 390 | } |
| @@ -134,13 +134,6 @@ static int minolduid; · 133 unmodified lines | |||
| 134 | static int ngroups_max = NGROUPS_MAX; | 134 | static int ngroups_max = NGROUPS_MAX; |
| 135 | static const int cap_last_cap = CAP_LAST_CAP; | 135 | static const int cap_last_cap = CAP_LAST_CAP; |
| 136 | 136 | ||
| 137 | /* | ||
| 138 | * This is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs | ||
| 139 | * and hung_task_check_interval_secs | ||
| 140 | */ | ||
| 141 | #ifdef CONFIG_DETECT_HUNG_TASK | ||
| 142 | static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); | ||
| 143 | #endif | ||
| 144 | 137 | ||
| 145 | #ifdef CONFIG_INOTIFY_USER | 138 | #ifdef CONFIG_INOTIFY_USER |
| 146 | #include <linux/inotify.h> | 139 | #include <linux/inotify.h> |
| @@ -2508,60 +2501,6 @@ static struct ctl_table kern_table[] = { · 2361 unmodified lines | |||
| 2508 | .proc_handler = proc_dointvec, | 2501 | .proc_handler = proc_dointvec, |
| 2509 | }, | 2502 | }, |
| 2510 | #endif | 2503 | #endif |
| 2511 | #ifdef CONFIG_DETECT_HUNG_TASK | ||
| 2512 | #ifdef CONFIG_SMP | ||
| 2513 | { | ||
| 2514 | .procname = "hung_task_all_cpu_backtrace", | ||
| 2515 | .data = &sysctl_hung_task_all_cpu_backtrace, | ||
| 2516 | .maxlen = sizeof(int), | ||
| 2517 | .mode = 0644, | ||
| 2518 | .proc_handler = proc_dointvec_minmax, | ||
| 2519 | .extra1 = SYSCTL_ZERO, | ||
| 2520 | .extra2 = SYSCTL_ONE, | ||
| 2521 | }, | ||
| 2522 | #endif /* CONFIG_SMP */ | ||
| 2523 | { | ||
| 2524 | .procname = "hung_task_panic", | ||
| 2525 | .data = &sysctl_hung_task_panic, | ||
| 2526 | .maxlen = sizeof(int), | ||
| 2527 | .mode = 0644, | ||
| 2528 | .proc_handler = proc_dointvec_minmax, | ||
| 2529 | .extra1 = SYSCTL_ZERO, | ||
| 2530 | .extra2 = SYSCTL_ONE, | ||
| 2531 | }, | ||
| 2532 | { | ||
| 2533 | .procname = "hung_task_check_count", | ||
| 2534 | .data = &sysctl_hung_task_check_count, | ||
| 2535 | .maxlen = sizeof(int), | ||
| 2536 | .mode = 0644, | ||
| 2537 | .proc_handler = proc_dointvec_minmax, | ||
| 2538 | .extra1 = SYSCTL_ZERO, | ||
| 2539 | }, | ||
| 2540 | { | ||
| 2541 | .procname = "hung_task_timeout_secs", | ||
| 2542 | .data = &sysctl_hung_task_timeout_secs, | ||
| 2543 | .maxlen = sizeof(unsigned long), | ||
| 2544 | .mode = 0644, | ||
| 2545 | .proc_handler = proc_dohung_task_timeout_secs, | ||
| 2546 | .extra2 = &hung_task_timeout_max, | ||
| 2547 | }, | ||
| 2548 | { | ||
| 2549 | .procname = "hung_task_check_interval_secs", | ||
| 2550 | .data = &sysctl_hung_task_check_interval_secs, | ||
| 2551 | .maxlen = sizeof(unsigned long), | ||
| 2552 | .mode = 0644, | ||
| 2553 | .proc_handler = proc_dohung_task_timeout_secs, | ||
| 2554 | .extra2 = &hung_task_timeout_max, | ||
| 2555 | }, | ||
| 2556 | { | ||
| 2557 | .procname = "hung_task_warnings", | ||
| 2558 | .data = &sysctl_hung_task_warnings, | ||
| 2559 | .maxlen = sizeof(int), | ||
| 2560 | .mode = 0644, | ||
| 2561 | .proc_handler = proc_dointvec_minmax, | ||
| 2562 | .extra1 = SYSCTL_NEG_ONE, | ||
| 2563 | }, | ||
| 2564 | #endif | ||
| 2565 | #ifdef CONFIG_RT_MUTEXES | 2504 | #ifdef CONFIG_RT_MUTEXES |
| 2566 | { | 2505 | { |
| 2567 | .procname = "max_lock_depth", | 2506 | .procname = "max_lock_depth", |