[PATCH 3/7] genirq/affinity: don't pass irq_affinity_desc array to irq_build_affinity_masks

Ming Lei
2021-08-14T12:36:16Z

Prepare for abstracting irq_build_affinity_masks() into one public helper
for assigning all CPUs evenly into several groups. Don't passing
irq_affinity_desc array to irq_build_affinity_masks, instead returning
one cpumask array by storing each assigned group into one element of
the array.

This way helps us to provide generic interface for grouping all CPUs
evenly from NUMA and CPU locality viewpoint, and the cost is one extra
allocation in irq_build_affinity_masks(), which should be fine since
it is done via GFP_KERNEL and irq_build_affinity_masks() is called very
less.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
kernel/irq/affinity.c | 34 ++++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c
index 0bc83d57cb34..aef12ec05dcf 100644
--- a/kernel/irq/affinity.c
+++ b/kernel/irq/affinity.c
@@ -249,7 +249,7 @@ static int __irq_build_affinity_masks(unsigned int startvec,
cpumask_var_t *node_to_cpumask,
const struct cpumask *cpu_mask,
struct cpumask *nmsk,
- struct irq_affinity_desc *masks)
+ struct cpumask *masks)
{
unsigned int i, n, nodes, cpus_per_vec, extra_vecs, done = 0;
unsigned int last_affv = numvecs;
@@ -268,7 +268,7 @@ static int __irq_build_affinity_masks(unsigned int startvec,
*/
if (numvecs <= nodes) {
for_each_node_mask(n, nodemsk) {
- cpumask_or(&masks[curvec].mask, &masks[curvec].mask,
+ cpumask_or(&masks[curvec], &masks[curvec],
node_to_cpumask[n]);
if (++curvec == last_affv)
curvec = 0;
@@ -320,7 +320,7 @@ static int __irq_build_affinity_masks(unsigned int startvec,
*/
if (curvec >= last_affv)
curvec = 0;
- irq_spread_init_one(&masks[curvec].mask, nmsk,
+ irq_spread_init_one(&masks[curvec], nmsk,
cpus_per_vec);
}
done += nv->nvectors;
@@ -334,16 +334,16 @@ static int __irq_build_affinity_masks(unsigned int startvec,
* 1) spread present CPU on these vectors
* 2) spread other possible CPUs on these vectors
*/
-static int irq_build_affinity_masks(unsigned int numvecs,
- struct irq_affinity_desc *masks)
+static struct cpumask *irq_build_affinity_masks(unsigned int numvecs)
{
unsigned int curvec = 0, nr_present = 0, nr_others = 0;
cpumask_var_t *node_to_cpumask;
cpumask_var_t nmsk, npresmsk;
int ret = -ENOMEM;
+ struct cpumask *masks = NULL;

if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL))
- return ret;
+ return NULL;

if (!zalloc_cpumask_var(&npresmsk, GFP_KERNEL))
goto fail_nmsk;
@@ -352,6 +352,10 @@ static int irq_build_affinity_masks(unsigned int numvecs,
if (!node_to_cpumask)
goto fail_npresmsk;

+ masks = kcalloc(numvecs, sizeof(*masks), GFP_KERNEL);
+ if (!masks)
+ goto fail_node_to_cpumask;
+
/* Stabilize the cpumasks */
cpus_read_lock();
build_node_to_cpumask(node_to_cpumask);
@@ -385,6 +389,7 @@ static int irq_build_affinity_masks(unsigned int numvecs,
if (ret >= 0)
WARN_ON(nr_present + nr_others < numvecs);

+ fail_node_to_cpumask:
free_node_to_cpumask(node_to_cpumask);

fail_npresmsk:
@@ -392,7 +397,11 @@ static int irq_build_affinity_masks(unsigned int numvecs,

fail_nmsk:
free_cpumask_var(nmsk);
- return ret < 0 ? ret : 0;
+ if (ret < 0) {
+ kfree(masks);
+ return NULL;
+ }
+ return masks;
}

static void default_calc_sets(struct irq_affinity *affd, unsigned int affvecs)
@@ -456,13 +465,18 @@ irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd)
*/
for (i = 0, usedvecs = 0; i < affd->nr_sets; i++) {
unsigned int this_vecs = affd->set_size[i];
- int ret;
+ int j;
+ struct cpumask *result = irq_build_affinity_masks(this_vecs);

- ret = irq_build_affinity_masks(this_vecs, &masks[curvec]);
- if (ret) {
+ if (!result) {
kfree(masks);
return NULL;
}
+
+ for (j = 0; j < this_vecs; j++)
+ cpumask_copy(&masks[curvec + j].mask, &result[j]);
+ kfree(result);
+
curvec += this_vecs;
usedvecs += this_vecs;
}
--
2.31.1