aboutsummaryrefslogtreecommitdiffstats
path: root/mm/percpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/percpu.c')
-rw-r--r--mm/percpu.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/mm/percpu.c b/mm/percpu.c
index bf80e55dbed..93b5a7c96a7 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -116,9 +116,9 @@ static int pcpu_atom_size __read_mostly;
116static int pcpu_nr_slots __read_mostly; 116static int pcpu_nr_slots __read_mostly;
117static size_t pcpu_chunk_struct_size __read_mostly; 117static size_t pcpu_chunk_struct_size __read_mostly;
118 118
119/* cpus with the lowest and highest unit numbers */ 119/* cpus with the lowest and highest unit addresses */
120static unsigned int pcpu_first_unit_cpu __read_mostly; 120static unsigned int pcpu_low_unit_cpu __read_mostly;
121static unsigned int pcpu_last_unit_cpu __read_mostly; 121static unsigned int pcpu_high_unit_cpu __read_mostly;
122 122
123/* the address of the first chunk which starts with the kernel static area */ 123/* the address of the first chunk which starts with the kernel static area */
124void *pcpu_base_addr __read_mostly; 124void *pcpu_base_addr __read_mostly;
@@ -984,19 +984,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
984{ 984{
985 void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr); 985 void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr);
986 bool in_first_chunk = false; 986 bool in_first_chunk = false;
987 unsigned long first_start, first_end; 987 unsigned long first_low, first_high;
988 unsigned int cpu; 988 unsigned int cpu;
989 989
990 /* 990 /*
991 * The following test on first_start/end isn't strictly 991 * The following test on unit_low/high isn't strictly
992 * necessary but will speed up lookups of addresses which 992 * necessary but will speed up lookups of addresses which
993 * aren't in the first chunk. 993 * aren't in the first chunk.
994 */ 994 */
995 first_start = pcpu_chunk_addr(pcpu_first_chunk, pcpu_first_unit_cpu, 0); 995 first_low = pcpu_chunk_addr(pcpu_first_chunk, pcpu_low_unit_cpu, 0);
996 first_end = pcpu_chunk_addr(pcpu_first_chunk, pcpu_last_unit_cpu, 996 first_high = pcpu_chunk_addr(pcpu_first_chunk, pcpu_high_unit_cpu,
997 pcpu_unit_pages); 997 pcpu_unit_pages);
998 if ((unsigned long)addr >= first_start && 998 if ((unsigned long)addr >= first_low &&
999 (unsigned long)addr < first_end) { 999 (unsigned long)addr < first_high) {
1000 for_each_possible_cpu(cpu) { 1000 for_each_possible_cpu(cpu) {
1001 void *start = per_cpu_ptr(base, cpu); 1001 void *start = per_cpu_ptr(base, cpu);
1002 1002
@@ -1233,7 +1233,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
1233 1233
1234 for (cpu = 0; cpu < nr_cpu_ids; cpu++) 1234 for (cpu = 0; cpu < nr_cpu_ids; cpu++)
1235 unit_map[cpu] = UINT_MAX; 1235 unit_map[cpu] = UINT_MAX;
1236 pcpu_first_unit_cpu = NR_CPUS; 1236
1237 pcpu_low_unit_cpu = NR_CPUS;
1238 pcpu_high_unit_cpu = NR_CPUS;
1237 1239
1238 for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) { 1240 for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) {
1239 const struct pcpu_group_info *gi = &ai->groups[group]; 1241 const struct pcpu_group_info *gi = &ai->groups[group];
@@ -1253,9 +1255,13 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
1253 unit_map[cpu] = unit + i; 1255 unit_map[cpu] = unit + i;
1254 unit_off[cpu] = gi->base_offset + i * ai->unit_size; 1256 unit_off[cpu] = gi->base_offset + i * ai->unit_size;
1255 1257
1256 if (pcpu_first_unit_cpu == NR_CPUS) 1258 /* determine low/high unit_cpu */
1257 pcpu_first_unit_cpu = cpu; 1259 if (pcpu_low_unit_cpu == NR_CPUS ||
1258 pcpu_last_unit_cpu = cpu; 1260 unit_off[cpu] < unit_off[pcpu_low_unit_cpu])
1261 pcpu_low_unit_cpu = cpu;
1262 if (pcpu_high_unit_cpu == NR_CPUS ||
1263 unit_off[cpu] > unit_off[pcpu_high_unit_cpu])
1264 pcpu_high_unit_cpu = cpu;
1259 } 1265 }
1260 } 1266 }
1261 pcpu_nr_units = unit; 1267 pcpu_nr_units = unit;