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.

[参考译文] AM623:向 CPSW 中的 ALE 表写入关键错误

Guru**** 2540720 points
Other Parts Discussed in Thread: SK-AM62B

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1537750/am623-critical-bug-writing-to-ale-table-in-cpsw

器件型号:AM623
主题中讨论的其他器件:SK-AM62B

工具/软件:

症状

在正常运行期间、以太网接口突然停止发送或接收数据包。 接口似乎已打开、可检测到以太网状态的任何变化。 在接口被关闭然后重新初始化之前、以太网不会再次开始工作。 如果没有非常具体的监控和解决方法、则在手动重置之前、产品将无法使用。

问题

CPSW 中的 ALE 表已损坏且 VLAN 配置已删除。 这可以 通过运行“switch-config -d“并观察表中的第一个条目是否已从 vlan 类型更改为 mcast 类型来验证。 VLAN 被覆盖、因为函数  cpsw_ale_match_free()  错误地将索引 0 返回为空。

如果出现错误:

  1. cpsw_ale_match_free() 调用 cpsw_ale_read()  
  2. cpsw_ale_read () 用索引 0 执行对 ale_table_control 的写入
  3. cpsw_ale_read() 从 ale_table 中读取字节作为全零

如果第二次调用 cpsw_ale_read()、则返回 ale_table 元素 0 的实际值。

复制

我们使用产品硬件和 SK-AM62B 开发板、在版本 9 和 11 的 SDK 上进行了复制。

当存在两个元素时、此问题会可靠地发生:

  • 运行 iperf3 使以太网流量持续
  • 重复从在没有主设备的情况下运行的 ptp4l 对 ALE 所做的更改

在 SK-AM62B 上进行复制的步骤:

在任何 Linux 服务器上:

  1. 启动 ptp4l 作为祖母:
    1. sudo ptp4l -i -m -l 6 --domainNumber=99
  2. 启动 iperf3 服务器:
    1. iperf3 -s

在 EVM 上:

  1. 显示 CPSW ALE 表的用户命令:
    1. switch-config -d  
    2. 注意条目#0 如下所示:
      1. 0  :类型:vlan、vid = 0、untag_FORCE = 0x7、reg_mcast = 0x0、unreg_mcast = 0x0、 Member_list = 0x7
  2. 验证 EVM 是否看到来自服务器的 PTP 流量:
    1. tcpdump -n dst 端口 319 或 dst 端口 320
  3. 在不同的域号上启动 ptp4l 以导致 ptp4l 定期打开/关闭套接字~8s:
    1. ptp4l -E –4 -H -i eth0 -s -l 6 -q -p /dev/ptp0 -m
  4. 启动 iperf3 客户端:
    1. iperf3 -c -t 5 -t 60000 -u --BIDIR -b 400m

有时、iperf3 将在 EVM 上闭合、当链路建立时以太网将断开。  再次使用“switch-config -d“命令并注意条目#0 现在是“type:MCAST“。

预期结果

