多核CPU下绑定某个中断到指定的CPU

Posted 美丽的时光机器

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多核CPU下绑定某个中断到指定的CPU相关的知识,希望对你有一定的参考价值。

前言:标题谈的是多核CPU下绑定某个中断到指定的CPU的方法,但是实际工作中,这个方法可以适配很多种数据接收的情况,所以就记录一下自己之前工作上遇到的具体某一个问题以及解决方法。

  之前有一个项目,需要串口接收大量的数据,硬件平台采用的是NXP的I.MX6D系列芯片,双核CPU。实际发现,在接收数据的时候,总是出现数据接收不及时的情况,分析了一下官方提供的Linux内核代码,默认使用的是串口中断的方式接收。产品运行的时候,1ms会上传64字节的数据到I.MX6的串口,也就是说单位时间内串口的中断量非常的大,将Linux系统的节拍提升到1000Hz也没有改善情况。实际上我在两小时内大约统计到了亿次级别的中断量。调试过程中,在板级文件中配置串口使用DMA功能,发现3.0.35版本的内核DMA功能是有问题的,实际数据接收的效果会出现很明显的数据丢失情况,效果还不如直接用串口中断接收的好。所以问题就在于怎样才能让中断接收更及时(PS:在刚开始分析这个问题的时候,我甚至怀疑是tty读取数据的速度跟不上uart中断接收数据造成的,然后去改动NXP官方的驱动,虽然数据接收有改善的现象,但是实际问题并没有得到解决)。

       频繁的产生硬件中断,是一件非常消耗CPU的事情,但是实际上并没有出现CPU以及系统跑不动的现象,但是系统能跑动并不代表着中断就能及时响应,因为Linux系统不是实时的操作系统。通过top命令查看,系统运行情况一切都正常。后来一想,双核CPU,我是不是两颗CPU都真正使用到了呢?会不会出现虽然是双核CPU,但是只跑单核的情况?带着这个问题,我查看了一下系统的中断分配情况(PS:为什么不是top命令来查看呢?我解释一下,当时使用top命令,确实是发现两颗CPU都是有4%左右的使用率,而且也在实时变动,干扰了我的判断,所以看底层最直接),具体的命令是#cat /proc/interrupts,这个命令会列出当前系统存在的中断,以及该中断是在哪一颗CPU上。运行命令后我发现,虽然是双核CPU,但是所有的中断(包括串口、SPI、I2C、SDMA、Timer等)都集中在了CPU0,也就是说实际上CPU1啥事儿都没干,CPU0在忙着中断接收数据,CPU1在一旁围观。这种情况,我不知道是官方提供的Linux内核对多核CPU适配不够好,还是需要实际使用者自己安装第三方工具来管理CPU中断资源的分配。

  运行# /etc/init.d/irqbalance stop 发现我们产品的根文件系统根本没有这个工具,因此初步分析是我们自己做的根文件系统没有安装SMP负载均衡相关的管理工具导致的所有中断都集中在CPU0来处理的情况。所以针对实际使用出现数据接收不及时以及丢包的情况,我将串口接收数据的中断绑定到了空闲的CPU1(其他跟数据接收不紧要的中断保持在CPU0来响应),具体命令是:# echo "2" > /proc/irq/62/smp_affinity,62这个数字就是串口的中断号。运行前面的命令之后,再次#cat /proc/interrupts,发现该串口中断已经成功指定在CPU1来执行,实际数据接收不及时的问题得到解决。

  总结:中断响应不及时这样的问题,影响因素有很多,比如系统本身就不是实时性的,存在很多的系统调度。再者I.MX6平台的串口使用中断接收数据,在中断的上半部将数据push到tty中,实际上tty是使用工作队列来接收数据的(tty注册了工作队列),难免会有调度上的不及时。而串口开启了DMA的话,也是在驱动probe阶段初始化了一个工作队列,将数据接收的工作放到了中断下半部来执行,进而push数据到tty(又有一个工作队列),相当于是如果使用DMA的话,数据接收流程就有了两个工作队列,也就造成了使用DMA的效果比串口中断接收还要更差(目前是我自己的理论分析,如果有错还请大家指出,谢谢)。同时中断处理函数还频繁使用了自旋锁,这也会导致中断响应变慢的情况,今后做系统优化,可以往这方面考虑。

以上是关于多核CPU下绑定某个中断到指定的CPU的主要内容,如果未能解决你的问题,请参考以下文章

记录一个多核CPU负载不均衡问题(动态绑定进程到指定cpu:taskset -pc $CPU $PID)

linux 将进程或者线程绑定到指定的cpu上

linux 多进程绑定问题

面试官:Java如何绑定线程到指定CPU上执行?

如何关闭linux smp中断

Linux的中断