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.

[参考译文] DRA829J:以太网驱动程序 am65-cpsw-nuss 导致内核 NULL 指针异常

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1433303/dra829j-kernel-null-pointer-exception-due-to-ethernet-driver-am65-cpsw-nuss

器件型号:DRA829J

工具与软件:

尊敬的:

如果 am65-cpsw-nuss 驱动程序中的 IRQ 请求失败、则会在清理链中导致 NULL 指针异常。 内核恐慌的根本原因是 free 方法中的 memset:

https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/net/ethernet/ti/am65-cpsw-nuss.c?h=ti-linux-6.1.y#n1674

实际崩溃发生在 free_netdev 方法中:

https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/net/core/dev.c?h=ti-linux-6.1.y#n10714

崩溃是在调用 list_for_each_entry_safe 时发生的、我认为这是由于在 memset 中 NAPI_TX 列表被覆盖0所致。

通过在 am65_cpsw_nuss_ndev_add_tx_napi 中捕获 IRQ 请求失败、很容易重现问题:

https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/net/ethernet/ti/am65-cpsw-nuss.c?h=ti-linux-6.1.y#n1722

只需在调用 devm_request_irq 后添加"ret =-ENOMEM"或"ret =-EINVAL"。

使用 memset 的原因是什么? 能否安全移除?

