KVM物理机上,vhost_net模块会为每个VM创建了两个内核线程,一个替VM发送数据到外面,另外一个替VM接收数据
- 当VM有数据发送的时候,发送线程就会把数据取出=>然后放到tun虚拟网卡=> tun处理逻辑是:通过模拟真实网卡(backlog 设备)把自己挂在NAPI上=》然后等待软中断来取出=》然后向上到二层网桥=>然后通过真实网卡发出去,如下图:
vm virtio driver
||向下
数据从VM发送到外面:kthread=》handle_tx(vhost_net)=》 vhost_get_vq_desc(vhost_net)=》tun_sendmsg(tun)=》tun_get_user(tun) =》netif_rx_ni(协议栈)=》插入backlog NPAI设备加入poll_list=》触发软中断net_rx_action=>process_backlog(backlog的poll处理函数)=>netif_receive_skb=>br_handle_frame=>进入tcp/ip协议栈
- 外网有数据要发往VM的时候,数据到物理网卡后=>触发硬件中断=>使用NAPI机制等待轮询=>在软中断在把数据从网卡中取出=>网桥=>tun虚拟网卡xmit=>xmit的处理逻辑:把数据发给vhost_net接收线程=>VM
如下图:
数据从外面接收到VM:kthread=》handle_rx(vhost_net)=》 tun_recvmsg(tun)=》tun_put_user(tun) =》vhost_add_used_and_signal_n(vhost)
^
||向上
tun_net_xmit(转发到虚拟网卡上)
||
dev_hard_start_xmit
||
dev_queue_xmit
||
br_flood_forward/br_forward/br_pass_frame_up(桥接转发)
||
pcnet32_rx => __netif_receive_skb_core=》br_handle_frame=》br_handle_frame_finish
数据到物理网卡后,触发硬件中断=》把nic放入轮询设备list=》irq_exit=》__do_softirq=》net_rx_action=》napi_poll=》pcnet32_poll=》