diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 146 |
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 | ||
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 | |||
5578 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); | 5594 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); |
5579 | static struct sched_group sched_group_phys[NR_CPUS]; | 5595 | static struct sched_group sched_group_phys[NR_CPUS]; |
5580 | static int cpu_to_phys_group(int cpu) | 5596 | static 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 | } |
5624 | static 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; | ||
5631 | next_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; | ||
5824 | next_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 |