如何强制Linux内核“冻结”(或几乎冻结)几百毫秒


17

我们正在非实时内核(CentOS 6)上运行实时进程,并且这种情况可能不会改变。

我们有一个流媒体视频应用程序,它需要一个定制的FPGA每次连续1.5小时连续提供约500 MB / s的PCIe流量。该应用程序运行良好-大多数时候。但是,在某些情况下,内核似乎一次最多只能停止响应对PCIe或内存请求的服务,最长可达500毫秒。这似乎是在来自另一个线程的突发文件IO期间发生的。我发现无法通过在主应用程序运行时仅从用户空间进行大量虚拟文件IO来尝试复制此问题。

有没有一种方法可以强制(模拟)Linux内核的全局“冻结”(特别是停止PCIe或所有DDR3内存访问等操作),以便我们可以重现此问题?

目前,我们已将最多10毫秒的缓冲实现到内部FPGA存储器中,但这还不够。我们可以缓冲到FPGA DDR3,然后转储到主机,但是我们需要一种在胁迫下测试此新功能的方法。

我们不希望内核永久冻结或锁定。我们希望能够设置时间间隔。

我正在寻找一些方法来/proc/sys/vm临时编写魔术值,这些临时值会使系统虚拟爬网,然后在几百毫秒后恢复原状,但是寻找打破它的可能方法的数量并不适合像我这样的新手(https://www.kernel.org/doc/Documentation/sysctl/vm.txt)。也许有些numactl魔术?


我的直觉是,这需要编写内核模块。您需要以某种方式冻结所有CPU上的所有线程,并安排在计时器中断时重新启动。
吉尔(Gilles)'所以

我不想冻结线程,我想冻结内核!我的意思是,我想防止在短时间内访问硬件(内存和/或PCIe和/或磁盘)。如果那行不通,我不介意使事情变得非常不优化,禁用L1缓存等。我只是不知道该怎么做。
Mark Lakata 2014年

1
啊,所以您不想冻结内核,只想冻结响应某些硬件的内核部分?同样,这也需要深入内核。
吉尔(Gilles)'所以

我不介意完全冻结内核,只要将硬件作为内核的一部分冻结即可。
马克·拉卡塔

1
事实证明,该问题与主机CPU刷新一些IO缓冲区(我们正在使用HDF5写入文件)时TLB抖动有关,并且这种TLB抖动导致协处理器也抖动,因为它是NUMA系统。我想我们现在需要的是在受控的时间内以编程方式导致TLB颠簸的可靠方法。
Mark Lakata 2015年

Answers:


9

进行快速测试的一种方法是使用启用了KGDB的内核,然后手动停止内核并进行测试,请参阅此链接

另一方面,我记得可能会导致您停顿的事情:

  • cpufreq,,cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency以ns为单位的值(我的AMD FX(tm)-8120八核处理器中为4000)应该不是问题,但请检查
  • 热调节CPU本身或电压调节器模块。
  • NAPI和/或繁重的网络流量
  • PCIe ASPM(cat /sys/module/pcie_aspm/parameters/policy
  • 目标设备(硬盘,NIC等)的缓冲区中的争用
  • PCIe总线中某些设备的固件中的错误(即使您不使用它),也可以尝试通过以下方法关闭电源: /sys/bus/pci/devices/$DEVICE/power/control

我可以使用kdb而不是kgdb这样做吗?我也从未用过。这是否像过去的Sun工作站上的“ Stop-A”命令序列?如果我只是快速执行SysRq-g,然后键入“ go”,是否很有可能不会破坏系统?(ref:kernel.org/pub/linux/kernel/people/jwessel/kdb/…
Mark Lakata 2014年

1
也许您将能够使用kdb。请注意,它应该可以与USB连接的键盘一起使用,但是请尽量使用一个PS / 2,以防万一。这是一个非常低级的调试器(内核),因此,一如既往地保留备份,如果备份失败,则可以保留两个部分:)。
JorgeNerín2014年

在诉诸于内核之前,我首先尝试为可能正在使用总线的PCIe设备卸载未使用的内核模块(最著名的是图形驱动程序),然后从系统中物理移除设备或关闭它们的电源。PCIe 1.0 x1的带宽为250MB / s,PCIe 2.0 x1的带宽高达500MB / s,原始设备和目标设备是否都可以不受中断地自由接受这样的持续速率,还是它们有更多的通道来提供更多的净空?
JorgeNerín2014年

延迟的另一个可能来源可能是某些设备的某些ACPI电源管理处理程序,或者甚至是某些等待外部事件的SMM CPU处理程序。
Franki 2014年

2

我们能否详细了解您的应用如何与FPGA通信?是从FPGA读取缓冲区的应用程序,还是向内核发送中断的FPGA(如网卡)?

我希望它可以在/ dev中打开一个块/字符,然后与其通信。这意味着它使用驱动程序在应用程序和/ dev / XXX文件之间进行通信。

我想有输出: cat /proc/interrupts; lsmod;ls -al /dev/yourmod

这是想法:

  • 如果是中断驱动的,则可以将CPU PIC设置为禁用相应的IRQ,然后重新启用它。这将导致卡的每个请求都被忽略(没有卡知道)。
  • 如果这就像读取缓冲区,则可以:
    • 将您的应用程序置于睡眠状态,这样就不会读取来自FPGA的数据,并且缓冲区将填满,然后唤醒您的应用程序并继续读取。
    • 使用“ crash”或“ kgdb”将“ read”值更改为“ noop”几秒钟,然后将其设置回默认功能。

请提供您可能会觉得有用的所有信息。


FPGA确实将DMA写入主机存储器,在这些中断期间,FPGA无法写入主机存储器,因此其内部FIFO备份。主机进程有一个基于消息的接口(通过PCIe发生),但是我敢肯定这没有涉及。为了进行验证,我基本上需要一种方法来禁止FPGA硬件写入主机内存几百毫秒。我不想解决内存问题,但是我想确保我们在FPGA上的实现能够处理内存中断(最长1000毫秒)。
Mark Lakata 2014年

好的,如果使用的是DMA,则可以查看一下: Claim_dma_lock()和dma_disable()上的kernel.org/doc/Documentation/DMA-ISA-LPC.txt。但是,您需要知道FPGA使用的地址。
Adrien M.

1

不确定是否有帮助。但是,如果您可以编写一个调用suspend另一个设备的内核模块功能的内核模块,则可能会这样做。

可以根据头文件http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/pci.h#L479挂起每个PCI设备

例如,这里是Intel e1000 NIC的挂起功能http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/net/e1000e/netdev.c#L4643

我记得,该功能主要在系统进入休眠状态时使用,设备驱动程序需要保存当前的运行状态并自行关闭。


谢谢,但我认为这行不通。我真的不想挂起设备,内核告诉设备为休眠做准备。我希望内核在不知道特定设备(在本例中为FPGA子板)的情况下(而不是较长的等待时间或超时)忽略 -或者我想停止所有SDRAM存储器的传输。
Mark Lakata 2014年

0

我认为您的思路是错误的。您的目标很明确。

方法不是停止其余过程,而是为您的主要过程提供接近实时的调度优先级。为此,请对您的重要用户空间进程使用nice

更困难的问题是PCIe中断处理,它位于内核空间中。

由于涉及硬件,因此您应该开始仔细研究主板上涉及的PCIe通道以及如何将其连接到特定的CPU插槽。

irqbalance通常在这里做得很好,但是您可以配置其行为以适合您的需求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.