From: Nick Piggin Anton was attempting to make a sched domain topology for his POWER5 and was having some trouble. This patch only includes code which is ifdefed out, but hopefully it will be of some use to implementors. --- 25-akpm/Documentation/sched-domains.txt | 7 ++ 25-akpm/kernel/sched.c | 78 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff -puN Documentation/sched-domains.txt~sched-domain-debugging Documentation/sched-domains.txt --- 25/Documentation/sched-domains.txt~sched-domain-debugging 2004-04-27 01:30:43.968485904 -0700 +++ 25-akpm/Documentation/sched-domains.txt 2004-04-27 01:30:43.973485144 -0700 @@ -46,3 +46,10 @@ The implementor should read comments in struct sched_domain fields, SD_FLAG_*, SD_*_INIT to get an idea of the specifics and what to tune. +Implementors should change the line +#undef SCHED_DOMAIN_DEBUG +to +#define SCHED_DOMAIN_DEBUG +in kernel/sched.c as this enables an error checking parse of the sched domains +which should catch most possible errors (described above). It also prints out +the domain structure in a visual format. diff -puN kernel/sched.c~sched-domain-debugging kernel/sched.c --- 25/kernel/sched.c~sched-domain-debugging 2004-04-27 01:30:43.970485600 -0700 +++ 25-akpm/kernel/sched.c 2004-04-27 01:30:43.976484688 -0700 @@ -3402,9 +3402,87 @@ static void __init arch_init_sched_domai #endif /* CONFIG_NUMA */ #endif /* ARCH_HAS_SCHED_DOMAIN */ +#undef SCHED_DOMAIN_DEBUG +#ifdef SCHED_DOMAIN_DEBUG +void sched_domain_debug(void) +{ + int i; + + for_each_cpu(i) { + int level = 0; + struct sched_domain *cpu_domain = cpu_sched_domain(i); + + printk(KERN_DEBUG "CPU%d: %s\n", + i, (cpu_online(i) ? " online" : "offline")); + + do { + int j; + char str[NR_CPUS]; + struct sched_group *group = cpu_domain->groups; + cpumask_t groupmask, tmp; + + cpumask_snprintf(str, NR_CPUS, cpu_domain->span); + cpus_clear(groupmask); + + printk(KERN_DEBUG); + for (j = 0; j < level + 1; j++) + printk(" "); + printk("domain %d: span %s\n", level, str); + + if (!cpu_isset(i, cpu_domain->span)) + printk(KERN_DEBUG "ERROR domain->span does not contain CPU%d\n", i); + if (!cpu_isset(i, group->cpumask)) + printk(KERN_DEBUG "ERROR domain->groups does not contain CPU%d\n", i); + + printk(KERN_DEBUG); + for (j = 0; j < level + 2; j++) + printk(" "); + printk("groups:"); + do { + if (group == NULL) { + printk(" ERROR: NULL"); + break; + } + + if (cpus_weight(group->cpumask) == 0) + printk(" ERROR empty group:"); + + cpus_and(tmp, groupmask, group->cpumask); + if (cpus_weight(tmp) > 0) + printk(" ERROR repeated CPUs:"); + + cpus_or(groupmask, groupmask, group->cpumask); + + cpumask_snprintf(str, NR_CPUS, group->cpumask); + printk(" %s", str); + + group = group->next; + } while (group != cpu_domain->groups); + printk("\n"); + + if (!cpus_equal(cpu_domain->span, groupmask)) + printk(KERN_DEBUG "ERROR groups don't span domain->span\n"); + + level++; + cpu_domain = cpu_domain->parent; + + if (cpu_domain) { + cpus_and(tmp, groupmask, cpu_domain->span); + if (!cpus_equal(tmp, groupmask)) + printk(KERN_DEBUG "ERROR parent span is not a superset of domain->span\n"); + } + + } while (cpu_domain); + } +} +#else +#define sched_domain_debug() {} +#endif + void __init sched_init_smp(void) { arch_init_sched_domains(); + sched_domain_debug(); } #else void __init sched_init_smp(void) _