diff options
Diffstat (limited to 'lib/cpumask.c')
| -rw-r--r-- | lib/cpumask.c | 74 | 
1 files changed, 26 insertions, 48 deletions
| diff --git a/lib/cpumask.c b/lib/cpumask.c index 830dd5dec40f..5f627084f2e9 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
| @@ -139,64 +139,42 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask) | |||
| 139 | #endif | 139 | #endif | 
| 140 | 140 | ||
| 141 | /** | 141 | /** | 
| 142 | * cpumask_set_cpu_local_first - set i'th cpu with local numa cpu's first | 142 | * cpumask_local_spread - select the i'th cpu with local numa cpu's first | 
| 143 | * | ||
| 144 | * @i: index number | 143 | * @i: index number | 
| 145 | * @numa_node: local numa_node | 144 | * @node: local numa_node | 
| 146 | * @dstp: cpumask with the relevant cpu bit set according to the policy | ||
| 147 | * | 145 | * | 
| 148 | * This function sets the cpumask according to a numa aware policy. | 146 | * This function selects an online CPU according to a numa aware policy; | 
| 149 | * cpumask could be used as an affinity hint for the IRQ related to a | 147 | * local cpus are returned first, followed by non-local ones, then it | 
| 150 | * queue. When the policy is to spread queues across cores - local cores | 148 | * wraps around. | 
| 151 | * first. | ||
| 152 | * | 149 | * | 
| 153 | * Returns 0 on success, -ENOMEM for no memory, and -EAGAIN when failed to set | 150 | * It's not very efficient, but useful for setup. | 
| 154 | * the cpu bit and need to re-call the function. | ||
| 155 | */ | 151 | */ | 
| 156 | int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp) | 152 | unsigned int cpumask_local_spread(unsigned int i, int node) | 
| 157 | { | 153 | { | 
| 158 | cpumask_var_t mask; | ||
| 159 | int cpu; | 154 | int cpu; | 
| 160 | int ret = 0; | ||
| 161 | |||
| 162 | if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) | ||
| 163 | return -ENOMEM; | ||
| 164 | 155 | ||
| 156 | /* Wrap: we always want a cpu. */ | ||
| 165 | i %= num_online_cpus(); | 157 | i %= num_online_cpus(); | 
| 166 | 158 | ||
| 167 | if (numa_node == -1 || !cpumask_of_node(numa_node)) { | 159 | if (node == -1) { | 
| 168 | /* Use all online cpu's for non numa aware system */ | 160 | for_each_cpu(cpu, cpu_online_mask) | 
| 169 | cpumask_copy(mask, cpu_online_mask); | 161 | if (i-- == 0) | 
| 162 | return cpu; | ||
| 170 | } else { | 163 | } else { | 
| 171 | int n; | 164 | /* NUMA first. */ | 
| 172 | 165 | for_each_cpu_and(cpu, cpumask_of_node(node), cpu_online_mask) | |
| 173 | cpumask_and(mask, | 166 | if (i-- == 0) | 
| 174 | cpumask_of_node(numa_node), cpu_online_mask); | 167 | return cpu; | 
| 175 | 168 | ||
| 176 | n = cpumask_weight(mask); | 169 | for_each_cpu(cpu, cpu_online_mask) { | 
| 177 | if (i >= n) { | 170 | /* Skip NUMA nodes, done above. */ | 
| 178 | i -= n; | 171 | if (cpumask_test_cpu(cpu, cpumask_of_node(node))) | 
| 179 | 172 | continue; | |
| 180 | /* If index > number of local cpu's, mask out local | 173 | |
| 181 | * cpu's | 174 | if (i-- == 0) | 
| 182 | */ | 175 | return cpu; | 
| 183 | cpumask_andnot(mask, cpu_online_mask, mask); | ||
| 184 | } | 176 | } | 
| 185 | } | 177 | } | 
| 186 | 178 | BUG(); | |
| 187 | for_each_cpu(cpu, mask) { | ||
| 188 | if (--i < 0) | ||
| 189 | goto out; | ||
| 190 | } | ||
| 191 | |||
| 192 | ret = -EAGAIN; | ||
| 193 | |||
| 194 | out: | ||
| 195 | free_cpumask_var(mask); | ||
| 196 | |||
| 197 | if (!ret) | ||
| 198 | cpumask_set_cpu(cpu, dstp); | ||
| 199 | |||
| 200 | return ret; | ||
| 201 | } | 179 | } | 
| 202 | EXPORT_SYMBOL(cpumask_set_cpu_local_first); | 180 | EXPORT_SYMBOL(cpumask_local_spread); | 
