Stop polluting sysctl, move to debugfs for SCHED_DEBUG stuff.
Showing the changes to kernel (3 of 3 files). Show all
Unified · Split
| @@ -299,6 +299,10 @@ static __init int sched_init_debug(void) · 298 unmodified lines | |||
| 299 | debugfs_create_file("tunable_scaling", 0644, debugfs_sched, NULL, &sched_scaling_fops); | 299 | debugfs_create_file("tunable_scaling", 0644, debugfs_sched, NULL, &sched_scaling_fops); |
| 300 | debugfs_create_u32("migration_cost_ns", 0644, debugfs_sched, &sysctl_sched_migration_cost); | 300 | debugfs_create_u32("migration_cost_ns", 0644, debugfs_sched, &sysctl_sched_migration_cost); |
| 301 | debugfs_create_u32("nr_migrate", 0644, debugfs_sched, &sysctl_sched_nr_migrate); | 301 | debugfs_create_u32("nr_migrate", 0644, debugfs_sched, &sysctl_sched_nr_migrate); |
| 302 | |||
| 303 | mutex_lock(&sched_domains_mutex); | ||
| 304 | update_sched_domain_debugfs(); | ||
| 305 | mutex_unlock(&sched_domains_mutex); | ||
| 302 | #endif | 306 | #endif |
| 303 | 307 | ||
| 304 | #ifdef CONFIG_NUMA_BALANCING | 308 | #ifdef CONFIG_NUMA_BALANCING |
| @@ -316,229 +320,88 @@ late_initcall(sched_init_debug); · 11 unmodified lines | |||
| 316 | 320 | ||
| 317 | #ifdef CONFIG_SMP | 321 | #ifdef CONFIG_SMP |
| 318 | 322 | ||
| 319 | #ifdef CONFIG_SYSCTL | 323 | static cpumask_var_t sd_sysctl_cpus; |
| 320 | 324 | static struct dentry *sd_dentry; | |
| 321 | static struct ctl_table sd_ctl_dir[] = { | ||
| 322 | { | ||
| 323 | .procname = "sched_domain", | ||
| 324 | .mode = 0555, | ||
| 325 | }, | ||
| 326 | {} | ||
| 327 | }; | ||
| 328 | |||
| 329 | static struct ctl_table sd_ctl_root[] = { | ||
| 330 | { | ||
| 331 | .procname = "kernel", | ||
| 332 | .mode = 0555, | ||
| 333 | .child = sd_ctl_dir, | ||
| 334 | }, | ||
| 335 | {} | ||
| 336 | }; | ||
| 337 | |||
| 338 | static struct ctl_table *sd_alloc_ctl_entry(int n) | ||
| 339 | { | ||
| 340 | struct ctl_table *entry = | ||
| 341 | kcalloc(n, sizeof(struct ctl_table), GFP_KERNEL); | ||
| 342 | |||
| 343 | return entry; | ||
| 344 | } | ||
| 345 | |||
| 346 | static void sd_free_ctl_entry(struct ctl_table **tablep) | ||
| 347 | { | ||
| 348 | struct ctl_table *entry; | ||
| 349 | |||
| 350 | /* | ||
| 351 | * In the intermediate directories, both the child directory and | ||
| 352 | * procname are dynamically allocated and could fail but the mode | ||
| 353 | * will always be set. In the lowest directory the names are | ||
| 354 | * static strings and all have proc handlers. | ||
| 355 | */ | ||
| 356 | for (entry = *tablep; entry->mode; entry++) { | ||
| 357 | if (entry->child) | ||
| 358 | sd_free_ctl_entry(&entry->child); | ||
| 359 | if (entry->proc_handler == NULL) | ||
| 360 | kfree(entry->procname); | ||
| 361 | } | ||
| 362 | |||
| 363 | kfree(*tablep); | ||
| 364 | *tablep = NULL; | ||
| 365 | } | ||
| 366 | |||
| 367 | static void | ||
| 368 | set_table_entry(struct ctl_table *entry, | ||
| 369 | const char *procname, void *data, int maxlen, | ||
| 370 | umode_t mode, proc_handler *proc_handler) | ||
| 371 | { | ||
| 372 | entry->procname = procname; | ||
| 373 | entry->data = data; | ||
| 374 | entry->maxlen = maxlen; | ||
| 375 | entry->mode = mode; | ||
| 376 | entry->proc_handler = proc_handler; | ||
| 377 | } | ||
| 378 | 325 | ||
| 379 | static int sd_ctl_doflags(struct ctl_table *table, int write, | 326 | static int sd_flags_show(struct seq_file *m, void *v) |
| 380 | void *buffer, size_t *lenp, loff_t *ppos) | ||
| 381 | { | 327 | { |
| 382 | unsigned long flags = *(unsigned long *)table->data; | 328 | unsigned long flags = *(unsigned int *)m->private; |
| 383 | size_t data_size = 0; | ||
| 384 | size_t len = 0; | ||
| 385 | char *tmp, *buf; | ||
| 386 | int idx; | 329 | int idx; |
| 387 | 330 | ||
| 388 | if (write) | ||
| 389 | return 0; | ||
| 390 | |||
| 391 | for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { | ||
| 392 | char *name = sd_flag_debug[idx].name; | ||
| 393 | |||
| 394 | /* Name plus whitespace */ | ||
| 395 | data_size += strlen(name) + 1; | ||
| 396 | } | ||
| 397 | |||
| 398 | if (*ppos > data_size) { | ||
| 399 | *lenp = 0; | ||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | |||
| 403 | buf = kcalloc(data_size + 1, sizeof(*buf), GFP_KERNEL); | ||
| 404 | if (!buf) | ||
| 405 | return -ENOMEM; | ||
| 406 | |||
| 407 | for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { | 331 | for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { |
| 408 | char *name = sd_flag_debug[idx].name; | 332 | seq_puts(m, sd_flag_debug[idx].name); |
| 409 | 333 | seq_puts(m, " "); | |
| 410 | len += snprintf(buf + len, strlen(name) + 2, "%s ", name); | ||
| 411 | } | ||
| 412 | |||
| 413 | tmp = buf + *ppos; | ||
| 414 | len -= *ppos; | ||
| 415 | |||
| 416 | if (len > *lenp) | ||
| 417 | len = *lenp; | ||
| 418 | if (len) | ||
| 419 | memcpy(buffer, tmp, len); | ||
| 420 | if (len < *lenp) { | ||
| 421 | ((char *)buffer)[len] = '\n'; | ||
| 422 | len++; | ||
| 423 | } | 334 | } |
| 424 | 335 | seq_puts(m, "\n"); | |
| 425 | *lenp = len; | ||
| 426 | *ppos += len; | ||
| 427 | |||
| 428 | kfree(buf); | ||
| 429 | 336 | ||
| 430 | return 0; | 337 | return 0; |
| 431 | } | 338 | } |
| 432 | 339 | ||
| 433 | static struct ctl_table * | 340 | static int sd_flags_open(struct inode *inode, struct file *file) |
| 434 | sd_alloc_ctl_domain_table(struct sched_domain *sd) | ||
| 435 | { | ||
| 436 | struct ctl_table *table = sd_alloc_ctl_entry(9); | ||
| 437 | |||
| 438 | if (table == NULL) | ||
| 439 | return NULL; | ||
| 440 | |||
| 441 | set_table_entry(&table[0], "min_interval", &sd->min_interval, sizeof(long), 0644, proc_doulongvec_minmax); | ||
| 442 | set_table_entry(&table[1], "max_interval", &sd->max_interval, sizeof(long), 0644, proc_doulongvec_minmax); | ||
| 443 | set_table_entry(&table[2], "busy_factor", &sd->busy_factor, sizeof(int), 0644, proc_dointvec_minmax); | ||
| 444 | set_table_entry(&table[3], "imbalance_pct", &sd->imbalance_pct, sizeof(int), 0644, proc_dointvec_minmax); | ||
| 445 | set_table_entry(&table[4], "cache_nice_tries", &sd->cache_nice_tries, sizeof(int), 0644, proc_dointvec_minmax); | ||
| 446 | set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0444, sd_ctl_doflags); | ||
| 447 | set_table_entry(&table[6], "max_newidle_lb_cost", &sd->max_newidle_lb_cost, sizeof(long), 0644, proc_doulongvec_minmax); | ||
| 448 | set_table_entry(&table[7], "name", sd->name, CORENAME_MAX_SIZE, 0444, proc_dostring); | ||
| 449 | /* &table[8] is terminator */ | ||
| 450 | |||
| 451 | return table; | ||
| 452 | } | ||
| 453 | |||
| 454 | static struct ctl_table *sd_alloc_ctl_cpu_table(int cpu) | ||
| 455 | { | 341 | { |
| 456 | struct ctl_table *entry, *table; | 342 | return single_open(file, sd_flags_show, inode->i_private); |
| 457 | struct sched_domain *sd; | ||
| 458 | int domain_num = 0, i; | ||
| 459 | char buf[32]; | ||
| 460 | |||
| 461 | for_each_domain(cpu, sd) | ||
| 462 | domain_num++; | ||
| 463 | entry = table = sd_alloc_ctl_entry(domain_num + 1); | ||
| 464 | if (table == NULL) | ||
| 465 | return NULL; | ||
| 466 | |||
| 467 | i = 0; | ||
| 468 | for_each_domain(cpu, sd) { | ||
| 469 | snprintf(buf, 32, "domain%d", i); | ||
| 470 | entry->procname = kstrdup(buf, GFP_KERNEL); | ||
| 471 | entry->mode = 0555; | ||
| 472 | entry->child = sd_alloc_ctl_domain_table(sd); | ||
| 473 | entry++; | ||
| 474 | i++; | ||
| 475 | } | ||
| 476 | return table; | ||
| 477 | } | 343 | } |
| 478 | 344 | ||
| 479 | static cpumask_var_t sd_sysctl_cpus; | 345 | static const struct file_operations sd_flags_fops = { |
| 480 | static struct ctl_table_header *sd_sysctl_header; | 346 | .open = sd_flags_open, |
| 347 | .read = seq_read, | ||
| 348 | .llseek = seq_lseek, | ||
| 349 | .release = single_release, | ||
| 350 | }; | ||
| 481 | 351 | ||
| 482 | void register_sched_domain_sysctl(void) | 352 | static void register_sd(struct sched_domain *sd, struct dentry *parent) |
| 483 | { | 353 | { |
| 484 | static struct ctl_table *cpu_entries; | 354 | #define SDM(type, mode, member) \ |
| 485 | static struct ctl_table **cpu_idx; | 355 | debugfs_create_##type(#member, mode, parent, &sd->member) |
| 486 | static bool init_done = false; | ||
| 487 | char buf[32]; | ||
| 488 | int i; | ||
| 489 | 356 | ||
| 490 | if (!cpu_entries) { | 357 | SDM(ulong, 0644, min_interval); |
| 491 | cpu_entries = sd_alloc_ctl_entry(num_possible_cpus() + 1); | 358 | SDM(ulong, 0644, max_interval); |
| 492 | if (!cpu_entries) | 359 | SDM(u64, 0644, max_newidle_lb_cost); |
| 493 | return; | 360 | SDM(u32, 0644, busy_factor); |
| 494 | 361 | SDM(u32, 0644, imbalance_pct); | |
| 495 | WARN_ON(sd_ctl_dir[0].child); | 362 | SDM(u32, 0644, cache_nice_tries); |
| 496 | sd_ctl_dir[0].child = cpu_entries; | 363 | SDM(str, 0444, name); |
| 497 | } | ||
| 498 | 364 | ||
| 499 | if (!cpu_idx) { | 365 | #undef SDM |
| 500 | struct ctl_table *e = cpu_entries; | ||
| 501 | 366 | ||
| 502 | cpu_idx = kcalloc(nr_cpu_ids, sizeof(struct ctl_table*), GFP_KERNEL); | 367 | debugfs_create_file("flags", 0444, parent, &sd->flags, &sd_flags_fops); |
| 503 | if (!cpu_idx) | 368 | } |
| 504 | return; | ||
| 505 | 369 | ||
| 506 | /* deal with sparse possible map */ | 370 | void update_sched_domain_debugfs(void) |
| 507 | for_each_possible_cpu(i) { | 371 | { |
| 508 | cpu_idx[i] = e; | 372 | int cpu, i; |
| 509 | e++; | ||
| 510 | } | ||
| 511 | } | ||
| 512 | 373 | ||
| 513 | if (!cpumask_available(sd_sysctl_cpus)) { | 374 | if (!cpumask_available(sd_sysctl_cpus)) { |
| 514 | if (!alloc_cpumask_var(&sd_sysctl_cpus, GFP_KERNEL)) | 375 | if (!alloc_cpumask_var(&sd_sysctl_cpus, GFP_KERNEL)) |
| 515 | return; | 376 | return; |
| 516 | } | ||
| 517 | |||
| 518 | if (!init_done) { | ||
| 519 | init_done = true; | ||
| 520 | /* init to possible to not have holes in @cpu_entries */ | ||
| 521 | cpumask_copy(sd_sysctl_cpus, cpu_possible_mask); | 377 | cpumask_copy(sd_sysctl_cpus, cpu_possible_mask); |
| 522 | } | 378 | } |
| 523 | 379 | ||
| 524 | for_each_cpu(i, sd_sysctl_cpus) { | 380 | if (!sd_dentry) |
| 525 | struct ctl_table *e = cpu_idx[i]; | 381 | sd_dentry = debugfs_create_dir("domains", debugfs_sched); |
| 382 | |||
| 383 | for_each_cpu(cpu, sd_sysctl_cpus) { | ||
| 384 | struct sched_domain *sd; | ||
| 385 | struct dentry *d_cpu; | ||
| 386 | char buf[32]; | ||
| 387 | |||
| 388 | snprintf(buf, sizeof(buf), "cpu%d", cpu); | ||
| 389 | debugfs_remove(debugfs_lookup(buf, sd_dentry)); | ||
| 390 | d_cpu = debugfs_create_dir(buf, sd_dentry); | ||
| 526 | 391 | ||
| 527 | if (e->child) | 392 | i = 0; |
| 528 | sd_free_ctl_entry(&e->child); | 393 | for_each_domain(cpu, sd) { |
| 394 | struct dentry *d_sd; | ||
| 529 | 395 | ||
| 530 | if (!e->procname) { | 396 | snprintf(buf, sizeof(buf), "domain%d", i); |
| 531 | snprintf(buf, 32, "cpu%d", i); | 397 | d_sd = debugfs_create_dir(buf, d_cpu); |
| 532 | e->procname = kstrdup(buf, GFP_KERNEL); | 398 | |
| 399 | register_sd(sd, d_sd); | ||
| 400 | i++; | ||
| 533 | } | 401 | } |
| 534 | e->mode = 0555; | ||
| 535 | e->child = sd_alloc_ctl_cpu_table(i); | ||
| 536 | 402 | ||
| 537 | __cpumask_clear_cpu(i, sd_sysctl_cpus); | 403 | __cpumask_clear_cpu(cpu, sd_sysctl_cpus); |
| 538 | } | 404 | } |
| 539 | |||
| 540 | WARN_ON(sd_sysctl_header); | ||
| 541 | sd_sysctl_header = register_sysctl_table(sd_ctl_root); | ||
| 542 | } | 405 | } |
| 543 | 406 | ||
| 544 | void dirty_sched_domain_sysctl(int cpu) | 407 | void dirty_sched_domain_sysctl(int cpu) |
| @@ -547,13 +410,6 @@ void dirty_sched_domain_sysctl(int cpu) · 2 unmodified lines | |||
| 547 | __cpumask_set_cpu(cpu, sd_sysctl_cpus); | 410 | __cpumask_set_cpu(cpu, sd_sysctl_cpus); |
| 548 | } | 411 | } |
| 549 | 412 | ||
| 550 | /* may be called multiple times per register */ | ||
| 551 | void unregister_sched_domain_sysctl(void) | ||
| 552 | { | ||
| 553 | unregister_sysctl_table(sd_sysctl_header); | ||
| 554 | sd_sysctl_header = NULL; | ||
| 555 | } | ||
| 556 | #endif /* CONFIG_SYSCTL */ | ||
| 557 | #endif /* CONFIG_SMP */ | 413 | #endif /* CONFIG_SMP */ |
| 558 | 414 | ||
| 559 | #ifdef CONFIG_FAIR_GROUP_SCHED | 415 | #ifdef CONFIG_FAIR_GROUP_SCHED |
| @@ -1552,20 +1552,16 @@ static inline unsigned int group_first_cpu(struct sched_group *group) · 1551 unmodified lines | |||
| 1552 | 1552 | ||
| 1553 | extern int group_balance_cpu(struct sched_group *sg); | 1553 | extern int group_balance_cpu(struct sched_group *sg); |
| 1554 | 1554 | ||
| 1555 | #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL) | 1555 | #ifdef CONFIG_SCHED_DEBUG |
| 1556 | void register_sched_domain_sysctl(void); | 1556 | void update_sched_domain_debugfs(void); |
| 1557 | void dirty_sched_domain_sysctl(int cpu); | 1557 | void dirty_sched_domain_sysctl(int cpu); |
| 1558 | void unregister_sched_domain_sysctl(void); | ||
| 1559 | #else | 1558 | #else |
| 1560 | static inline void register_sched_domain_sysctl(void) | 1559 | static inline void update_sched_domain_debugfs(void) |
| 1561 | { | 1560 | { |
| 1562 | } | 1561 | } |
| 1563 | static inline void dirty_sched_domain_sysctl(int cpu) | 1562 | static inline void dirty_sched_domain_sysctl(int cpu) |
| 1564 | { | 1563 | { |
| 1565 | } | 1564 | } |
| 1566 | static inline void unregister_sched_domain_sysctl(void) | ||
| 1567 | { | ||
| 1568 | } | ||
| 1569 | #endif | 1565 | #endif |
| 1570 | 1566 | ||
| 1571 | extern int sched_update_scaling(void); | 1567 | extern int sched_update_scaling(void); |
| @@ -2223,7 +2223,6 @@ int sched_init_domains(const struct cpumask *cpu_map) · 2222 unmodified lines | |||
| 2223 | doms_cur = &fallback_doms; | 2223 | doms_cur = &fallback_doms; |
| 2224 | cpumask_and(doms_cur[0], cpu_map, housekeeping_cpumask(HK_FLAG_DOMAIN)); | 2224 | cpumask_and(doms_cur[0], cpu_map, housekeeping_cpumask(HK_FLAG_DOMAIN)); |
| 2225 | err = build_sched_domains(doms_cur[0], NULL); | 2225 | err = build_sched_domains(doms_cur[0], NULL); |
| 2226 | register_sched_domain_sysctl(); | ||
| 2227 | 2226 | ||
| 2228 | return err; | 2227 | return err; |
| 2229 | } | 2228 | } |
| @@ -2298,9 +2297,6 @@ void partition_sched_domains_locked(int ndoms_new, cpumask_var_t doms_new[], · 68 unmodified lines | |||
| 2298 | 2297 | ||
| 2299 | lockdep_assert_held(&sched_domains_mutex); | 2298 | lockdep_assert_held(&sched_domains_mutex); |
| 2300 | 2299 | ||
| 2301 | /* Always unregister in case we don't destroy any domains: */ | ||
| 2302 | unregister_sched_domain_sysctl(); | ||
| 2303 | |||
| 2304 | /* Let the architecture update CPU core mappings: */ | 2300 | /* Let the architecture update CPU core mappings: */ |
| 2305 | new_topology = arch_update_cpu_topology(); | 2301 | new_topology = arch_update_cpu_topology(); |
| 2306 | 2302 | ||
| @@ -2389,7 +2385,7 @@ match3: · 82 unmodified lines | |||
| 2389 | dattr_cur = dattr_new; | 2385 | dattr_cur = dattr_new; |
| 2390 | ndoms_cur = ndoms_new; | 2386 | ndoms_cur = ndoms_new; |
| 2391 | 2387 | ||
| 2392 | register_sched_domain_sysctl(); | 2388 | update_sched_domain_debugfs(); |
| 2393 | } | 2389 | } |
| 2394 | 2390 | ||
| 2395 | /* | 2391 | /* |