【问题标题】:PCI driver failed: Detected PCI bus error on devicePCI 驱动程序失败:在设备上检测到 PCI 总线错误
【发布时间】:2019-08-22 21:05:11
【问题描述】:

我正在尝试在 ppc64(power pc) 机器上使用我自己的自定义驱动程序对特定 pci 设备进行重置。

此驱动程序可在另一台 ppc64 机器上运行。

这是负责执行此操作的函数。 我删除了几行代码以强调重要的流程。

int reset_device(void)
{
    pdev =  g_reset_info.devs[ix];        
    err = pci_enable_device(pdev);

    if (err) {
        return err;
    }
    pci_set_master(pdev);
    err = pci_save_state(pdev);
    if (err) {
            return err;
    }

    pdev =  g_reset_info.devs[ix];

    err = pci_set_pcie_reset_state(pdev, pcie_hot_reset);
    if (err) {
        return err;
    }

    msleep(jiffies_to_msecs(HZ/2));
    msleep(jiffies_to_msecs(HZ/2));

    pdev =  g_reset_info.devs[ix];

    err = pci_set_pcie_reset_state(pdev, pcie_deassert_reset);
        if (err) {
            return err;
        }

    pdev =  g_reset_info.devs[ix];
    pci_restore_state(pdev);

    msleep(jiffies_to_msecs(HZ/2));
    msleep(jiffies_to_msecs(HZ/2));

    return 0;
}

这是来自 dmesg 的输出:

mst_ppc_pci_reset_driver reset_device 63 Send hot reset to device: 0000:50:00.0 
mst_ppc_pci_reset_driver reset_device 81 Deassert device: 0000:50:00.0 
Call Trace: 
[c000000186f92fe0] [c0000000000155ac] .show_stack+0x6c/0x198 (unreliable) 
[c000000186f93090] [c000000000076a8c] .eeh_dn_check_failure+0x354/0x3f0 
[c000000186f93150] [c000000000029b7c] .rtas_read_config+0x13c/0x198 
[c000000186f931f0] [c00000000039c8d0] .pci_bus_read_config_word+0xa0/0xf8 
[c000000186f932b0] [c0000000003a2730] .pci_find_capability+0x40/0xd0 
[c000000186f93360] [c0000000003a2b6c] .pci_restore_pcie_state+0x54/0x2e8 
[c000000186f93410] [c0000000003a501c] .pci_restore_state+0x84/0x1b8 
[c000000186f934d0] [d000000003810384] .reset_device+0x184/0x430 [mst_ppc_pci_reset] 
[c000000186f93590] [c0000000003a6254] .local_pci_probe+0x7c/0xf8 
[c000000186f93620] [c0000000003a63a8] .__pci_device_probe+0xd8/0x128 
[c000000186f936d0] [c0000000003a72a8] .pci_device_probe+0x38/0x68 
[c000000186f93760] [c0000000004d0bd8] .really_probe+0xb0/0x288 
[c000000186f93810] [c0000000004d0e4c] .driver_probe_device+0x9c/0x110 
[c000000186f938a0] [c0000000004d0fbc] .__driver_attach+0xfc/0x100 
[c000000186f93930] [c0000000004cfee4] .bus_for_each_dev+0xc4/0x118 
[c000000186f939e0] [c0000000004d08a8] .driver_attach+0x28/0x40 
[c000000186f93a60] [c0000000004cf3b0] .bus_add_driver+0x190/0x340 
[c000000186f93b10] [c0000000004d1950] .driver_register+0x98/0x1b8 
[c000000186f93bb0] [c0000000003a760c] .__pci_register_driver+0x64/0x140 
[c000000186f93c50] [d0000000038107c0] .init+0x28/0x400 [mst_ppc_pci_reset] 
[c000000186f93cd0] [c00000000000ab68] .do_one_initcall+0x68/0x1e0 
[c000000186f93d90] [c00000000010893c] .SyS_init_module+0xcc/0x218 
[c000000186f93e30] [c0000000000098ec] syscall_exit+0x0/0x40 
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0xf (was 0xffffffff, writing 0xff) 
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0xe (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0xd (was 0xffffffff, writing 0x40)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0xc (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0xb (was 0xffffffff, writing 0x6115b3)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0xa (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x9 (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x8 (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x7 (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x6 (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x5 (was 0xffffffff, writing 0x0)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x4 (was 0xffffffff, writing 0x9e00000c)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x3 (was 0xffffffff, writing 0x20)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x2 (was 0xffffffff, writing 0x2070000)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x1 (was 0xffffffff, writing 0x100146)
mst_ppc_pci_reset_driver 0000:50:00.0: restoring config space at offset 0x0 (was 0xffffffff, writing 0x101115b3)
EEH: Detected PCI bus error on device <null>
EEH: This PCI device has failed 1 times in the last hour:
EEH: Bus location=U78CB.001.WZS02VY-P1-C11-T1 driver=mst_ppc_pci_reset_driver pci addr=0000:50:00.0
EEH: Device location=U78CB.001.WZS02VY-P1-C11-T1 driver= pci addr=<null>
EEH: of node=/pci@800000020000013/pci15b3,61@0
EEH: PCI device/vendor: 101115b3
EEH: PCI cmd/status register: 00100140
EEH: PCI-E capabilities and status follow:
EEH: PCI-E 00: 0002c010
EEH: PCI-E 01: 19008fe2
EEH: PCI-E 02: 0000595e
EEH: PCI-E 03: 0043f103
EEH: PCI-E 04: 10830000
EEH: PCI-E 05: 00000000
EEH: PCI-E 06: 00000000
EEH: PCI-E 07: 00000000
EEH: PCI-E 08: 00000000
EEH: PCI-E AER capability register set follows:
EEH: PCI-E AER 00: 00010001
EEH: PCI-E AER 01: 00000000
EEH: PCI-E AER 02: 00000000
EEH: PCI-E AER 03: 00062010
EEH: PCI-E AER 04: 00000000
EEH: PCI-E AER 05: 00002000
EEH: PCI-E AER 06: 000001e4
EEH: PCI-E AER 07: 00000000
EEH: PCI-E AER 08: 00000000
EEH: PCI-E AER 09: 00000000
EEH: PCI-E AER 0a: 00000000
EEH: PCI-E AER 0b: 00000000
EEH: PCI-E AER 0c: 00000000
EEH: PCI-E AER 0d: 00000000
RTAS: event: 2736, Type: Platform Error, Severity: 2
mst_ppc_pci_reset_driver 0000:50:00.0: PME# disabled

【问题讨论】:

    标签: linux-kernel linux-device-driver powerpc pci


    【解决方案1】:

    在调试此类问题时,最好跟踪您正在使用的内核版本并提供有关您正在测试的硬件的具体细节。从您的内核具有eeh_dn_check_failure() 而不是eeh_check_dev_failure() 的事实来看,我可以推测这是一个非常 旧的内核。您测试的其他系统是否具有相同的内核?一样的固件?所有这些都与您的问题有关。

    无论如何,我想说您需要在取消断言重置和恢复配置空间之间等待一秒钟。 PCI 规范要求系统软件在尝试 IO(包括配置周期)之前在重置后给设备一秒钟的时间进行初始化。在 2015 年提交 26833a5029b7 ("powerpc/eeh: Make the delay for PE reset unified") 在取消断言后添加了延迟(至少在 powerpc 上),以便为您处理。考虑到您的内核已经足够老,仍然有 eeh_dn_check_failure()(在 2012 年重命名,请参阅 f8f7d63fd96e),您可能没有那个补丁,需要自己等待。

    可能发生的情况是设备尚未准备好响应配置访问并丢弃它们。管理程序将检测到超时并假定设备出现故障,因此它使用 IBM 的 Power 硬件具有的 EEH 机制隔离设备(冻结它)。通常,操作系统会在发生这种情况后尝试解冻并重置设备,但这可能会因多种原因而失败,尤其是在较旧的内核上。

    【讨论】:

    • 嗨奥利弗,感谢您的回复。问题机器的内核版本是 3.0.101-63-ppc64,好机器的内核版本是 2.6.32-696.el6.ppc64。我添加了 1 秒的睡眠,它解决了问题!但是你怎么解释2.6版本不需要这个sleep而3.0版本需要这个sleep呢?
    • 如果不阅读每个版本的代码并跟踪发生的情况,很难说。较旧的内核可能有一个内置的等待,它在某个时候被删除,或者你可能只是走运了。有时竞争条件会被其他代码的行为所掩盖,并且修改某些内容会导致您遇到以前隐藏的竞争。
    猜你喜欢
    • 2016-04-26
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 2014-05-18
    • 2012-11-25
    • 2023-04-11
    • 2012-12-01
    • 1970-01-01
    相关资源
    最近更新 更多