当前位置: 首页 > news >正文

Virtio 驱动初始化数据收发流程详解

Virtio 驱动核心流程详解

一、整体架构概览

virtqueue
中断/通知
sk_buff
数据
前端驱动
后端设备
协议栈

二、初始化流程

1. 核心步骤
Linux KernelVirtio DriverVirtio Device设备发现(PCI/MMIO)读取设备ID特性协商(feature bits)配置virtqueues分配virtnet_info结构创建net_device对象设置DRIVER_OK状态注册网络设备预填充RX缓冲区Linux KernelVirtio DriverVirtio Device
2. 关键函数调用栈
virtnet_probe()├─ virtio_cread_feature()       // 特性协商├─ alloc_etherdev_mq()          // 创建net_device├─ virtnet_find_vqs()           // 初始化virtqueues│   ├─ virtio_find_vqs()│   └─ virtqueue_set_affinity()├─ register_netdev()            // 注册网络设备└─ virtnet_alloc_rx_buffers()   // 预填充接收缓冲区

三、数据发送流程(TX)

1. 核心流程
Network StackVirtio DriverVirtio BackendPhysical NICndo_start_xmit(skb)映射DMA区域添加描述符到TX virtqueuevirtqueue_kick()通知发送网络数据发送完成更新used ring发送中断通知处理TX完成中断回收sk_buff解除DMA映射Network StackVirtio DriverVirtio BackendPhysical NIC
2. 关键函数
// 发送入口
start_xmit(struct sk_buff *skb)├─ skb_to_sgvec()               // 创建分散/聚集列表├─ virtqueue_add_outbuf()       // 添加发送描述符└─ virtqueue_kick()             // 通知设备// 发送完成处理
skb_xmit_done(struct virtqueue *vq)├─ virtqueue_get_buf()          // 获取完成描述符├─ dma_unmap_single()           // 解除DMA映射└─ dev_consume_skb_any()        // 释放sk_buff

四、数据接收流程(RX)

1. 核心流程
Network StackVirtio DriverVirtio BackendPhysical NIC应用接收网络数据从RX virtqueue获取缓冲区DMA写入数据更新used ring发送中断通知调度NAPIvirtnet_poll()从used ring取描述符构造sk_buffnapi_gro_receive()补充新缓冲区virtqueue_kick()传递数据Network StackVirtio DriverVirtio BackendPhysical NIC应用
2. 关键函数
// 中断处理
virtnet_interrupt()└─ napi_schedule()             // 调度NAPI轮询// 接收处理
virtnet_poll(struct napi_struct *napi)├─ virtqueue_get_buf()         // 获取接收描述符├─ virtnet_receive_skb()       // 构造sk_buff├─ napi_gro_receive()          // 提交协议栈└─ virtqueue_add_inbuf()       // 补充新缓冲区

五、关键数据结构

1. virtio_device
struct virtio_device {struct device dev;             // 设备模型struct virtio_device_id id;    // 设备标识struct virtio_config_ops *config; // 配置操作struct list_head vqs;          // virtqueue列表u64 features;                  // 协商特性void *priv;                    // 驱动私有数据
};
2. virtqueue
struct virtqueue {struct list_head list;         // 设备链表void (*callback)(struct virtqueue *vq); // 回调函数const char *name;              // 队列名称struct virtio_device *vdev;    // 关联设备unsigned int index;            // 队列索引void *priv;                    // 私有数据struct vring vring;            // 虚拟环结构
};
3. vring (核心通信结构)
struct vring {unsigned int num;              // 描述符数量struct vring_desc *desc;       // 描述符表struct vring_avail *avail;     // 可用环struct vring_used *used;       // 已用环
};
4. virtnet_info (网络设备私有数据)
struct virtnet_info {struct virtio_device *vdev;     // virtio设备struct net_device *dev;         // 网络设备struct virtqueue *rvq, *svq;    // 接收/发送队列struct receive_queue *rq;       // 接收队列数组struct send_queue *sq;          // 发送队列数组u16 curr_queue_pairs;           // 活动队列对struct bpf_prog __rcu *xdp_prog; // XDP程序
};

六、性能优化机制

