#include #include /* Don't do any NUMA setup on Opteron right now. They seem to be better off with flat scheduling. This is just for SMT. */ #ifdef CONFIG_SCHED_SMT static struct sched_group sched_group_cpus[NR_CPUS]; static struct sched_group sched_group_phys[NR_CPUS]; static DEFINE_PER_CPU(struct sched_domain, cpu_domains); static DEFINE_PER_CPU(struct sched_domain, phys_domains); __init void arch_init_sched_domains(void) { int i; struct sched_group *first = NULL, *last = NULL; /* Set up domains */ for_each_cpu(i) { struct sched_domain *cpu_domain = &per_cpu(cpu_domains, i); struct sched_domain *phys_domain = &per_cpu(phys_domains, i); *cpu_domain = SD_SIBLING_INIT; /* Disable SMT NICE for CMP */ /* RED-PEN use a generic flag */ if (cpu_data[i].x86_vendor == X86_VENDOR_AMD) cpu_domain->flags &= ~SD_SHARE_CPUPOWER; cpu_domain->span = cpu_sibling_map[i]; cpu_domain->parent = phys_domain; cpu_domain->groups = &sched_group_cpus[i]; *phys_domain = SD_CPU_INIT; phys_domain->span = cpu_possible_map; phys_domain->groups = &sched_group_phys[first_cpu(cpu_domain->span)]; } /* Set up CPU (sibling) groups */ for_each_cpu(i) { struct sched_domain *cpu_domain = &per_cpu(cpu_domains, i); int j; first = last = NULL; if (i != first_cpu(cpu_domain->span)) continue; for_each_cpu_mask(j, cpu_domain->span) { struct sched_group *cpu = &sched_group_cpus[j]; cpus_clear(cpu->cpumask); cpu_set(j, cpu->cpumask); cpu->cpu_power = SCHED_LOAD_SCALE; if (!first) first = cpu; if (last) last->next = cpu; last = cpu; } last->next = first; } first = last = NULL; /* Set up physical groups */ for_each_cpu(i) { struct sched_domain *cpu_domain = &per_cpu(cpu_domains, i); struct sched_group *cpu = &sched_group_phys[i]; if (i != first_cpu(cpu_domain->span)) continue; cpu->cpumask = cpu_domain->span; /* * Make each extra sibling increase power by 10% of * the basic CPU. This is very arbitrary. */ cpu->cpu_power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE*(cpus_weight(cpu->cpumask)-1) / 10; if (!first) first = cpu; if (last) last->next = cpu; last = cpu; } last->next = first; mb(); for_each_cpu(i) { struct sched_domain *cpu_domain = &per_cpu(cpu_domains, i); cpu_attach_domain(cpu_domain, i); } } #endif