linux - `entry_SYSCALL64_slow_path` 和 `entry_SYSCALL64_fast_path` 的区别
问题描述
我们知道系统调用会调用entry_64.Sentry_SYSCALL_64
中的函数。当我阅读源代码时,我发现在准备寄存器后有两种不同类型的调用,一种是,另一种是。你能说出这两个函数的区别吗?entry_SYSCALL64_slow_path
entry_SYSCALL64_fast_path
解决方案
进入entry_SYSCALL_64
Linux 后将:
- 交换
gs
以获取每个 cpu 的参数。 - 从上面的参数设置堆栈。
- 禁用 IRQ。
- 在堆栈上创建部分结构。
pt_regs
这会保存调用者上下文。 - 如果当前任务有
_TIF_WORK_SYSCALL_ENTRY
或已_TIF_ALLWORK_MASK
设置,则进入慢速路径。 - 否则输入快速路径。
_TIF_WORK_SYSCALL_ENTRY
在此处定义,并带有注释说明:
/* * work to do in syscall_trace_enter(). Also includes TIF_NOHZ for * enter_from_user_mode() */
_TIF_ALLWORK_MASK
似乎没有为 x86 定义,这里有 MIPS 的定义,并带有注释说明:
/* work to do on any return to u-space */
快速路径
Linux 将:
- 启用 IRQ。
- 检查系统调用号是否超出范围(请注意,该
pt_regs
结构已使用ENOSYS
的值创建rax
)。 - 通过间接跳转调度到系统调用。
rax
将系统调用的返回值 ( ) 保存rax
到pt_regs
堆栈中。- 再次检查
_TIF_ALLWORK_MASK
当前任务是否设置了,如果是则跳转到慢速返回路径。 - 恢复调用者上下文并发出
sysret
.
慢回程
- 将之前未保存的寄存器保存在
pt_regs
(rbx
,rbp
,r12
-r15
) 中。 - 调用
syscall_return_slowpath
,定义在这里。
请注意,第 2 点最终会调用trace_sys_exit
.
慢路
- 将之前未保存的寄存器保存在
pt_regs
(见上文) - 调用
do_syscall_64
,定义在这里。
第 2 点将调用syscall_trace_enter
.
因此,慢速与快速路径与ptrace
. 我还没有深入研究代码,但我想如果ptrace
调用者不需要,整个机器都会被跳过。
这确实是一个重要的优化。
推荐阅读
- flutter - Flutter SocketException (SocketException: OS Error: Connection denied, errno = 111, address = localhost, port = 51500)
- javascript - 对于 javascript 中的“onevent change”,我试图访问函数的参数,但收到错误为“未定义”
- matlab - 存储来自 MATLAB for 循环的值,类似于 Python 字典
- android - Firebase + Proguard/R8
- lorawan - 如果我想每 100 毫秒传输 50 字节的有效负载,LoRaWAN 是一个很好的解决方案吗?
- java - 如何在android中使用FCM向单个设备发送数据消息
- docker - Windows 的 $(which docker) 相当于什么?
- c - 如何在 C 中巧妙地将 32 位以上的数字(38 位)转换为 32 位系统上的字符串
- javascript - Javascript - 添加与对象键相关的所有成本的总和
- sql - 将 varchar 类型的列中的特定单元格转换为 nvarchar