.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * kernel/sched/debug.c |
---|
3 | 4 | * |
---|
4 | 5 | * Print the CFS rbtree and other debugging details |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright(C) 2007, Red Hat, Inc., Ingo Molnar |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | 8 | */ |
---|
12 | 9 | #include "sched.h" |
---|
13 | 10 | |
---|
.. | .. |
---|
51 | 48 | #define SCHED_FEAT(name, enabled) \ |
---|
52 | 49 | #name , |
---|
53 | 50 | |
---|
54 | | -static const char * const sched_feat_names[] = { |
---|
| 51 | +const char * const sched_feat_names[] = { |
---|
55 | 52 | #include "features.h" |
---|
56 | 53 | }; |
---|
57 | 54 | |
---|
| 55 | +EXPORT_SYMBOL_GPL(sched_feat_names); |
---|
58 | 56 | #undef SCHED_FEAT |
---|
59 | 57 | |
---|
60 | 58 | static int sched_feat_show(struct seq_file *m, void *v) |
---|
.. | .. |
---|
82 | 80 | struct static_key sched_feat_keys[__SCHED_FEAT_NR] = { |
---|
83 | 81 | #include "features.h" |
---|
84 | 82 | }; |
---|
| 83 | +EXPORT_SYMBOL_GPL(sched_feat_keys); |
---|
85 | 84 | |
---|
86 | 85 | #undef SCHED_FEAT |
---|
87 | 86 | |
---|
.. | .. |
---|
234 | 233 | *tablep = NULL; |
---|
235 | 234 | } |
---|
236 | 235 | |
---|
237 | | -static int min_load_idx = 0; |
---|
238 | | -static int max_load_idx = CPU_LOAD_IDX_MAX-1; |
---|
239 | | - |
---|
240 | 236 | static void |
---|
241 | 237 | set_table_entry(struct ctl_table *entry, |
---|
242 | 238 | const char *procname, void *data, int maxlen, |
---|
243 | | - umode_t mode, proc_handler *proc_handler, |
---|
244 | | - bool load_idx) |
---|
| 239 | + umode_t mode, proc_handler *proc_handler) |
---|
245 | 240 | { |
---|
246 | 241 | entry->procname = procname; |
---|
247 | 242 | entry->data = data; |
---|
248 | 243 | entry->maxlen = maxlen; |
---|
249 | 244 | entry->mode = mode; |
---|
250 | 245 | entry->proc_handler = proc_handler; |
---|
| 246 | +} |
---|
251 | 247 | |
---|
252 | | - if (load_idx) { |
---|
253 | | - entry->extra1 = &min_load_idx; |
---|
254 | | - entry->extra2 = &max_load_idx; |
---|
| 248 | +static int sd_ctl_doflags(struct ctl_table *table, int write, |
---|
| 249 | + void *buffer, size_t *lenp, loff_t *ppos) |
---|
| 250 | +{ |
---|
| 251 | + unsigned long flags = *(unsigned long *)table->data; |
---|
| 252 | + size_t data_size = 0; |
---|
| 253 | + size_t len = 0; |
---|
| 254 | + char *tmp, *buf; |
---|
| 255 | + int idx; |
---|
| 256 | + |
---|
| 257 | + if (write) |
---|
| 258 | + return 0; |
---|
| 259 | + |
---|
| 260 | + for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { |
---|
| 261 | + char *name = sd_flag_debug[idx].name; |
---|
| 262 | + |
---|
| 263 | + /* Name plus whitespace */ |
---|
| 264 | + data_size += strlen(name) + 1; |
---|
255 | 265 | } |
---|
| 266 | + |
---|
| 267 | + if (*ppos > data_size) { |
---|
| 268 | + *lenp = 0; |
---|
| 269 | + return 0; |
---|
| 270 | + } |
---|
| 271 | + |
---|
| 272 | + buf = kcalloc(data_size + 1, sizeof(*buf), GFP_KERNEL); |
---|
| 273 | + if (!buf) |
---|
| 274 | + return -ENOMEM; |
---|
| 275 | + |
---|
| 276 | + for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { |
---|
| 277 | + char *name = sd_flag_debug[idx].name; |
---|
| 278 | + |
---|
| 279 | + len += snprintf(buf + len, strlen(name) + 2, "%s ", name); |
---|
| 280 | + } |
---|
| 281 | + |
---|
| 282 | + tmp = buf + *ppos; |
---|
| 283 | + len -= *ppos; |
---|
| 284 | + |
---|
| 285 | + if (len > *lenp) |
---|
| 286 | + len = *lenp; |
---|
| 287 | + if (len) |
---|
| 288 | + memcpy(buffer, tmp, len); |
---|
| 289 | + if (len < *lenp) { |
---|
| 290 | + ((char *)buffer)[len] = '\n'; |
---|
| 291 | + len++; |
---|
| 292 | + } |
---|
| 293 | + |
---|
| 294 | + *lenp = len; |
---|
| 295 | + *ppos += len; |
---|
| 296 | + |
---|
| 297 | + kfree(buf); |
---|
| 298 | + |
---|
| 299 | + return 0; |
---|
256 | 300 | } |
---|
257 | 301 | |
---|
258 | 302 | static struct ctl_table * |
---|
259 | 303 | sd_alloc_ctl_domain_table(struct sched_domain *sd) |
---|
260 | 304 | { |
---|
261 | | - struct ctl_table *table = sd_alloc_ctl_entry(14); |
---|
| 305 | + struct ctl_table *table = sd_alloc_ctl_entry(9); |
---|
262 | 306 | |
---|
263 | 307 | if (table == NULL) |
---|
264 | 308 | return NULL; |
---|
265 | 309 | |
---|
266 | | - set_table_entry(&table[0] , "min_interval", &sd->min_interval, sizeof(long), 0644, proc_doulongvec_minmax, false); |
---|
267 | | - set_table_entry(&table[1] , "max_interval", &sd->max_interval, sizeof(long), 0644, proc_doulongvec_minmax, false); |
---|
268 | | - set_table_entry(&table[2] , "busy_idx", &sd->busy_idx, sizeof(int) , 0644, proc_dointvec_minmax, true ); |
---|
269 | | - set_table_entry(&table[3] , "idle_idx", &sd->idle_idx, sizeof(int) , 0644, proc_dointvec_minmax, true ); |
---|
270 | | - set_table_entry(&table[4] , "newidle_idx", &sd->newidle_idx, sizeof(int) , 0644, proc_dointvec_minmax, true ); |
---|
271 | | - set_table_entry(&table[5] , "wake_idx", &sd->wake_idx, sizeof(int) , 0644, proc_dointvec_minmax, true ); |
---|
272 | | - set_table_entry(&table[6] , "forkexec_idx", &sd->forkexec_idx, sizeof(int) , 0644, proc_dointvec_minmax, true ); |
---|
273 | | - set_table_entry(&table[7] , "busy_factor", &sd->busy_factor, sizeof(int) , 0644, proc_dointvec_minmax, false); |
---|
274 | | - set_table_entry(&table[8] , "imbalance_pct", &sd->imbalance_pct, sizeof(int) , 0644, proc_dointvec_minmax, false); |
---|
275 | | - set_table_entry(&table[9] , "cache_nice_tries", &sd->cache_nice_tries, sizeof(int) , 0644, proc_dointvec_minmax, false); |
---|
276 | | - set_table_entry(&table[10], "flags", &sd->flags, sizeof(int) , 0644, proc_dointvec_minmax, false); |
---|
277 | | - set_table_entry(&table[11], "max_newidle_lb_cost", &sd->max_newidle_lb_cost, sizeof(long), 0644, proc_doulongvec_minmax, false); |
---|
278 | | - set_table_entry(&table[12], "name", sd->name, CORENAME_MAX_SIZE, 0444, proc_dostring, false); |
---|
279 | | - /* &table[13] is terminator */ |
---|
| 310 | + set_table_entry(&table[0], "min_interval", &sd->min_interval, sizeof(long), 0644, proc_doulongvec_minmax); |
---|
| 311 | + set_table_entry(&table[1], "max_interval", &sd->max_interval, sizeof(long), 0644, proc_doulongvec_minmax); |
---|
| 312 | + set_table_entry(&table[2], "busy_factor", &sd->busy_factor, sizeof(int), 0644, proc_dointvec_minmax); |
---|
| 313 | + set_table_entry(&table[3], "imbalance_pct", &sd->imbalance_pct, sizeof(int), 0644, proc_dointvec_minmax); |
---|
| 314 | + set_table_entry(&table[4], "cache_nice_tries", &sd->cache_nice_tries, sizeof(int), 0644, proc_dointvec_minmax); |
---|
| 315 | + set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0444, sd_ctl_doflags); |
---|
| 316 | + set_table_entry(&table[6], "max_newidle_lb_cost", &sd->max_newidle_lb_cost, sizeof(long), 0644, proc_doulongvec_minmax); |
---|
| 317 | + set_table_entry(&table[7], "name", sd->name, CORENAME_MAX_SIZE, 0444, proc_dostring); |
---|
| 318 | + /* &table[8] is terminator */ |
---|
280 | 319 | |
---|
281 | 320 | return table; |
---|
282 | 321 | } |
---|
.. | .. |
---|
417 | 456 | } |
---|
418 | 457 | |
---|
419 | 458 | P(se->load.weight); |
---|
420 | | - P(se->runnable_weight); |
---|
421 | 459 | #ifdef CONFIG_SMP |
---|
422 | 460 | P(se->avg.load_avg); |
---|
423 | 461 | P(se->avg.util_avg); |
---|
424 | | - P(se->avg.runnable_load_avg); |
---|
| 462 | + P(se->avg.runnable_avg); |
---|
425 | 463 | #endif |
---|
426 | 464 | |
---|
427 | 465 | #undef PN_SCHEDSTAT |
---|
.. | .. |
---|
474 | 512 | else |
---|
475 | 513 | SEQ_printf(m, " %c", task_state_to_char(p)); |
---|
476 | 514 | |
---|
477 | | - SEQ_printf(m, "%15s %5d %9Ld.%06ld %9Ld %5d ", |
---|
| 515 | + SEQ_printf(m, " %15s %5d %9Ld.%06ld %9Ld %5d ", |
---|
478 | 516 | p->comm, task_pid_nr(p), |
---|
479 | 517 | SPLIT_NS(p->se.vruntime), |
---|
480 | 518 | (long long)(p->nvcsw + p->nivcsw), |
---|
.. | .. |
---|
501 | 539 | |
---|
502 | 540 | SEQ_printf(m, "\n"); |
---|
503 | 541 | SEQ_printf(m, "runnable tasks:\n"); |
---|
504 | | - SEQ_printf(m, " S task PID tree-key switches prio" |
---|
| 542 | + SEQ_printf(m, " S task PID tree-key switches prio" |
---|
505 | 543 | " wait-time sum-exec sum-sleep\n"); |
---|
506 | 544 | SEQ_printf(m, "-------------------------------------------------------" |
---|
507 | | - "----------------------------------------------------\n"); |
---|
| 545 | + "------------------------------------------------------\n"); |
---|
508 | 546 | |
---|
509 | 547 | rcu_read_lock(); |
---|
510 | 548 | for_each_process_thread(g, p) { |
---|
.. | .. |
---|
560 | 598 | SEQ_printf(m, " .%-30s: %d\n", "nr_running", cfs_rq->nr_running); |
---|
561 | 599 | SEQ_printf(m, " .%-30s: %ld\n", "load", cfs_rq->load.weight); |
---|
562 | 600 | #ifdef CONFIG_SMP |
---|
563 | | - SEQ_printf(m, " .%-30s: %ld\n", "runnable_weight", cfs_rq->runnable_weight); |
---|
564 | 601 | SEQ_printf(m, " .%-30s: %lu\n", "load_avg", |
---|
565 | 602 | cfs_rq->avg.load_avg); |
---|
566 | | - SEQ_printf(m, " .%-30s: %lu\n", "runnable_load_avg", |
---|
567 | | - cfs_rq->avg.runnable_load_avg); |
---|
| 603 | + SEQ_printf(m, " .%-30s: %lu\n", "runnable_avg", |
---|
| 604 | + cfs_rq->avg.runnable_avg); |
---|
568 | 605 | SEQ_printf(m, " .%-30s: %lu\n", "util_avg", |
---|
569 | 606 | cfs_rq->avg.util_avg); |
---|
570 | 607 | SEQ_printf(m, " .%-30s: %u\n", "util_est_enqueued", |
---|
.. | .. |
---|
573 | 610 | cfs_rq->removed.load_avg); |
---|
574 | 611 | SEQ_printf(m, " .%-30s: %ld\n", "removed.util_avg", |
---|
575 | 612 | cfs_rq->removed.util_avg); |
---|
576 | | - SEQ_printf(m, " .%-30s: %ld\n", "removed.runnable_sum", |
---|
577 | | - cfs_rq->removed.runnable_sum); |
---|
| 613 | + SEQ_printf(m, " .%-30s: %ld\n", "removed.runnable_avg", |
---|
| 614 | + cfs_rq->removed.runnable_avg); |
---|
578 | 615 | #ifdef CONFIG_FAIR_GROUP_SCHED |
---|
579 | 616 | SEQ_printf(m, " .%-30s: %lu\n", "tg_load_avg_contrib", |
---|
580 | 617 | cfs_rq->tg_load_avg_contrib); |
---|
.. | .. |
---|
674 | 711 | SEQ_printf(m, " .%-30s: %Ld.%06ld\n", #x, SPLIT_NS(rq->x)) |
---|
675 | 712 | |
---|
676 | 713 | P(nr_running); |
---|
677 | | - SEQ_printf(m, " .%-30s: %lu\n", "load", |
---|
678 | | - rq->load.weight); |
---|
679 | 714 | P(nr_switches); |
---|
680 | | - P(nr_load_updates); |
---|
681 | 715 | P(nr_uninterruptible); |
---|
682 | 716 | PN(next_balance); |
---|
683 | 717 | SEQ_printf(m, " .%-30s: %ld\n", "curr->pid", (long)(task_pid_nr(rq->curr))); |
---|
684 | 718 | PN(clock); |
---|
685 | 719 | PN(clock_task); |
---|
686 | | - P(cpu_load[0]); |
---|
687 | | - P(cpu_load[1]); |
---|
688 | | - P(cpu_load[2]); |
---|
689 | | - P(cpu_load[3]); |
---|
690 | | - P(cpu_load[4]); |
---|
691 | 720 | #undef P |
---|
692 | 721 | #undef PN |
---|
693 | 722 | |
---|
.. | .. |
---|
718 | 747 | |
---|
719 | 748 | static const char *sched_tunable_scaling_names[] = { |
---|
720 | 749 | "none", |
---|
721 | | - "logaritmic", |
---|
| 750 | + "logarithmic", |
---|
722 | 751 | "linear" |
---|
723 | 752 | }; |
---|
724 | 753 | |
---|
.. | .. |
---|
791 | 820 | int cpu; |
---|
792 | 821 | |
---|
793 | 822 | sched_debug_header(NULL); |
---|
794 | | - for_each_online_cpu(cpu) |
---|
| 823 | + for_each_online_cpu(cpu) { |
---|
| 824 | + /* |
---|
| 825 | + * Need to reset softlockup watchdogs on all CPUs, because |
---|
| 826 | + * another CPU might be blocked waiting for us to process |
---|
| 827 | + * an IPI or stop_machine. |
---|
| 828 | + */ |
---|
| 829 | + touch_nmi_watchdog(); |
---|
| 830 | + touch_all_softlockup_watchdogs(); |
---|
795 | 831 | print_cpu(NULL, cpu); |
---|
796 | | - |
---|
| 832 | + } |
---|
797 | 833 | } |
---|
798 | 834 | |
---|
799 | 835 | /* |
---|
.. | .. |
---|
851 | 887 | |
---|
852 | 888 | __initcall(init_sched_debug_procfs); |
---|
853 | 889 | |
---|
854 | | -#define __P(F) SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)F) |
---|
855 | | -#define P(F) SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)p->F) |
---|
856 | | -#define __PN(F) SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)F)) |
---|
857 | | -#define PN(F) SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)p->F)) |
---|
| 890 | +#define __PS(S, F) SEQ_printf(m, "%-45s:%21Ld\n", S, (long long)(F)) |
---|
| 891 | +#define __P(F) __PS(#F, F) |
---|
| 892 | +#define P(F) __PS(#F, p->F) |
---|
| 893 | +#define PM(F, M) __PS(#F, p->F & (M)) |
---|
| 894 | +#define __PSN(S, F) SEQ_printf(m, "%-45s:%14Ld.%06ld\n", S, SPLIT_NS((long long)(F))) |
---|
| 895 | +#define __PN(F) __PSN(#F, F) |
---|
| 896 | +#define PN(F) __PSN(#F, p->F) |
---|
858 | 897 | |
---|
859 | 898 | |
---|
860 | 899 | #ifdef CONFIG_NUMA_BALANCING |
---|
.. | .. |
---|
871 | 910 | static void sched_show_numa(struct task_struct *p, struct seq_file *m) |
---|
872 | 911 | { |
---|
873 | 912 | #ifdef CONFIG_NUMA_BALANCING |
---|
874 | | - struct mempolicy *pol; |
---|
875 | | - |
---|
876 | 913 | if (p->mm) |
---|
877 | 914 | P(mm->numa_scan_seq); |
---|
878 | | - |
---|
879 | | - task_lock(p); |
---|
880 | | - pol = p->mempolicy; |
---|
881 | | - if (pol && !(pol->flags & MPOL_F_MORON)) |
---|
882 | | - pol = NULL; |
---|
883 | | - mpol_get(pol); |
---|
884 | | - task_unlock(p); |
---|
885 | 915 | |
---|
886 | 916 | P(numa_pages_migrated); |
---|
887 | 917 | P(numa_preferred_nid); |
---|
.. | .. |
---|
889 | 919 | SEQ_printf(m, "current_node=%d, numa_group_id=%d\n", |
---|
890 | 920 | task_node(p), task_numa_group_id(p)); |
---|
891 | 921 | show_numa_stats(p, m); |
---|
892 | | - mpol_put(pol); |
---|
893 | 922 | #endif |
---|
894 | 923 | } |
---|
895 | 924 | |
---|
.. | .. |
---|
903 | 932 | SEQ_printf(m, |
---|
904 | 933 | "---------------------------------------------------------" |
---|
905 | 934 | "----------\n"); |
---|
906 | | -#define __P(F) \ |
---|
907 | | - SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)F) |
---|
908 | | -#define P(F) \ |
---|
909 | | - SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)p->F) |
---|
910 | | -#define P_SCHEDSTAT(F) \ |
---|
911 | | - SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)schedstat_val(p->F)) |
---|
912 | | -#define __PN(F) \ |
---|
913 | | - SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)F)) |
---|
914 | | -#define PN(F) \ |
---|
915 | | - SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)p->F)) |
---|
916 | | -#define PN_SCHEDSTAT(F) \ |
---|
917 | | - SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)schedstat_val(p->F))) |
---|
| 935 | + |
---|
| 936 | +#define P_SCHEDSTAT(F) __PS(#F, schedstat_val(p->F)) |
---|
| 937 | +#define PN_SCHEDSTAT(F) __PSN(#F, schedstat_val(p->F)) |
---|
918 | 938 | |
---|
919 | 939 | PN(se.exec_start); |
---|
920 | 940 | PN(se.vruntime); |
---|
.. | .. |
---|
974 | 994 | } |
---|
975 | 995 | |
---|
976 | 996 | __P(nr_switches); |
---|
977 | | - SEQ_printf(m, "%-45s:%21Ld\n", |
---|
978 | | - "nr_voluntary_switches", (long long)p->nvcsw); |
---|
979 | | - SEQ_printf(m, "%-45s:%21Ld\n", |
---|
980 | | - "nr_involuntary_switches", (long long)p->nivcsw); |
---|
| 997 | + __PS("nr_voluntary_switches", p->nvcsw); |
---|
| 998 | + __PS("nr_involuntary_switches", p->nivcsw); |
---|
981 | 999 | |
---|
982 | 1000 | P(se.load.weight); |
---|
983 | | - P(se.runnable_weight); |
---|
984 | 1001 | #ifdef CONFIG_SMP |
---|
985 | 1002 | P(se.avg.load_sum); |
---|
986 | | - P(se.avg.runnable_load_sum); |
---|
| 1003 | + P(se.avg.runnable_sum); |
---|
987 | 1004 | P(se.avg.util_sum); |
---|
988 | 1005 | P(se.avg.load_avg); |
---|
989 | | - P(se.avg.runnable_load_avg); |
---|
| 1006 | + P(se.avg.runnable_avg); |
---|
990 | 1007 | P(se.avg.util_avg); |
---|
991 | 1008 | P(se.avg.last_update_time); |
---|
992 | 1009 | P(se.avg.util_est.ewma); |
---|
993 | | - P(se.avg.util_est.enqueued); |
---|
| 1010 | + PM(se.avg.util_est.enqueued, ~UTIL_AVG_UNCHANGED); |
---|
| 1011 | +#endif |
---|
| 1012 | +#ifdef CONFIG_UCLAMP_TASK |
---|
| 1013 | + __PS("uclamp.min", p->uclamp_req[UCLAMP_MIN].value); |
---|
| 1014 | + __PS("uclamp.max", p->uclamp_req[UCLAMP_MAX].value); |
---|
| 1015 | + __PS("effective uclamp.min", uclamp_eff_value(p, UCLAMP_MIN)); |
---|
| 1016 | + __PS("effective uclamp.max", uclamp_eff_value(p, UCLAMP_MAX)); |
---|
994 | 1017 | #endif |
---|
995 | 1018 | P(policy); |
---|
996 | 1019 | P(prio); |
---|
997 | | - if (p->policy == SCHED_DEADLINE) { |
---|
| 1020 | + if (task_has_dl_policy(p)) { |
---|
998 | 1021 | P(dl.runtime); |
---|
999 | 1022 | P(dl.deadline); |
---|
1000 | 1023 | } |
---|
1001 | 1024 | #undef PN_SCHEDSTAT |
---|
1002 | | -#undef PN |
---|
1003 | | -#undef __PN |
---|
1004 | 1025 | #undef P_SCHEDSTAT |
---|
1005 | | -#undef P |
---|
1006 | | -#undef __P |
---|
1007 | 1026 | |
---|
1008 | 1027 | { |
---|
1009 | 1028 | unsigned int this_cpu = raw_smp_processor_id(); |
---|
.. | .. |
---|
1011 | 1030 | |
---|
1012 | 1031 | t0 = cpu_clock(this_cpu); |
---|
1013 | 1032 | t1 = cpu_clock(this_cpu); |
---|
1014 | | - SEQ_printf(m, "%-45s:%21Ld\n", |
---|
1015 | | - "clock-delta", (long long)(t1-t0)); |
---|
| 1033 | + __PS("clock-delta", t1-t0); |
---|
1016 | 1034 | } |
---|
1017 | 1035 | |
---|
1018 | 1036 | sched_show_numa(p, m); |
---|