Re: [PATCH] sched_groups are expected to be circular linked list, make it so right after allocation

Peter Zijlstra
2012-05-09T12:30:56Z

On Wed, 2012-05-09 at 14:21 +0200, Peter Zijlstra wrote:
> Does something like the below give any clues as to how we got there?

New version that checks we include the right cpu in build_sched_domain()
too.. on a related note, we should add a printk-%p modifier for cpulist,
this cpulist_scnprintf() stuff gets annoying.

---
include/linux/sched.h | 9 +++++++++
kernel/sched/core.c | 26 ++++++++++++++++++++++++++
2 files changed, 35 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 714fa99..416aad9 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1041,6 +1041,15 @@ struct sched_domain {
unsigned long span[0];
};

+static inline char *sched_domain_name(struct sched_domain *sd)
+{
+#ifdef CONFIG_SCHED_DEBUG
+ return sd->name;
+#else
+ return "";
+#endif
+}
+
static inline struct cpumask *sched_domain_span(struct sched_domain *sd)
{
return to_cpumask(sd->span);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 7b77e3b..2884134 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6072,6 +6072,22 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu)
last = sg;
last->next = first;
}
+ if (!groups) {
+ char str[256];
+
+ printk(KERN_ERR "sched: Topology is hosed for CPU-%d!!\n", cpu);
+ cpulist_scnprintf(str, sizeof(str), sched_domain_span(sd));
+ printk(KERN_ERR "sched: domain: %s %s\n", sched_domain_name(sd), str);
+
+ sg = first;
+ if (sg) do {
+ cpulist_scnprintf(str, sizeof(str), sched_group_cpus(sg));
+ printk(KERN_ERR "sched: group: %s\n", str);
+ sg = sg->next;
+ } while (sg != first);
+
+ BUG();
+ }
sd->groups = groups;

return 0;
@@ -6440,6 +6456,16 @@ struct sched_domain *build_sched_domain(struct sched_domain_topology_level *tl,

set_domain_attribute(sd, attr);
cpumask_and(sched_domain_span(sd), cpu_map, tl->mask(cpu));
+ if (!cpumask_test_cpu(cpu, sched_domain_span(sd))) {
+ char str[256];
+ cpulist_scnprintf(str, sizeof(str), cpu_map);
+ printk(KERN_ERR "sched: Bonkers domain doesn't include its own cpu: %d %s\n",
+ cpu, str);
+ cpulist_scnprintf(str, sizeof(str), tl->mask(cpu));
+ printk(KERN_ERR "sched: Bonkers domain doesn't include its own cpu: %d %s\n",
+ cpu, str);
+ WARN(1);
+ }
if (child) {
sd->level = child->level + 1;
sched_domain_level_max = max(sched_domain_level_max, sd->level);