diff options
-rw-r--r-- | drivers/nvme/host/pci.c | 7 | ||||
-rw-r--r-- | include/linux/interrupt.h | 9 | ||||
-rw-r--r-- | kernel/irq/affinity.c | 16 |
3 files changed, 21 insertions, 11 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 9bc585415d9b..21ffd671b6ed 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -2081,12 +2081,11 @@ static void nvme_calc_io_queues(struct nvme_dev *dev, unsigned int irq_queues) | |||
2081 | static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues) | 2081 | static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues) |
2082 | { | 2082 | { |
2083 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 2083 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
2084 | int irq_sets[2]; | ||
2085 | struct irq_affinity affd = { | 2084 | struct irq_affinity affd = { |
2086 | .pre_vectors = 1, | 2085 | .pre_vectors = 1, |
2087 | .nr_sets = ARRAY_SIZE(irq_sets), | 2086 | .nr_sets = 2, |
2088 | .sets = irq_sets, | ||
2089 | }; | 2087 | }; |
2088 | unsigned int *irq_sets = affd.set_size; | ||
2090 | int result = 0; | 2089 | int result = 0; |
2091 | unsigned int irq_queues, this_p_queues; | 2090 | unsigned int irq_queues, this_p_queues; |
2092 | 2091 | ||
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 35e7389c2011..5afdfd5dc39b 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -241,20 +241,23 @@ struct irq_affinity_notify { | |||
241 | void (*release)(struct kref *ref); | 241 | void (*release)(struct kref *ref); |
242 | }; | 242 | }; |
243 | 243 | ||
244 | #define IRQ_AFFINITY_MAX_SETS 4 | ||
245 | |||
244 | /** | 246 | /** |
245 | * struct irq_affinity - Description for automatic irq affinity assignements | 247 | * struct irq_affinity - Description for automatic irq affinity assignements |
246 | * @pre_vectors: Don't apply affinity to @pre_vectors at beginning of | 248 | * @pre_vectors: Don't apply affinity to @pre_vectors at beginning of |
247 | * the MSI(-X) vector space | 249 | * the MSI(-X) vector space |
248 | * @post_vectors: Don't apply affinity to @post_vectors at end of | 250 | * @post_vectors: Don't apply affinity to @post_vectors at end of |
249 | * the MSI(-X) vector space | 251 | * the MSI(-X) vector space |
250 | * @nr_sets: Length of passed in *sets array | 252 | * @nr_sets: The number of interrupt sets for which affinity |
251 | * @sets: Number of affinitized sets | 253 | * spreading is required |
254 | * @set_size: Array holding the size of each interrupt set | ||
252 | */ | 255 | */ |
253 | struct irq_affinity { | 256 | struct irq_affinity { |
254 | unsigned int pre_vectors; | 257 | unsigned int pre_vectors; |
255 | unsigned int post_vectors; | 258 | unsigned int post_vectors; |
256 | unsigned int nr_sets; | 259 | unsigned int nr_sets; |
257 | unsigned int *sets; | 260 | unsigned int set_size[IRQ_AFFINITY_MAX_SETS]; |
258 | }; | 261 | }; |
259 | 262 | ||
260 | /** | 263 | /** |
diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index 82e8799374e9..278289c091bb 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c | |||
@@ -238,9 +238,10 @@ static int irq_build_affinity_masks(const struct irq_affinity *affd, | |||
238 | * Returns the irq_affinity_desc pointer or NULL if allocation failed. | 238 | * Returns the irq_affinity_desc pointer or NULL if allocation failed. |
239 | */ | 239 | */ |
240 | struct irq_affinity_desc * | 240 | struct irq_affinity_desc * |
241 | irq_create_affinity_masks(unsigned int nvecs, const struct irq_affinity *affd) | 241 | irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd) |
242 | { | 242 | { |
243 | unsigned int affvecs, curvec, usedvecs, nr_sets, i; | 243 | unsigned int affvecs, curvec, usedvecs, nr_sets, i; |
244 | unsigned int set_size[IRQ_AFFINITY_MAX_SETS]; | ||
244 | struct irq_affinity_desc *masks = NULL; | 245 | struct irq_affinity_desc *masks = NULL; |
245 | 246 | ||
246 | /* | 247 | /* |
@@ -250,6 +251,9 @@ irq_create_affinity_masks(unsigned int nvecs, const struct irq_affinity *affd) | |||
250 | if (nvecs == affd->pre_vectors + affd->post_vectors) | 251 | if (nvecs == affd->pre_vectors + affd->post_vectors) |
251 | return NULL; | 252 | return NULL; |
252 | 253 | ||
254 | if (WARN_ON_ONCE(affd->nr_sets > IRQ_AFFINITY_MAX_SETS)) | ||
255 | return NULL; | ||
256 | |||
253 | masks = kcalloc(nvecs, sizeof(*masks), GFP_KERNEL); | 257 | masks = kcalloc(nvecs, sizeof(*masks), GFP_KERNEL); |
254 | if (!masks) | 258 | if (!masks) |
255 | return NULL; | 259 | return NULL; |
@@ -263,11 +267,15 @@ irq_create_affinity_masks(unsigned int nvecs, const struct irq_affinity *affd) | |||
263 | */ | 267 | */ |
264 | affvecs = nvecs - affd->pre_vectors - affd->post_vectors; | 268 | affvecs = nvecs - affd->pre_vectors - affd->post_vectors; |
265 | nr_sets = affd->nr_sets; | 269 | nr_sets = affd->nr_sets; |
266 | if (!nr_sets) | 270 | if (!nr_sets) { |
267 | nr_sets = 1; | 271 | nr_sets = 1; |
272 | set_size[0] = affvecs; | ||
273 | } else { | ||
274 | memcpy(set_size, affd->set_size, nr_sets * sizeof(unsigned int)); | ||
275 | } | ||
268 | 276 | ||
269 | for (i = 0, usedvecs = 0; i < nr_sets; i++) { | 277 | for (i = 0, usedvecs = 0; i < nr_sets; i++) { |
270 | unsigned int this_vecs = affd->sets ? affd->sets[i] : affvecs; | 278 | unsigned int this_vecs = set_size[i]; |
271 | int ret; | 279 | int ret; |
272 | 280 | ||
273 | ret = irq_build_affinity_masks(affd, curvec, this_vecs, | 281 | ret = irq_build_affinity_masks(affd, curvec, this_vecs, |
@@ -314,7 +322,7 @@ unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec, | |||
314 | unsigned int i; | 322 | unsigned int i; |
315 | 323 | ||
316 | for (i = 0, set_vecs = 0; i < affd->nr_sets; i++) | 324 | for (i = 0, set_vecs = 0; i < affd->nr_sets; i++) |
317 | set_vecs += affd->sets[i]; | 325 | set_vecs += affd->set_size[i]; |
318 | } else { | 326 | } else { |
319 | get_online_cpus(); | 327 | get_online_cpus(); |
320 | set_vecs = cpumask_weight(cpu_possible_mask); | 328 | set_vecs = cpumask_weight(cpu_possible_mask); |