我们需要在驱动程序中采取某种变通办法来防止此故障。 我们还需要一名了解硬件设计的人员来建议是否从同一根本原因导致其他失效模式。

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

    你好 Mathew、  

    感谢您分享有关此问题的详细信息。 这个问题引起了我们内部团队的关注。 我想问、在我们研究这个问题时、是否有这个问题 系统 ptp4l 流量正在运行且 iperf3 正在运行时可简化、或者在 ptp4l 未运行时是否可以重现此问题?

    -道林

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

    我们很少在我们的产品上看到这一点(运行 1-3 天后)、我们通常总是有 ptp4l 在运行、但不经常改变 ALE。 在没有主设备的情况下使用 ptp4l 只是一种定期将多播元素写入 ALE 的方法。 我想说的是,覆盖 ALE 中的第一个项目只发生在 100 次更新中的 1 次,所以在一个合理的时间范围内复制它需要像 ptp4l 或 ethtool 这样的东西来对 ALE 进行更改。

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

    尊敬的 Mathew:  

    使用不带主设备的 ptp4l 只是一种定期将多播元素写入 ALE 的方法。 我想说的是,覆盖 ALE 中的第一个项目只发生在 100 次更新中的 1 次,所以在一个合理的时间范围内复制它需要像 ptp4l 或 ethtool 这样的东西来对 ALE 进行更改。

    我懂了。 另一个问题是、在设置中、eth0 是  系统  EVM 上直接连接到 Linux 主机 PC 的接口(即另一个接口 eth1 未连接到任何内容)?  

    -道林

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

    正确

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

    您好、Matthew、  

    看起来我们正在等待我们的 CPSW 硬件专家提供的一些反馈;但是他本月底之前就已离职。 请问您最晚能等待有关此问题的反馈的时间是多久?

    -道林

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

    尊敬的 Daolin:

    这已变得至关重要。  客户将回答您的问题(您等待此问题反馈的最晚时间是多久?) 很快。  

    TI 方面的状态是什么?  

    我们的 CPSW 硬件专家是否提供了任何反馈?  

     您是否能够重现此问题?

    E2E 的其他信息... 可能相关的问题、但与不同的器件有关。

    wrt “如果第二次调用 cpsw_ale_read()、则返回 ale_table 元素 0 的实际值“..(https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1479969/tda4ve-q1-cpsw-ethernet-randomly-fails-on-linux-due-to-ale-corruption/5803226?tisearch=e2e-sitesearch&keymatch=AM623%2520ALE%2520corrupt#5803226 )。  这一个仍然在工作,但说.. “我已在内部报告该问题并重新创建。 目前的建议是两次阅读 ALE 条目。 目前仍在就该问题的根本原因进行讨论。“  JIRA= ETHFW-2586。

    谢谢、Merril

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

    您好 Newman:  

    了解重要性。

    在 TI 方面、我们请了另一位负责 CPSW 硬件专家休假的硬件专家、总体建议将读取 ALE 条目两次作为权变措施。 目前、我们没有根本原因导致该问题、但通过测试 ALE 条目作为该问题的解决方法 的两倍、我们没有看到出现该问题。  

    [quote userid=“5988" url="“ url="~“~/support/processors-group/processors/f/processors-forum/1537750/am623-critical-bug-writing-to-ale-table-in-cpsw/5929776

    E2E 的其他信息... 可能相关的问题、但与不同的器件有关。

    wrt “如果第二次调用 cpsw_ale_read()、则返回 ale_table 元素 0 的实际值“..(https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1479969/tda4ve-q1-cpsw-ethernet-randomly-fails-on-linux-due-to-ale-corruption/5803226?tisearch=e2e-sitesearch&keymatch=AM623%2520ALE%2520corrupt#5803226 )。  这一个仍然在工作,但说.. “我已在内部报告该问题并重新创建。 目前的建议是两次阅读 ALE 条目。 目前仍在就该问题的根本原因进行讨论。“  JIRA= ETHFW-2586。

    [/报价]

    我们认为该问题和建议的解决方法与您指出的其他主题相同。

    -道林

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

    尊敬的 Daolin:

    我们目前有一个权变措施。 如果我们在向客户发布之前需要额外的紧急修复、我有大约两周的时间。 现在、我需要通过专家的意见来判断这种故障模式是独特的、还是存在潜在硬件问题可能带来问题的其他方法。

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

    Daolin Qiu 所述、如果 first 为 0、则第二次读取是有效的解决方法。

     Pekka

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

    看起来我们已经排列好了根本原因。 第二种阅读方法将降低诚实性,但不能保证它永远不会发生。 使用多个读写器时、硬件数据结构不安全。 完整的权变措施如下所示:

    软件必须防止整个写入(ALE 条目添加)或写入/读取(ALE 条目读取)被另一个进程中断。

    当您用 tablewr=0 写入 ALE_TBLCTL 时、总线将保持关断状态、直到找到该条目并更新寄存器。 您必须确保在读取完内容之前、其他进程不会开始写入条目。

    表写入也是如此。 必须确保从写入第一个字到写入 ALE_TBLCTL 寄存器、没有其他过程会触及表寄存器。

    我们没有确保上述内容的更新计划。

     Pekka

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

    根据今天的电话、我将添加 我收集的其他测试结果:

    寄存器重新读取

    我修改了 ALE 读取功能以读取寄存器两次、 故障仍然发生。 将结果打印到系统日志时、两组读取始终相同。

    下面的代码是重建、因为我不再测试确切的版本:

    static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
    {
    	int i;
    
    	WARN_ON(idx > ale->params.ale_entries);
    
    	writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
    
    	for (i = 0; i < ALE_ENTRY_WORDS; i++)
    		ale_entry[i] = readl_relaxed(ale->params.ale_regs +
    					     ALE_TABLE + 4 * i);
    
    	for (i = 0; i < ALE_ENTRY_WORDS; i++)
    		ale_entry[i] = readl_relaxed(ale->params.ale_regs +
    					     ALE_TABLE + 4 * i);
    	return idx;
    }

    控制写入和数据读取之间的延迟

    在 ALE_READ 函数中、我测试了在  writel_relaxed (idx、ale->params.ale_regs + ale_table_control) 之后添加延迟;

    由于各种延迟、我发现误差率没有提高。

    控制寄存器在函数期间发生变化的可能性(来自另一个线程)

    我修改了 ALE 读取功能、以便在读取后读回控制寄存器。 在正常运行期间、寄存器不会改变功能。 使用 devmem2 执行异常写入将导致激活 PRINT 语句的争用。

    static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
    {
    	int i, after_idx;
    
    	WARN_ON(idx > ale->params.ale_entries);
    
    	writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
    
    	for (i = 0; i < ALE_ENTRY_WORDS; i++)
    		ale_entry[i] = readl_relaxed(ale->params.ale_regs + ALE_TABLE + 4 * i);
    
        after_idx = readl_relaxed(ale->params.ale_regs + ALE_TABLE_CONTROL);
        if(after_idx != idx){
            dev_err(ale->params.dev, "cpsw_ale_read: idx changed during read!!!\n");
        }
    	return idx;
    }

    空 ALE 数据的来源

    我执行了一项测试、以表明空数据寄存器不仅仅是 ALE 表中不同行的内容。 我使用脚本将值写入每个表条目的地址部分、同时将 Type bits 保留为 Free (00)。 发生故障时、将返回所有零、而不是另一条 ALE 记录的内容。

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

    增加了我们当前测试为可通过 Yocto 等应用的补丁的修复程序

    diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
    index 64bf22cd860c..347351df82ec 100644
    --- a/drivers/net/ethernet/ti/cpsw_ale.c
    +++ b/drivers/net/ethernet/ti/cpsw_ale.c
    @@ -317,6 +317,7 @@ static int cpsw_ale_read(struct cpsw_ale *ale, int idx, u32 *ale_entry)
     
     	WARN_ON(idx > ale->params.ale_entries);
     
    +	writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
     	writel_relaxed(idx, ale->params.ale_regs + ALE_TABLE_CONTROL);
     
     	for (i = 0; i < ALE_ENTRY_WORDS; i++)

    到目前为止、执行控制寄存器写入两次似乎可以消除错误读取。

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

    您好、Matthew、  

    感谢您分享这些全面的测试和结果。

    抱歉、我认为这一问题的解决方法是阅读两次还是写两次、存在一些混淆。 检查我们之前看到的情况、确实有两次写入是此问题的主要解决方法(就像您当前所做的那样)。 请参阅  关于:TDA4VM:几小时后 eth0 断开连接 

    似乎我们已经排列了根本原因。 第二种阅读方法将降低诚实性,但不能保证它永远不会发生。 一个硬件数据结构不安全,使用多个读写器。[/报价]

    正如 Pekka 在调用和本线程中提到的、我们认为在仍在处理对 ALE 表的读取/写入时、确保没有多个进程尝试访问 ALE 表可能是一个根本原因。 从我们这边来看、我们正在努力确认这是否确实是根本原因。 我会在获得更多信息时通过更新进行响应。  

    请继续通过此 E2E 渠道进行通信。 如果您遇到其他问题、请单独提交 E2E 工单。

    -道林

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

    谢谢、Daolin。  

    我期待着你的发现,如果我们有任何更相关的意见,我会发布。

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

    您好、Matthew、  

    正如 Pekka 在调用和本线程中提到的、我们认为在处理 ALE 表的读/写时、确保没有多个进程尝试访问 ALE 表可能是一个根本原因。 从我们这边来看、我们正在努力确认这是否确实是根本原因。 我会在获得更多信息时通过更新进行响应。  [/报价]

    我想告诉大家、在内部、为了了解更多有关此方面的信息、我们在内部确实需要与我们的  CPSW 硬件专家进行讨论、他们将在下周前休假。 我将尝试更新你,当我发现更多下周.

    -道林

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

    您好 Matthew、  

    我们还需要一位了解硬件设计的人员来告知是否可能从同一个根本原因导致其他失效模式。

    我在内部收到的信息表明根本原因是“索引计算使用上一周期索引的高位和当前周期索引的低位“、因此每次读取 ALE 条目 0x0 时都会返回错误的索引、并发现通过将 ALE_TBLCTL 寄存器填充/写入索引 0 两次、在读取 ALE 条目 0x0 时会返回正确的索引 0。  

    抱歉、我认为这一问题的解决方法是阅读两次还是写两次、存在一些混淆。 检查我们之前看到的情况、确实有两次写入是此问题的主要解决方法(就像您当前所做的那样)。 请参阅  关于:TDA4VM:在几小时后 eth0 断开连接 [/报价]

    我的理解是、官方解决方案写了两次、我们计划将此内容添加为勘误表并进行同等修复。 将尝试在发生此更改时通知您更新。  

    -道林