virtio_net与vhost协议feature过程

本文以vhost_user后端为例进行描述,kernel的vhost_net与vhost_user类似,只是在qemu中注册了不同接口而已。
参考链接,本文是对下面文章的总结。
http://blog.chinaunix.net/uid-28541347-id-5787244.html

协商核心:协商的目的是为了对guest的virtio_net设备与后端的vhost_user之间协商共同支持的feature集合,以最终确定整个流程中启用的最终feature集合,
但qemu-kvm架构中,guest与vhost_user(一般是ovs-dpdk进程)是不直接通信的,所以他们之间的feature需要一个中间人,即:qemu模块。

协商涉及4个核心模块: guest:virtio_net《》qemu:virtio_net代理《》qemu:vhost_user《====》dpdk:vhost_user

static const struct { int valid; enum virtio_ib_qp_attr_mask req_param[VIRTIO_IB_QPT_UD + 1]; enum virtio_ib_qp_attr_mask opt_param[VIRTIO_IB_QPT_UD + 1]; } qp_state_table[VIRTIO_IB_QPS_ERR + 1][VIRTIO_IB_QPS_ERR + 1] = { [VIRTIO_IB_QPS_RESET] = { [VIRTIO_IB_QPS_RESET] = { .valid = 1 }, [VIRTIO_IB_QPS_INIT] = { .valid = 1, .req_param = { [VIRTIO_IB_QPT_UD] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_UC] = VIRTIO_IB_QP_ACCESS_FLAGS, [VIRTIO_IB_QPT_RC] = VIRTIO_IB_QP_ACCESS_FLAGS, [VIRTIO_IB_QPT_SMI] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_GSI] = VIRTIO_IB_QP_QKEY, } }, }, [VIRTIO_IB_QPS_INIT] = { [VIRTIO_IB_QPS_RESET] = { .valid = 1 }, [VIRTIO_IB_QPS_ERR] = { .valid = 1 }, [VIRTIO_IB_QPS_INIT] = { .valid = 1, .opt_param = { [VIRTIO_IB_QPT_UD] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_UC] = VIRTIO_IB_QP_ACCESS_FLAGS, [VIRTIO_IB_QPT_RC] = VIRTIO_IB_QP_ACCESS_FLAGS, [VIRTIO_IB_QPT_SMI] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_GSI] = VIRTIO_IB_QP_QKEY, } }, [VIRTIO_IB_QPS_RTR] = { .valid = 1, .req_param = { [VIRTIO_IB_QPT_UC] = (VIRTIO_IB_QP_AV | VIRTIO_IB_QP_PATH_MTU | VIRTIO_IB_QP_DEST_QPN | VIRTIO_IB_QP_RQ_PSN), [VIRTIO_IB_QPT_RC] = (VIRTIO_IB_QP_AV | VIRTIO_IB_QP_PATH_MTU | VIRTIO_IB_QP_DEST_QPN | VIRTIO_IB_QP_RQ_PSN | VIRTIO_IB_QP_MAX_DEST_RD_ATOMIC | VIRTIO_IB_QP_MIN_RNR_TIMER), }, .opt_param = { [VIRTIO_IB_QPT_UD] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_UC] = VIRTIO_IB_QP_ACCESS_FLAGS, [VIRTIO_IB_QPT_RC] = VIRTIO_IB_QP_ACCESS_FLAGS, [VIRTIO_IB_QPT_SMI] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_GSI] = VIRTIO_IB_QP_QKEY, }, }, }, [VIRTIO_IB_QPS_RTR] = { [VIRTIO_IB_QPS_RESET] = { .valid = 1 }, [VIRTIO_IB_QPS_ERR] = { .valid = 1 }, [VIRTIO_IB_QPS_RTS] = { .valid = 1, .req_param = { [VIRTIO_IB_QPT_UD] = VIRTIO_IB_QP_SQ_PSN, [VIRTIO_IB_QPT_UC] = VIRTIO_IB_QP_SQ_PSN, [VIRTIO_IB_QPT_RC] = (VIRTIO_IB_QP_TIMEOUT | VIRTIO_IB_QP_RETRY_CNT | VIRTIO_IB_QP_RNR_RETRY | VIRTIO_IB_QP_SQ_PSN | VIRTIO_IB_QP_MAX_QP_RD_ATOMIC), [VIRTIO_IB_QPT_SMI] = VIRTIO_IB_QP_SQ_PSN, [VIRTIO_IB_QPT_GSI] = VIRTIO_IB_QP_SQ_PSN, }, .opt_param = { [VIRTIO_IB_QPT_UD] = (VIRTIO_IB_QP_CUR_STATE | VIRTIO_IB_QP_QKEY), [VIRTIO_IB_QPT_UC] = (VIRTIO_IB_QP_CUR_STATE | VIRTIO_IB_QP_ACCESS_FLAGS), [VIRTIO_IB_QPT_RC] = (VIRTIO_IB_QP_CUR_STATE | VIRTIO_IB_QP_ACCESS_FLAGS | VIRTIO_IB_QP_MIN_RNR_TIMER), [VIRTIO_IB_QPT_SMI] = (VIRTIO_IB_QP_CUR_STATE | VIRTIO_IB_QP_QKEY), [VIRTIO_IB_QPT_GSI] = (VIRTIO_IB_QP_CUR_STATE | VIRTIO_IB_QP_QKEY), } } },
最新发布
04-09
<think>嗯,我现在需要解释用户提供的这个C语言结构体。看起来这是一个关于虚拟化InfiniBand队列对(QP)状态转换的表格。首先,我得理解这个结构体的各个部分。 首先,结构体是static const的,说明它是静态且不可修改的。内部有三个成员:valid、req_param和opt_param,它们都是数组。外层是一个二维数组qp_state_table,索引是两个状态,可能代表从当前状态到目标状态的转换规则。 接下来,枚举类型如enum virtio_ib_qp_attr_mask可能表示不同的QP属性掩码,用于标识必需或可选的参数。数组的维度是[VIRTIO_IB_QPS_ERR + 1][VIRTIO_IB_QPS_ERR + 1],说明状态包括RESET、INIT、RTR、RTS、ERR等,每个状态之间的转换都有对应的规则。 然后,初始化部分。例如,当从RESET状态转换到INIT状态时,req_param数组根据不同的QP类型(UD、UC、RC等)设置不同的必需参数。比如UD类型的QP需要QKEY,而UC和RC需要访问权限标志。 在状态转换到RTR时,req_param可能包括地址向量(AV)、路径MTU、目标QP号等。而opt_param可能包含一些可选参数,比如访问标志或QKEY。 当从RTR转换到RTS时,必需参数可能包括SQ_PSN,对于RC类型还有超时、重试计数等。可选参数可能包含当前状态和一些其他标志。 我需要确保解释清楚每个状态转换的条件,以及不同QP类型所需的参数。同时,要说明valid字段的作用,可能表示该状态转换是否有效。例如,从RESET到INIT有效,而从RESET到其他状态可能无效。 可能还需要提到,这种表格用于验证QP状态转换时的参数是否符合规范,确保驱动程序在修改QP状态时提供必要的参数,避免错误。 需要注意的是,VIRTIO_IB_QPT_UD等是QP类型,而VIRTIO_IB_QP_QKEY等是属性掩码,使用位或操作组合。这表示在设置QP属性时,可能需要同时满足多个条件。 用户可能想知道这个结构体在代码中的作用,以及如何被使用。比如,当尝试将QP从当前状态转换到目标状态时,系统会检查该表格,确认valid是否为1,并检查req_param和opt_param是否满足。 可能存在一些错误处理,比如无效的状态转换会导致错误码返回,或者触发异常处理流程。 总结来说,这个结构体是一个状态机表格,管理不同QP类型在不同状态转换时的参数要求,确保状态转换的合法性。</think>以下是对该数据结构的详细分步解释: ### 一、结构体定义分析 ```c static const struct { int valid; // 状态转换有效性标志 enum virtio_ib_qp_attr_mask req_param[VIRTIO_IB_QPT_UD + 1]; // 必需参数掩码 enum virtio_ib_qp_attr_mask opt_param[VIRTIO_IB_QPT_UD + 1]; // 可选参数掩码 } qp_state_table[VIRTIO_IB_QPS_ERR + 1][VIRTIO_IB_QPS_ERR + 1] = { ... }; ``` #### 关键要素 1. **二维状态转换表** - 第一维表示当前QP状态 - 第二维表示目标QP状态 - 索引范围:`[VIRTIO_IB_QPS_RESET]`到`[VIRTIO_IB_QPS_ERR]` 2. **成员说明** | 成员 | 说明 | |------------|----------------------------------------------------------------------| | `valid` | 值为1表示允许此状态转换 | | `req_param`| 按QP类型存储必须提供的参数(位掩码) | | `opt_param`| 按QP类型存储可选提供的参数(位掩码) | ### 二、状态转换规则 #### 1. RESET状态转换规则 ```c [VIRTIO_IB_QPS_RESET] = { [VIRTIO_IB_QPS_RESET] = { .valid = 1 }, // 允许保持RESET状态 [VIRTIO_IB_QPS_INIT] = { .valid = 1, .req_param = { // 不同类型QP的必须参数 [VIRTIO_IB_QPT_UD] = VIRTIO_IB_QP_QKEY, [VIRTIO_IB_QPT_UC] = VIRTIO_IB_QP_ACCESS_FLAGS, ... } } } ``` - **典型场景**:当QP从RESET切换到INIT状态时 - **UD类型QP**必须提供:$QKEY$ - **UC/RC类型QP**必须提供:$访问权限标志$ #### 2. INIT状态转换规则 ```c [VIRTIO_IB_QPS_INIT] = { [VIRTIO_IB_QPS_RTR] = { .valid = 1, .req_param = { // RC类型需要5个必要参数 [VIRTIO_IB_QPT_RC] = VIRTIO_IB_QP_AV | VIRTIO_IB_QP_PATH_MTU | ... } } } ``` - **RC类型QP**需要: $$ \text{AV} \ | \ \text{Path MTU} \ | \ \text{Dest QPN} \ | \ \text{RQ PSN} \ | \ \cdots $$ #### 3. RTR→RTS转换规则 ```c [VIRTIO_IB_QPS_RTR] = { [VIRTIO_IB_QPS_RTS] = { .req_param = { [VIRTIO_IB_QPT_RC] = VIRTIO_IB_QP_TIMEOUT | VIRTIO_IB_QP_RETRY_CNT | ... } } } ``` - **RC类型QP**进入RTS状态必须提供: $$ \text{Timeout} \ | \ \text{Retry Count} \ | \ \text{RNR Retry} \ | \ \cdots $$ ### 三、设计特点分析 1. **类型敏感参数要求** 通过`[VIRTIO_IB_QPT_UD]`等索引区分不同传输类型的参数需求 2. **位掩码组合** 使用`|`运算符组合多个参数要求,例如: $$ \text{VIRTIO\_IB\_QP\_AV} \ | \ \text{VIRTIO\_IB\_QP\_PATH\_MTU} $$ 3. **状态机完整性** 包含`[VIRTIO_IB_QPS_ERR]`处理,确保错误状态可恢复 ### 四、典型应用场景 1. **QP修改操作验证** 驱动程序调用`ib_modify_qp()`时,内核通过此表: - 检查`valid`字段 - 验证是否提供了所有`req_param` - 处理`opt_param` 2. **协议兼容性保证** 确保不同virtio后端实现遵循相同的状态转换规则 该数据结构体现了InfiniBand规范中QP状态机的严格管理要求,通过编译期确定的常量数据,实现了高效的状态转换验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值