Linux下USB操作时/proc/softirqs中Tasklet计数激增问题咨询
排查EHCI PCI设备USB操作时Tasklet计数异常增长的思路
针对你这台legacy设备在USB操作时tasklet计数线性飙升的问题——半小时就突破百万确实很反常,结合你的硬件配置和给出的/proc/interrupts、/proc/softirqs输出,我整理了几个实用的排查方向:
先再明确下你的设备背景:
- 芯片组:Intel NM10 express
- CPU:Atom D2250 Dual Core(带超线程,对应4个逻辑核心)
- 内存:1GB
- USB控制器驱动:ehci-pci
1. 先检查中断亲和性的影响
从你给出的/proc/interrupts能看到,EHCI/USB1的中断(IRQ23)完全绑定在CPU3上,而/proc/softirqs里CPU3的TASKLET和HI软中断计数都异常偏高,这说明所有USB相关的软中断都压在单个CPU上处理,很可能因为负载过高导致tasklet堆积。
- 可以临时调整IRQ23的亲和性,让它分散到所有CPU试试:
这里echo f > /proc/irq/23/smp_affinityf是十六进制,代表允许4个逻辑核心都处理该中断。之后再做USB操作,观察tasklet计数的增长速度是否放缓。如果有明显改善,那就是单CPU扛下所有USB中断导致的软中断处理不及时。
2. 追踪USB中断与tasklet的触发源头
EHCI控制器频繁触发中断是tasklet暴增的直接原因,得搞清楚是设备本身的问题还是驱动配置的问题:
- 用
perf工具抓一下USB相关的中断和tasklet调度情况:
跑个几分钟USB操作后,用perf record -e irq:irq_handler_entry,irq:irq_handler_exit,tasklet:tasklet_schedule -gperf report查看调用链,重点看ehci_irq这类EHCI驱动函数的调度频率,确认是不是每次USB传输都在触发中断和tasklet。 - 也可以查看EHCI控制器的PCI寄存器状态,找中断触发的具体原因:
看输出里的lspci -vvv -s $(lspci | grep EHCI | awk '{print $1}')Capabilities部分,有没有异常的中断标志位一直被置位,比如持续的“传输完成中断”或者“错误中断”。
3. 排查EHCI驱动的tasklet泄漏问题
老版本的EHCI-PCI驱动(尤其适配这类legacy硬件的)可能存在tasklet调度后未正确回收的bug,导致tasklet被重复调度或者处理失败:
- 先查内核日志里的USB相关错误:
重点找dmesg | grep -i usbehci_hcd相关的警告或报错,比如传输失败、控制器重置、tasklet调度超时之类的信息,这些都可能是泄漏的线索。 - 如果你的内核版本比较老,建议升级到对应主线的长期支持版本(比如5.4、6.1系列),很多老驱动的tasklet泄漏问题已经被社区修复了。
4. 检查内存压力对tasklet处理的影响
你的设备只有1GB内存,USB操作时如果内存不足,会导致内核无法及时分配tasklet所需的资源,进而让tasklet一直处于待调度状态,计数持续上涨:
- 用
top或vmstat监控USB操作时的内存使用:
看vmstat 1si(swap in)和so(swap out)列是不是持续非零,或者free内存是不是快耗尽了。如果是内存不够,尝试关闭其他后台进程,或者临时加内存测试。
5. 验证USB外设的兼容性问题
有时候是外设本身的问题,比如损坏的U盘、兼容性差的USB设备,会持续发送无效数据包,逼得控制器频繁触发中断:
- 换几个不同的USB设备试试(比如大厂的U盘、普通USB鼠标),看tasklet计数是不是依然疯涨。
- 如果只有特定设备触发问题,那就是该设备和EHCI控制器不兼容,可以试试在BIOS里调整USB模式(比如关闭EHCI,改用UHCI/OHCI,不过会牺牲点性能),或者直接换设备。
从你的输出数据来看,CPU3的IRQ23计数(141万+)和TASKLET计数(116万+)高度对应,说明绝大多数tasklet都是USB中断触发的。优先从中断亲和性和驱动bug这两个方向入手排查,应该能快速找到原因。
内容的提问来源于stack exchange,提问作者Raxesh Oriya
相关产品推荐
相关产品推荐

