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.

Merge branch 'mlx5-misc-patches-2024-08-08'

Tariq Toukan says:

====================
mlx5 misc patches 2024-08-08

This patchset contains multiple enhancements from the team to the mlx5
core and Eth drivers.

Patch #1 by Chris bumps a defined value to permit more devices doing TC
offloads.

Patch #2 by Jianbo adds an IPsec fast-path optimization to replace the
slow async handling.

Patches #3 and #4 by Jianbo add TC offload support for complicated rules
to overcome firmware limitation.

Patch #5 by Gal unifies the access macro to advertised/supported link
modes.

Patches #6 to #9 by Gal adds extack messages in ethtool ops to replace
prints to the kernel log.

Patch #10 by Cosmin switches to using 'update' verb instead of 'replace'
to better reflect the operation.

Patch #11 by Cosmin exposes an update connection tracking operation to
replace the assumed delete+add implementaiton.
====================

Link: https://patch.msgid.link/20240808055927.2059700-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+253 -74
+4 -2
drivers/net/ethernet/mellanox/mlx5/core/en.h
··· 1172 1172 struct ethtool_ringparam *param, 1173 1173 struct kernel_ethtool_ringparam *kernel_param); 1174 1174 int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv, 1175 - struct ethtool_ringparam *param); 1175 + struct ethtool_ringparam *param, 1176 + struct netlink_ext_ack *extack); 1176 1177 void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv, 1177 1178 struct ethtool_channels *ch); 1178 1179 int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv, 1179 1180 struct ethtool_channels *ch); 1180 1181 int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv, 1181 1182 struct ethtool_coalesce *coal, 1182 - struct kernel_ethtool_coalesce *kernel_coal); 1183 + struct kernel_ethtool_coalesce *kernel_coal, 1184 + struct netlink_ext_ack *extack); 1183 1185 int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv, 1184 1186 struct ethtool_coalesce *coal, 1185 1187 struct kernel_ethtool_coalesce *kernel_coal,
+2
drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs.h
··· 25 25 struct mlx5_flow_attr *attr, 26 26 struct flow_rule *flow_rule); 27 27 void (*ct_rule_del)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule); 28 + int (*ct_rule_update)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule, 29 + struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr); 28 30 29 31 size_t priv_size; 30 32 };
+21
drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_dmfs.c
··· 65 65 kfree(dmfs_rule); 66 66 } 67 67 68 + static int mlx5_ct_fs_dmfs_ct_rule_update(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule, 69 + struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr) 70 + { 71 + struct mlx5_ct_fs_dmfs_rule *dmfs_rule = container_of(fs_rule, 72 + struct mlx5_ct_fs_dmfs_rule, 73 + fs_rule); 74 + struct mlx5e_priv *priv = netdev_priv(fs->netdev); 75 + struct mlx5_flow_handle *rule; 76 + 77 + rule = mlx5_tc_rule_insert(priv, spec, attr); 78 + if (IS_ERR(rule)) 79 + return PTR_ERR(rule); 80 + mlx5_tc_rule_delete(priv, dmfs_rule->rule, dmfs_rule->attr); 81 + 82 + dmfs_rule->rule = rule; 83 + dmfs_rule->attr = attr; 84 + 85 + return 0; 86 + } 87 + 68 88 static struct mlx5_ct_fs_ops dmfs_ops = { 69 89 .ct_rule_add = mlx5_ct_fs_dmfs_ct_rule_add, 70 90 .ct_rule_del = mlx5_ct_fs_dmfs_ct_rule_del, 91 + .ct_rule_update = mlx5_ct_fs_dmfs_ct_rule_update, 71 92 72 93 .init = mlx5_ct_fs_dmfs_init, 73 94 .destroy = mlx5_ct_fs_dmfs_destroy,
+26
drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c
··· 368 368 kfree(smfs_rule); 369 369 } 370 370 371 + static int mlx5_ct_fs_smfs_ct_rule_update(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule, 372 + struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr) 373 + { 374 + struct mlx5_ct_fs_smfs_rule *smfs_rule = container_of(fs_rule, 375 + struct mlx5_ct_fs_smfs_rule, 376 + fs_rule); 377 + struct mlx5_ct_fs_smfs *fs_smfs = mlx5_ct_fs_priv(fs); 378 + struct mlx5dr_action *actions[3]; /* We only need to create 3 actions, see below. */ 379 + struct mlx5dr_rule *rule; 380 + 381 + actions[0] = smfs_rule->count_action; 382 + actions[1] = attr->modify_hdr->action.dr_action; 383 + actions[2] = fs_smfs->fwd_action; 384 + 385 + rule = mlx5_smfs_rule_create(smfs_rule->smfs_matcher->dr_matcher, spec, 386 + ARRAY_SIZE(actions), actions, spec->flow_context.flow_source); 387 + if (!rule) 388 + return -EINVAL; 389 + 390 + mlx5_smfs_rule_destroy(smfs_rule->rule); 391 + smfs_rule->rule = rule; 392 + 393 + return 0; 394 + } 395 + 371 396 static struct mlx5_ct_fs_ops fs_smfs_ops = { 372 397 .ct_rule_add = mlx5_ct_fs_smfs_ct_rule_add, 373 398 .ct_rule_del = mlx5_ct_fs_smfs_ct_rule_del, 399 + .ct_rule_update = mlx5_ct_fs_smfs_ct_rule_update, 374 400 375 401 .init = mlx5_ct_fs_smfs_init, 376 402 .destroy = mlx5_ct_fs_smfs_destroy,
+21 -25
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
··· 876 876 } 877 877 878 878 static int 879 - mlx5_tc_ct_entry_replace_rule(struct mlx5_tc_ct_priv *ct_priv, 880 - struct flow_rule *flow_rule, 881 - struct mlx5_ct_entry *entry, 882 - bool nat, u8 zone_restore_id) 879 + mlx5_tc_ct_entry_update_rule(struct mlx5_tc_ct_priv *ct_priv, 880 + struct flow_rule *flow_rule, 881 + struct mlx5_ct_entry *entry, 882 + bool nat, u8 zone_restore_id) 883 883 { 884 884 struct mlx5_ct_zone_rule *zone_rule = &entry->zone_rules[nat]; 885 885 struct mlx5_flow_attr *attr = zone_rule->attr, *old_attr; 886 886 struct mlx5e_mod_hdr_handle *mh; 887 - struct mlx5_ct_fs_rule *rule; 888 887 struct mlx5_flow_spec *spec; 889 888 int err; 890 889 ··· 901 902 err = mlx5_tc_ct_entry_create_mod_hdr(ct_priv, attr, flow_rule, &mh, zone_restore_id, 902 903 nat, mlx5_tc_ct_entry_in_ct_nat_table(entry)); 903 904 if (err) { 904 - ct_dbg("Failed to create ct entry mod hdr"); 905 + ct_dbg("Failed to create ct entry mod hdr, err: %d", err); 905 906 goto err_mod_hdr; 906 907 } 907 908 908 909 mlx5_tc_ct_set_tuple_match(ct_priv, spec, flow_rule); 909 910 mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG, entry->tuple.zone, MLX5_CT_ZONE_MASK); 910 911 911 - rule = ct_priv->fs_ops->ct_rule_add(ct_priv->fs, spec, attr, flow_rule); 912 - if (IS_ERR(rule)) { 913 - err = PTR_ERR(rule); 914 - ct_dbg("Failed to add replacement ct entry rule, nat: %d", nat); 912 + err = ct_priv->fs_ops->ct_rule_update(ct_priv->fs, zone_rule->rule, spec, attr); 913 + if (err) { 914 + ct_dbg("Failed to update ct entry rule, nat: %d, err: %d", nat, err); 915 915 goto err_rule; 916 916 } 917 917 918 - ct_priv->fs_ops->ct_rule_del(ct_priv->fs, zone_rule->rule); 919 - zone_rule->rule = rule; 920 918 mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, old_attr, zone_rule->mh); 921 919 zone_rule->mh = mh; 922 920 mlx5_put_label_mapping(ct_priv, old_attr->ct_attr.ct_labels_id); 923 921 924 922 kfree(old_attr); 925 923 kvfree(spec); 926 - ct_dbg("Replaced ct entry rule in zone %d", entry->tuple.zone); 924 + ct_dbg("Updated ct entry rule in zone %d", entry->tuple.zone); 927 925 928 926 return 0; 929 927 ··· 1137 1141 } 1138 1142 1139 1143 static int 1140 - mlx5_tc_ct_entry_replace_rules(struct mlx5_tc_ct_priv *ct_priv, 1141 - struct flow_rule *flow_rule, 1142 - struct mlx5_ct_entry *entry, 1143 - u8 zone_restore_id) 1144 + mlx5_tc_ct_entry_update_rules(struct mlx5_tc_ct_priv *ct_priv, 1145 + struct flow_rule *flow_rule, 1146 + struct mlx5_ct_entry *entry, 1147 + u8 zone_restore_id) 1144 1148 { 1145 1149 int err = 0; 1146 1150 1147 1151 if (mlx5_tc_ct_entry_in_ct_table(entry)) { 1148 - err = mlx5_tc_ct_entry_replace_rule(ct_priv, flow_rule, entry, false, 1149 - zone_restore_id); 1152 + err = mlx5_tc_ct_entry_update_rule(ct_priv, flow_rule, entry, false, 1153 + zone_restore_id); 1150 1154 if (err) 1151 1155 return err; 1152 1156 } 1153 1157 1154 1158 if (mlx5_tc_ct_entry_in_ct_nat_table(entry)) { 1155 - err = mlx5_tc_ct_entry_replace_rule(ct_priv, flow_rule, entry, true, 1156 - zone_restore_id); 1159 + err = mlx5_tc_ct_entry_update_rule(ct_priv, flow_rule, entry, true, 1160 + zone_restore_id); 1157 1161 if (err && mlx5_tc_ct_entry_in_ct_table(entry)) 1158 1162 mlx5_tc_ct_entry_del_rule(ct_priv, entry, false); 1159 1163 } ··· 1161 1165 } 1162 1166 1163 1167 static int 1164 - mlx5_tc_ct_block_flow_offload_replace(struct mlx5_ct_ft *ft, struct flow_rule *flow_rule, 1165 - struct mlx5_ct_entry *entry, unsigned long cookie) 1168 + mlx5_tc_ct_block_flow_offload_update(struct mlx5_ct_ft *ft, struct flow_rule *flow_rule, 1169 + struct mlx5_ct_entry *entry, unsigned long cookie) 1166 1170 { 1167 1171 struct mlx5_tc_ct_priv *ct_priv = ft->ct_priv; 1168 1172 int err; 1169 1173 1170 - err = mlx5_tc_ct_entry_replace_rules(ct_priv, flow_rule, entry, ft->zone_restore_id); 1174 + err = mlx5_tc_ct_entry_update_rules(ct_priv, flow_rule, entry, ft->zone_restore_id); 1171 1175 if (!err) 1172 1176 return 0; 1173 1177 ··· 1212 1216 entry->restore_cookie = meta_action->ct_metadata.cookie; 1213 1217 spin_unlock_bh(&ct_priv->ht_lock); 1214 1218 1215 - err = mlx5_tc_ct_block_flow_offload_replace(ft, flow_rule, entry, cookie); 1219 + err = mlx5_tc_ct_block_flow_offload_update(ft, flow_rule, entry, cookie); 1216 1220 mlx5_tc_ct_entry_put(entry); 1217 1221 return err; 1218 1222 }
+1
drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
··· 109 109 struct completion init_done; 110 110 struct completion del_hw_done; 111 111 struct mlx5_flow_attr *attr; 112 + struct mlx5_flow_attr *extra_split_attr; 112 113 struct list_head attrs; 113 114 u32 chain_mapping; 114 115 };
+1
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
··· 127 127 MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt, 128 128 attrs->lft.hard_packet_limit); 129 129 MLX5_SET(ipsec_aso, aso_ctx, hard_lft_arm, 1); 130 + MLX5_SET(ipsec_aso, aso_ctx, remove_flow_enable, 1); 130 131 } 131 132 132 133 if (attrs->lft.soft_packet_limit != XFRM_INF) {
+44 -42
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
··· 83 83 ({ \ 84 84 struct ptys2ethtool_config *cfg; \ 85 85 const unsigned int modes[] = { __VA_ARGS__ }; \ 86 - unsigned int i, bit, idx; \ 86 + unsigned int i; \ 87 87 cfg = &ptys2##table##_ethtool_table[reg_]; \ 88 88 bitmap_zero(cfg->supported, \ 89 89 __ETHTOOL_LINK_MODE_MASK_NBITS); \ 90 90 bitmap_zero(cfg->advertised, \ 91 91 __ETHTOOL_LINK_MODE_MASK_NBITS); \ 92 92 for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) { \ 93 - bit = modes[i] % 64; \ 94 - idx = modes[i] / 64; \ 95 - __set_bit(bit, &cfg->supported[idx]); \ 96 - __set_bit(bit, &cfg->advertised[idx]); \ 93 + bitmap_set(cfg->supported, modes[i], 1); \ 94 + bitmap_set(cfg->advertised, modes[i], 1); \ 97 95 } \ 98 96 }) 99 97 ··· 352 354 } 353 355 354 356 int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv, 355 - struct ethtool_ringparam *param) 357 + struct ethtool_ringparam *param, 358 + struct netlink_ext_ack *extack) 356 359 { 357 360 struct mlx5e_params new_params; 358 361 u8 log_rq_size; 359 362 u8 log_sq_size; 360 363 int err = 0; 361 364 362 - if (param->rx_jumbo_pending) { 363 - netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n", 364 - __func__); 365 - return -EINVAL; 366 - } 367 - if (param->rx_mini_pending) { 368 - netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n", 369 - __func__); 370 - return -EINVAL; 371 - } 372 - 373 365 if (param->rx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) { 374 - netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n", 375 - __func__, param->rx_pending, 376 - 1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE); 366 + NL_SET_ERR_MSG_FMT_MOD(extack, "rx (%d) < min (%d)", 367 + param->rx_pending, 368 + 1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE); 377 369 return -EINVAL; 378 370 } 379 371 380 372 if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { 381 - netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n", 382 - __func__, param->tx_pending, 383 - 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); 373 + NL_SET_ERR_MSG_FMT_MOD(extack, "tx (%d) < min (%d)", 374 + param->tx_pending, 375 + 1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE); 384 376 return -EINVAL; 385 377 } 386 378 ··· 406 418 { 407 419 struct mlx5e_priv *priv = netdev_priv(dev); 408 420 409 - return mlx5e_ethtool_set_ringparam(priv, param); 421 + return mlx5e_ethtool_set_ringparam(priv, param, extack); 410 422 } 411 423 412 424 void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv, ··· 545 557 546 558 int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv, 547 559 struct ethtool_coalesce *coal, 548 - struct kernel_ethtool_coalesce *kernel_coal) 560 + struct kernel_ethtool_coalesce *kernel_coal, 561 + struct netlink_ext_ack *extack) 549 562 { 550 563 struct dim_cq_moder *rx_moder, *tx_moder; 551 564 552 - if (!MLX5_CAP_GEN(priv->mdev, cq_moderation)) 565 + if (!MLX5_CAP_GEN(priv->mdev, cq_moderation)) { 566 + NL_SET_ERR_MSG_MOD(extack, "CQ moderation not supported"); 553 567 return -EOPNOTSUPP; 568 + } 554 569 555 570 rx_moder = &priv->channels.params.rx_cq_moderation; 556 571 coal->rx_coalesce_usecs = rx_moder->usec; ··· 577 586 { 578 587 struct mlx5e_priv *priv = netdev_priv(netdev); 579 588 580 - return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal); 589 + return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal, extack); 581 590 } 582 591 583 592 static int mlx5e_ethtool_get_per_queue_coalesce(struct mlx5e_priv *priv, u32 queue, ··· 699 708 int err = 0; 700 709 701 710 if (!MLX5_CAP_GEN(mdev, cq_moderation) || 702 - !MLX5_CAP_GEN(mdev, cq_period_mode_modify)) 711 + !MLX5_CAP_GEN(mdev, cq_period_mode_modify)) { 712 + NL_SET_ERR_MSG_MOD(extack, "CQ moderation not supported"); 703 713 return -EOPNOTSUPP; 714 + } 704 715 705 716 if (coal->tx_coalesce_usecs > MLX5E_MAX_COAL_TIME || 706 717 coal->rx_coalesce_usecs > MLX5E_MAX_COAL_TIME) { 707 - netdev_info(priv->netdev, "%s: maximum coalesce time supported is %lu usecs\n", 708 - __func__, MLX5E_MAX_COAL_TIME); 718 + NL_SET_ERR_MSG_FMT_MOD( 719 + extack, 720 + "Max coalesce time %lu usecs, tx-usecs (%u) rx-usecs (%u)", 721 + MLX5E_MAX_COAL_TIME, coal->tx_coalesce_usecs, 722 + coal->rx_coalesce_usecs); 709 723 return -ERANGE; 710 724 } 711 725 712 726 if (coal->tx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES || 713 727 coal->rx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES) { 714 - netdev_info(priv->netdev, "%s: maximum coalesced frames supported is %lu\n", 715 - __func__, MLX5E_MAX_COAL_FRAMES); 728 + NL_SET_ERR_MSG_FMT_MOD( 729 + extack, 730 + "Max coalesce frames %lu, tx-frames (%u) rx-frames (%u)", 731 + MLX5E_MAX_COAL_FRAMES, coal->tx_max_coalesced_frames, 732 + coal->rx_max_coalesced_frames); 716 733 return -ERANGE; 717 734 } 718 735 719 736 if ((kernel_coal->use_cqe_mode_rx || kernel_coal->use_cqe_mode_tx) && 720 737 !MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe)) { 721 - NL_SET_ERR_MSG_MOD(extack, "cqe_mode_rx/tx is not supported on this device"); 738 + NL_SET_ERR_MSG_MOD(extack, "cqe-mode-rx/tx is not supported on this device"); 722 739 return -EOPNOTSUPP; 723 740 } 724 741 ··· 1298 1299 u32 i, ptys_modes = 0; 1299 1300 1300 1301 for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) { 1301 - if (*ptys2legacy_ethtool_table[i].advertised == 0) 1302 + if (bitmap_empty(ptys2legacy_ethtool_table[i].advertised, 1303 + __ETHTOOL_LINK_MODE_MASK_NBITS)) 1302 1304 continue; 1303 1305 if (bitmap_intersects(ptys2legacy_ethtool_table[i].advertised, 1304 1306 link_modes, ··· 1313 1313 static u32 mlx5e_ethtool2ptys_ext_adver_link(const unsigned long *link_modes) 1314 1314 { 1315 1315 u32 i, ptys_modes = 0; 1316 - unsigned long modes[2]; 1316 + __ETHTOOL_DECLARE_LINK_MODE_MASK(modes); 1317 1317 1318 1318 for (i = 0; i < MLX5E_EXT_LINK_MODES_NUMBER; ++i) { 1319 - if (ptys2ext_ethtool_table[i].advertised[0] == 0 && 1320 - ptys2ext_ethtool_table[i].advertised[1] == 0) 1319 + if (bitmap_empty(ptys2ext_ethtool_table[i].advertised, 1320 + __ETHTOOL_LINK_MODE_MASK_NBITS)) 1321 1321 continue; 1322 - memset(modes, 0, sizeof(modes)); 1322 + bitmap_zero(modes, __ETHTOOL_LINK_MODE_MASK_NBITS); 1323 1323 bitmap_and(modes, ptys2ext_ethtool_table[i].advertised, 1324 1324 link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS); 1325 1325 1326 - if (modes[0] == ptys2ext_ethtool_table[i].advertised[0] && 1327 - modes[1] == ptys2ext_ethtool_table[i].advertised[1]) 1326 + if (bitmap_equal(modes, ptys2ext_ethtool_table[i].advertised, 1327 + __ETHTOOL_LINK_MODE_MASK_NBITS)) 1328 1328 ptys_modes |= MLX5E_PROT_MASK(i); 1329 1329 } 1330 1330 return ptys_modes; ··· 2015 2015 if (size_read == -EINVAL) 2016 2016 return -EINVAL; 2017 2017 if (size_read < 0) { 2018 - netdev_err(priv->netdev, "%s: mlx5_query_module_eeprom_by_page failed:0x%x\n", 2019 - __func__, size_read); 2018 + NL_SET_ERR_MSG_FMT_MOD( 2019 + extack, 2020 + "Query module eeprom by page failed, read %u bytes, err %d\n", 2021 + i, size_read); 2020 2022 return i; 2021 2023 } 2022 2024
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
··· 360 360 { 361 361 struct mlx5e_priv *priv = netdev_priv(dev); 362 362 363 - return mlx5e_ethtool_set_ringparam(priv, param); 363 + return mlx5e_ethtool_set_ringparam(priv, param, extack); 364 364 } 365 365 366 366 static void mlx5e_rep_get_channels(struct net_device *dev, ··· 386 386 { 387 387 struct mlx5e_priv *priv = netdev_priv(netdev); 388 388 389 - return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal); 389 + return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal, extack); 390 390 } 391 391 392 392 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
+120
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
··· 1740 1740 } 1741 1741 1742 1742 static int 1743 + extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr) 1744 + { 1745 + bool int_dest = false, ext_dest = false; 1746 + struct mlx5_esw_flow_attr *esw_attr; 1747 + int i; 1748 + 1749 + if (flow->attr != attr || 1750 + !list_is_first(&attr->list, &flow->attrs)) 1751 + return 0; 1752 + 1753 + if (flow_flag_test(flow, SLOW)) 1754 + return 0; 1755 + 1756 + esw_attr = attr->esw_attr; 1757 + if (!esw_attr->split_count || 1758 + esw_attr->split_count == esw_attr->out_count - 1) 1759 + return 0; 1760 + 1761 + if (esw_attr->dest_int_port && 1762 + (esw_attr->dests[esw_attr->split_count].flags & 1763 + MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE)) 1764 + return esw_attr->split_count + 1; 1765 + 1766 + for (i = esw_attr->split_count; i < esw_attr->out_count; i++) { 1767 + /* external dest with encap is considered as internal by firmware */ 1768 + if (esw_attr->dests[i].vport == MLX5_VPORT_UPLINK && 1769 + !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP_VALID)) 1770 + ext_dest = true; 1771 + else 1772 + int_dest = true; 1773 + 1774 + if (ext_dest && int_dest) 1775 + return esw_attr->split_count; 1776 + } 1777 + 1778 + return 0; 1779 + } 1780 + 1781 + static int 1782 + extra_split_attr_dests(struct mlx5e_tc_flow *flow, 1783 + struct mlx5_flow_attr *attr, int split_count) 1784 + { 1785 + struct mlx5e_post_act *post_act = get_post_action(flow->priv); 1786 + struct mlx5e_tc_flow_parse_attr *parse_attr, *parse_attr2; 1787 + struct mlx5_esw_flow_attr *esw_attr, *esw_attr2; 1788 + struct mlx5e_post_act_handle *handle; 1789 + struct mlx5_flow_attr *attr2; 1790 + int i, j, err; 1791 + 1792 + if (IS_ERR(post_act)) 1793 + return PTR_ERR(post_act); 1794 + 1795 + attr2 = mlx5_alloc_flow_attr(mlx5e_get_flow_namespace(flow)); 1796 + parse_attr2 = kvzalloc(sizeof(*parse_attr), GFP_KERNEL); 1797 + if (!attr2 || !parse_attr2) { 1798 + err = -ENOMEM; 1799 + goto err_free; 1800 + } 1801 + attr2->parse_attr = parse_attr2; 1802 + 1803 + handle = mlx5e_tc_post_act_add(post_act, attr2); 1804 + if (IS_ERR(handle)) { 1805 + err = PTR_ERR(handle); 1806 + goto err_free; 1807 + } 1808 + 1809 + esw_attr = attr->esw_attr; 1810 + esw_attr2 = attr2->esw_attr; 1811 + esw_attr2->in_rep = esw_attr->in_rep; 1812 + 1813 + parse_attr = attr->parse_attr; 1814 + parse_attr2->filter_dev = parse_attr->filter_dev; 1815 + 1816 + for (i = split_count, j = 0; i < esw_attr->out_count; i++, j++) 1817 + esw_attr2->dests[j] = esw_attr->dests[i]; 1818 + 1819 + esw_attr2->out_count = j; 1820 + attr2->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 1821 + 1822 + err = mlx5e_tc_post_act_offload(post_act, handle); 1823 + if (err) 1824 + goto err_post_act_offload; 1825 + 1826 + err = mlx5e_tc_post_act_set_handle(flow->priv->mdev, handle, 1827 + &parse_attr->mod_hdr_acts); 1828 + if (err) 1829 + goto err_post_act_set_handle; 1830 + 1831 + esw_attr->out_count = split_count; 1832 + attr->extra_split_ft = mlx5e_tc_post_act_get_ft(post_act); 1833 + flow->extra_split_attr = attr2; 1834 + 1835 + attr2->post_act_handle = handle; 1836 + 1837 + return 0; 1838 + 1839 + err_post_act_set_handle: 1840 + mlx5e_tc_post_act_unoffload(post_act, handle); 1841 + err_post_act_offload: 1842 + mlx5e_tc_post_act_del(post_act, handle); 1843 + err_free: 1844 + kvfree(parse_attr2); 1845 + kfree(attr2); 1846 + return err; 1847 + } 1848 + 1849 + static int 1743 1850 post_process_attr(struct mlx5e_tc_flow *flow, 1744 1851 struct mlx5_flow_attr *attr, 1745 1852 struct netlink_ext_ack *extack) 1746 1853 { 1854 + int extra_split; 1747 1855 bool vf_tun; 1748 1856 int err = 0; 1749 1857 ··· 1861 1753 1862 1754 if (mlx5e_is_eswitch_flow(flow) && has_encap_dests(attr)) { 1863 1755 err = mlx5e_tc_tun_encap_dests_set(flow->priv, flow, attr, extack, &vf_tun); 1756 + if (err) 1757 + goto err_out; 1758 + } 1759 + 1760 + extra_split = extra_split_attr_dests_needed(flow, attr); 1761 + if (extra_split > 0) { 1762 + err = extra_split_attr_dests(flow, attr, extra_split); 1864 1763 if (err) 1865 1764 goto err_out; 1866 1765 } ··· 2086 1971 mlx5e_tc_act_stats_del_flow(get_act_stats_handle(priv), flow); 2087 1972 2088 1973 free_flow_post_acts(flow); 1974 + if (flow->extra_split_attr) { 1975 + mlx5_free_flow_attr_actions(flow, flow->extra_split_attr); 1976 + kvfree(flow->extra_split_attr->parse_attr); 1977 + kfree(flow->extra_split_attr); 1978 + } 2089 1979 mlx5_free_flow_attr_actions(flow, attr); 2090 1980 2091 1981 kvfree(attr->esw_attr->rx_tun_attr);
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
··· 86 86 u32 dest_chain; 87 87 struct mlx5_flow_table *ft; 88 88 struct mlx5_flow_table *dest_ft; 89 + struct mlx5_flow_table *extra_split_ft; 89 90 u8 inner_match_level; 90 91 u8 outer_match_level; 91 92 u8 tun_ip_version; ··· 140 139 #define MLX5E_TC_TABLE_CHAIN_TAG_BITS 16 141 140 #define MLX5E_TC_TABLE_CHAIN_TAG_MASK GENMASK(MLX5E_TC_TABLE_CHAIN_TAG_BITS - 1, 0) 142 141 143 - #define MLX5E_TC_MAX_INT_PORT_NUM (8) 142 + #define MLX5E_TC_MAX_INT_PORT_NUM (32) 144 143 145 144 #if IS_ENABLED(CONFIG_MLX5_CLS_ACT) 146 145
+7
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
··· 613 613 } 614 614 } 615 615 616 + if (attr->extra_split_ft) { 617 + flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; 618 + dest[*i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 619 + dest[*i].ft = attr->extra_split_ft; 620 + (*i)++; 621 + } 622 + 616 623 out: 617 624 return err; 618 625 }
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
··· 74 74 { 75 75 struct mlx5e_priv *priv = mlx5i_epriv(dev); 76 76 77 - return mlx5e_ethtool_set_ringparam(priv, param); 77 + return mlx5e_ethtool_set_ringparam(priv, param, extack); 78 78 } 79 79 80 80 static void mlx5i_get_ringparam(struct net_device *dev, ··· 132 132 { 133 133 struct mlx5e_priv *priv = mlx5i_epriv(netdev); 134 134 135 - return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal); 135 + return mlx5e_ethtool_get_coalesce(priv, coal, kernel_coal, extack); 136 136 } 137 137 138 138 static int mlx5i_get_ts_info(struct net_device *netdev,