【问题标题】:In multi-core machine, Linux OS, when process scheduler will migrate one process to another cpu在多核机器,Linux 操作系统中,当进程调度器将一个进程迁移到另一个 cpu 时
【发布时间】:2014-06-09 04:56:41
【问题描述】:

在我的rss为65G的程序中,调用forksys_clone->dup_mm->copy_page_range会消耗2秒以上。在这种情况下,一个 cpu 在执行 fork 时将 100% sys,同时一个线程在 fork 完成之前无法获得 cpu 时间。该机器有 16 个 CPU,其他 CPU 空闲。

所以我的问题是一个 cpu 忙于 fork,为什么调度程序不将等待这个 cpu 的进程迁移到其他空闲 cpu?一般来说,调度程序何时以及如何在 cpu 之间迁移进程?

我搜索了这个网站,现有的帖子无法回答我的问题。

【问题讨论】:

  • 为什么你认为这个其他线程正在挨饿?可能是它在某个资源/内存锁上休眠,在 fork 期间不可用。
  • 抱歉,我的描述不清楚。实际上,wait-cpu 线程是我的 IO 线程,它从客户端发送/接收包,在我的观察中,包始终存在,但 IO 线程无法接收它。在 systemtap 的帮助下,我发现 IO 线程无法获得 CPU 时间。我可以找到一个 100% sys(do sys_clone) 的 cpu,同时另一个 cpu 处于空闲状态。
  • sys_clone 可能会在执行dup_mmpi_lockmm->mmap_sem)时阻塞某些内核互斥体,并且您的 I/O 线程需要锁定相同的互斥体/信号量。尝试为第二个线程获取堆栈(内核或用户)...(您确定只有 fork 可能对您有用吗?尝试 vfork+exec = posix_spawn,如果在 fork 之后有 exec。)
  • 雷蒙德,有更新吗?

标签: linux fork scheduler multicore


【解决方案1】:

rss为65G,调用fork时,sys_clone->dup_mm->copy_page_range会消耗2秒以上

在执行fork(或clone)时,应将现有进程的 vmas 复制到新进程的 vmas 中。 dup_mm function (kernel/fork.c) 创建新的 mm 并进行实际复制。没有直接调用copy_page_range,但我认为,static function dup_mmap 可能内联到dup_mm,它可以调用copy_page_range

dup_mmap 中有几把锁,新的mm 和旧的oldmm 都有:

356         down_write(&oldmm->mmap_sem);

在获取mmap_sem 读取器/写入器信号量后,所有 mmap 都有一个循环来复制它们的元信息:

381         for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) 

只有在循环之后(在你的情况下它很长),mmap_sem 才被解锁:

465 out:
468         up_write(&oldmm->mmap_sem);

虽然写入器关闭了 rwlock mmap_sep,但没有任何其他读取器或写入器可以对 oldmm 中的 mmap 执行任何操作。

一个线程在 fork 完成之前无法获得 cpu 时间 所以我的问题是一个cpu忙于fork,为什么调度程序不将等待这个cpu的进程迁移到其他空闲cpu?

您确定,其他线程已准备好运行并且不想对 mmap 做任何事情,例如:

  • 映射新的东西或取消映射不需要的东西,
  • 扩大或缩小其堆 (brk),
  • 不断增长它的堆栈,
  • 页面错误
  • 或许多其他活动...?

其实wait-cpu线程是我的IO线程,它从客户端发送/接收包,在我观察中,包一直存在,但是IO线程收不到。

您应该检查您的 wait-cpu 线程堆栈(甚至还有 SysRq),以及 I/O 类型。 mmaping 文件是 I/O 的变体,将在 mmap_sem 上被 fork 阻塞。

您还可以检查 wait-cpu 线程的“最后使用的 CPU”,例如在top 监控实用程序中,通过启用线程视图(H 键)并将“上次使用的 CPU”列添加到输出(fj 在旧版本中;f 滚动到 P,输入新版本)。我认为您的 wait-cpu 线程可能已经在另一个 CPU 上,只是不允许(未准备好)运行。

如果你只使用 fork 来制作exec,它可以用于:

  • 要么切换到vfork+exec(或者只是切换到posix_spawn)。 vfork will suspend 您的进程(但 may not suspend your other threads, it is dangerous)直到新进程执行 execexit,但执行可能比等待复制 65 GB 的 mmap 更快。
  • 或不从具有多个活动线程和多 GB 虚拟内存的多线程进程中执行 fork。您可以创建小型(没有多 GB mmaped)辅助进程,使用 ipc 或套接字或管道与其通信,并要求它分叉并做任何您想做的事情。

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2014-04-16
    • 2018-07-01
    相关资源
    最近更新 更多