.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2006 Jake Moilanen <moilanen@austin.ibm.com>, IBM Corp. |
---|
3 | 4 | * Copyright 2006-2007 Michael Ellerman, IBM Corp. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or |
---|
6 | | - * modify it under the terms of the GNU General Public License |
---|
7 | | - * as published by the Free Software Foundation; version 2 of the |
---|
8 | | - * License. |
---|
9 | | - * |
---|
10 | 5 | */ |
---|
11 | 6 | |
---|
| 7 | +#include <linux/crash_dump.h> |
---|
12 | 8 | #include <linux/device.h> |
---|
13 | 9 | #include <linux/irq.h> |
---|
14 | 10 | #include <linux/msi.h> |
---|
.. | .. |
---|
203 | 199 | /* Get the top level device in the PE */ |
---|
204 | 200 | edev = pdn_to_eeh_dev(PCI_DN(dn)); |
---|
205 | 201 | if (edev->pe) |
---|
206 | | - edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); |
---|
| 202 | + edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, |
---|
| 203 | + entry); |
---|
207 | 204 | dn = pci_device_to_OF_node(edev->pdev); |
---|
208 | 205 | if (!dn) |
---|
209 | 206 | return NULL; |
---|
.. | .. |
---|
462 | 459 | return hwirq; |
---|
463 | 460 | } |
---|
464 | 461 | |
---|
465 | | - virq = irq_create_mapping(NULL, hwirq); |
---|
| 462 | + /* |
---|
| 463 | + * Depending on the number of online CPUs in the original |
---|
| 464 | + * kernel, it is likely for CPU #0 to be offline in a kdump |
---|
| 465 | + * kernel. The associated IRQs in the affinity mappings |
---|
| 466 | + * provided by irq_create_affinity_masks() are thus not |
---|
| 467 | + * started by irq_startup(), as per-design for managed IRQs. |
---|
| 468 | + * This can be a problem with multi-queue block devices driven |
---|
| 469 | + * by blk-mq : such a non-started IRQ is very likely paired |
---|
| 470 | + * with the single queue enforced by blk-mq during kdump (see |
---|
| 471 | + * blk_mq_alloc_tag_set()). This causes the device to remain |
---|
| 472 | + * silent and likely hangs the guest at some point. |
---|
| 473 | + * |
---|
| 474 | + * We don't really care for fine-grained affinity when doing |
---|
| 475 | + * kdump actually : simply ignore the pre-computed affinity |
---|
| 476 | + * masks in this case and let the default mask with all CPUs |
---|
| 477 | + * be used when creating the IRQ mappings. |
---|
| 478 | + */ |
---|
| 479 | + if (is_kdump_kernel()) |
---|
| 480 | + virq = irq_create_mapping(NULL, hwirq); |
---|
| 481 | + else |
---|
| 482 | + virq = irq_create_mapping_affinity(NULL, hwirq, |
---|
| 483 | + entry->affinity); |
---|
466 | 484 | |
---|
467 | 485 | if (!virq) { |
---|
468 | 486 | pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq); |
---|