Merge branch 'devlink-show-controller-number'
Parav Pandit says: ==================== devlink show controller number Currently a devlink instance that supports an eswitch handles eswitch ports of two type of controllers. (1) controller discovered on same system where eswitch resides. This is the case where PCI PF/VF of a controller and devlink eswitch instance both are located on a single system. (2) controller located on external system. This is the case where a controller is plugged in one system and its devlink eswitch ports are located in a different system. In this case devlink instance of the eswitch only have access to ports of the controller. However, there is no way to describe that a eswitch devlink port belongs to which controller (mainly which external host controller). This problem is more prevalent when port attribute such as PF and VF numbers are overlapping between multiple controllers of same eswitch. Due to this, for a specific switch_id, unique phys_port_name cannot be constructed for such devlink ports. This short series overcomes this limitation by defining two new attributes. (a) external: Indicates if port belongs to external controller (b) controller number: Indicates a controller number of the port Based on this a unique phys_port_name is prepared using controller number. phys_port_name construction using unique controller number is only applicable to external controller ports. This ensures that for non smartnic usecases where there is no external controller, phys_port_name stays same as before. Patch summary: Patch-1 Added mlx5 driver to read controller number Patch-2 Adds the missing comment for the port attributes Patch-3 Move structure comments away from structure fields Patch-4 external attribute added for PCI port flavours Patch-5 Add controller number Patch-6 Use controller number to build phys_port_name --- Changelog: v2->v3: - Updated diagram to get rid of controller 'A' and 'B' - Kept ports of single controller together in diagram - Updated diagram for pf1's VF and SF and its ports v1->v2: - Added text diagram of multiple controllers - Updated example for a VF - Addressed comments from Jiri and Jakub - Moved controller number attribute to PCI port flavours This enables to better, hirerchical view with controller and its PF, VF numbers - Split 'external' and 'controller number' attributes as two different attributes - Merged mlx5_core driver to avoid compiliation break ==================== Acked-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
b599a5b9e1
|
@ -1210,16 +1210,22 @@ is_devlink_port_supported(const struct mlx5_core_dev *dev,
|
|||
static int register_devlink_port(struct mlx5_core_dev *dev,
|
||||
struct mlx5e_rep_priv *rpriv)
|
||||
{
|
||||
struct mlx5_esw_offload *offloads = &dev->priv.eswitch->offloads;
|
||||
struct devlink *devlink = priv_to_devlink(dev);
|
||||
struct mlx5_eswitch_rep *rep = rpriv->rep;
|
||||
struct devlink_port_attrs attrs = {};
|
||||
struct netdev_phys_item_id ppid = {};
|
||||
unsigned int dl_port_index = 0;
|
||||
u32 controller_num = 0;
|
||||
bool external;
|
||||
u16 pfnum;
|
||||
|
||||
if (!is_devlink_port_supported(dev, rpriv))
|
||||
return 0;
|
||||
|
||||
external = mlx5_core_is_ecpf_esw_manager(dev);
|
||||
if (external)
|
||||
controller_num = offloads->host_number + 1;
|
||||
mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid);
|
||||
dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, rep->vport);
|
||||
pfnum = PCI_FUNC(dev->pdev->devfn);
|
||||
|
@ -1232,12 +1238,13 @@ static int register_devlink_port(struct mlx5_core_dev *dev,
|
|||
} else if (rep->vport == MLX5_VPORT_PF) {
|
||||
memcpy(rpriv->dl_port.attrs.switch_id.id, &ppid.id[0], ppid.id_len);
|
||||
rpriv->dl_port.attrs.switch_id.id_len = ppid.id_len;
|
||||
devlink_port_attrs_pci_pf_set(&rpriv->dl_port, pfnum);
|
||||
devlink_port_attrs_pci_pf_set(&rpriv->dl_port, controller_num,
|
||||
pfnum, external);
|
||||
} else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport)) {
|
||||
memcpy(rpriv->dl_port.attrs.switch_id.id, &ppid.id[0], ppid.id_len);
|
||||
rpriv->dl_port.attrs.switch_id.id_len = ppid.id_len;
|
||||
devlink_port_attrs_pci_vf_set(&rpriv->dl_port,
|
||||
pfnum, rep->vport - 1);
|
||||
devlink_port_attrs_pci_vf_set(&rpriv->dl_port, controller_num,
|
||||
pfnum, rep->vport - 1, external);
|
||||
}
|
||||
return devlink_port_register(devlink, &rpriv->dl_port, dl_port_index);
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ struct mlx5_esw_offload {
|
|||
atomic64_t num_flows;
|
||||
enum devlink_eswitch_encap_mode encap;
|
||||
struct ida vport_metadata_ida;
|
||||
unsigned int host_number; /* ECPF supports one external host */
|
||||
};
|
||||
|
||||
/* E-Switch MC FDB table hash node */
|
||||
|
|
|
@ -2110,6 +2110,24 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, unsigned long type
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int mlx5_esw_host_number_init(struct mlx5_eswitch *esw)
|
||||
{
|
||||
const u32 *query_host_out;
|
||||
|
||||
if (!mlx5_core_is_ecpf_esw_manager(esw->dev))
|
||||
return 0;
|
||||
|
||||
query_host_out = mlx5_esw_query_functions(esw->dev);
|
||||
if (IS_ERR(query_host_out))
|
||||
return PTR_ERR(query_host_out);
|
||||
|
||||
/* Mark non local controller with non zero controller number. */
|
||||
esw->offloads.host_number = MLX5_GET(query_esw_functions_out, query_host_out,
|
||||
host_params_context.host_number);
|
||||
kvfree(query_host_out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esw_offloads_enable(struct mlx5_eswitch *esw)
|
||||
{
|
||||
struct mlx5_vport *vport;
|
||||
|
@ -2124,6 +2142,10 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
|
|||
mutex_init(&esw->offloads.termtbl_mutex);
|
||||
mlx5_rdma_enable_roce(esw->dev);
|
||||
|
||||
err = mlx5_esw_host_number_init(esw);
|
||||
if (err)
|
||||
goto err_vport_metadata;
|
||||
|
||||
err = esw_set_passing_vport_metadata(esw, true);
|
||||
if (err)
|
||||
goto err_vport_metadata;
|
||||
|
|
|
@ -57,13 +57,30 @@ struct devlink_port_phys_attrs {
|
|||
u32 split_subport_number; /* If the port is split, this is the number of subport. */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct devlink_port_pci_pf_attrs - devlink port's PCI PF attributes
|
||||
* @controller: Associated controller number
|
||||
* @pf: Associated PCI PF number for this port.
|
||||
* @external: when set, indicates if a port is for an external controller
|
||||
*/
|
||||
struct devlink_port_pci_pf_attrs {
|
||||
u16 pf; /* Associated PCI PF for this port. */
|
||||
u32 controller;
|
||||
u16 pf;
|
||||
u8 external:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct devlink_port_pci_vf_attrs - devlink port's PCI VF attributes
|
||||
* @controller: Associated controller number
|
||||
* @pf: Associated PCI PF number for this port.
|
||||
* @vf: Associated PCI VF for of the PCI PF for this port.
|
||||
* @external: when set, indicates if a port is for an external controller
|
||||
*/
|
||||
struct devlink_port_pci_vf_attrs {
|
||||
u16 pf; /* Associated PCI PF for this port. */
|
||||
u16 vf; /* Associated PCI VF for of the PCI PF for this port. */
|
||||
u32 controller;
|
||||
u16 pf;
|
||||
u16 vf;
|
||||
u8 external:1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -73,6 +90,9 @@ struct devlink_port_pci_vf_attrs {
|
|||
* @splittable: indicates if the port can be split.
|
||||
* @lanes: maximum number of lanes the port supports. 0 value is not passed to netlink.
|
||||
* @switch_id: if the port is part of switch, this is buffer with ID, otherwise this is NULL
|
||||
* @phys: physical port attributes
|
||||
* @pci_pf: PCI PF port attributes
|
||||
* @pci_vf: PCI VF port attributes
|
||||
*/
|
||||
struct devlink_port_attrs {
|
||||
u8 split:1,
|
||||
|
@ -1203,9 +1223,10 @@ void devlink_port_type_ib_set(struct devlink_port *devlink_port,
|
|||
void devlink_port_type_clear(struct devlink_port *devlink_port);
|
||||
void devlink_port_attrs_set(struct devlink_port *devlink_port,
|
||||
struct devlink_port_attrs *devlink_port_attrs);
|
||||
void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf);
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
|
||||
u16 pf, u16 vf);
|
||||
void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, bool external);
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, u16 vf, bool external);
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
|
|
|
@ -458,6 +458,8 @@ enum devlink_attr {
|
|||
DEVLINK_ATTR_PORT_LANES, /* u32 */
|
||||
DEVLINK_ATTR_PORT_SPLITTABLE, /* u8 */
|
||||
|
||||
DEVLINK_ATTR_PORT_EXTERNAL, /* u8 */
|
||||
DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, /* u32 */
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
__DEVLINK_ATTR_MAX,
|
||||
|
|
|
@ -523,15 +523,20 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
|
|||
return -EMSGSIZE;
|
||||
switch (devlink_port->attrs.flavour) {
|
||||
case DEVLINK_PORT_FLAVOUR_PCI_PF:
|
||||
if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
|
||||
attrs->pci_pf.pf))
|
||||
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
|
||||
attrs->pci_pf.controller) ||
|
||||
nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
|
||||
return -EMSGSIZE;
|
||||
if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
|
||||
return -EMSGSIZE;
|
||||
break;
|
||||
case DEVLINK_PORT_FLAVOUR_PCI_VF:
|
||||
if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
|
||||
attrs->pci_vf.pf) ||
|
||||
nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,
|
||||
attrs->pci_vf.vf))
|
||||
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
|
||||
attrs->pci_vf.controller) ||
|
||||
nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
|
||||
nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
|
||||
return -EMSGSIZE;
|
||||
if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
|
||||
return -EMSGSIZE;
|
||||
break;
|
||||
case DEVLINK_PORT_FLAVOUR_PHYSICAL:
|
||||
|
@ -7715,9 +7720,12 @@ EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
|
|||
* devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
|
||||
*
|
||||
* @devlink_port: devlink port
|
||||
* @controller: associated controller number for the devlink port instance
|
||||
* @pf: associated PF for the devlink port instance
|
||||
* @external: indicates if the port is for an external controller
|
||||
*/
|
||||
void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf)
|
||||
void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, bool external)
|
||||
{
|
||||
struct devlink_port_attrs *attrs = &devlink_port->attrs;
|
||||
int ret;
|
||||
|
@ -7726,8 +7734,9 @@ void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u16 pf)
|
|||
DEVLINK_PORT_FLAVOUR_PCI_PF);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
attrs->pci_pf.controller = controller;
|
||||
attrs->pci_pf.pf = pf;
|
||||
attrs->pci_pf.external = external;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
|
||||
|
||||
|
@ -7735,11 +7744,13 @@ EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
|
|||
* devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
|
||||
*
|
||||
* @devlink_port: devlink port
|
||||
* @controller: associated controller number for the devlink port instance
|
||||
* @pf: associated PF for the devlink port instance
|
||||
* @vf: associated VF of a PF for the devlink port instance
|
||||
* @external: indicates if the port is for an external controller
|
||||
*/
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
|
||||
u16 pf, u16 vf)
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, u16 vf, bool external)
|
||||
{
|
||||
struct devlink_port_attrs *attrs = &devlink_port->attrs;
|
||||
int ret;
|
||||
|
@ -7748,8 +7759,10 @@ void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,
|
|||
DEVLINK_PORT_FLAVOUR_PCI_VF);
|
||||
if (ret)
|
||||
return;
|
||||
attrs->pci_vf.controller = controller;
|
||||
attrs->pci_vf.pf = pf;
|
||||
attrs->pci_vf.vf = vf;
|
||||
attrs->pci_vf.external = external;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
|
||||
|
||||
|
@ -7780,9 +7793,23 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
|
|||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
case DEVLINK_PORT_FLAVOUR_PCI_PF:
|
||||
if (attrs->pci_pf.external) {
|
||||
n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
|
||||
if (n >= len)
|
||||
return -EINVAL;
|
||||
len -= n;
|
||||
name += n;
|
||||
}
|
||||
n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
|
||||
break;
|
||||
case DEVLINK_PORT_FLAVOUR_PCI_VF:
|
||||
if (attrs->pci_vf.external) {
|
||||
n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
|
||||
if (n >= len)
|
||||
return -EINVAL;
|
||||
len -= n;
|
||||
name += n;
|
||||
}
|
||||
n = snprintf(name, len, "pf%uvf%u",
|
||||
attrs->pci_vf.pf, attrs->pci_vf.vf);
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче