This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM6442:在 AM64上使用 DP83822处理 IRQ 的潜在竞态条件

Guru**** 2408820 points
Other Parts Discussed in Thread: AM6442

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1477225/am6442-potential-race-condition-handling-irq-with-dp83822-on-am64

器件型号:AM6442

工具与软件:

大家好!

我使用的是 AM64 MPU 和 DP83822 PHY、并且我要将 PHY 中断引脚配置为触发 IRQ。 根据 DP83822数据表:

   '当这个引脚被配置为一个中断引脚时、这个引脚在一个中断条件出现时被置为低电平。 该引脚有一个带弱内部上拉电阻的开漏输出。 某些应用可能需要外部上拉电阻器。"

在 MPU 端、GPIO 控制器文档说明:

   "中断可以由上升沿和/或下降沿触发、为每个可中断的 GPIO 信号指定。"

由于 GPIO 限制、我只能将中断配置为下降沿。 我还注意到、在 Linux 中、drivers/net/phy/phy.c 文件将中断模式设置为 IRQF_OneShot

* IRQF_OneShot -在 Hardirq 处理程序完成后不重新启用中断。
*由需要保持的线程化中断使用
* IRQ 行被禁用,直到线程处理程序运行完毕。



我的问题是、在 读取 PHY 的 MICR 寄存器(这将清除中断)和返回 IRQ_HANDLED (这将重新启用中断)之间、drivers/net/phy/dp83822.c dp83822_handle_interrupt 可能存在竞态条件。

请注意、应如何正确处理此问题以避免这种情况? 我们可以触发 EN 级别的中断吗? 我使用 GPIO1_28。

