powerpc/smp: Optimize update_mask_by_l2
All threads of a SMT4 core can either be part of this CPU's l2-cache mask or not related to this CPU l2-cache mask. Use this relation to reduce the number of iterations needed to find all the CPUs that share the same l2-cache. Use a temporary mask to iterate through the CPUs that may share l2_cache mask. Also instead of setting one CPU at a time into cpu_l2_cache_mask, copy the SMT4/sub mask at one shot. Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200921095653.9701-10-srikar@linux.vnet.ibm.com
This commit is contained in:
parent
375370a10d
commit
3ab33d6dc3
@ -670,6 +670,28 @@ static void set_cpus_unrelated(int i, int j,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extends set_cpus_related. Instead of setting one CPU at a time in
|
||||||
|
* dstmask, set srcmask at oneshot. dstmask should be super set of srcmask.
|
||||||
|
*/
|
||||||
|
static void or_cpumasks_related(int i, int j, struct cpumask *(*srcmask)(int),
|
||||||
|
struct cpumask *(*dstmask)(int))
|
||||||
|
{
|
||||||
|
struct cpumask *mask;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
mask = srcmask(j);
|
||||||
|
for_each_cpu(k, srcmask(i))
|
||||||
|
cpumask_or(dstmask(k), dstmask(k), mask);
|
||||||
|
|
||||||
|
if (i == j)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mask = srcmask(i);
|
||||||
|
for_each_cpu(k, srcmask(j))
|
||||||
|
cpumask_or(dstmask(k), dstmask(k), mask);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* parse_thread_groups: Parses the "ibm,thread-groups" device tree
|
* parse_thread_groups: Parses the "ibm,thread-groups" device tree
|
||||||
* property for the CPU device node @dn and stores
|
* property for the CPU device node @dn and stores
|
||||||
@ -1220,7 +1242,9 @@ static struct device_node *cpu_to_l2cache(int cpu)
|
|||||||
|
|
||||||
static bool update_mask_by_l2(int cpu)
|
static bool update_mask_by_l2(int cpu)
|
||||||
{
|
{
|
||||||
|
struct cpumask *(*submask_fn)(int) = cpu_sibling_mask;
|
||||||
struct device_node *l2_cache, *np;
|
struct device_node *l2_cache, *np;
|
||||||
|
cpumask_var_t mask;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
l2_cache = cpu_to_l2cache(cpu);
|
l2_cache = cpu_to_l2cache(cpu);
|
||||||
@ -1240,22 +1264,37 @@ static bool update_mask_by_l2(int cpu)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpumask_set_cpu(cpu, cpu_l2_cache_mask(cpu));
|
alloc_cpumask_var_node(&mask, GFP_KERNEL, cpu_to_node(cpu));
|
||||||
for_each_cpu_and(i, cpu_online_mask, cpu_cpu_mask(cpu)) {
|
cpumask_and(mask, cpu_online_mask, cpu_cpu_mask(cpu));
|
||||||
|
|
||||||
|
if (has_big_cores)
|
||||||
|
submask_fn = cpu_smallcore_mask;
|
||||||
|
|
||||||
|
/* Update l2-cache mask with all the CPUs that are part of submask */
|
||||||
|
or_cpumasks_related(cpu, cpu, submask_fn, cpu_l2_cache_mask);
|
||||||
|
|
||||||
|
/* Skip all CPUs already part of current CPU l2-cache mask */
|
||||||
|
cpumask_andnot(mask, mask, cpu_l2_cache_mask(cpu));
|
||||||
|
|
||||||
|
for_each_cpu(i, mask) {
|
||||||
/*
|
/*
|
||||||
* when updating the marks the current CPU has not been marked
|
* when updating the marks the current CPU has not been marked
|
||||||
* online, but we need to update the cache masks
|
* online, but we need to update the cache masks
|
||||||
*/
|
*/
|
||||||
np = cpu_to_l2cache(i);
|
np = cpu_to_l2cache(i);
|
||||||
if (!np)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (np == l2_cache)
|
/* Skip all CPUs already part of current CPU l2-cache */
|
||||||
set_cpus_related(cpu, i, cpu_l2_cache_mask);
|
if (np == l2_cache) {
|
||||||
|
or_cpumasks_related(cpu, i, submask_fn, cpu_l2_cache_mask);
|
||||||
|
cpumask_andnot(mask, mask, submask_fn(i));
|
||||||
|
} else {
|
||||||
|
cpumask_andnot(mask, mask, cpu_l2_cache_mask(i));
|
||||||
|
}
|
||||||
|
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
}
|
}
|
||||||
of_node_put(l2_cache);
|
of_node_put(l2_cache);
|
||||||
|
free_cpumask_var(mask);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user