diff options
author | Sam Bobroff <sbobroff@linux.ibm.com> | 2018-09-11 21:23:31 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-10-13 07:21:25 -0400 |
commit | e762bb891a294af00b83f54062dae4e24565edf8 (patch) | |
tree | fea29a58bb89668f7d6e86b60d6f875de11b4728 | |
parent | eed4bdbeecd0b59d3e487d1a2b726d51810015ab (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.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_pe.c | 70 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 8 | ||||
-rw-r--r-- | drivers/pci/hotplug/pnv_php.c | 2 |
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); | |||
58 | int rtas_write_config(struct pci_dn *, int where, int size, u32 val); | 58 | int rtas_write_config(struct pci_dn *, int where, int size, u32 val); |
59 | int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); | 59 | int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); |
60 | void eeh_pe_state_mark(struct eeh_pe *pe, int state); | 60 | void eeh_pe_state_mark(struct eeh_pe *pe, int state); |
61 | void eeh_pe_mark_isolated(struct eeh_pe *pe); | ||
61 | void eeh_pe_state_clear(struct eeh_pe *pe, int state); | 62 | void eeh_pe_state_clear(struct eeh_pe *pe, int state); |
62 | void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state); | 63 | void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state); |
63 | void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode); | 64 | void 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 | */ |
551 | static void *__eeh_pe_state_mark(struct eeh_pe *pe, void *flag) | 550 | void 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 | } |
558 | EXPORT_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 | */ |
588 | void eeh_pe_state_mark(struct eeh_pe *pe, int state) | 568 | void 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 | } |
592 | EXPORT_SYMBOL_GPL(eeh_pe_state_mark); | 586 | EXPORT_SYMBOL_GPL(eeh_pe_mark_isolated); |
593 | 587 | ||
594 | static void *__eeh_pe_dev_mode_mark(struct eeh_dev *edev, void *flag) | 588 | static 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 | } |