| .. | .. |
|---|
| 4 | 4 | #include <linux/bitops.h> |
|---|
| 5 | 5 | #include <linux/cpumask.h> |
|---|
| 6 | 6 | #include <linux/export.h> |
|---|
| 7 | | -#include <linux/bootmem.h> |
|---|
| 7 | +#include <linux/memblock.h> |
|---|
| 8 | +#include <linux/numa.h> |
|---|
| 8 | 9 | |
|---|
| 9 | 10 | /** |
|---|
| 10 | 11 | * cpumask_next - get the next cpu in a cpumask |
|---|
| .. | .. |
|---|
| 163 | 164 | */ |
|---|
| 164 | 165 | void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask) |
|---|
| 165 | 166 | { |
|---|
| 166 | | - *mask = memblock_virt_alloc(cpumask_size(), 0); |
|---|
| 167 | + *mask = memblock_alloc(cpumask_size(), SMP_CACHE_BYTES); |
|---|
| 168 | + if (!*mask) |
|---|
| 169 | + panic("%s: Failed to allocate %u bytes\n", __func__, |
|---|
| 170 | + cpumask_size()); |
|---|
| 167 | 171 | } |
|---|
| 168 | 172 | |
|---|
| 169 | 173 | /** |
|---|
| .. | .. |
|---|
| 206 | 210 | /* Wrap: we always want a cpu. */ |
|---|
| 207 | 211 | i %= num_online_cpus(); |
|---|
| 208 | 212 | |
|---|
| 209 | | - if (node == -1) { |
|---|
| 213 | + if (node == NUMA_NO_NODE) { |
|---|
| 210 | 214 | for_each_cpu(cpu, cpu_online_mask) |
|---|
| 211 | 215 | if (i-- == 0) |
|---|
| 212 | 216 | return cpu; |
|---|
| .. | .. |
|---|
| 228 | 232 | BUG(); |
|---|
| 229 | 233 | } |
|---|
| 230 | 234 | EXPORT_SYMBOL(cpumask_local_spread); |
|---|
| 235 | + |
|---|
| 236 | +static DEFINE_PER_CPU(int, distribute_cpu_mask_prev); |
|---|
| 237 | + |
|---|
| 238 | +/** |
|---|
| 239 | + * Returns an arbitrary cpu within srcp1 & srcp2. |
|---|
| 240 | + * |
|---|
| 241 | + * Iterated calls using the same srcp1 and srcp2 will be distributed within |
|---|
| 242 | + * their intersection. |
|---|
| 243 | + * |
|---|
| 244 | + * Returns >= nr_cpu_ids if the intersection is empty. |
|---|
| 245 | + */ |
|---|
| 246 | +int cpumask_any_and_distribute(const struct cpumask *src1p, |
|---|
| 247 | + const struct cpumask *src2p) |
|---|
| 248 | +{ |
|---|
| 249 | + int next, prev; |
|---|
| 250 | + |
|---|
| 251 | + /* NOTE: our first selection will skip 0. */ |
|---|
| 252 | + prev = __this_cpu_read(distribute_cpu_mask_prev); |
|---|
| 253 | + |
|---|
| 254 | + next = cpumask_next_and(prev, src1p, src2p); |
|---|
| 255 | + if (next >= nr_cpu_ids) |
|---|
| 256 | + next = cpumask_first_and(src1p, src2p); |
|---|
| 257 | + |
|---|
| 258 | + if (next < nr_cpu_ids) |
|---|
| 259 | + __this_cpu_write(distribute_cpu_mask_prev, next); |
|---|
| 260 | + |
|---|
| 261 | + return next; |
|---|
| 262 | +} |
|---|
| 263 | +EXPORT_SYMBOL(cpumask_any_and_distribute); |
|---|