aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c146
1 files changed, 102 insertions, 44 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 78acdefeccca..7854ee516b92 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -145,7 +145,8 @@
145 (v1) * (v2_max) / (v1_max) 145 (v1) * (v2_max) / (v1_max)
146 146
147#define DELTA(p) \ 147#define DELTA(p) \
148 (SCALE(TASK_NICE(p), 40, MAX_BONUS) + INTERACTIVE_DELTA) 148 (SCALE(TASK_NICE(p) + 20, 40, MAX_BONUS) - 20 * MAX_BONUS / 40 + \
149 INTERACTIVE_DELTA)
149 150
150#define TASK_INTERACTIVE(p) \ 151#define TASK_INTERACTIVE(p) \
151 ((p)->prio <= (p)->static_prio - DELTA(p)) 152 ((p)->prio <= (p)->static_prio - DELTA(p))
@@ -2878,13 +2879,11 @@ asmlinkage void __sched schedule(void)
2878 * schedule() atomically, we ignore that path for now. 2879 * schedule() atomically, we ignore that path for now.
2879 * Otherwise, whine if we are scheduling when we should not be. 2880 * Otherwise, whine if we are scheduling when we should not be.
2880 */ 2881 */
2881 if (likely(!current->exit_state)) { 2882 if (unlikely(in_atomic() && !current->exit_state)) {
2882 if (unlikely(in_atomic())) { 2883 printk(KERN_ERR "BUG: scheduling while atomic: "
2883 printk(KERN_ERR "BUG: scheduling while atomic: " 2884 "%s/0x%08x/%d\n",
2884 "%s/0x%08x/%d\n", 2885 current->comm, preempt_count(), current->pid);
2885 current->comm, preempt_count(), current->pid); 2886 dump_stack();
2886 dump_stack();
2887 }
2888 } 2887 }
2889 profile_hit(SCHED_PROFILING, __builtin_return_address(0)); 2888 profile_hit(SCHED_PROFILING, __builtin_return_address(0));
2890 2889
@@ -5575,11 +5574,31 @@ static int cpu_to_cpu_group(int cpu)
5575} 5574}
5576#endif 5575#endif
5577 5576
5577#ifdef CONFIG_SCHED_MC
5578static DEFINE_PER_CPU(struct sched_domain, core_domains);
5579static struct sched_group sched_group_core[NR_CPUS];
5580#endif
5581
5582#if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
5583static int cpu_to_core_group(int cpu)
5584{
5585 return first_cpu(cpu_sibling_map[cpu]);
5586}
5587#elif defined(CONFIG_SCHED_MC)
5588static int cpu_to_core_group(int cpu)
5589{
5590 return cpu;
5591}
5592#endif
5593
5578static DEFINE_PER_CPU(struct sched_domain, phys_domains); 5594static DEFINE_PER_CPU(struct sched_domain, phys_domains);
5579static struct sched_group sched_group_phys[NR_CPUS]; 5595static struct sched_group sched_group_phys[NR_CPUS];
5580static int cpu_to_phys_group(int cpu) 5596static int cpu_to_phys_group(int cpu)
5581{ 5597{
5582#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)
5583 return first_cpu(cpu_sibling_map[cpu]); 5602 return first_cpu(cpu_sibling_map[cpu]);
5584#else 5603#else
5585 return cpu; 5604 return cpu;
@@ -5602,6 +5621,32 @@ static int cpu_to_allnodes_group(int cpu)
5602{ 5621{
5603 return cpu_to_node(cpu); 5622 return cpu_to_node(cpu);
5604} 5623}
5624static void init_numa_sched_groups_power(struct sched_group *group_head)
5625{
5626 struct sched_group *sg = group_head;
5627 int j;
5628
5629 if (!sg)
5630 return;
5631next_sg:
5632 for_each_cpu_mask(j, sg->cpumask) {
5633 struct sched_domain *sd;
5634
5635 sd = &per_cpu(phys_domains, j);
5636 if (j != first_cpu(sd->groups->cpumask)) {
5637 /*
5638 * Only add "power" once for each
5639 * physical package.
5640 */
5641 continue;
5642 }
5643
5644 sg->cpu_power += sd->groups->cpu_power;
5645 }
5646 sg = sg->next;
5647 if (sg != group_head)
5648 goto next_sg;
5649}
5605#endif 5650#endif
5606 5651
5607/* 5652/*
@@ -5677,6 +5722,17 @@ void build_sched_domains(const cpumask_t *cpu_map)
5677 sd->parent = p; 5722 sd->parent = p;
5678 sd->groups = &sched_group_phys[group]; 5723 sd->groups = &sched_group_phys[group];
5679 5724
5725#ifdef CONFIG_SCHED_MC
5726 p = sd;
5727 sd = &per_cpu(core_domains, i);
5728 group = cpu_to_core_group(i);
5729 *sd = SD_MC_INIT;
5730 sd->span = cpu_coregroup_map(i);
5731 cpus_and(sd->span, sd->span, *cpu_map);
5732 sd->parent = p;
5733 sd->groups = &sched_group_core[group];
5734#endif
5735
5680#ifdef CONFIG_SCHED_SMT 5736#ifdef CONFIG_SCHED_SMT
5681 p = sd; 5737 p = sd;
5682 sd = &per_cpu(cpu_domains, i); 5738 sd = &per_cpu(cpu_domains, i);
@@ -5702,6 +5758,19 @@ void build_sched_domains(const cpumask_t *cpu_map)
5702 } 5758 }
5703#endif 5759#endif
5704 5760
5761#ifdef CONFIG_SCHED_MC
5762 /* Set up multi-core groups */
5763 for_each_cpu_mask(i, *cpu_map) {
5764 cpumask_t this_core_map = cpu_coregroup_map(i);
5765 cpus_and(this_core_map, this_core_map, *cpu_map);
5766 if (i != first_cpu(this_core_map))
5767 continue;
5768 init_sched_build_groups(sched_group_core, this_core_map,
5769 &cpu_to_core_group);
5770 }
5771#endif
5772
5773
5705 /* Set up physical groups */ 5774 /* Set up physical groups */
5706 for (i = 0; i < MAX_NUMNODES; i++) { 5775 for (i = 0; i < MAX_NUMNODES; i++) {
5707 cpumask_t nodemask = node_to_cpumask(i); 5776 cpumask_t nodemask = node_to_cpumask(i);
@@ -5798,51 +5867,38 @@ void build_sched_domains(const cpumask_t *cpu_map)
5798 power = SCHED_LOAD_SCALE; 5867 power = SCHED_LOAD_SCALE;
5799 sd->groups->cpu_power = power; 5868 sd->groups->cpu_power = power;
5800#endif 5869#endif
5870#ifdef CONFIG_SCHED_MC
5871 sd = &per_cpu(core_domains, i);
5872 power = SCHED_LOAD_SCALE + (cpus_weight(sd->groups->cpumask)-1)
5873 * SCHED_LOAD_SCALE / 10;
5874 sd->groups->cpu_power = power;
5801 5875
5802 sd = &per_cpu(phys_domains, i); 5876 sd = &per_cpu(phys_domains, i);
5877
5878 /*
5879 * This has to be < 2 * SCHED_LOAD_SCALE
5880 * Lets keep it SCHED_LOAD_SCALE, so that
5881 * while calculating NUMA group's cpu_power
5882 * we can simply do
5883 * numa_group->cpu_power += phys_group->cpu_power;
5884 *
5885 * See "only add power once for each physical pkg"
5886 * comment below
5887 */
5888 sd->groups->cpu_power = SCHED_LOAD_SCALE;
5889#else
5890 sd = &per_cpu(phys_domains, i);
5803 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE * 5891 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE *
5804 (cpus_weight(sd->groups->cpumask)-1) / 10; 5892 (cpus_weight(sd->groups->cpumask)-1) / 10;
5805 sd->groups->cpu_power = power; 5893 sd->groups->cpu_power = power;
5806
5807#ifdef CONFIG_NUMA
5808 sd = &per_cpu(allnodes_domains, i);
5809 if (sd->groups) {
5810 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE *
5811 (cpus_weight(sd->groups->cpumask)-1) / 10;
5812 sd->groups->cpu_power = power;
5813 }
5814#endif 5894#endif
5815 } 5895 }
5816 5896
5817#ifdef CONFIG_NUMA 5897#ifdef CONFIG_NUMA
5818 for (i = 0; i < MAX_NUMNODES; i++) { 5898 for (i = 0; i < MAX_NUMNODES; i++)
5819 struct sched_group *sg = sched_group_nodes[i]; 5899 init_numa_sched_groups_power(sched_group_nodes[i]);
5820 int j;
5821
5822 if (sg == NULL)
5823 continue;
5824next_sg:
5825 for_each_cpu_mask(j, sg->cpumask) {
5826 struct sched_domain *sd;
5827 int power;
5828
5829 sd = &per_cpu(phys_domains, j);
5830 if (j != first_cpu(sd->groups->cpumask)) {
5831 /*
5832 * Only add "power" once for each
5833 * physical package.
5834 */
5835 continue;
5836 }
5837 power = SCHED_LOAD_SCALE + SCHED_LOAD_SCALE *
5838 (cpus_weight(sd->groups->cpumask)-1) / 10;
5839 5900
5840 sg->cpu_power += power; 5901 init_numa_sched_groups_power(sched_group_allnodes);
5841 }
5842 sg = sg->next;
5843 if (sg != sched_group_nodes[i])
5844 goto next_sg;
5845 }
5846#endif 5902#endif
5847 5903
5848 /* Attach the domains */ 5904 /* Attach the domains */
@@ -5850,6 +5906,8 @@ next_sg:
5850 struct sched_domain *sd; 5906 struct sched_domain *sd;
5851#ifdef CONFIG_SCHED_SMT 5907#ifdef CONFIG_SCHED_SMT
5852 sd = &per_cpu(cpu_domains, i); 5908 sd = &per_cpu(cpu_domains, i);
5909#elif defined(CONFIG_SCHED_MC)
5910 sd = &per_cpu(core_domains, i);
5853#else 5911#else
5854 sd = &per_cpu(phys_domains, i); 5912 sd = &per_cpu(phys_domains, i);
5855#endif 5913#endif