forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/arch/powerpc/platforms/pseries/msi.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2006 Jake Moilanen <moilanen@austin.ibm.com>, IBM Corp.
34 * 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
- *
105 */
116
7
+#include <linux/crash_dump.h>
128 #include <linux/device.h>
139 #include <linux/irq.h>
1410 #include <linux/msi.h>
....@@ -203,7 +199,8 @@
203199 /* Get the top level device in the PE */
204200 edev = pdn_to_eeh_dev(PCI_DN(dn));
205201 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);
207204 dn = pci_device_to_OF_node(edev->pdev);
208205 if (!dn)
209206 return NULL;
....@@ -462,7 +459,28 @@
462459 return hwirq;
463460 }
464461
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);
466484
467485 if (!virq) {
468486 pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);