tcp rev + tcp syn send
1 | __dev_xmit_skb (\root\codes\kernel-dev\linux\net\core\dev.c:3760) |
1 | static inline struct sock *__inet_lookup(struct net *net, |
到TCP层后,skb需要转换成 struct sock
,从 kernel 协议栈查找skb -> struct sk 映射
1 | struct sock *__inet_lookup_established(struct net *net, |
sock#sk_data_ready 回调通知
注意看左侧callstack,协议栈收到数据后
- tcp_rcv_established
- syn rcv 后进入 established 状态
- tcp_queue_rcv
- __skb_queue_tail
- tcp_data_ready
- tcp_data_queue
-
tcp_queue_rcv
- __skb_queue_tail
-
tcp_data_ready
struct sock#sk_data_ready
默认是sock_def_readable
唤醒
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15void sock_def_readable(struct sock *sk)
{
struct socket_wq *wq;
trace_sk_data_ready(sk);
rcu_read_lock();
wq = rcu_dereference(sk->sk_wq);
// CC-NET-TCP 唤醒 sk 的 waiters
if (skwq_has_sleeper(wq))
wake_up_interruptible_sync_poll(&wq->wait, EPOLLIN | EPOLLPRI |
EPOLLRDNORM | EPOLLRDBAND);
sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
rcu_read_unlock();
}
-
如何唤醒accept syscall
tcp server运行过程
bind: 分配 port
listen: Move a socket into listening state.
blocking accept: thread blocking to require new socket
1 | bind(); |
1 | const struct proto_ops inet_stream_ops = { |
注册唤醒回调
accept blocking
inet_csk_accept
prepare_to_wait_exclusive
1 | bool |
如何唤醒epoll等异步回调机制
未完待续…