- 论坛徽章:
- 6
|
回复 21# eexplorer
tcp_recvmsg -> install ucopy reader -> no data so call sk_wait_data() -> set task to TASK_INTERRUPTIBLE -> sk_wait_event -> release_sock
If at this time, we received a skb in softirq which is added into backlog queue (since lock is owned by user), then we call into __release_sock(sk).
In __release_sock, we call into sk_backlog_rcv() -> tcp_v4_do_rcv-> tcp_rcv_established, 这个时候 tp->ucopy.task == current && socked_owned_by_user(sk) 都满足了。
因为在sk_wait_data()里已经把task设为INTERRUPTIBLE了,所以在tcp_rcv_established里需要把task重新设为RUNNING,因为在__release_sock里会调用cond_reschedule_softirq(),如果不设成RUNNING的话,current_task 就会被schedule出去,运行不了了。
所以,tcp_recvmsg就是在这里主动的等skb (通过cond_sched_softirq,enable softirq后,把自己schedule出去,但是需要自己一直保持RUNNING的状态),softirq把skb加到backlog里 (tcp_v4_rcv ),由tcp_recvmsg主动调tcp_v4_do_rcv()来处理。
Cool, man!
|
|