继续分析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 后,通过客户端的回调函数通知客户端。这种通知机制可以用于与客户端交互,以便客户端能够感知并采取相应的措施,例如调整网络拓扑、重新配置虚拟机网络等。