Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/mlx5: Implement query_port_speed callback

Implement the query_port_speed callback for mlx5 driver to support
querying effective port bandwidth.

For LAG configurations, query the aggregated speed from the LAG layer
or from the modified vport max_tx_speed.

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Or Har-Toov and committed by
Leon Romanovsky
aaecff5e 3fd984d5

+126
+124
drivers/infiniband/hw/mlx5/main.c
··· 1581 1581 return 0; 1582 1582 } 1583 1583 1584 + static int mlx5_ib_query_port_speed_from_port(struct mlx5_ib_dev *dev, 1585 + u32 port_num, u64 *speed) 1586 + { 1587 + struct ib_port_speed_info speed_info; 1588 + struct ib_port_attr attr = {}; 1589 + int err; 1590 + 1591 + err = mlx5_ib_query_port(&dev->ib_dev, port_num, &attr); 1592 + if (err) 1593 + return err; 1594 + 1595 + if (attr.state == IB_PORT_DOWN) { 1596 + *speed = 0; 1597 + return 0; 1598 + } 1599 + 1600 + err = ib_port_attr_to_speed_info(&attr, &speed_info); 1601 + if (err) 1602 + return err; 1603 + 1604 + *speed = speed_info.rate; 1605 + return 0; 1606 + } 1607 + 1608 + static int mlx5_ib_query_port_speed_from_vport(struct mlx5_core_dev *mdev, 1609 + u8 op_mod, u16 vport, 1610 + u8 other_vport, u64 *speed, 1611 + struct mlx5_ib_dev *dev, 1612 + u32 port_num) 1613 + { 1614 + u32 max_tx_speed; 1615 + int err; 1616 + 1617 + err = mlx5_query_vport_max_tx_speed(mdev, op_mod, vport, other_vport, 1618 + &max_tx_speed); 1619 + if (err) 1620 + return err; 1621 + 1622 + if (max_tx_speed == 0) 1623 + /* Value 0 indicates field not supported, fallback */ 1624 + return mlx5_ib_query_port_speed_from_port(dev, port_num, 1625 + speed); 1626 + 1627 + *speed = max_tx_speed; 1628 + return 0; 1629 + } 1630 + 1631 + static int mlx5_ib_query_port_speed_from_bond(struct mlx5_ib_dev *dev, 1632 + u32 port_num, u64 *speed) 1633 + { 1634 + struct mlx5_core_dev *mdev = dev->mdev; 1635 + u32 bond_speed; 1636 + int err; 1637 + 1638 + err = mlx5_lag_query_bond_speed(mdev, &bond_speed); 1639 + if (err) 1640 + return err; 1641 + 1642 + *speed = bond_speed / MLX5_MAX_TX_SPEED_UNIT; 1643 + 1644 + return 0; 1645 + } 1646 + 1647 + static int mlx5_ib_query_port_speed_non_rep(struct mlx5_ib_dev *dev, 1648 + u32 port_num, u64 *speed) 1649 + { 1650 + u16 op_mod = MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT; 1651 + 1652 + if (mlx5_lag_is_roce(dev->mdev)) 1653 + return mlx5_ib_query_port_speed_from_bond(dev, port_num, 1654 + speed); 1655 + 1656 + return mlx5_ib_query_port_speed_from_vport(dev->mdev, op_mod, 0, false, 1657 + speed, dev, port_num); 1658 + } 1659 + 1660 + static int mlx5_ib_query_port_speed_rep(struct mlx5_ib_dev *dev, u32 port_num, 1661 + u64 *speed) 1662 + { 1663 + struct mlx5_eswitch_rep *rep; 1664 + struct mlx5_core_dev *mdev; 1665 + u16 op_mod; 1666 + 1667 + if (!dev->port[port_num - 1].rep) { 1668 + mlx5_ib_warn(dev, "Representor doesn't exist for port %u\n", 1669 + port_num); 1670 + return -EINVAL; 1671 + } 1672 + 1673 + rep = dev->port[port_num - 1].rep; 1674 + mdev = mlx5_eswitch_get_core_dev(rep->esw); 1675 + if (!mdev) 1676 + return -ENODEV; 1677 + 1678 + if (rep->vport == MLX5_VPORT_UPLINK) { 1679 + if (mlx5_lag_is_sriov(mdev)) 1680 + return mlx5_ib_query_port_speed_from_bond(dev, 1681 + port_num, 1682 + speed); 1683 + 1684 + return mlx5_ib_query_port_speed_from_port(dev, port_num, 1685 + speed); 1686 + } 1687 + 1688 + op_mod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT; 1689 + return mlx5_ib_query_port_speed_from_vport(dev->mdev, op_mod, 1690 + rep->vport, true, speed, dev, 1691 + port_num); 1692 + } 1693 + 1694 + int mlx5_ib_query_port_speed(struct ib_device *ibdev, u32 port_num, u64 *speed) 1695 + { 1696 + struct mlx5_ib_dev *dev = to_mdev(ibdev); 1697 + 1698 + if (mlx5_ib_port_link_layer(ibdev, port_num) == 1699 + IB_LINK_LAYER_INFINIBAND || mlx5_core_mp_enabled(dev->mdev)) 1700 + return mlx5_ib_query_port_speed_from_port(dev, port_num, speed); 1701 + else if (!dev->is_rep) 1702 + return mlx5_ib_query_port_speed_non_rep(dev, port_num, speed); 1703 + else 1704 + return mlx5_ib_query_port_speed_rep(dev, port_num, speed); 1705 + } 1706 + 1584 1707 static int mlx5_ib_query_gid(struct ib_device *ibdev, u32 port, int index, 1585 1708 union ib_gid *gid) 1586 1709 { ··· 4428 4305 .query_device = mlx5_ib_query_device, 4429 4306 .query_gid = mlx5_ib_query_gid, 4430 4307 .query_pkey = mlx5_ib_query_pkey, 4308 + .query_port_speed = mlx5_ib_query_port_speed, 4431 4309 .query_qp = mlx5_ib_query_qp, 4432 4310 .query_srq = mlx5_ib_query_srq, 4433 4311 .query_ucontext = mlx5_ib_query_ucontext,
+2
drivers/infiniband/hw/mlx5/mlx5_ib.h
··· 1435 1435 struct ib_port_attr *props); 1436 1436 int mlx5_ib_query_port(struct ib_device *ibdev, u32 port, 1437 1437 struct ib_port_attr *props); 1438 + int mlx5_ib_query_port_speed(struct ib_device *ibdev, u32 port_num, 1439 + u64 *speed); 1438 1440 void mlx5_ib_populate_pas(struct ib_umem *umem, size_t page_size, __be64 *pas, 1439 1441 u64 access_flags); 1440 1442 int mlx5_ib_get_cqe_size(struct ib_cq *ibcq);