IO操作期间的用户空间线程延迟

Pat*_*all 7 linux multithreading scheduling linux-kernel embedded-linux

我正在使用嵌入式Linux内核进行项目,并且在访问闪存时遇到了线程延迟问题.

我的应用程序是多线程的,有些线程必须在不到500毫秒的时间内完成给定的任务.问题是这些线程有时会在超过1秒的时间内"冻结",并且我的执行时间超过500毫秒.

这种行为似乎与闪存写入有关,因为它也发生在我从shell执行"dd"命令以在闪存中连续写入时.

我尝试了各种配置:

  • 增加了我的实时线程的优先级:SCHED_RR,优先级= 55
  • 更改了IO调度程序:deadline => cfq(更好:15分钟后失败,而不是3分钟).

通过使用ftrace工具,我可以看到,在"冻结"时间内,一些线程和进程仍在运行,其他任务之间有很多"空闲"任务时间(空闲任务时隙持续时间> 20ms):

  • 2个网络线程(SCHED_RR,优先级= 50)
  • dd过程

我不明白:

  • 为什么所有其他任务在所有这些时间都被"锁定"(有时在请求互斥锁时,有时在计算简单的16位CRC时).
  • 为什么在此期间使用ftrace(在sched事件之间)可以看到如此多的空闲时间.
  • 为什么更高的应用程序线程优先级无法解决问题.

我怀疑与内核中的IO管理有关的东西,好像内核抢占了每个非IO线程,以便完成与IO相关的所有工作(网络,文件......).

有没有人知道可能导致这种延迟的原因?

我的内核设置:

  • Linux内核版本2.6.39
  • 已启用抢占选项
  • 滴答
  • HZ = 1000
  • CFQ调度程序(默认设置)

编辑:

由于我不是专家,我与您分享ftrace capture(与kernelshark一起查看):https://drive.google.com/file/d/0B6pJb20-D0D2NHZBUHJVRlV0aDg/view ? usp = sharing

也许它可以帮助你了解我的系统上发生了什么.

在这个捕获中,我使用外部"dd"命令再现了我在名义条件下应用程序遇到的类似行为.

在时间戳上,"洞"("冻结")是(不再是我的应用程序中的自定义ftrace标记):

  • 开始于:469.118370
  • 结束:469.802940

另一个小"洞"

  • 开始于:469.807644
  • 结束:469.952975

blu*_*ift 2

我认为这可能是因为内核决定它必须刷新一些文件系统元数据,或者执行其他文件系统内务处理,并且必须停止您的进程,直到它完成足够的工作。

我遇到了类似的问题,并使用多线程和用户态缓冲区来吸收停顿。在这里查看我的旧问题和答案