diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-27 14:33:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-27 14:33:44 -0400 |
commit | b4322e7057ca851b0a3e15f29e26806efeada100 (patch) | |
tree | ed49e26f5f735fad7377f26fab241fe1b49672eb | |
parent | 31cafd958932a90174118ad062fdc37ffb6bf31c (diff) | |
parent | 9983b6f0cf8263e51bcf4c8a9dc0c1ef175b3c60 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu:
percpu: fix first chunk match in per_cpu_ptr_to_phys()
percpu: fix trivial bugs in pcpu_build_alloc_info()
-rw-r--r-- | mm/percpu.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/mm/percpu.c b/mm/percpu.c index 39f7dfd59585..6470e7710231 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -229,8 +229,8 @@ static int __maybe_unused pcpu_page_idx(unsigned int cpu, int page_idx) | |||
229 | return pcpu_unit_map[cpu] * pcpu_unit_pages + page_idx; | 229 | return pcpu_unit_map[cpu] * pcpu_unit_pages + page_idx; |
230 | } | 230 | } |
231 | 231 | ||
232 | static unsigned long __maybe_unused pcpu_chunk_addr(struct pcpu_chunk *chunk, | 232 | static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk, |
233 | unsigned int cpu, int page_idx) | 233 | unsigned int cpu, int page_idx) |
234 | { | 234 | { |
235 | return (unsigned long)chunk->base_addr + pcpu_unit_offsets[cpu] + | 235 | return (unsigned long)chunk->base_addr + pcpu_unit_offsets[cpu] + |
236 | (page_idx << PAGE_SHIFT); | 236 | (page_idx << PAGE_SHIFT); |
@@ -978,7 +978,32 @@ bool is_kernel_percpu_address(unsigned long addr) | |||
978 | */ | 978 | */ |
979 | phys_addr_t per_cpu_ptr_to_phys(void *addr) | 979 | phys_addr_t per_cpu_ptr_to_phys(void *addr) |
980 | { | 980 | { |
981 | if (pcpu_addr_in_first_chunk(addr)) { | 981 | void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr); |
982 | bool in_first_chunk = false; | ||
983 | unsigned long first_start, first_end; | ||
984 | unsigned int cpu; | ||
985 | |||
986 | /* | ||
987 | * The following test on first_start/end isn't strictly | ||
988 | * necessary but will speed up lookups of addresses which | ||
989 | * aren't in the first chunk. | ||
990 | */ | ||
991 | first_start = pcpu_chunk_addr(pcpu_first_chunk, pcpu_first_unit_cpu, 0); | ||
992 | first_end = pcpu_chunk_addr(pcpu_first_chunk, pcpu_last_unit_cpu, | ||
993 | pcpu_unit_pages); | ||
994 | if ((unsigned long)addr >= first_start && | ||
995 | (unsigned long)addr < first_end) { | ||
996 | for_each_possible_cpu(cpu) { | ||
997 | void *start = per_cpu_ptr(base, cpu); | ||
998 | |||
999 | if (addr >= start && addr < start + pcpu_unit_size) { | ||
1000 | in_first_chunk = true; | ||
1001 | break; | ||
1002 | } | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | if (in_first_chunk) { | ||
982 | if ((unsigned long)addr < VMALLOC_START || | 1007 | if ((unsigned long)addr < VMALLOC_START || |
983 | (unsigned long)addr >= VMALLOC_END) | 1008 | (unsigned long)addr >= VMALLOC_END) |
984 | return __pa(addr); | 1009 | return __pa(addr); |
@@ -1086,7 +1111,7 @@ struct pcpu_alloc_info * __init pcpu_build_alloc_info( | |||
1086 | static int group_map[NR_CPUS] __initdata; | 1111 | static int group_map[NR_CPUS] __initdata; |
1087 | static int group_cnt[NR_CPUS] __initdata; | 1112 | static int group_cnt[NR_CPUS] __initdata; |
1088 | const size_t static_size = __per_cpu_end - __per_cpu_start; | 1113 | const size_t static_size = __per_cpu_end - __per_cpu_start; |
1089 | int group_cnt_max = 0, nr_groups = 1, nr_units = 0; | 1114 | int nr_groups = 1, nr_units = 0; |
1090 | size_t size_sum, min_unit_size, alloc_size; | 1115 | size_t size_sum, min_unit_size, alloc_size; |
1091 | int upa, max_upa, uninitialized_var(best_upa); /* units_per_alloc */ | 1116 | int upa, max_upa, uninitialized_var(best_upa); /* units_per_alloc */ |
1092 | int last_allocs, group, unit; | 1117 | int last_allocs, group, unit; |
@@ -1096,7 +1121,7 @@ struct pcpu_alloc_info * __init pcpu_build_alloc_info( | |||
1096 | 1121 | ||
1097 | /* this function may be called multiple times */ | 1122 | /* this function may be called multiple times */ |
1098 | memset(group_map, 0, sizeof(group_map)); | 1123 | memset(group_map, 0, sizeof(group_map)); |
1099 | memset(group_cnt, 0, sizeof(group_map)); | 1124 | memset(group_cnt, 0, sizeof(group_cnt)); |
1100 | 1125 | ||
1101 | /* | 1126 | /* |
1102 | * Determine min_unit_size, alloc_size and max_upa such that | 1127 | * Determine min_unit_size, alloc_size and max_upa such that |
@@ -1130,7 +1155,6 @@ struct pcpu_alloc_info * __init pcpu_build_alloc_info( | |||
1130 | } | 1155 | } |
1131 | group_map[cpu] = group; | 1156 | group_map[cpu] = group; |
1132 | group_cnt[group]++; | 1157 | group_cnt[group]++; |
1133 | group_cnt_max = max(group_cnt_max, group_cnt[group]); | ||
1134 | } | 1158 | } |
1135 | 1159 | ||
1136 | /* | 1160 | /* |