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

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

我的应用程序是多线程的,一些线程必须在不到500毫秒内完成给定的任务。 问题在于这些线程有时会在1秒钟内“冻结”,而我的500毫秒执行时间很好。

这种行为似乎与闪存写入有关,因为它也发生在我从外壳执行“dd”命令以连续写入闪存时发生。

我尝试了各种配置:

  • 增加了我的实时线程的优先级:SCHED_RR,优先级= 55
  • 更改了IO调度程序:deadline => cfq(更好:在15分钟而不是3分钟后发生故障)。
  • 通过使用ftrace工具,我可以看到,在“冻结”期间,一些线程和进程仍在运行,其他任务(空闲任务时隙持续时间> 20ms)之间有很多“空闲”任务时间:

  • 2个网络线程(SCHED_RR,优先级= 50)
  • dd过程
  • 我不明白:

  • 为什么所有其他任务都在这段时间内“锁定”(有时需要互斥锁,有时需要计算简单的16位CRC时)。
  • 为什么在这段时间内ftrace(调度事件之间)可以看到这么多的空闲时间。
  • 为什么更高的应用程序线程优先级不能解决问题。
  • 我怀疑某些东西与内核中的IO管理有关,就像内核抢占每个非IO线程以完成与IO(网络,文件...)相关的所有工作一样。

    任何人都知道什么可能会导致这种延迟?

    我的内核设置:

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

  • 编辑:

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

    也许它可以帮助你看到我的系统上发生了什么。

    在这个捕获中,我使用外部“dd”命令重现了我在名义条件下遇到的类似行为。

    “洞”(“冻结”)是(在我的应用程序没有更多的自定义ftrace标记)在时间戳:

  • 开始:469.118370
  • 结束:469.802940
  • 另一个小“洞”

  • 开始:469.807644
  • 结束:469.952975

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

    我有类似的问题,并使用多线程和一个用户级缓冲区吸收摊位。 看到我的旧问题,并在这里回答。


    我更新了这个主题的状态:我们认为我们找到了锁的根本原因。

    我的公司聘请了一位Linux专家2天。

    感谢他,我们发现:

    这些锁是由内核完成数据刷新时阻止所有闪存访问的事实造成的。

    特别是我们的记录器模块(用于时间戳...),它调用syslog()函数。

    但是,即使syslogd守护进程是访问闪存的真实进程,这个syslog()函数也会阻止该进程...(我们怀疑用于syslog通信的unix套接字阻塞,直到资源可用为止,如写入bash pipe'|'大量的日志到位于闪存中的文件)。

    解决方案是将实时线程与其他线程之间的所有访问权限分开,并通过对独立线程执行日志/闪存访问(将非阻塞自定义消息队列作为通信项目)

    它似乎有效!

    我以前没有读过blueshift答案,但似乎他是对的;-)

    链接地址: http://www.djcxy.com/p/84883.html

    上一篇: Userspace Thread Latency during IO operations

    下一篇: How can I find out what is preventing a Linux task from being scheduled?