enable swtichdev模式的时候,每个vport会创建一个devlink_rate,并且devlink_rate->priv设置为mlx5_vport。
mlx5_esw_offloads_devlink_port_register
devl_rate_leaf_create
创建devlink rate group时,用户态调用如下:
main
dl_cmd
cmd_port
cmd_port_function
cmd_port_function_rate
cmd_port_fn_rate_add
dl_argv_parse
dl_argv_handle_rate_node
mnlu_gen_socket_cmd_prepare(DEVLINK_CMD_RATE_NEW)
dl_opts_put
} else if (opts->present & DL_OPT_PORT_FN_RATE_NODE_NAME) {
mnl_attr_put_strz(nlh, DEVLINK_ATTR_BUS_NAME, opts->bus_name);
mnl_attr_put_strz(nlh, DEVLINK_ATTR_DEV_NAME, opts->dev_name);
mnl_attr_put_strz(nlh, DEVLINK_ATTR_RATE_NODE_NAME,
opts->rate_node_name);
}
内核态调用如下:
devlink_nl_ops
{
.cmd = DEVLINK_CMD_RATE_NEW,
.validate = GENL_DONT_VALIDATE_STRICT,
.pre_doit = devlink_nl_pre_doit,
.doit = devlink_nl_rate_new_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_rate_new_nl_policy,
.maxattr = DEVLINK_ATTR_RATE_TX_WEIGHT,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
devlink_nl_pre_doit
__devlink_nl_pre_doit
devlink_get_from_attrs_lock
devlinks_xa_for_each_registered_get(net, index, devlink) {
if (strcmp(devlink->dev->bus->name, busname) == 0 &&
strcmp(dev_name(devlink->dev), devname) == 0) {
devlink_nl_rate_new_doit
rate_node_new -> mlx5_esw_devlink_rate_node_new
esw = mlx5_devlink_eswitch_get(rate_node->devlink)
group = esw_qos_create_rate_group(esw, extack)
__esw_qos_create_rate_group
list_add_tail(&group->list, &esw->qos.groups)
*priv = group
devlink rate group的priv指针指向mlx5_esw_rate_group
将一个vf加入到group调用如下:
devlink_nl_rate_parent_node_set
mlx5_esw_devlink_rate_parent_set
mlx5_esw_qos_vport_update_group
vf的devlink_port->devlink_rate->priv是mlx5_vport
group的devlink_port->devlink_rate->priv是mlx5_esw_rate_group
这样的话,驱动就得到了相应的信息,调用如下:
devlink_nl_rate_parent_node_set
mlx5_esw_devlink_rate_parent_set
mlx5_esw_qos_vport_update_group
OFED支持老kernel,需要sysfs的支持,初始化的时候,就会生成两个目录sriov和groups:
/sys/class/net/enp8s0f0/device/sriov/groups
调用如下:
probe_one
mlx5_init_one
mlx5_init_once
mlx5_sriov_init
mlx5_sriov_sysfs_init
sriov->config = kobject_create_and_add("sriov", &device->kobj)
sriov->groups_config = kobject_init_and_add("groups", sriov->config)
enable sriov的时候,每个vf会再创建一个以vf num为名字的目录:
mlx5_core_sriov_configure
mlx5_sriov_enable
mlx5_device_enable_sriov
mlx5_create_vfs_sysfs
kobject_init_and_add(sriov->config);