[   2.562201] am65-cpsw-nuss c000000.ethernet:请求 tx0 IRQ 43失败、-12
[   2.569525] am65-cpsw-nuss c000000.ethernet:无法添加 TX Napi -12
[   2.578000]无法处理虚拟地址0000000000000000处的内核 NULL 指针解除引用
[   2.586786]存储器中止信息:
[   2.589587]  ESR = 0x0000000096000004
[   2.59333333]  EC = 0x25:DABT (当前 EL)、IL = 32位
[   2.598636]  设置= 0、FNV = 0
[   2.601684]  EA = 0、S1PTW = 0
[   2.604819]  FSC = 0x04:0级转换故障
[   2.60969]数据中止信息:
[   2.612562]  ISV = 0、ISS = 0x00000004
[   2.616394]  CM = 0、WNR = 0
[   2.619351][0000000000000000]用户地址、但 ACTIVE_MM 被交换
[   2.625695]内部错误:Oops:0000000096000004 [#1] preempty SMP
[2.631947]   模块链接如下:
[   2.634995] CPU:0 PID:9 Comm:kworker/U4:0 not damed 6.1.69-ti-g4a7ab3a0163e #1
[   2.642636]硬件名称: Schneider Electric Automation Server Premium 3 (DT)
[   2.649841]工作队列:Events_unbound defered_probe_work_func
[   2.655676] pstate:60000005 (NZCv daif -pan -uao -tco -dit -ssbs BTYPE=-)
[2.662622]   PC : free_netdev+0xc0/0x1b0
[2.666452]   lr : free_netdev+0xc0/0x1b0
[2.670276]   sp : ffff80000983bb10.
[2.67359]   x29:ff80000983bb10 x28:0000000000000000 x27:00000000000000000000
[   2.680704] x26:ffffff00000000c000 x25:ffff00000000900d x24:0000000000000048
[2.687827]   x23:0000000000000022 x22:ffffff80000983bb58 x21:ffff0000028fb050
[2.694950]   x20:ffffff0000028fb000 x19:fffffffffffffffffffffffffffluff 8 x18:0000000000000008.
[   2.702075] x17:202c333420717269 x16:000000000008 x15:0000000000000001
[   2.709197] x14:0000000000000026 x13:0000000000000399 x12:00000000000000000001
[2.716322]   x11:0000000000000000 x10:00000000000009a0 x9:ffff80000983b910
[2.723445]   x8 : ffffff0000000d7a00 x7 : ffff00005fbb7340 x6 : ffff8000094dad30.
[2.730568]   x5: 0000000000000000 x4: 0000000000000000 x3 : ff80000009566bf8.
[   2.737692] x2 : 0000000000000000 x1 : 000000000000 x0 : ffff0000000d7000
[   2.744817]呼叫跟踪:
[   2.747252] FREE_NETDEV+0xc0/0x1b0
[   2.750731] devm_free_netdev+0x14/0x20
[   2.754561] DevRes_release_all+0xa8/0x110
[   2.758649] device_unbind_cleanup+0x18/0x70
[   2.762909] REQUITE_PROBET+0x21c/0x2dc
[   2.766561] __driver_probe_device+0x78/0x114
[2.770909]    DRIVER_PROBE_DEVICE+0xd8/0x15c
[   2.775081] __device_attach_driver+0xb8/0x134
[   2.779514] bus_for_each_drv+0x80/0xdc
[   2.783339] __DEVICE_Attach+0xa0/0x1a0
[   2.787164] device_initial_probe+0x14/0x20
[   2.791336] BUS_PROTECT_DEVICE+0x98/0xa0
[   2.795161] Defered_probe_work_func+0x88/0xc0
[   2.799680] process_one_work+0x1b0/0x320
[   2.803655] worker_thread+0x220/0x430  
[   2.807428] kthread+0x104/0x10c
[   2.810647] ret_from_fork+0x10/0x20
[2.814219]   编码: 97fff8a5 9400631c 35fffee0 97d6f36a (f940ae62)
[2.820298]--[   结束跟踪0000000000000000]--

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

    您好!

    您是否正在尝试暂停并恢复?

    默认情况下、SDK 不支持该功能。

    如果不 选中"暂停"和"恢复"、我可以知道您在哪种情况下观察到故障吗?

    此致、
    Sudheer

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

    尊敬的:

    我正在尝试使用可重定位内核实现 kdump/kexec 以捕获内核崩溃转储。

    在这种情况下、devm_request_irq 会返回-einval 和内核 panics。

    但即使在正常引导场景下、如果 devm_request_irq 返回-EINVAL 或-ENOMEM 内核会因内存集而出现紧急情况。

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

    您好!

    您能否确认您使用的是哪个 SDK 版本?

    此致、
    Sudheer

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

    尊敬的:

    我们使用的是 SDK 9.0

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

    您好!

    驱动程序中的 Memset 仅出现在三个位置。
    其中一个寄存器在处理数据包以获取 Rx 数据包的时间戳期间执行。
    其他将在释放/移除 Tx 通道时调用、这将在暂停序列期间调用。

    此外、在您的情况下、为什么"devm_request_irq"失败? 您是否对驱动程序进行了任何更改?
    此外、在上面的调用跟踪中、我无法从 CPSW 驱动程序中看到任何 API? 所有这些似乎都是内核 API。

    此致、
    Sudheer

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

    尊敬的:

    调用跟踪如下所示:

    am65_cpsw_nuss_probe -> am65_cpsw_nuss_register_ndevs -> am65_cpsw_nuss_init_tx_chns

    am65_cpsw_nuss_init_tx_chns 中的错误处理调用 devm_add_action (dev、am65_cpsw_nuss_free_tx_chns、common)。 在 am65_cpsw_nuss_free_tx_chns 中调用 memset。

    我们未对驱动程序进行任何更改。 内核将首先调用 am65_cpsw_nuss_free_tx_chns、然后调用 free_netdev 作为错误处理的一部分。

    为什么 devm_request_irq 失败与之无关。 失败的 IRQ 请求不应导致内核出现紧急情况。

    我的问题是、为什么 FREE_TX_CHNS 方法中有一个 memset (TX_CHN、0、sizeof (* TX_CHN))?

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

    尊敬的:

    通过你的屏幕截图的外观,你已经添加了 ret =-EINVAL 在第2283行。

    根据我原来的帖子、尝试在 devm_request_irq 后面添加它。 第2212行。

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

    您好!

    根据我原来的帖子、尝试在 devm_request_irq 后面添加它。 SDK 10中的第2212行。

    我还观察到由于 free_netdev()导致的内核恐慌。

    此致、
    Sudheer

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

    您好!

    您能否整合以下补丁并检查一次、我在我身边进行了测试、但未发现此问题。

    https://github.com/torvalds/linux/commit/03c96bc9d3d2d?diff=split&w=0

    问题可能是因为某些端口可能未注册、但仍在尝试从内核中释放。 以上补丁将不允许内核在驱动程序中释放 netdev、而是释放。

    此致、
    Sudheer

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

    谢谢! 这样就可以解决问题。