工具与软件:
大家好!
在使用与 EVM 类似的自定义 AM64X 板时、Linux 内核不稳定。
使用从 TI 配方继承而来的最新 Yocto、 然后再编辑 DTS 对我们来说,事情是非常稳定的。
所以我们正在进行测试、以便在我们升级到这个新的内核版本时、我们能够注意到是否引入了不稳定性。
我正在分享我用于测试的脚本、如果有兴趣、可以帮助重现此脚本。 如果这是一个问题、它似乎与初始化有关。 看起来像是一个竞态条件。
这是一条可怕的消息、对于这个新内核、我只遇到它一次、但它会在您升级和关闭 PRU 以太网接口时发生:
[ 293.313047] rpmsg_PRU virtio0.rpmsg-pru.-1.34:消息长度表已满
[ 293.813048] rpmsg_PRU virtio0.rpmsg-pru.-1.34:消息长度表已满
[ 294.313037] rpmsg_pru virtio0.rpmsg-pru.-1.34:消息长度表已满
当我添加然后多次删除 eth1和 eth2时、仍然会看到这些错误(我们为它们使用 PRU_ICSG0)。 我将使用延迟、这样测试就不会太苛刻。 我正在连接用于测试的程序。
[ 5523.786702] PAGE_POOL_RELEASE_RETRY() STALL POOL SHUTDOWN 28 inflight 5427 sec
[ 5523.786713] PAGE_POOL_RELEASE_RETRY () STALL POOL SHUTDOWN 14 inflight 3323 sec
[ 5523.801594] PAGE_POOL_RELEASE_RETRY () STALL POOL SHUTDOWN 10 inflight 3857 sec
[ 5523.818608] PAGE_POOL_RELEASE_RETRY () STALL POOL SHUTDOWN 11 inflight 4471 sec
这是否需要关注?
运行固件:
30004000.RTU 8 运行 ti-pruss/am65x-sr2-rtu0-prueth-Fw.elf /bus@f4000/icssg@30000000/RTU@4000
30006000.RTU 10 运行 ti-pruss/am65x-sr2-rtu1-prueth-Fw.elf /bus@f4000/icssg@30000000/RTU@6000
3000a000.txpru 2 运行 ti-prus/am65x-sr2-txpru0-prueth-Fw.elf /bus@f4000/icssg@300000000000/txpru@a000
3000c000.txpru 3 运行 ti-prus/am65x-sr2-txpru1-prueth-Fw.elf /bus@f4000/icssg@300000000000/txpru@c000
30034000.PRU 7 运行 ti-pruss/am65x-sr2-pru0-prueth-Fw.elf /bus@f4000/icssg@300000000000/PRU@34000
30038000.PRU 9 运行 ti-pruss/am65x-sr2-pru1-prueth-Fw.elf /bus@f4000/icssg@30000000000000/PRU@38000
此致。
import os import time import subprocess import json import threading import sys PING_RETRIES = 3 CONFIG_DELAY_UP_SEC = 3 CONFIG_DELAY_DOWN_SEC = 1 def run_command(command): return subprocess.run(command, shell=True, capture_output=True, text=True).stdout.strip() def configure_interface(iface, ip, subnet): os.system(f"ifconfig {iface} {ip} netmask {subnet} up") def deconfigure_interface(iface): os.system(f"ifconfig {iface} down") def ping_test(ip): return os.system(f"ping -c {PING_RETRIES} {ip}") == 0 def check_interfaces(): output = run_command("ip -j a") interfaces = json.loads(output) return interfaces def is_interface_up_and_ip_correct(iface, expected_ip): interfaces = check_interfaces() for interface in interfaces: if interface['ifname'] == iface: if "UP" in interface['flags']: for addr in interface['addr_info']: if addr.get('local') == expected_ip: return True return False def interface_test(iface, config): ip1 = config["ip1"] ip2 = config["ip2"] current_ip = ip1 while True: configure_interface(iface, current_ip, config["subnet"]) time.sleep(CONFIG_DELAY_UP_SEC) if is_interface_up_and_ip_correct(iface, current_ip) and ping_test(config["ping_target"]): print(f"{iface} ping success with IP {current_ip}") else: print(f"{iface} ping failed or not configured correctly with IP {current_ip}") deconfigure_interface(iface) time.sleep(CONFIG_DELAY_DOWN_SEC) current_ip = ip2 if current_ip == ip1 else ip1 def start_interface_in_thread(iface, config): thread = threading.Thread(target=interface_test, args=(iface, config)) thread.start() return thread def main(): interfaces = { "eth1": { "ip1": "10.42.1.7", "ip2": "10.42.1.8", "subnet": "255.255.255.0", "ping_target": "10.42.1.1" }, "eth2": { "ip1": "10.42.2.8", "ip2": "10.42.2.9", "subnet": "255.255.255.0", "ping_target": "10.42.2.1" } } while True: threads = [] for iface, config in interfaces.items(): thread = start_interface_in_thread(iface, config) threads.append(thread) for thread in threads: thread.join() # Wait for all threads to finish before next iteration if __name__ == "__main__": try: main() except KeyboardInterrupt: sys.exit(1)