目标:
分析 kernel 驱动收到后skb
1. 如何唤醒epoll callback?
2. accpet syscall 如何从listener socket spawn 子 socket?
一个极简epoll server程序(无法编译,只说明流程)
1 | // 创建listener socket |
epoll 注册 wake callback
直接看追踪的call stack
epoll_ctl(ep, EPOLL_CTL_ADD, child, &event)
: called from epoll_ctl syscall- ep_insert:
1 | // ep_insert |
把 ep_ptable_queue_proc
放入 _qproc
,在接下来的 poll_wait
调用
1 | static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc) |
- ep_item_poll
- 如果fd不是file epoll,那么通过vfs定向给具体实现
- vfs_poll: virtual fs poll,call
file->f_op->poll(file, pt);
- sock poll: 文件底层对应的是sock
- unix_poll: address family unix poll
- sock_poll: socket 文件类型的poll
- tcp_poll: tcp socket poll 实现
- sock_poll_wait
- poll_wait
- ep_ptable_queue_proc
1. ep_poll_callback 添加到 wait queue
struct file 转换成 struct sock
struct sock
有最核心弄明白的点在于skb buff 如何转换成 struct socket
结构
1 | static __poll_t sock_poll(struct file *file, poll_table *wait) |
sock_poll将 file->private_data
转换成 struct sock
,从而调用到epoll的socket实现
Why does the Linux kernel have `struct sock` and `struct socket`? - Stack Overflow
sock wake epoll callback
唤醒ep->wq
ep_poll_callback