From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753420AbdBCOgT (ORCPT ); Fri, 3 Feb 2017 09:36:19 -0500 Received: from bombadil.infradead.org ([65.50.211.133]:46791 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752248AbdBCOgR (ORCPT ); Fri, 3 Feb 2017 09:36:17 -0500 From: Christoph Hellwig To: Thomas Gleixner , Jens Axboe Cc: Keith Busch , linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/6] genirq/affinity: assign vectors to all present CPUs Date: Fri, 3 Feb 2017 15:35:56 +0100 Message-Id: <20170203143600.32307-3-hch@lst.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170203143600.32307-1-hch@lst.de> References: <20170203143600.32307-1-hch@lst.de> X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently we only assign spread vectors to online CPUs, which ties the IRQ mapping to the currently online devices and doesn't deal nicely with the fact that CPUs could come and go rapidly due to e.g. power management. Instead assign vectors to all present CPUs to avoid this churn. Signed-off-by: Christoph Hellwig --- kernel/irq/affinity.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index 4544b115f5eb..6cd20a569359 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c @@ -4,6 +4,8 @@ #include #include +static cpumask_var_t node_to_present_cpumask[MAX_NUMNODES] __read_mostly; + static void irq_spread_init_one(struct cpumask *irqmsk, struct cpumask *nmsk, int cpus_per_vec) { @@ -40,8 +42,8 @@ static int get_nodes_in_cpumask(const struct cpumask *mask, nodemask_t *nodemsk) int n, nodes = 0; /* Calculate the number of nodes in the supplied affinity mask */ - for_each_online_node(n) { - if (cpumask_intersects(mask, cpumask_of_node(n))) { + for_each_node(n) { + if (cpumask_intersects(mask, node_to_present_cpumask[n])) { node_set(n, *nodemsk); nodes++; } @@ -77,9 +79,7 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) for (curvec = 0; curvec < affd->pre_vectors; curvec++) cpumask_copy(masks + curvec, irq_default_affinity); - /* Stabilize the cpumasks */ - get_online_cpus(); - nodes = get_nodes_in_cpumask(cpu_online_mask, &nodemsk); + nodes = get_nodes_in_cpumask(cpu_present_mask, &nodemsk); /* * If the number of nodes in the mask is greater than or equal the @@ -87,7 +87,8 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) */ if (affv <= nodes) { for_each_node_mask(n, nodemsk) { - cpumask_copy(masks + curvec, cpumask_of_node(n)); + cpumask_copy(masks + curvec, + node_to_present_cpumask[n]); if (++curvec == last_affv) break; } @@ -103,7 +104,7 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) int ncpus, v, vecs_to_assign = vecs_per_node; /* Get the cpus on this node which are in the mask */ - cpumask_and(nmsk, cpu_online_mask, cpumask_of_node(n)); + cpumask_and(nmsk, cpu_present_mask, node_to_present_cpumask[n]); /* Calculate the number of cpus per vector */ ncpus = cpumask_weight(nmsk); @@ -126,8 +127,6 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd) } done: - put_online_cpus(); - /* Fill out vectors at the end that don't need affinity */ for (; curvec < nvecs; curvec++) cpumask_copy(masks + curvec, irq_default_affinity); @@ -145,12 +144,26 @@ int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd) { int resv = affd->pre_vectors + affd->post_vectors; int vecs = maxvec - resv; - int cpus; - /* Stabilize the cpumasks */ - get_online_cpus(); - cpus = cpumask_weight(cpu_online_mask); - put_online_cpus(); + return min_t(int, cpumask_weight(cpu_present_mask), vecs) + resv; +} + +static int __init irq_build_cpumap(void) +{ + int node, cpu; + + for (node = 0; node < nr_node_ids; node++) { + if (!zalloc_cpumask_var(&node_to_present_cpumask[node], + GFP_KERNEL)) + panic("can't allocate early memory\n"); + } - return min(cpus, vecs) + resv; + for_each_present_cpu(cpu) { + node = cpu_to_node(cpu); + cpumask_set_cpu(cpu, node_to_present_cpumask[node]); + } + + return 0; } + +subsys_initcall(irq_build_cpumap); -- 2.11.0