Linux “entry\u SYSCALL64\u slow\u path”和“entry\u SYSCALL64\u fast\u path”之间的区别`

Linux “entry\u SYSCALL64\u slow\u path”和“entry\u SYSCALL64\u fast\u path”之间的区别`,linux,linux-kernel,system-calls,Linux,Linux Kernel,System Calls,我们知道系统调用将在中调用函数entry\u SYSCALL\u 64。当我阅读源代码时,我发现在准备寄存器之后有两种不同类型的调用,一种是entry\u SYSCALL64\u slow\u path,另一种是entry\u SYSCALL64\u fast\u path。你能说出这两个函数之间的区别吗?在进入entry\u SYSCALL\u 64时,Linux将: 交换gs以获取每cpu参数 根据上述参数设置堆栈 禁用IRQ 在堆栈上创建一个部分结构。这将保存调用方上下文 如果当前任务设置

我们知道系统调用将在中调用函数
entry\u SYSCALL\u 64
。当我阅读源代码时,我发现在准备寄存器之后有两种不同类型的调用,一种是
entry\u SYSCALL64\u slow\u path
,另一种是
entry\u SYSCALL64\u fast\u path
。你能说出这两个函数之间的区别吗?

在进入
entry\u SYSCALL\u 64
时,Linux将:

  • 交换
    gs
    以获取每cpu参数
  • 根据上述参数设置堆栈
  • 禁用IRQ
  • 在堆栈上创建一个部分结构。这将保存调用方上下文
  • 如果当前任务设置了
    \u TIF\u WORK\u SYSCALL\u条目
    \u TIF\u ALLWORK\u掩码
    ,则它将进入慢速路径
  • 否则,请输入快速路径
  • \u TIF\u WORK\u SYSCALL\u条目
    定义为注释,说明:

    \u TIF\u ALLWORK\u MASK
    似乎没有为x86定义,MIPS的定义带有一条注释,说明:

    快车道 Linux将:

  • 启用IRQ
  • 检查系统调用号是否超出范围(注意,
    pt_regs
    结构已使用
    ENOSYS
    rax
    的值创建)
  • 通过间接跳转分派到系统调用
  • 将系统调用的返回值(
    rax
    )保存到堆栈上
    pt_regs
    中的
    rax
  • 再次检查是否为当前任务设置了
    \TIF\u ALLWORK\u MASK
    ,如果设置了,它将跳转到慢速返回路径
  • 恢复调用方上下文并发出一个
    sysret
  • 慢返回路径
  • 将之前未保存的寄存器保存到
    pt_regs
    rbx
    rbp
    r12
    -
    r15
  • 调用
    syscall\u return\u slowpath
    ,已定义
  • 请注意,点2最终将调用
    跟踪系统退出

    慢路
  • 将之前未保存的寄存器保存到
    pt_regs
    (见上文)
  • 调用
    do\u syscall\u 64
    ,已定义
  • 第2点将调用
    syscall\u trace\u enter


    因此,慢与快的路径与
    ptrace
    有关。我还没有深入研究代码,但是如果调用方不需要
    ptrace
    ,我想整个机器都会被跳过。

    这确实是一个重要的优化。

    它与ptrace有关。如果进程被跟踪或步进,或者syscall仿真Linux将保存一些额外的regs并调用syscall处理程序。否则,它只从汇编代码中调用处理程序。我从来没有探究过这些差异。你好,谢谢你的回复,非常清楚。我还有一个问题,有没有方便的方法一步一步地调试代码,以便更深入地了解它?@tyChen是的,请看。不过,我从来没有这样做过。GDB甚至还有图形前端。
    /*
     * work to do in syscall_trace_enter().  Also includes TIF_NOHZ for
     * enter_from_user_mode()
     */
    
    /* work to do on any return to u-space */