diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index a96a05d23262..8a8b71b5751b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -5574,11 +5574,31 @@ static int cpu_to_cpu_group(int cpu) | |||
| 5574 | } | 5574 | } |
| 5575 | #endif | 5575 | #endif |
| 5576 | 5576 | ||
| 5577 | #ifdef CONFIG_SCHED_MC | ||
| 5578 | static DEFINE_PER_CPU(struct sched_domain, core_domains); | ||
| 5579 | static struct sched_group sched_group_core[NR_CPUS]; | ||
| 5580 | #endif | ||
| 5581 | |||
| 5582 | #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT) | ||
| 5583 | static int cpu_to_core_group(int cpu) | ||
| 5584 | { | ||
| 5585 | return first_cpu(cpu_sibling_map[cpu]); | ||
| 5586 | } | ||
| 5587 | #elif defined(CONFIG_SCHED_MC) | ||
| 5588 | static int cpu_to_core_group(int cpu) | ||
| 5589 | { | ||
| 5590 | return cpu; | ||
| 5591 | } | ||
| 5592 | #endif | ||
| 5593 | |||
| 5577 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); | 5594 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); |
| 5578 | static struct sched_group sched_group_phys[NR_CPUS]; | 5595 | static struct sched_group sched_group_phys[NR_CPUS]; |
| 5579 | static int cpu_to_phys_group(int cpu) | 5596 | static int cpu_to_phys_group(int cpu) |
| 5580 | { | 5597 | { |
| 5581 | #ifdef CONFIG_SCHED_SMT | 5598 | #if defined(CONFIG_SCHED_MC) |
| 5599 | cpumask_t mask = cpu_coregroup_map(cpu); | ||
| 5600 | return first_cpu(mask); | ||
| 5601 | #elif defined(CONFIG_SCHED_SMT) | ||
| 5582 | return first_cpu(cpu_sibling_map[cpu]); | 5602 | return first_cpu(cpu_sibling_map[cpu]); |
| 5583 | #else | 5603 | #else |
| 5584 | return cpu; | 5604 | return cpu; |
| @@ -5676,6 +5696,17 @@ void build_sched_domains(const cpumask_t *cpu_map) | |||
| 5676 | sd->parent = p; | 5696 | sd->parent = p; |
| 5677 | sd->groups = &sched_group_phys[group]; | 5697 | sd->groups = &sched_group_phys[group]; |
| 5678 | 5698 | ||
| 5699 | #ifdef CONFIG_SCHED_MC | ||
| 5700 | p = sd; | ||
| 5701 | sd = &per_cpu(core_domains, i); | ||
| 5702 | group = cpu_to_core_group(i); | ||
| 5703 | *sd = SD_MC_INIT; | ||
| 5704 | sd->span = cpu_coregroup_map(i); | ||
| 5705 | cpus_and(sd->span, sd->span, *cpu_map); | ||
| 5706 | sd->parent = p; | ||
| 5707 | sd->groups = &sched_group_core[group]; | ||
| 5708 | #endif | ||
| 5709 | |||
| 5679 | #ifdef CONFIG_SCHED_SMT | 5710 | #ifdef CONFIG_SCHED_SMT |
| 5680 | p = sd; | 5711 | p = sd; |
| 5681 | sd = &per_cpu(cpu_domains, i); | 5712 | sd = &per_cpu(cpu_domains, i); |
| @@ -5701,6 +5732,19 @@ void build_sched_domains(const cpumask_t *cpu_map) | |||
| 5701 | } | 5732 | } |
| 5702 | #endif | 5733 | #endif |
| 5703 | 5734 | ||
| 5735 | #ifdef CONFIG_SCHED_MC | ||
| 5736 | /* Set up multi-core groups */ | ||
| 5737 | for_each_cpu_mask(i, *cpu_map) { | ||
| 5738 | cpumask_t this_core_map = cpu_coregroup_map(i); | ||
| 5739 | cpus_and(this_core_map, this_core_map, *cpu_map); | ||
| 5740 | if (i != first_cpu(this_core_map)) | ||
| 5741 | continue; | ||
| 5742 | init_sched_build_groups(sched_group_core, this_core_map, | ||
| 5743 | &cpu_to_core_group); | ||
| 5744 | } | ||
| 5745 | #endif | ||
| 5746 | |||
| 5747 | |||
| 5704 | /* Set up physical groups */ | 5748 | /* Set up physical groups */ |
| 5705 | for (i = 0; i < MAX_NUMNODES; i++) { | 5749 | for (i = 0; i < MAX_NUMNODES; i++) { |
| 5706 | cpumask_t nodemask = node_to_cpumask(i); | 5750 | cpumask_t nodemask = node_to_cpumask(i); |
| @@ -5797,11 +5841,31 @@ void build_sched_domains(const cpumask_t *cpu_map) | |||
| 5797 | power = SCHED_LOAD_SCALE; | 5841 | power = SCHED_LOAD_SCALE; |
| 5798 | sd->groups->cpu_power = power; | 5842 | sd->groups->cpu_power = power; |
| 5799 | #endif | 5843 | #endif |
| 5844 | #ifdef CONFIG_SCHED_MC | ||
| 5845 | sd = &per_cpu(core_domains, i); | ||
| 5846 | power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1) | ||
| 5847 | * SCHED_LOAD_SCALE / 10; | ||
| 5848 | sd->groups->cpu_power = power; | ||
| 5849 | |||
| 5850 | sd = &per_cpu(phys_domains, i); | ||
| 5800 | 5851 | ||
| 5852 | /* | ||
| 5853 | * This has to be < 2 * SCHED_LOAD_SCALE | ||
| 5854 | * Lets keep it SCHED_LOAD_SCALE, so that | ||
| 5855 | * while calculating NUMA group's cpu_power | ||
| 5856 | * we can simply do | ||
| 5857 | * numa_group->cpu_power += phys_group->cpu_power; | ||
| 5858 | * | ||
| 5859 | * See "only add power once for each physical pkg" | ||
| 5860 | * comment below | ||
| 5861 | */ | ||
| 5862 | sd->groups->cpu_power = SCHED_LOAD_SCALE; | ||
| 5863 | #else | ||
| 5801 | sd = &per_cpu(phys_domains, i); | 5864 | sd = &per_cpu(phys_domains, i); |
| 5802 | power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE * | 5865 | power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE * |
| 5803 | (cpus_weight(sd->groups->cpumask)-1) / 10; | 5866 | (cpus_weight(sd->groups->cpumask)-1) / 10; |
| 5804 | sd->groups->cpu_power = power; | 5867 | sd->groups->cpu_power = power; |
| 5868 | #endif | ||
| 5805 | 5869 | ||
| 5806 | #ifdef CONFIG_NUMA | 5870 | #ifdef CONFIG_NUMA |
| 5807 | sd = &per_cpu(allnodes_domains, i); | 5871 | sd = &per_cpu(allnodes_domains, i); |
| @@ -5823,7 +5887,6 @@ void build_sched_domains(const cpumask_t *cpu_map) | |||
| 5823 | next_sg: | 5887 | next_sg: |
| 5824 | for_each_cpu_mask(j, sg->cpumask) { | 5888 | for_each_cpu_mask(j, sg->cpumask) { |
| 5825 | struct sched_domain *sd; | 5889 | struct sched_domain *sd; |
| 5826 | int power; | ||
| 5827 | 5890 | ||
| 5828 | sd = &per_cpu(phys_domains, j); | 5891 | sd = &per_cpu(phys_domains, j); |
| 5829 | if (j != first_cpu(sd->groups->cpumask)) { | 5892 | if (j != first_cpu(sd->groups->cpumask)) { |
| @@ -5833,10 +5896,8 @@ next_sg: | |||
| 5833 | */ | 5896 | */ |
| 5834 | continue; | 5897 | continue; |
| 5835 | } | 5898 | } |
| 5836 | power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE * | ||
| 5837 | (cpus_weight(sd->groups->cpumask)-1) / 10; | ||
| 5838 | 5899 | ||
| 5839 | sg->cpu_power += power; | 5900 | sg->cpu_power += sd->groups->cpu_power; |
| 5840 | } | 5901 | } |
| 5841 | sg = sg->next; | 5902 | sg = sg->next; |
| 5842 | if (sg != sched_group_nodes[i]) | 5903 | if (sg != sched_group_nodes[i]) |
| @@ -5849,6 +5910,8 @@ next_sg: | |||
| 5849 | struct sched_domain *sd; | 5910 | struct sched_domain *sd; |
| 5850 | #ifdef CONFIG_SCHED_SMT | 5911 | #ifdef CONFIG_SCHED_SMT |
| 5851 | sd = &per_cpu(cpu_domains, i); | 5912 | sd = &per_cpu(cpu_domains, i); |
| 5913 | #elif defined(CONFIG_SCHED_MC) | ||
| 5914 | sd = &per_cpu(core_domains, i); | ||
| 5852 | #else | 5915 | #else |
| 5853 | sd = &per_cpu(phys_domains, i); | 5916 | sd = &per_cpu(phys_domains, i); |
| 5854 | #endif | 5917 | #endif |
