aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Bobroff <sbobroff@linux.ibm.com>2018-09-11 21:23:31 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-10-13 07:21:25 -0400
commite762bb891a294af00b83f54062dae4e24565edf8 (patch)
treefea29a58bb89668f7d6e86b60d6f875de11b4728
parenteed4bdbeecd0b59d3e487d1a2b726d51810015ab (diff)
powerpc/eeh: Cleanup eeh_pe_state_mark()
Currently, eeh_pe_state_mark() marks a PE (and it's children) with a state and then performs additional processing if that state included EEH_PE_ISOLATED. The state parameter is always a constant at the call site, so rearrange eeh_pe_state_mark() into two functions and just call the appropriate one at each site. Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/ppc-pci.h1
-rw-r--r--arch/powerpc/kernel/eeh.c8
-rw-r--r--arch/powerpc/kernel/eeh_driver.c10
-rw-r--r--arch/powerpc/kernel/eeh_pe.c70
-rw-r--r--arch/powerpc/platforms/powernv/eeh-powernv.c8
-rw-r--r--drivers/pci/hotplug/pnv_php.c2
6 files changed, 46 insertions, 53 deletions
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 726288048652..f67da277d652 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -58,6 +58,7 @@ void eeh_save_bars(struct eeh_dev *edev);
58int rtas_write_config(struct pci_dn *, int where, int size, u32 val); 58int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
59int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); 59int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
60void eeh_pe_state_mark(struct eeh_pe *pe, int state); 60void eeh_pe_state_mark(struct eeh_pe *pe, int state);
61void eeh_pe_mark_isolated(struct eeh_pe *pe);
61void eeh_pe_state_clear(struct eeh_pe *pe, int state); 62void eeh_pe_state_clear(struct eeh_pe *pe, int state);
62void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state); 63void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state);
63void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode); 64void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode);
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index d5d0390f1d30..12e5311d06ed 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -404,7 +404,7 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
404 } 404 }
405 405
406 /* Isolate the PHB and send event */ 406 /* Isolate the PHB and send event */
407 eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); 407 eeh_pe_mark_isolated(phb_pe);
408 eeh_serialize_unlock(flags); 408 eeh_serialize_unlock(flags);
409 409
410 pr_err("EEH: PHB#%x failure detected, location: %s\n", 410 pr_err("EEH: PHB#%x failure detected, location: %s\n",
@@ -563,7 +563,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
563 * with other functions on this device, and functions under 563 * with other functions on this device, and functions under
564 * bridges. 564 * bridges.
565 */ 565 */
566 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 566 eeh_pe_mark_isolated(pe);
567 eeh_serialize_unlock(flags); 567 eeh_serialize_unlock(flags);
568 568
569 /* Most EEH events are due to device driver bugs. Having 569 /* Most EEH events are due to device driver bugs. Having
@@ -830,7 +830,7 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
830 eeh_pe_state_clear(pe, EEH_PE_ISOLATED); 830 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
831 break; 831 break;
832 case pcie_hot_reset: 832 case pcie_hot_reset:
833 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 833 eeh_pe_mark_isolated(pe);
834 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); 834 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
835 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); 835 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
836 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); 836 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
@@ -839,7 +839,7 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
839 eeh_ops->reset(pe, EEH_RESET_HOT); 839 eeh_ops->reset(pe, EEH_RESET_HOT);
840 break; 840 break;
841 case pcie_warm_reset: 841 case pcie_warm_reset:
842 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 842 eeh_pe_mark_isolated(pe);
843 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); 843 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
844 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); 844 eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);
845 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); 845 eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index ffe8293d1f06..c827617613c1 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -1029,7 +1029,7 @@ void eeh_handle_special_event(void)
1029 phb_pe = eeh_phb_pe_get(hose); 1029 phb_pe = eeh_phb_pe_get(hose);
1030 if (!phb_pe) continue; 1030 if (!phb_pe) continue;
1031 1031
1032 eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED); 1032 eeh_pe_mark_isolated(phb_pe);
1033 } 1033 }
1034 1034
1035 eeh_serialize_unlock(flags); 1035 eeh_serialize_unlock(flags);
@@ -1044,11 +1044,9 @@ void eeh_handle_special_event(void)
1044 /* Purge all events of the PHB */ 1044 /* Purge all events of the PHB */
1045 eeh_remove_event(pe, true); 1045 eeh_remove_event(pe, true);
1046 1046
1047 if (rc == EEH_NEXT_ERR_DEAD_PHB) 1047 if (rc != EEH_NEXT_ERR_DEAD_PHB)
1048 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 1048 eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
1049 else 1049 eeh_pe_mark_isolated(pe);
1050 eeh_pe_state_mark(pe,
1051 EEH_PE_ISOLATED | EEH_PE_RECOVERING);
1052 1050
1053 eeh_serialize_unlock(flags); 1051 eeh_serialize_unlock(flags);
1054 1052
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 2b376718237f..e43dcefbe73f 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -540,56 +540,50 @@ void eeh_pe_update_time_stamp(struct eeh_pe *pe)
540} 540}
541 541
542/** 542/**
543 * __eeh_pe_state_mark - Mark the state for the PE 543 * eeh_pe_state_mark - Mark specified state for PE and its associated device
544 * @data: EEH PE 544 * @pe: EEH PE
545 * @flag: state
546 * 545 *
547 * The function is used to mark the indicated state for the given 546 * EEH error affects the current PE and its child PEs. The function
548 * PE. Also, the associated PCI devices will be put into IO frozen 547 * is used to mark appropriate state for the affected PEs and the
549 * state as well. 548 * associated devices.
550 */ 549 */
551static void *__eeh_pe_state_mark(struct eeh_pe *pe, void *flag) 550void eeh_pe_state_mark(struct eeh_pe *root, int state)
552{ 551{
553 int state = *((int *)flag); 552 struct eeh_pe *pe;
554 struct eeh_dev *edev, *tmp;
555 struct pci_dev *pdev;
556
557 /* Keep the state of permanently removed PE intact */
558 if (pe->state & EEH_PE_REMOVED)
559 return NULL;
560
561 pe->state |= state;
562
563 /* Offline PCI devices if applicable */
564 if (!(state & EEH_PE_ISOLATED))
565 return NULL;
566
567 eeh_pe_for_each_dev(pe, edev, tmp) {
568 pdev = eeh_dev_to_pci_dev(edev);
569 if (pdev)
570 pdev->error_state = pci_channel_io_frozen;
571 }
572
573 /* Block PCI config access if required */
574 if (pe->state & EEH_PE_CFG_RESTRICTED)
575 pe->state |= EEH_PE_CFG_BLOCKED;
576 553
577 return NULL; 554 eeh_for_each_pe(root, pe)
555 if (!(pe->state & EEH_PE_REMOVED))
556 pe->state |= state;
578} 557}
558EXPORT_SYMBOL_GPL(eeh_pe_state_mark);
579 559
580/** 560/**
581 * eeh_pe_state_mark - Mark specified state for PE and its associated device 561 * eeh_pe_mark_isolated
582 * @pe: EEH PE 562 * @pe: EEH PE
583 * 563 *
584 * EEH error affects the current PE and its child PEs. The function 564 * Record that a PE has been isolated by marking the PE and it's children as
585 * is used to mark appropriate state for the affected PEs and the 565 * EEH_PE_ISOLATED (and EEH_PE_CFG_BLOCKED, if required) and their PCI devices
586 * associated devices. 566 * as pci_channel_io_frozen.
587 */ 567 */
588void eeh_pe_state_mark(struct eeh_pe *pe, int state) 568void eeh_pe_mark_isolated(struct eeh_pe *root)
589{ 569{
590 eeh_pe_traverse(pe, __eeh_pe_state_mark, &state); 570 struct eeh_pe *pe;
571 struct eeh_dev *edev;
572 struct pci_dev *pdev;
573
574 eeh_pe_state_mark(root, EEH_PE_ISOLATED);
575 eeh_for_each_pe(root, pe) {
576 list_for_each_entry(edev, &pe->edevs, entry) {
577 pdev = eeh_dev_to_pci_dev(edev);
578 if (pdev)
579 pdev->error_state = pci_channel_io_frozen;
580 }
581 /* Block PCI config access if required */
582 if (pe->state & EEH_PE_CFG_RESTRICTED)
583 pe->state |= EEH_PE_CFG_BLOCKED;
584 }
591} 585}
592EXPORT_SYMBOL_GPL(eeh_pe_state_mark); 586EXPORT_SYMBOL_GPL(eeh_pe_mark_isolated);
593 587
594static void *__eeh_pe_dev_mode_mark(struct eeh_dev *edev, void *flag) 588static void *__eeh_pe_dev_mode_mark(struct eeh_dev *edev, void *flag)
595{ 589{
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index a7e59dbf2696..fd1db9f286f1 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -590,7 +590,7 @@ static int pnv_eeh_get_phb_state(struct eeh_pe *pe)
590 EEH_STATE_MMIO_ENABLED | 590 EEH_STATE_MMIO_ENABLED |
591 EEH_STATE_DMA_ENABLED); 591 EEH_STATE_DMA_ENABLED);
592 } else if (!(pe->state & EEH_PE_ISOLATED)) { 592 } else if (!(pe->state & EEH_PE_ISOLATED)) {
593 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 593 eeh_pe_mark_isolated(pe);
594 pnv_eeh_get_phb_diag(pe); 594 pnv_eeh_get_phb_diag(pe);
595 595
596 if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) 596 if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
@@ -692,7 +692,7 @@ static int pnv_eeh_get_pe_state(struct eeh_pe *pe)
692 if (phb->freeze_pe) 692 if (phb->freeze_pe)
693 phb->freeze_pe(phb, pe->addr); 693 phb->freeze_pe(phb, pe->addr);
694 694
695 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 695 eeh_pe_mark_isolated(pe);
696 pnv_eeh_get_phb_diag(pe); 696 pnv_eeh_get_phb_diag(pe);
697 697
698 if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) 698 if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
@@ -1597,7 +1597,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
1597 if ((ret == EEH_NEXT_ERR_FROZEN_PE || 1597 if ((ret == EEH_NEXT_ERR_FROZEN_PE ||
1598 ret == EEH_NEXT_ERR_FENCED_PHB) && 1598 ret == EEH_NEXT_ERR_FENCED_PHB) &&
1599 !((*pe)->state & EEH_PE_ISOLATED)) { 1599 !((*pe)->state & EEH_PE_ISOLATED)) {
1600 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); 1600 eeh_pe_mark_isolated(*pe);
1601 pnv_eeh_get_phb_diag(*pe); 1601 pnv_eeh_get_phb_diag(*pe);
1602 1602
1603 if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) 1603 if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
@@ -1626,7 +1626,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
1626 } 1626 }
1627 1627
1628 /* We possibly migrate to another PE */ 1628 /* We possibly migrate to another PE */
1629 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); 1629 eeh_pe_mark_isolated(*pe);
1630 } 1630 }
1631 1631
1632 /* 1632 /*
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 3276a5e4c430..b5ba26d14a9a 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -736,7 +736,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
736 pe = edev ? edev->pe : NULL; 736 pe = edev ? edev->pe : NULL;
737 if (pe) { 737 if (pe) {
738 eeh_serialize_lock(&flags); 738 eeh_serialize_lock(&flags);
739 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 739 eeh_pe_mark_isolated(pe);
740 eeh_serialize_unlock(flags); 740 eeh_serialize_unlock(flags);
741 eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE); 741 eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE);
742 } 742 }