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

Merge branch 'mlx4-dynamic-tc-tx-queues'

Tariq Toukan says:

====================
mlx4_en dynamic TC tx queues

This patchset from Inbar aligns the number of TX queues
to the actual need, according to the TC configuration.

Series generated against net-next commit:
2ee87db3a287 Merge branch 'nfp-get_phys_port_name-for-representors-and-SR-IOV-reorder'
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+79 -26
+3 -3
drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
··· 238 238 priv->flags &= ~MLX4_EN_FLAG_DCB_ENABLED; 239 239 } 240 240 241 - if (mlx4_en_setup_tc(dev, num_tcs)) 241 + if (mlx4_en_alloc_tx_queue_per_tc(dev, num_tcs)) 242 242 return 1; 243 243 244 244 return 0; ··· 303 303 int has_ets_tc = 0; 304 304 305 305 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { 306 - if (ets->prio_tc[i] >= MLX4_EN_NUM_UP) { 306 + if (ets->prio_tc[i] >= MLX4_EN_NUM_UP_HIGH) { 307 307 en_err(priv, "Bad priority in UP <=> TC mapping. TC: %d, UP: %d\n", 308 308 i, ets->prio_tc[i]); 309 309 return -EINVAL; ··· 472 472 goto err; 473 473 if (mlx4_en_dcbnl_ieee_setpfc(dev, &pfc)) 474 474 goto err; 475 - if (mlx4_en_setup_tc(dev, 0)) 475 + if (mlx4_en_alloc_tx_queue_per_tc(dev, 0)) 476 476 goto err; 477 477 } 478 478
+10 -7
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
··· 1750 1750 channel->max_tx = MLX4_EN_MAX_TX_RING_P_UP; 1751 1751 1752 1752 channel->rx_count = priv->rx_ring_num; 1753 - channel->tx_count = priv->tx_ring_num[TX] / MLX4_EN_NUM_UP; 1753 + channel->tx_count = priv->tx_ring_num[TX] / 1754 + priv->prof->num_up; 1754 1755 } 1755 1756 1756 1757 static int mlx4_en_set_channels(struct net_device *dev, ··· 1764 1763 int port_up = 0; 1765 1764 int xdp_count; 1766 1765 int err = 0; 1766 + u8 up; 1767 1767 1768 1768 if (!channel->tx_count || !channel->rx_count) 1769 1769 return -EINVAL; ··· 1775 1773 1776 1774 mutex_lock(&mdev->state_lock); 1777 1775 xdp_count = priv->tx_ring_num[TX_XDP] ? channel->rx_count : 0; 1778 - if (channel->tx_count * MLX4_EN_NUM_UP + xdp_count > MAX_TX_RINGS) { 1776 + if (channel->tx_count * priv->prof->num_up + xdp_count > 1777 + MAX_TX_RINGS) { 1779 1778 err = -EINVAL; 1780 1779 en_err(priv, 1781 1780 "Total number of TX and XDP rings (%d) exceeds the maximum supported (%d)\n", 1782 - channel->tx_count * MLX4_EN_NUM_UP + xdp_count, 1781 + channel->tx_count * priv->prof->num_up + xdp_count, 1783 1782 MAX_TX_RINGS); 1784 1783 goto out; 1785 1784 } 1786 1785 1787 1786 memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); 1788 1787 new_prof.num_tx_rings_p_up = channel->tx_count; 1789 - new_prof.tx_ring_num[TX] = channel->tx_count * MLX4_EN_NUM_UP; 1788 + new_prof.tx_ring_num[TX] = channel->tx_count * priv->prof->num_up; 1790 1789 new_prof.tx_ring_num[TX_XDP] = xdp_count; 1791 1790 new_prof.rx_ring_num = channel->rx_count; 1792 1791 ··· 1802 1799 1803 1800 mlx4_en_safe_replace_resources(priv, tmp); 1804 1801 1805 - netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]); 1806 1802 netif_set_real_num_rx_queues(dev, priv->rx_ring_num); 1807 1803 1808 - if (netdev_get_num_tc(dev)) 1809 - mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP); 1804 + up = (priv->prof->num_up == MLX4_EN_NUM_UP_LOW) ? 1805 + 0 : priv->prof->num_up; 1806 + mlx4_en_setup_tc(dev, up); 1810 1807 1811 1808 en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num[TX]); 1812 1809 en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num);
+3 -1
drivers/net/ethernet/mellanox/mlx4/en_main.c
··· 169 169 params->prof[i].tx_ppp = pfctx; 170 170 params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; 171 171 params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; 172 + params->prof[i].num_up = MLX4_EN_NUM_UP_LOW; 173 + params->prof[i].num_tx_rings_p_up = params->num_tx_rings_p_up; 172 174 params->prof[i].tx_ring_num[TX] = params->num_tx_rings_p_up * 173 - MLX4_EN_NUM_UP; 175 + params->prof[i].num_up; 174 176 params->prof[i].rss_rings = 0; 175 177 params->prof[i].inline_thold = inline_thold; 176 178 }
+54 -6
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
··· 60 60 int i; 61 61 unsigned int offset = 0; 62 62 63 - if (up && up != MLX4_EN_NUM_UP) 63 + if (up && up != MLX4_EN_NUM_UP_HIGH) 64 64 return -EINVAL; 65 65 66 66 netdev_set_num_tc(dev, up); 67 - 67 + netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]); 68 68 /* Partition Tx queues evenly amongst UP's */ 69 69 for (i = 0; i < up; i++) { 70 70 netdev_set_tc_queue(dev, i, priv->num_tx_rings_p_up, offset); ··· 86 86 return 0; 87 87 } 88 88 89 + int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc) 90 + { 91 + struct mlx4_en_priv *priv = netdev_priv(dev); 92 + struct mlx4_en_dev *mdev = priv->mdev; 93 + struct mlx4_en_port_profile new_prof; 94 + struct mlx4_en_priv *tmp; 95 + int port_up = 0; 96 + int err = 0; 97 + 98 + tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 99 + if (!tmp) 100 + return -ENOMEM; 101 + 102 + mutex_lock(&mdev->state_lock); 103 + memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); 104 + new_prof.num_up = (tc == 0) ? MLX4_EN_NUM_UP_LOW : 105 + MLX4_EN_NUM_UP_HIGH; 106 + new_prof.tx_ring_num[TX] = new_prof.num_tx_rings_p_up * 107 + new_prof.num_up; 108 + err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true); 109 + if (err) 110 + goto out; 111 + 112 + if (priv->port_up) { 113 + port_up = 1; 114 + mlx4_en_stop_port(dev, 1); 115 + } 116 + 117 + mlx4_en_safe_replace_resources(priv, tmp); 118 + if (port_up) { 119 + err = mlx4_en_start_port(dev); 120 + if (err) { 121 + en_err(priv, "Failed starting port for setup TC\n"); 122 + goto out; 123 + } 124 + } 125 + 126 + err = mlx4_en_setup_tc(dev, tc); 127 + out: 128 + mutex_unlock(&mdev->state_lock); 129 + kfree(tmp); 130 + return err; 131 + } 132 + 89 133 static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, 90 134 u32 chain_index, __be16 proto, 91 135 struct tc_to_netdev *tc) ··· 137 93 if (tc->type != TC_SETUP_MQPRIO) 138 94 return -EINVAL; 139 95 96 + if (tc->mqprio->num_tc && tc->mqprio->num_tc != MLX4_EN_NUM_UP_HIGH) 97 + return -EINVAL; 98 + 140 99 tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; 141 100 142 - return mlx4_en_setup_tc(dev, tc->mqprio->num_tc); 101 + return mlx4_en_alloc_tx_queue_per_tc(dev, tc->mqprio->num_tc); 143 102 } 144 103 145 104 #ifdef CONFIG_RFS_ACCEL ··· 2191 2144 2192 2145 memcpy(&dst->hwtstamp_config, &prof->hwtstamp_config, 2193 2146 sizeof(dst->hwtstamp_config)); 2194 - dst->num_tx_rings_p_up = src->mdev->profile.num_tx_rings_p_up; 2147 + dst->num_tx_rings_p_up = prof->num_tx_rings_p_up; 2195 2148 dst->rx_ring_num = prof->rx_ring_num; 2196 2149 dst->flags = prof->flags; 2197 2150 dst->mdev = src->mdev; ··· 2244 2197 dst->tx_ring[t] = src->tx_ring[t]; 2245 2198 dst->tx_cq[t] = src->tx_cq[t]; 2246 2199 } 2200 + dst->num_tx_rings_p_up = src->num_tx_rings_p_up; 2247 2201 dst->rx_ring_num = src->rx_ring_num; 2248 2202 memcpy(dst->prof, src->prof, sizeof(struct mlx4_en_port_profile)); 2249 2203 } ··· 2828 2780 if (priv->tx_ring_num[TX] + xdp_ring_num > MAX_TX_RINGS) { 2829 2781 tx_changed = 1; 2830 2782 new_prof.tx_ring_num[TX] = 2831 - MAX_TX_RINGS - ALIGN(xdp_ring_num, MLX4_EN_NUM_UP); 2783 + MAX_TX_RINGS - ALIGN(xdp_ring_num, priv->prof->num_up); 2832 2784 en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n"); 2833 2785 } 2834 2786 ··· 3319 3271 priv->flags |= MLX4_EN_DCB_ENABLED; 3320 3272 priv->cee_config.pfc_state = false; 3321 3273 3322 - for (i = 0; i < MLX4_EN_NUM_UP; i++) 3274 + for (i = 0; i < MLX4_EN_NUM_UP_HIGH; i++) 3323 3275 priv->cee_config.dcb_pfc[i] = pfc_disabled; 3324 3276 3325 3277 if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETS_CFG) {
+2 -1
drivers/net/ethernet/mellanox/mlx4/en_resources.c
··· 63 63 context->local_qpn = cpu_to_be32(qpn); 64 64 context->pri_path.ackto = 1 & 0x07; 65 65 context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6; 66 - if (user_prio >= 0) { 66 + /* force user priority per tx ring */ 67 + if (user_prio >= 0 && priv->prof->num_up == MLX4_EN_NUM_UP_HIGH) { 67 68 context->pri_path.sched_queue |= user_prio << 3; 68 69 context->pri_path.feup = MLX4_FEUP_FORCE_ETH_UP; 69 70 }
+1 -5
drivers/net/ethernet/mellanox/mlx4/en_tx.c
··· 691 691 { 692 692 struct mlx4_en_priv *priv = netdev_priv(dev); 693 693 u16 rings_p_up = priv->num_tx_rings_p_up; 694 - u8 up = 0; 695 694 696 695 if (netdev_get_num_tc(dev)) 697 696 return skb_tx_hash(dev, skb); 698 697 699 - if (skb_vlan_tag_present(skb)) 700 - up = skb_vlan_tag_get(skb) >> VLAN_PRIO_SHIFT; 701 - 702 - return fallback(dev, skb) % rings_p_up + up * rings_p_up; 698 + return fallback(dev, skb) % rings_p_up; 703 699 } 704 700 705 701 static void mlx4_bf_copy(void __iomem *dst, const void *src,
+6 -3
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
··· 115 115 #define MLX4_EN_SMALL_PKT_SIZE 64 116 116 #define MLX4_EN_MIN_TX_RING_P_UP 1 117 117 #define MLX4_EN_MAX_TX_RING_P_UP 32 118 - #define MLX4_EN_NUM_UP 8 118 + #define MLX4_EN_NUM_UP_LOW 1 119 + #define MLX4_EN_NUM_UP_HIGH 8 119 120 #define MLX4_EN_DEF_RX_RING_SIZE 1024 120 121 #define MLX4_EN_DEF_TX_RING_SIZE MLX4_EN_DEF_RX_RING_SIZE 121 122 #define MAX_TX_RINGS (MLX4_EN_MAX_TX_RING_P_UP * \ 122 - MLX4_EN_NUM_UP) 123 + MLX4_EN_NUM_UP_HIGH) 123 124 124 125 #define MLX4_EN_DEFAULT_TX_WORK 256 125 126 ··· 387 386 u8 rx_ppp; 388 387 u8 tx_pause; 389 388 u8 tx_ppp; 389 + u8 num_up; 390 390 int rss_rings; 391 391 int inline_thold; 392 392 struct hwtstamp_config hwtstamp_config; ··· 487 485 488 486 struct mlx4_en_cee_config { 489 487 bool pfc_state; 490 - enum dcb_pfc_type dcb_pfc[MLX4_EN_NUM_UP]; 488 + enum dcb_pfc_type dcb_pfc[MLX4_EN_NUM_UP_HIGH]; 491 489 }; 492 490 #endif 493 491 ··· 763 761 #endif 764 762 765 763 int mlx4_en_setup_tc(struct net_device *dev, u8 up); 764 + int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc); 766 765 767 766 #ifdef CONFIG_RFS_ACCEL 768 767 void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv);