我已经为LinuxV4.1.15(非PCIe )创建了一个带有一个IRQ的PREEMPT_RT驱动程序,该驱动程序是由一个PREEMPT_RT生成的。我的ISR是:
static irq_handler int_handler(int irq, void* dev_id, struct pt_regs* regs)
{
spin_lock(&my_lock);
msi_counter++;
spin_unlock(&my_lock);
return (irq_handler_t) IRQ_HANDLED;
}MSI是从FPGA (旋风V)每300我们发送一次,我的ISR非常快地被触发,并且不被失败地处理(延迟<5 us)。问题是,大约每3s(具有相对较小抖动的3s),我的ISR的延迟跃升到大约1.5ms到2ms;这是通过改变我的ISR,将一个值写回FPGA并从FPGA监视一个引脚来测量的。spin_lock for msi_counter仅在代码中的另一个位置使用,但只用于减少计数器,其方式与ISR递增计数器的方式相同。我使用的iMX6四核CPU在1 GHz和系统是使用一个赤裸的Yocto图像(核心图像最小),所以没有真正的运行在CPU上。CPU连接到的唯一其他硬件是以太网,但是发送的数据很少,数据更新的频率超过3秒。
问题:
其他信息:
request_irq()的标志更改为IRFQ_NO_SUSPEND | IRFQ_NO_THREAD,以及其他值,似乎没有什么可以解决这种周期性延迟增加的问题。cat /proc/interrupts时,它显示只有核心0(四个核中的第一个)是运行我的ISR的唯一核心。我不知道这是否有任何意义,但我认为这是值得一提的。最后解决办法:
我创建了一个PREEMPT_RT内核映像并创建了带有标志IRQF_NO_SUSPEND | IRQF_NO_THREAD | IRQF_PERCPU的ISR request_irq()。我还用一个spin_lock取代了atomic_t,最大的改进来自于PREEMPT_RT。我现在的平均潜伏期是12倍。
发布于 2017-02-11 05:59:45
您可以在spin_lock前后添加一个计时器。如果时差超过某一阈值,则增加另一次。您可以数一数spin_lock造成延迟的频率。如果它匹配您看到延迟的频率,那么您可以尝试找出为什么其他锁持有人不释放它。它能在握着锁的时候被抢占吗?
另一件要研究的事情是,spin_lock本身是否应该花很长时间才能有一个低但不是零的概率?
https://stackoverflow.com/questions/42172316
复制相似问题