Commit 361f2a2a1536a1d7ff6f52bf0e4848c1441e17ab
Committed by
Benjamin Herrenschmidt
1 parent
d92a208d08
powrpc/powernv: Reset PHB in kdump kernel
In the kdump scenario, the first kerenl doesn't shutdown PCI devices and the kdump kerenl clean PHB IODA table at the early probe time. That means the kdump kerenl can't support PCI transactions piled by the first kerenl. Otherwise, lots of EEH errors and frozen PEs will be detected. In order to avoid the EEH errors, the PHB is resetted to drop all PCI transaction from the first kerenl. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Showing 3 changed files with 24 additions and 4 deletions Side-by-side Diff
arch/powerpc/platforms/powernv/eeh-ioda.c
... | ... | @@ -388,13 +388,16 @@ |
388 | 388 | if (rc <= 0) |
389 | 389 | break; |
390 | 390 | |
391 | - msleep(rc); | |
391 | + if (system_state < SYSTEM_RUNNING) | |
392 | + udelay(1000 * rc); | |
393 | + else | |
394 | + msleep(rc); | |
392 | 395 | } |
393 | 396 | |
394 | 397 | return rc; |
395 | 398 | } |
396 | 399 | |
397 | -static int ioda_eeh_phb_reset(struct pci_controller *hose, int option) | |
400 | +int ioda_eeh_phb_reset(struct pci_controller *hose, int option) | |
398 | 401 | { |
399 | 402 | struct pnv_phb *phb = hose->private_data; |
400 | 403 | s64 rc = OPAL_HARDWARE; |
... | ... | @@ -422,8 +425,12 @@ |
422 | 425 | * need the PCI bus settlement delay. |
423 | 426 | */ |
424 | 427 | rc = ioda_eeh_phb_poll(phb); |
425 | - if (option == EEH_RESET_DEACTIVATE) | |
426 | - msleep(EEH_PE_RST_SETTLE_TIME); | |
428 | + if (option == EEH_RESET_DEACTIVATE) { | |
429 | + if (system_state < SYSTEM_RUNNING) | |
430 | + udelay(1000 * EEH_PE_RST_SETTLE_TIME); | |
431 | + else | |
432 | + msleep(EEH_PE_RST_SETTLE_TIME); | |
433 | + } | |
427 | 434 | out: |
428 | 435 | if (rc != OPAL_SUCCESS) |
429 | 436 | return -EIO; |
arch/powerpc/platforms/powernv/pci-ioda.c
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | |
14 | 14 | #include <linux/kernel.h> |
15 | 15 | #include <linux/pci.h> |
16 | +#include <linux/crash_dump.h> | |
16 | 17 | #include <linux/debugfs.h> |
17 | 18 | #include <linux/delay.h> |
18 | 19 | #include <linux/string.h> |
... | ... | @@ -1393,6 +1394,17 @@ |
1393 | 1394 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); |
1394 | 1395 | if (rc) |
1395 | 1396 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); |
1397 | + | |
1398 | + /* If we're running in kdump kerenl, the previous kerenl never | |
1399 | + * shutdown PCI devices correctly. We already got IODA table | |
1400 | + * cleaned out. So we have to issue PHB reset to stop all PCI | |
1401 | + * transactions from previous kerenl. | |
1402 | + */ | |
1403 | + if (is_kdump_kernel()) { | |
1404 | + pr_info(" Issue PHB reset ...\n"); | |
1405 | + ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL); | |
1406 | + ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET); | |
1407 | + } | |
1396 | 1408 | } |
1397 | 1409 | |
1398 | 1410 | void __init pnv_pci_init_ioda2_phb(struct device_node *np) |
arch/powerpc/platforms/powernv/pci.h
... | ... | @@ -205,6 +205,7 @@ |
205 | 205 | extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, |
206 | 206 | __be64 *startp, __be64 *endp, bool rm); |
207 | 207 | extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); |
208 | +extern int ioda_eeh_phb_reset(struct pci_controller *hose, int option); | |
208 | 209 | |
209 | 210 | #endif /* __POWERNV_PCI_H */ |
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540
-
mentioned in commit 71b540