提前感谢您的任何见解!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Remi、您好!  

    Milan 在一个电话中通知我、尝试使用 AM6442配置 PHY 中断模式的原因是 RSTP 恢复时间不符合要求。 您或米兰是否能够阐明需要满足的预期恢复时间? 此外、当前测量的 RSTP 恢复时间是多少?

    使用 AM6442将 PHY 配置为中断模式的主要问题是、如果 DP83822 PHY 仅支持电平中断、而 AM6442上的 GPIO 仅支持边沿中断、则可能会由于电平和边沿中断差异而缺少事件。   有关更多详细信息、请参阅 e2e.ti.com/.../5104744  

    [报价 userid="643222" url="~/support/processors-group/processors/f/processors-forum/1477225/am6442-potential-race-condition-handling-irq-with-dp83822-on-am64 ]根据 DP83822数据表:

       '当这个引脚被配置为一个中断引脚时、这个引脚在一个中断条件出现时被置为低电平。 该引脚有一个带弱内部上拉电阻的开漏输出。 某些应用可能需要外部上拉电阻器。"
    [报价]

    在我看来、这种描述意味着 DP83822 PHY 仅对电平敏感。 我将与 TI PHY 团队核实、以便仔细核实这一点。

    -道林

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Daolin。

    感谢您的帮助和链接、这些链接与我们的分析一致。

    预期恢复时间为100ms、包括20块电路板的传播时间。

    目前、我们修补了 drivers/net/phy/phy.c、可以处理过快的中断。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Remi:  

    感谢您澄清恢复时间要求。 您是否碰巧知道当前测量的 RSTP 恢复时间(即不符合要求的时间)?

    [报价 userid="576780" url="~/support/processors-group/processors/f/processors-forum/1477225/am6442-potential-race-condition-handling-irq-with-dp83822-on-am64/5671428 #5671428"]据我所知、此描述暗示 DP83822 PHY 仅对电平敏感。 我将与 TI PHY 团队核实一下。

    PHY 的反馈为 DP83822对电平敏感:"我们期望的是、如果 PHY 没有置位 INT、则该引脚为高电平(因为 OD PU 使电压处于高电平)。 每当存在 INT 时、PHY 就会将引脚拉至低电平、从而指示 SoC 对其进行检查(可能通过 ISR 进行检查)。 每当读取 INT 寄存器时、中断就会清除、并且该引脚应处于高电平、直到下一个 INT。"

    [报价 userid="643222" url="~/support/processors-group/processors/f/processors-forum/1477225/am6442-potential-race-condition-handling-irq-with-dp83822-on-am64 "]我担心在 读取 PHY 的 MICR 寄存器(这将清除中断)与返回 IRQ_Handle (这将重新启用中断)之间、drivers/net/phy/dp83822.c dp83822_handle_interrupt 可能存在竞态条件。

    我将该主题引导至 TI PHY 专家、以帮助就有关 DP83822 PHY 驱动程序的问题提供建议。 如果您在周二之前尚未收到回复、请 ping 此主题。

    -道林

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Daolin:

    currenlty 项目告诉我们、 恢复时间超过1秒... 它们的最大时间为1.3s、平均时间为785ms…… 该测试配置中请求的时间为100ms。

    通过对中断进行一些测试、得到36ms-130ms……

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Milan:

    据我所知、您观察的是 dp83822.c 和 phy.c 之间的中断状态机相对于启用/清除中断有效、但时序是个问题?  

    目前、我们已经修补了 drivers/net/phy/phy.c、可以处理太快的中断。

    请分享有关您已尝试的补丁的更多详细信息。 如果读取和清除中断之间的时序太短、我们可以使用 dp83822.c 或 phy.c 中的功能作为权变措施。

    谢谢!

    Evan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Evan:

    Remi 本周关闭,他可以提供更多的信息下星期,当他回来...

    问题是边沿中断出现在  读取 PHY 的 MICR 寄存器 和返回 IRQ_Handled 之间

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Milan:

    我理解、将等待 Remi 确认更多信息、然后再提供解决方法建议。

    谢谢!

    Evan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Daolin 和 Evan、

    感谢您的答复。

    我的补丁在 phy.c 中断处理过程结束时生成一个新中断。 该案例涵盖了在我们的板上使用单个 PHY 观察到的情况、即在当前中断线程完成执行之前发生新的中断。 该方法还适用于多个 PHY 共享同一中断线路的设置、例如在 EVM 上。 这可确保正确处理共享同一中断线路的所有 PHY。  

    该修改包括在 phy_interrupt 函数结束时、恰好在返回之前、在 drivers/net/phy/phy.c 中添加以下代码:

        if (ret == IRQ_HANDLED) {
            generic_handle_irq(irq);
        }

    我的完整功能:

    static irqreturn_t phy_interrupt(int irq, void *phy_dat)
    {
        struct phy_device *phydev = phy_dat;
        struct phy_driver *drv = phydev->drv;
        irqreturn_t ret;
     
        /* Wakeup interrupts may occur during a system sleep transition.
         * Postpone handling until the PHY has resumed.
         */
        if (IS_ENABLED(CONFIG_PM_SLEEP) && phydev->irq_suspended) {
            struct net_device *netdev = phydev->attached_dev;
     
            if (netdev) {
                struct device *parent = netdev->dev.parent;
     
                if (netdev->wol_enabled)
                    pm_system_wakeup();
                else if (device_may_wakeup(&netdev->dev))
                    pm_wakeup_dev_event(&netdev->dev, 0, true);
                else if (parent && device_may_wakeup(parent))
                    pm_wakeup_dev_event(parent, 0, true);
            }
     
            phydev->irq_rerun = 1;
            disable_irq_nosync(irq);
            return IRQ_HANDLED;
        }
     
        mutex_lock(&phydev->lock);
        ret = drv->handle_interrupt(phydev);
        mutex_unlock(&phydev->lock);
     
        // WORKAROUND: The interrupt is shared between multiple PHYs.
        // Since one PHY's interrupt may mask another's, we trigger a new
        // interrupt to ensure all PHYs get a chance to handle their events.
        // If no PHY reports an event, we are done!
        if (ret == IRQ_HANDLED) {
            generic_handle_irq(irq);
        }
     
        return ret;
    }

    此致、

    雷米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Remi:

    我同意您对此变通办法的方法。 使用此补丁时、您是否发现任何功能问题或边缘情况?

    谢谢!

    Evan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Evan:

    使用此补丁程序时、您是否发现任何功能问题或边缘情况?

    还不是很远。 我会向团队核实他们是否完成了强化测试。

    谢谢

    雷米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Evan:

    我们已验证该权变措施可以很好地适应 RSTP 时序。 但是、我们注意到、当启用 PHY 的 FLD 中断时、以下跟踪会在引导阶段出现一次:

    [   15.656912] ------------[ cut here ]------------
    [   15.656931] irq 475 handler irq_default_primary_handler+0x0/0x10 enabled interrupts
    [   15.656980] WARNING: CPU: 0 PID: 247 at __handle_irq_event_percpu+0x208/0x290
    [   15.656993] Modules linked in: cdns3 cdns_usb_common irq_pruss_intc icssg_prueth pru_rproc icss_iep cdns3_ti ti_k3_r5_remoteproc pruss omap_mailbox
    [   15.657035] CPU: 0 PID: 247 Comm: irq/475-3003240 Not tainted 6.1.108-rt40-senux #1
    [   15.657046] Hardware name: P3Y EP based on Texas Instruments AM642 EVM (DT)
    [   15.657052] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
    [   15.657060] pc : __handle_irq_event_percpu+0x208/0x290
    [   15.657068] lr : __handle_irq_event_percpu+0x208/0x290
    [   15.657075] sp : ffff800009ac3cc0
    [   15.657078] x29: ffff800009ac3cc0 x28: ffff8000080a0000 x27: ffff000003717000
    [   15.657089] x26: 0000000000012400 x25: ffff800008bd3008 x24: ffff800008bd3008
    [   15.657100] x23: 00000000000001db x22: ffff000001f78600 x21: 0000000000000000
    [   15.657111] x20: 0000000000000002 x19: ffff00000405a480 x18: ffffffffffffffff
    [   15.657122] x17: ffff800014394000 x16: ffff800008000000 x15: ffff800089ac3618
    [   15.657132] x14: 00000000fffffffd x13: 0a73747075727265 x12: 746e692064656c62
    [   15.657143] x11: 656820747563205b x10: 000000000000002f x9 : ffff80000809aa78
    [   15.657154] x8 : 000000000000002f x7 : 75727265746e6920 x6 : ffff800008e6ecb8
    [   15.657164] x5 : 0000000000000000 x4 : ffff00001cf68a10 x3 : 0000000000000000
    [   15.657174] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000003717000
    [   15.657185] Call trace:
    [   15.657189]  __handle_irq_event_percpu+0x208/0x290
    [   15.657197]  handle_irq_event+0x6c/0x120
    [   15.657205]  handle_simple_irq+0x98/0x11c
    [   15.657215]  generic_handle_irq+0x34/0x50
    [   15.657222]  phy_interrupt+0x6c/0x80
    [   15.657234]  irq_thread_fn+0x30/0x90
    [   15.657242]  irq_thread+0x148/0x204
    [   15.657249]  kthread+0x11c/0x120
    [   15.657257]  ret_from_fork+0x10/0x20
    [   15.657268] ---[ end trace 0000000000000000 ]---

    该警告似乎源自kernel/irq/handle.c,特别是在__handle_irq_event_percpu函数中,在这段代码:

    if (WARN_ONCE(!irqs_disabled(),  
        "irq %u handler %pS enabled interrupts", irq, action->handler))  
        local_irq_disable();

    如果您对此行为有任何想法、请告知我们。

    此致、
    雷米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Remi:

    发生该错误后是否可以共享 PHY 寄存器转储? 我想确认标记了哪些中断。

    我不清楚该错误是特定于 FLD 中断还是任何 PHY 中断。 在禁用 FLD 的情况下、触发链路 状态 或自动协商完成中断(0x12[13、10])是否会导致任何错误?

    谢谢!
    Evan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Evan、您好!

    实际上、如果在启动期间插入了电缆、则会显示警告。 它与 FLD 激活无关。

    在插入电缆的情况下进行引导=>警告

    160728.423: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0001
    160728.439: 0x786d
    160752.314: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0002
    160752.333: 0x2000
    160753.539: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0003
    160753.555: 0xa240
    160754.942: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0004
    160754.958: 0x0101
    160756.105: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0005
    160756.143: 0xc101
    160804.757: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0006
    160804.817: 0x000f
    160811.178: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0007
    160811.211: 0x2001
    160816.693: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0008
    160816.713: 0x4000
    160818.045: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0009
    160818.060: 0x0000
    160833.096: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x000A 
    160833.117: 0x0100
    160849.502: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x000B
    160849.518: 0x1000
    160850.771: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x000C
    160850.834: 0x0000
    160852.348: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x000D
    160852.356: 0x401f
    160858.940: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x000E
    160859.003: 0x1000
    160904.169: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x000F
    160904.185: 0x0000
    160906.336: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0010
    160906.398: 0x0615
    160919.702: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0011
    160919.720: 0x010b
    160924.665: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0012
    160924.725: 0x00fc
    160929.732: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0013
    160929.749: 0x00f7
    160933.815: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0014
    160933.842: 0x0000
    160936.849: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0015
    160936.864: 0x0000
    160938.172: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0016
    160938.188: 0x0100
    160944.235: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0017
    160944.259: 0x1249
    160949.915: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0018
    160949.930: 0x0400
    160954.589: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0019
    160954.605: 0x8c21
    161000.482: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x001A
    161000.498: 0x0000
    161008.433: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x001B
    161008.450: 0x007d
    161010.222: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x001C
    161010.237: 0x05ee
    161014.178: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x001E
    161014.194: 0x0102
    161015.489: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x001F
    161015.505: 0x0000
    161959.853: root@p3y:~# mdio 30032400.mdio phy 1 raw 0x0025
    161959.870: ERROR: Register 37 is out of range [0-31]

    此致、

    雷米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 R é mi:

    实际上、如果在启动过程中插入电缆、将显示警告。

    您是否仅在包含 phy.c 的补丁时才观察到该情况?

    https://docs.kernel.org/networking/phy.html

    参考内核文档、如果 MAC 中断由于  在启动时看到 PHY 链路状态变化而发生变化、那么这里可能存在一个问题。

    您能否尝试使用以下任一建议进行测试:

    1) 1)在调用 phy_start 之前、将 phydev->IRQ 设置为 PHY_MAC_INTERRUPT

    2) 2)将 phydev->IRQ 设置 PHY_POLL  

    谢谢!
    Evan