Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1645404 > unrolled thread
| Started by | Christoph Hellwig <hch@lst.de> |
|---|---|
| First post | 2017-05-19 11:00 +0200 |
| Last post | 2017-05-23 11:40 +0200 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
spread MSI(-X) vectors to all possible CPUs V2 Christoph Hellwig <hch@lst.de> - 2017-05-19 11:00 +0200
[PATCH 1/7] genirq: allow assigning affinity to present but not online CPUs Christoph Hellwig <hch@lst.de> - 2017-05-19 11:00 +0200
[PATCH 2/7] genirq/affinity: assign vectors to all present CPUs Christoph Hellwig <hch@lst.de> - 2017-05-19 11:00 +0200
Re: [PATCH 2/7] genirq/affinity: assign vectors to all present CPUs Thomas Gleixner <tglx@linutronix.de> - 2017-05-21 20:40 +0200
Re: [PATCH 2/7] genirq/affinity: assign vectors to all present CPUs Christoph Hellwig <hch@lst.de> - 2017-05-23 11:40 +0200
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-05-19 11:00 +0200 |
| Subject | spread MSI(-X) vectors to all possible CPUs V2 |
| Message-ID | <tILVn-84l-11@gated-at.bofh.it> |
Hi all, this series changes our automatic MSI-X vector assignment so that it takes all present CPUs into account instead of all online ones. This allows to better deal with cpu hotplug events, which could happen frequently due to power management for example. Changes since V1: - rebase to current Linus' tree - add irq_lock_sparse calls - move memory allocations outside of (raw) spinlocks - remove the irq_force_complete_move call - factor some common code into helpers - identation fixups
[toc] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-05-19 11:00 +0200 |
| Subject | [PATCH 1/7] genirq: allow assigning affinity to present but not online CPUs |
| Message-ID | <tILVo-84l-31@gated-at.bofh.it> |
| In reply to | #1645404 |
This will allow us to spread MSI/MSI-X affinity over all present CPUs and
thus better deal with systems where cpus are take on and offline all the
time.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
kernel/irq/manage.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 070be980c37a..5c25d4a5dc46 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -361,17 +361,17 @@ static int setup_affinity(struct irq_desc *desc, struct cpumask *mask)
if (irqd_affinity_is_managed(&desc->irq_data) ||
irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
if (cpumask_intersects(desc->irq_common_data.affinity,
- cpu_online_mask))
+ cpu_present_mask))
set = desc->irq_common_data.affinity;
else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
}
- cpumask_and(mask, cpu_online_mask, set);
+ cpumask_and(mask, cpu_present_mask, set);
if (node != NUMA_NO_NODE) {
const struct cpumask *nodemask = cpumask_of_node(node);
- /* make sure at least one of the cpus in nodemask is online */
+ /* make sure at least one of the cpus in nodemask is present */
if (cpumask_intersects(mask, nodemask))
cpumask_and(mask, mask, nodemask);
}
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-05-19 11:00 +0200 |
| Subject | [PATCH 2/7] genirq/affinity: assign vectors to all present CPUs |
| Message-ID | <tILVo-84l-35@gated-at.bofh.it> |
| In reply to | #1645404 |
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 <hch@lst.de>
---
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 e2d356dd7581..414b0be64bfc 100644
--- a/kernel/irq/affinity.c
+++ b/kernel/irq/affinity.c
@@ -4,6 +4,8 @@
#include <linux/slab.h>
#include <linux/cpu.h>
+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;
}
@@ -101,7 +102,7 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
vecs_per_node = (affv - (curvec - affd->pre_vectors)) / nodes;
/* 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);
@@ -128,8 +129,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);
@@ -147,12 +146,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
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-05-21 20:40 +0200 |
| Subject | Re: [PATCH 2/7] genirq/affinity: assign vectors to all present CPUs |
| Message-ID | <tJDVL-2VV-1@gated-at.bofh.it> |
| In reply to | #1645406 |
On Fri, 19 May 2017, Christoph Hellwig wrote:
> - /* Stabilize the cpumasks */
> - get_online_cpus();
How is that protected against physical CPU hotplug? Physical CPU hotplug
manipulates the present mask.
> - nodes = get_nodes_in_cpumask(cpu_online_mask, &nodemsk);
> + nodes = get_nodes_in_cpumask(cpu_present_mask, &nodemsk);
> +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]);
> + }
This mask needs updating on physical hotplug as well.
Thanks,
tglx
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2017-05-23 11:40 +0200 |
| Subject | Re: [PATCH 2/7] genirq/affinity: assign vectors to all present CPUs |
| Message-ID | <tKesh-1hY-5@gated-at.bofh.it> |
| In reply to | #1646390 |
On Sun, May 21, 2017 at 08:31:47PM +0200, Thomas Gleixner wrote: > On Fri, 19 May 2017, Christoph Hellwig wrote: > > - /* Stabilize the cpumasks */ > > - get_online_cpus(); > > How is that protected against physical CPU hotplug? Physical CPU hotplug > manipulates the present mask. It does indeed seem to. Documentation/core-api/cpu_hotplug.rst claims there are no locking rules for manipulations of cpu_present_mask, maybe it needs and update to mention get/put_online_cpus() ? Or maybe I should just switch to possible_cpu mask here like a lot of code seems to do to avoid the hot plug issues, but that might be a bit of a waste.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web