Skip to content

Commit c947234

Browse files
yuqijin16sfrothwell
authored andcommitted
lib-optimize-cpumask_local_spread-v8
1. Fix confusing comments 2. Improve the loop for choosing the nearest node. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Yuqi Jin <[email protected]> Signed-off-by: Shaokun Zhang <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Rusty Russell <[email protected]> Cc: Juergen Gross <[email protected]> Cc: Paul Burton <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Anshuman Khandual <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Stephen Rothwell <[email protected]>
1 parent d4ebfca commit c947234

File tree

2 files changed

+32
-31
lines changed

2 files changed

+32
-31
lines changed

include/linux/cpumask.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ static inline unsigned int cpumask_any_but(const struct cpumask *mask,
189189
return 1;
190190
}
191191

192-
static inline unsigned int cpumask_local_spread(unsigned int i, int node)
192+
static inline unsigned int cpumask_local_spread(unsigned int cpu_index, int node)
193193
{
194194
return 0;
195195
}

lib/cpumask.c

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -193,80 +193,81 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask)
193193
}
194194
#endif
195195

196-
static int find_nearest_node(int node, bool *used)
196+
static int find_nearest_node(int node, nodemask_t nodes)
197197
{
198198
int i, min_dist, node_id = -1;
199199

200200
/* Choose the first unused node to compare */
201-
for (i = 0; i < nr_node_ids; i++) {
202-
if (used[i] == false) {
201+
for (i = 0; i < nr_node_ids; i++)
202+
if (!node_isset(i, nodes)) {
203203
min_dist = node_distance(node, i);
204204
node_id = i;
205205
break;
206206
}
207-
}
208207

209208
/* Compare and return the nearest node */
210-
for (i = 0; i < nr_node_ids; i++) {
211-
if (node_distance(node, i) < min_dist && used[i] == false) {
209+
for (i = 0; i < nr_node_ids; i++)
210+
if (!node_isset(i, nodes) &&
211+
node_distance(node, i) < min_dist) {
212212
min_dist = node_distance(node, i);
213213
node_id = i;
214214
}
215-
}
216215

217216
return node_id;
218217
}
219218

220219
/**
221220
* cpumask_local_spread - select the i'th cpu with local numa cpu's first
222-
* @i: index number
221+
* @cpu_index: index number
223222
* @node: local numa_node
224223
*
225224
* This function selects an online CPU according to a numa aware policy;
226-
* local cpus are returned first, followed by the next one which is the
227-
* nearest unused NUMA node based on NUMA distance, then it wraps around.
225+
* Loop through all the online CPUs on the system. Start with the CPUs on
226+
* 'node', then fall back to CPUs on NUMA nodes which are increasingly far
227+
* away.
228228
*
229-
* It's not very efficient, but useful for setup.
229+
* This function is not very efficient, especially for large 'cpu_index'
230+
* because it loops over the same CPUs on each call and does not remember
231+
* its state from previous calls, but it is useful for setup.
230232
*/
231-
unsigned int cpumask_local_spread(unsigned int i, int node)
233+
unsigned int cpumask_local_spread(unsigned int cpu_index, int node)
232234
{
233-
static DEFINE_SPINLOCK(spread_lock);
234-
static bool used[MAX_NUMNODES];
235-
unsigned long flags;
236-
int cpu, hk_flags, j, id;
235+
int cpu, hk_flags, j, ncpus, id;
237236
const struct cpumask *mask;
237+
struct cpumask nmsk;
238+
nodemask_t nodes_msk;
238239

239240
hk_flags = HK_FLAG_DOMAIN | HK_FLAG_MANAGED_IRQ;
240241
mask = housekeeping_cpumask(hk_flags);
241242
/* Wrap: we always want a cpu. */
242-
i %= cpumask_weight(mask);
243+
cpu_index %= cpumask_weight(mask);
243244

244245
if (node == NUMA_NO_NODE) {
245246
for_each_cpu(cpu, mask) {
246-
if (i-- == 0)
247+
if (cpu_index-- == 0)
247248
return cpu;
248249
}
249250
} else {
250-
spin_lock_irqsave(&spread_lock, flags);
251-
memset(used, 0, nr_node_ids * sizeof(bool));
252251
/* select node according to the distance from local node */
252+
nodes_clear(nodes_msk);
253253
for (j = 0; j < nr_node_ids; j++) {
254-
id = find_nearest_node(node, used);
254+
id = find_nearest_node(node, nodes_msk);
255255
if (id < 0)
256256
break;
257-
258-
for_each_cpu_and(cpu, cpumask_of_node(id), mask)
259-
if (i-- == 0) {
260-
spin_unlock_irqrestore(&spread_lock,
261-
flags);
257+
cpumask_and(&nmsk, mask, cpumask_of_node(id));
258+
ncpus = cpumask_weight(&nmsk);
259+
if (cpu_index >= ncpus) {
260+
cpu_index -= ncpus;
261+
node_set(id, nodes_msk);
262+
continue;
263+
}
264+
for_each_cpu(cpu, &nmsk)
265+
if (cpu_index-- == 0)
262266
return cpu;
263-
}
264-
used[id] = true;
265267
}
266-
spin_unlock_irqrestore(&spread_lock, flags);
267268

268269
for_each_cpu(cpu, mask)
269-
if (i-- == 0)
270+
if (cpu_index-- == 0)
270271
return cpu;
271272
}
272273
BUG();

0 commit comments

Comments
 (0)