aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-06-27 14:33:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-06-27 14:33:44 -0400
commitb4322e7057ca851b0a3e15f29e26806efeada100 (patch)
treeed49e26f5f735fad7377f26fab241fe1b49672eb
parent31cafd958932a90174118ad062fdc37ffb6bf31c (diff)
parent9983b6f0cf8263e51bcf4c8a9dc0c1ef175b3c60 (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.c36
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
232static unsigned long __maybe_unused pcpu_chunk_addr(struct pcpu_chunk *chunk, 232static 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 */
979phys_addr_t per_cpu_ptr_to_phys(void *addr) 979phys_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 /*