18 Sep, 2009

2 commits

  • When booting with pci=nomsi aer causes lost interrupts and
    lockdep inversions.

    So check if MSIs are not disabled before initializing the aer
    driver.

    Signed-off-by: Andi Kleen
    Signed-off-by: Jesse Barnes

    Andi Kleen
     
  • The definition of the ASPM support field in the Link Capabilities
    Register had been changed by the "ASPM optionality ECN" as follows:

    00b Reserved
    01b L0s Supported
    10b Reserved
    11b L0s and L1 Supported

    00b No ASPM Support
    01b L0s Supported
    10b L1 Supported
    11b L0s and L1 Supported

    Current linux ASPM driver doesn't enable ASPM if the support field is
    00b or 10b. So there is no impact about 00b. But current linux ASPM
    driver doesn't enable L1 if the support field is 10b. With this patch,
    10b (L1 support) is handled properly.

    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     

15 Sep, 2009

1 commit

  • After commit c82f63e411f1b58427c103bd95af2863b1c96dd1
    (PCI: check saved state before restore) pcie_portdrv_slot_reset()
    may not work correctly if dev->error_state is equal to
    pci_channel_io_frozen, because dev->state_saved need not be set at
    that time. Fix this issue by setting dev->state_saved before
    pci_restore_state() is called in pcie_portdrv_slot_reset().

    Signed-off-by: Rafael J. Wysocki
    Signed-off-by: Jesse Barnes

    Rafael J. Wysocki
     

11 Sep, 2009

1 commit


10 Sep, 2009

20 commits

  • There is a very old quirk for the intel E7502 E7320 and E7525 memory
    controller hubs that disables usage of msi interrupts on pcie hotplug
    bridges of those devices, and disables changing the affinity of irqs.

    Today all we have to do to disable msi on a specific device is to set
    dev->no_msi, which is much more straightforward than the previous
    logic.

    The re-running of this fixup after pci hotplug happens below these
    devices is totally bogus. All of the state we change is pure software
    state and we don't change the hardware at all. Which means hotplug on
    the lower devices doesn't have a chance to change this state. So we
    can safely remove the special case from the pciehp driver and the pcie
    portdriver.

    I suspect the special case was someone's expermental debug code that
    slipped in. Certainly it isn't mentioned in commit
    6fb8880a61510295aece04a542767161f624dffe aka BKrev:
    41966101LJ_ogfOU0m2aE6teZfQnuQ where the code first appears.

    Reviewed-by: Kenji Kaneshige
    Signed-off-by: "Eric W. Biederman"
    Signed-off-by: Jesse Barnes

    Eric W. Biederman
     
  • This patch is required not to lost error records by action invoked on
    error recovery, such as slot reset etc.

    Following sample (real machine + dummy record injected by aer-inject)
    shows that record of 28:00.1 could not be retrieved by recovery of 28:00.0:

    - Before:

    pcieport-driver 0000:00:02.0: AER: Multiple Uncorrected (Non-Fatal) error received: id=2801
    e1000e 0000:28:00.0: PCIE Bus Error: severity=Uncorrected (Non-Fatal), type=Transaction Layer, id=2800(Receiver ID)
    e1000e 0000:28:00.0: device [8086:1096] error status/mask=00001000/00100000
    e1000e 0000:28:00.0: [12] Poisoned TLP (First)
    e1000e 0000:28:00.0: TLP Header: 00000000 00000001 00000002 00000003
    e1000e 0000:28:00.0: broadcast error_detected message
    e1000e 0000:28:00.0: broadcast slot_reset message
    e1000e 0000:28:00.0: setting latency timer to 64
    e1000e 0000:28:00.0: restoring config space at offset 0x1 (was 0x100547, writing 0x100147)
    e1000e 0000:28:00.0: PME# disabled
    e1000e 0000:28:00.0: PME# disabled
    e1000e 0000:28:00.1: setting latency timer to 64
    e1000e 0000:28:00.1: restoring config space at offset 0x1 (was 0x100547, writing 0x100147)
    e1000e 0000:28:00.1: PME# disabled
    e1000e 0000:28:00.1: PME# disabled
    e1000e 0000:28:00.0: broadcast resume message
    e1000e 0000:28:00.0: AER driver successfully recovered
    e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX

    - After:

    pcieport-driver 0000:00:02.0: AER: Multiple Uncorrected (Non-Fatal) error received: id=2801
    e1000e 0000:28:00.0: PCIE Bus Error: severity=Uncorrected (Non-Fatal), type=Transaction Layer, id=2800(Receiver ID)
    e1000e 0000:28:00.0: device [8086:1096] error status/mask=00001000/00100000
    e1000e 0000:28:00.0: [12] Poisoned TLP (First)
    e1000e 0000:28:00.0: TLP Header: 00000000 00000001 00000002 00000003
    e1000e 0000:28:00.1: PCIE Bus Error: severity=Uncorrected (Non-Fatal), type=Transaction Layer, id=2801(Receiver ID)
    e1000e 0000:28:00.1: device [8086:1096] error status/mask=00081000/00100000
    e1000e 0000:28:00.1: [12] Poisoned TLP (First)
    e1000e 0000:28:00.1: [19] ECRC
    e1000e 0000:28:00.1: TLP Header: 00000000 00000001 00000002 00000003
    e1000e 0000:28:00.1: Error of this Agent(2801) is reported first
    e1000e 0000:28:00.0: broadcast error_detected message
    e1000e 0000:28:00.0: broadcast slot_reset message
    e1000e 0000:28:00.0: setting latency timer to 64
    e1000e 0000:28:00.0: restoring config space at offset 0x1 (was 0x100547, writing 0x100147)
    e1000e 0000:28:00.0: PME# disabled
    e1000e 0000:28:00.0: PME# disabled
    e1000e 0000:28:00.1: setting latency timer to 64
    e1000e 0000:28:00.1: restoring config space at offset 0x1 (was 0x100547, writing 0x100147)
    e1000e 0000:28:00.1: PME# disabled
    e1000e 0000:28:00.1: PME# disabled
    e1000e 0000:28:00.0: broadcast resume message
    e1000e 0000:28:00.0: AER driver successfully recovered
    e1000e: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Use dev_printk like format.

    Sample (real machine + dummy error injected by aer-inject):

    - Before:

    +------ PCI-Express Device Error ------+
    Error Severity : Corrected
    PCIE Bus Error type : Data Link Layer
    Bad TLP :
    Receiver ID : 2800
    VendorID=8086h, DeviceID=1096h, Bus=28h, Device=00h, Function=00h
    +------ PCI-Express Device Error ------+
    Error Severity : Corrected
    PCIE Bus Error type : Data Link Layer
    Bad TLP :
    Bad DLLP :
    Receiver ID : 2801
    VendorID=8086h, DeviceID=1096h, Bus=28h, Device=00h, Function=01h
    Error of this Agent(2801) is reported first

    - After:

    pcieport-driver 0000:00:02.0: AER: Multiple Corrected error received: id=2801
    e1000e 0000:28:00.0: PCIE Bus Error: severity=Corrected, type=Data Link Layer, id=2800(Receiver ID)
    e1000e 0000:28:00.0: device [8086:1096] error status/mask=00000040/00000000
    e1000e 0000:28:00.0: [ 6] Bad TLP
    e1000e 0000:28:00.1: PCIE Bus Error: severity=Corrected, type=Data Link Layer, id=2801(Receiver ID)
    e1000e 0000:28:00.1: device [8086:1096] error status/mask=000000c0/00000000
    e1000e 0000:28:00.1: [ 6] Bad TLP
    e1000e 0000:28:00.1: [ 7] Bad DLLP
    e1000e 0000:28:00.1: Error of this Agent(2801) is reported first

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Compact struct and codes.

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Cleanup.

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Multiple bits might be set in the Uncorrectable Error Status
    register. But aer_print_error_source() only report a error of
    the lowest bit set in the error status register.

    So print strings for all bits unmasked and set.

    And check First Error Pointer to mark the error occured first.
    This FEP is not valid when the corresponing bit of the Uncorrectable
    Error Status register is not set, or unimplemented or undefined.

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • ERR_{,UN}CORRECTABLE_ERROR_MASK are set of error bits which linux know,
    set of PCI_ERR_COR_* and PCI_ERR_UNC_* defined in linux/pci_regs.h.
    This masks make aerdrv not to report errors of unknown bit, while aerdrv
    have ability to report such undefined errors as "Unknown Error Bit %2d".

    OTOH aerdrv_errprint does not have any check of setting in mask register.
    So it could report masked wrong error by finding bit in status without
    knowing that the bit is masked in the mask register.

    This patch changes aerdrv to use mask state in mask register propely
    instead of defined/hardcoded ERR_{,UN}CORRECTABLE_ERROR_MASK.
    This change prevents aerdrv from reporting masked error, and also enable
    reporting unknown errors.

    Signed-off-by: Hidetoshi Seto
    Reviewed-by: Andrew Patterson
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • The static buffer errmsg_buff[] is used only for building error
    message in fixed format, and is protected by a spinlock.

    This patch removes this buffer and the spinlock.

    Signed-off-by: Hidetoshi Seto
    Reviewed-by: Andrew Patterson
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • The flag AER_MULTI_ERROR_VALID_FLAG in info->flag does mean that the
    root port receives multiple error messages. Error messages can be
    posted from different devices, so it does not mean that each reported
    device has multiple errors.

    If there are multiple error devices and the root port has valid error
    source ID, it would be nice to report which device is the error source
    reported first.

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • In case of multiple errors, struct aer_err_info would be reused among
    all reported devices. So the info->status should be initialized before
    recycled. Otherwise error of one device might be reported as the error
    of another device. Also info->flags has similar problem on reporting
    TLP header.

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Definitions of MASK macros in aerdrv_errprint.c are tricky and unsafe.

    For example, AER_AGENT_TRANSMITTER_MASK(_sev, _stat) does work like:
    static inline func(int _sev, int _stat)
    {
    if (_sev == AER_CORRECTABLE)
    return (_stat & (PCI_ERR_COR_REP_ROLL|PCI_ERR_COR_REP_TIMER));
    else
    return (_stat & PCI_ERR_COR_REP_ROLL);
    }
    In case of else path here, for uncorrectable errors, testing bits in
    _stat by PCI_ERR_COR_* does not make sense because _stat should have only
    PCI_ERR_UNC_* bits originated in uncorrectable error status register.
    But at this time this is safe because uncorrectable error using bit
    position same to PCI_ERR_COR_REP_ROLL(= bit position 8) is not defined.
    Likewise, AER_AGENT_COMPLETER_MASK is always PCI_ERR_UNC_COMP_ABORT but
    it works because bit 15 of correctable error status is not defined.

    It means that these MASK macros will turn to be wrong once if new error
    is defined. (In fact, bit 15 of correctable is now defined in PCIe 2.1)

    This patch changes these MASK macros to be more strict, not to return
    PCI_ERR_COR_* bits for uncorrectable error status and vise versa.

    Signed-off-by: Hidetoshi Seto
    Reviewed-by: Andrew Patterson
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Add workaround macro to reduce the number of checkpatch warning:
    WARNING: printk() should include KERN_ facility level

    Before:
    total: 0 errors, 10 warnings, 247 lines checked
    After:
    total: 0 errors, 1 warnings, 243 lines checked

    Signed-off-by: Hidetoshi Seto
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • Before:
    drivers/pci/pcie/aer/aer_inject.c
    total: 4 errors, 4 warnings, 473 lines checked
    drivers/pci/pcie/aer/aerdrv.c
    total: 5 errors, 2 warnings, 333 lines checked
    drivers/pci/pcie/aer/aerdrv.h
    total: 1 errors, 0 warnings, 139 lines checked
    drivers/pci/pcie/aer/aerdrv_core.c
    total: 4 errors, 3 warnings, 872 lines checked
    drivers/pci/pcie/aer/aerdrv_errprint.c
    total: 12 errors, 11 warnings, 248 lines checked

    After:
    drivers/pci/pcie/aer/aer_inject.c
    total: 0 errors, 0 warnings, 466 lines checked
    drivers/pci/pcie/aer/aerdrv.c
    total: 0 errors, 0 warnings, 335 lines checked
    drivers/pci/pcie/aer/aerdrv.h
    total: 0 errors, 0 warnings, 139 lines checked
    drivers/pci/pcie/aer/aerdrv_core.c
    total: 0 errors, 0 warnings, 869 lines checked
    drivers/pci/pcie/aer/aerdrv_errprint.c
    total: 0 errors, 10 warnings, 247 lines checked

    Signed-off-by: Hidetoshi Seto
    Reviewed-by: Andrew Patterson
    Signed-off-by: Jesse Barnes

    Hidetoshi Seto
     
  • The L0s state can be managed separately for each direction (upstream
    direction and downstream direction) of the link. But in the current
    implementation, those are mixed up. With this patch, L0s for each
    direction are managed separately.

    To maintain three states (upstream direction L0s, downstream L0s and
    L1), 'aspm_support', 'aspm_enabled', 'aspm_capable', 'aspm_disable'
    and 'aspm_default' fields in struct pcie_link_state are changed to
    3-bit from 2-bit. The 'latency' field is separated to two 'latency_up'
    and 'latency_dw' fields to maintain exit latencies for each direction
    of the link. For L0, 'latency_up.l0' and 'latency_dw.l0' are used to
    configure upstream direction L0s and downstream direction L0s
    respectively. For L1, larger value of 'latency_up.l1' and
    'latency_dw.l1' is considered as L1 exit latency.

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     
  • In the current implementation, ASPM L0s/L1 is disabled for all links
    in the hierarchy if one of the link doesn't meet latency requirement.
    But we can partially enable ASPM L0s/L1 on sub-tree in the hierarchy.
    This patch allows partial L0s/L1 enablement in the hierarchy. And it
    also reduce the calculation cost of ASPM configuration very much.

    In the previous implementation, all links were enabled with the same
    state. With this patch, enabled state for each link is determined
    simply as follows (the 'requested' is from policy_to_aspm_state()).

    enabled = requested & (link->aspm_capable & link->aspm_disable)

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     
  • Introduce 'aspm_capable' field to maintain the capable ASPM setting of
    the link. By the 'aspm_capable', we don't need to recheck latency
    every time ASPM policy is changed.

    Each bit in 'aspm_capable' is associated to ASPM state (L0S/L1). The
    bit is set if the associated ASPM state is supported by the link and
    it satisfies the latency requirement (i.e. exit latency < endpoint
    acceptable latency). The 'aspm_capable' is updated when

    - an endpoint device is added (boot time or hot-plug time)
    - an endpoint device is removed (hot-unplug time)
    - PCI power state is changed.

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     
  • Introduce 'aspm_disable' flag to manage disabled ASPM state more
    robust way.

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     
  • Fix possible NULL dereference in pcie_aspm_exit_link_state(). This
    patch also cleanup some code.

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     
  • Remove the following check in __pcie_aspm_config_link() because it
    nerver be true.

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     
  • We must not clear bits in 'aspm_enabled' using 'aspm_support', or
    'aspm_enabled' and 'aspm_default' might be different from the actual
    state. In addtion, 'aspm_default' should be intialized even if
    'aspm_support' is 0.

    Acked-by: Shaohua Li
    Signed-off-by: Kenji Kaneshige
    Signed-off-by: Jesse Barnes

    Kenji Kaneshige
     

30 Jun, 2009

1 commit


19 Jun, 2009

14 commits


17 Jun, 2009

1 commit

  • Debugging PCIE AER code can be very difficult because it is hard
    to trigger various real hardware errors. This patch provide a
    software based error injection tool, which can fake various PCIE
    errors with a user space helper tool named "aer-inject". Which
    can be gotten from:

    http://www.kernel.org/pub/linux/kernel/people/yhuang/

    The patch fakes AER error by faking some PCIE AER related
    registers and an AER interrupt for specified the PCIE device.

    Signed-off-by: Huang Ying
    Signed-off-by: Jesse Barnes

    Huang Ying