1. 批处理优化
高开销
减少通知次数
VRING_AVAIL_F_NO_INTERRUPT
单包处理
性能瓶颈
批量处理
吞吐量提升
延迟通知
降低中断频率
2. NAPI机制
// 混合中断与轮询
static int virtnet_poll(struct napi_struct *napi, int budget)
{while (packets < budget && (buf = virtqueue_get_buf(vq, &len))) {// 处理数据包packets++;}if (packets < budget) {napi_complete(napi);       // 退出轮询模式virtqueue_enable_cb(vq);    // 启用回调}return packets;
}
3. 零拷贝技术
接收零拷贝
发送零拷贝
数据拷贝
DMA直接访问
mmap
直接访问
固定映射
直接写入
驱动DMA区域
预注册内存
用户空间
驱动DMA区域
用户空间内存
物理网卡
传统方式
高CPU开销
零拷贝
CPU效率提升

七、错误处理机制

1. 队列满处理
netdev_tx_t start_xmit(...)
{if (virtqueue_full(vq)) {netif_stop_queue(dev);    // 停止协议栈入队return NETDEV_TX_BUSY;    // 通知重试}// ...正常发送...
}// 在完成中断中恢复
void skb_xmit_done(...)
{if (netif_queue_stopped(dev) && !virtqueue_full(vq)) {netif_wake_queue(dev);    // 唤醒协议栈}
}
2. 设备重置恢复
static void virtnet_reset(struct virtio_device *vdev)
{// 1. 停止所有数据传输virtnet_freeze_down(vdev);// 2. 重置设备状态virtio_reset_device(vdev);// 3. 重新协商特性virtio_negotiate_features(vdev);// 4. 重建virtqueuesvirtnet_del_vqs(vi);virtnet_find_vqs(vi);// 5. 恢复数据传输virtnet_restore_up(vdev);
}

八、多队列支持

1. 配置流程
支持
检查VIRTIO_NET_F_MQ
读取max_queue_pairs
配置实际队列数
分配队列资源
设置CPU亲和性
启用RSS/Flow Director
2. 数据分发
// 发送队列选择
u16 virtnet_select_queue(struct net_device *dev, struct sk_buff *skb)
{// 1. XDP优先if (vi->xdp_prog)return vi->curr_queue_pairs;// 2. 使用RSS哈希return skb_get_hash(skb) % vi->curr_queue_pairs;
}// 接收中断绑定
static irqreturn_t virtnet_interrupt(int irq, void *dev_id)
{struct receive_queue *rq = dev_id;napi_schedule(&rq->napi);  // 调度对应队列的NAPI
}

九、XDP支持

1. 工作流程
XDP_PASS
XDP_TX
XDP_REDIRECT
XDP_DROP
网络数据
驱动RX路径
XDP程序
协议栈
原路返回
其他设备/CPU
丢弃数据包
2. 关键实现
static struct sk_buff *virtnet_run_xdp(...)
{struct bpf_prog *xdp_prog = rcu_dereference(rq->xdp_prog);xdp_prepare_buff(xdp, buf, offset, len);act = bpf_prog_run_xdp(xdp_prog, xdp);switch (act) {case XDP_PASS:return build_skb(...);case XDP_TX:xdpf = convert_to_xdp_frame(xdp);virtnet_xdp_xmit(dev, 1, &xdpf, 0);break;case XDP_REDIRECT:xdp_do_redirect(dev, xdp, xdp_prog);break;}
}

十、总结:Virtio核心优势

  1. 标准化接口

    • 统一的前后端通信协议
    • 支持多种传输机制(PCI、MMIO、channel)
  2. 高性能设计

    • 零拷贝数据传输
    • 批处理与延迟通知
    • 多队列并行处理
  3. 灵活扩展性

    • 特性协商机制
    • 可扩展的virtqueue设计
    • 支持现代功能(XDP、TLS offload)
  4. 跨平台支持

    • 支持KVM、QEMU、Docker等环境
    • 兼容多种客户机OS(Linux、Windows)
  5. 生产级可靠性

    • 完善的错误恢复机制
    • 热升级支持
    • 实时监控接口

Virtio通过将虚拟设备标准化,在保持高性能的同时,显著降低了虚拟化环境中I/O栈的复杂度,成为现代云计算基础设施的核心组件。其设计思想也影响了物理设备驱动的发展,推动了零拷贝、多队列等技术在物理网卡中的广泛应用。

http://www.dtcms.com/a/324405.html

相关文章:

  • 如何解决线上gc频繁的问题?
  • 《C语言》结构体和联合体练习题--2
  • Excel合并同步工具V1.0
  • 比特币现货和比特币合约的区别与联系
  • 数据结构——哈希表、树、gdb调试、时间复杂度
  • 【走进Docker的世界】Docker环境搭建
  • 自动驾驶控制算法——Stanley 控制器
  • 构建健壮的商品数据采集服务:处理京东 API 限流与错误
  • python洛谷做题27:P5724 【深基4.习5】求极差 / 最大跨度值 / 最大值和最小值的差
  • mcp-go v0.37.0 版本发布:重大变更与新特性解析
  • 利用容器编排完成haproxy和nginx负载均衡架构实施
  • GitLab 零基础入门指南:从安装到项目管理全流程
  • Elasticsearch QueryDSL 教程
  • 应对高并发 - TCP/IP网络栈核心参数调优
  • 【递归、搜索与回溯算法】递归算法
  • 【代码随想录day 16】 力扣 513.找树左下角的值
  • 米哈游笔试——求强势顶点的个数
  • [python] typing 中的overload
  • Android视图回调机制:从post到ViewTreeObserver,从源码分析到最佳实践
  • MariaDB 数据库管理
  • 基于PyTorch一文讲清楚损失函数与激活函数并配上详细的图文讲解
  • Pytorch深度学习框架实战教程12:Pytorch混合精度推理,性能加速147%的技术实现
  • MPLS对LSP连通性的检测
  • 使用Blender可视化多传感器坐标系转换
  • 移动端常见的8大css兼容性问题和处理方法
  • #Linux内存管理# 浅析缺页中断中私有映射且发生写时复制COW的工作原理
  • 《Qt————Tcp通讯》
  • 容器网络隔离测试于VPS服务器环境的桥接模式验证
  • Docker 详细介绍及使用方法
  • 【大智慧数据】心智开花的时候