继续分析710的驱动代码:
今天主要分析这个代码:
客户端通知函数
作用
今天要分析的是一个客户端通知函数,该函数i40e_notify_client_of_vf_enable的作用是:
在 PF 上启用或禁用 VF 后,通过客户端的回调函数通知客户端。
传入参数
struct i40e_pf *pf(表示 PF(Physical Function,物理功能)设备信息)
u32 num_vfs(当前启用的 VF 数量,0表示禁用):
代码片段分析
void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs)
{
struct i40e_client_instance *cdev = pf->cinst;
if (!cdev || !cdev->client)
return;
if (!cdev->client->ops || !cdev->client->ops->vf_enable) {
dev_dbg(&pf->pdev->dev,
"Cannot locate client instance VF enable routine\n");
return;
}
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) {
dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n");
return;
}
cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs);
}
首先:
struct i40e_client_instance *cdev = pf->cinst;
获取 PF 结构中的客户端实例指针。PF 可能与一个客户端实例相关联,用于通信或共享信息。
if (!cdev || !cdev->client)
检查客户端实例指针和客户端是否存在。如果不存在,说明没有客户端与该 PF 关联,直接返回。
if (!cdev->client->ops || !cdev->client->ops->vf_enable) {
检查客户端的ops和 VF 启用的回调函数是否存在。如果不存在,输出调试信息
dev_dbg(&pf->pdev->dev,
"Cannot locate client instance VF enable routine\n");
并返回。
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state))
检查客户端实例的状态位,确保客户端已经打开。如果没有打开,输出调试信息
dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n");
并返回。
cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client, num_vfs);
调用客户端的 VF 启用回调函数。这个回调函数通常由客户端注册,以便在 VF 启用或禁用时接收通知。传递了客户端的 LAN 信息、客户端实例和 VF 数量作为参数。
其中最需要解释的就是这最后一句代码:
cdev是一个结构体的变量:
/* Client device */
struct i40e_client_instance {
struct list_head list;
struct i40e_info lan_info;
struct i40e_client *client;
unsigned long state;
};
cdev->client是结构体的嵌套:嵌套了
struct i40e_client *client;
详细信息如下
struct i40e_client {
struct list_head list; /* list of registered clients */
char name[I40E_CLIENT_STR_LENGTH];
struct i40e_client_version version;
unsigned long state; /* client state */
atomic_t ref_cnt; /* Count of all the client devices of this kind */
u32 flags;
#define I40E_CLIENT_FLAGS_LAUNCH_ON_PROBE BIT(0)
#define I40E_TX_FLAGS_NOTIFY_OTHER_EVENTS BIT(2)
u8 type;
#define I40E_CLIENT_IWARP 0
/* client ops provided by the client */
const struct i40e_client_ops *ops;
};
在client结构体中又嵌套了一个结构体ops
const struct i40e_client_ops *ops;
struct i40e_client_ops {
/* Should be called from register_client() or whenever PF is ready
* to create a specific client instance.
*/
int (*open)(struct i40e_info *ldev, struct i40e_client *client);
/* Should be called when netdev is unavailable or when unregister
* call comes in. If the close is happenening due to a reset being
* triggered set the reset bit to true.
*/
void (*close)(struct i40e_info *ldev, struct i40e_client *client,
bool reset);
/* called when some l2 managed parameters changes - mtu */
void (*l2_param_change)(struct i40e_info *ldev,
struct i40e_client *client,
struct i40e_params *params);
int (*virtchnl_receive)(struct i40e_info *ldev,
struct i40e_client *client, u32 vf_id,
u8 *msg, u16 len);
/* called when a VF is reset by the PF */
void (*vf_reset)(struct i40e_info *ldev,
struct i40e_client *client, u32 vf_id);
/* called when the number of VFs changes */
void (*vf_enable)(struct i40e_info *ldev,
struct i40e_client *client, u32 num_vfs);
/* returns true if VF is capable of specified offload */
int (*vf_capable)(struct i40e_info *ldev,
struct i40e_client *client, u32 vf_id);
};
最后实际上调用的是结构体i40e_client_ops *ops;中的
void (*vf_enable)(struct i40e_info *ldev,
struct i40e_client *client, u32 num_vfs);
这是一个回掉函数 ,主要作用是启用vf。
总结
该函数的作用是在 PF 上启用或禁用 VF 后,通过客户端的回调函数通知客户端。这种通知机制可以用于与客户端交互,以便客户端能够感知并采取相应的措施,例如调整网络拓扑、重新配置虚拟机网络等。