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

Merge tag 'mlx5-fixes-2023-02-07' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5 fixes 2023-02-07

This series provides bug fixes to mlx5 driver.

* tag 'mlx5-fixes-2023-02-07' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
net/mlx5: Serialize module cleanup with reload and remove
net/mlx5: fw_tracer, Zero consumer index when reloading the tracer
net/mlx5: fw_tracer, Clear load bit when freeing string DBs buffers
net/mlx5: Expose SF firmware pages counter
net/mlx5: Store page counters in a single array
net/mlx5e: IPoIB, Show unknown speed instead of error
net/mlx5e: Fix crash unsetting rx-vlan-filter in switchdev mode
net/mlx5: Bridge, fix ageing of peer FDB entries
net/mlx5: DR, Fix potential race in dr_rule_create_rule_nic
net/mlx5e: Update rx ring hw mtu upon each rx-fcs flag change
====================

Link: https://lore.kernel.org/r/20230208030302.95378-1-saeed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+86 -126
+3 -2
drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
··· 245 245 pages = dev->priv.dbg.pages_debugfs; 246 246 247 247 debugfs_create_u32("fw_pages_total", 0400, pages, &dev->priv.fw_pages); 248 - debugfs_create_u32("fw_pages_vfs", 0400, pages, &dev->priv.vfs_pages); 249 - debugfs_create_u32("fw_pages_host_pf", 0400, pages, &dev->priv.host_pf_pages); 248 + debugfs_create_u32("fw_pages_vfs", 0400, pages, &dev->priv.page_counters[MLX5_VF]); 249 + debugfs_create_u32("fw_pages_sfs", 0400, pages, &dev->priv.page_counters[MLX5_SF]); 250 + debugfs_create_u32("fw_pages_host_pf", 0400, pages, &dev->priv.page_counters[MLX5_HOST_PF]); 250 251 debugfs_create_u32("fw_pages_alloc_failed", 0400, pages, &dev->priv.fw_pages_alloc_failed); 251 252 debugfs_create_u32("fw_pages_give_dropped", 0400, pages, &dev->priv.give_pages_dropped); 252 253 debugfs_create_u32("fw_pages_reclaim_discard", 0400, pages,
+2 -1
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
··· 64 64 MLX5_GET(mtrc_cap, out, num_string_trace); 65 65 tracer->str_db.num_string_db = MLX5_GET(mtrc_cap, out, num_string_db); 66 66 tracer->owner = !!MLX5_GET(mtrc_cap, out, trace_owner); 67 + tracer->str_db.loaded = false; 67 68 68 69 for (i = 0; i < tracer->str_db.num_string_db; i++) { 69 70 mtrc_cap_sp = MLX5_ADDR_OF(mtrc_cap, out, string_db_param[i]); ··· 757 756 if (err) 758 757 mlx5_core_warn(dev, "FWTracer: Failed to set tracer configurations %d\n", err); 759 758 759 + tracer->buff.consumer_index = 0; 760 760 return err; 761 761 } 762 762 ··· 822 820 mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner); 823 821 if (tracer->owner) { 824 822 tracer->owner = false; 825 - tracer->buff.consumer_index = 0; 826 823 return; 827 824 } 828 825
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/ecpf.c
··· 87 87 88 88 mlx5_host_pf_cleanup(dev); 89 89 90 - err = mlx5_wait_for_pages(dev, &dev->priv.host_pf_pages); 90 + err = mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_HOST_PF]); 91 91 if (err) 92 92 mlx5_core_warn(dev, "Timeout reclaiming external host PF pages err(%d)\n", err); 93 93 }
-4
drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
··· 438 438 439 439 switch (event) { 440 440 case SWITCHDEV_FDB_ADD_TO_BRIDGE: 441 - /* only handle the event on native eswtich of representor */ 442 - if (!mlx5_esw_bridge_is_local(dev, rep, esw)) 443 - break; 444 - 445 441 fdb_info = container_of(info, 446 442 struct switchdev_notifier_fdb_info, 447 443 info);
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
··· 443 443 444 444 void mlx5e_disable_cvlan_filter(struct mlx5e_flow_steering *fs, bool promisc) 445 445 { 446 - if (fs->vlan->cvlan_filter_disabled) 446 + if (!fs->vlan || fs->vlan->cvlan_filter_disabled) 447 447 return; 448 448 449 449 fs->vlan->cvlan_filter_disabled = true;
+19 -71
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 591 591 rq->ix = c->ix; 592 592 rq->channel = c; 593 593 rq->mdev = mdev; 594 - rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); 594 + rq->hw_mtu = 595 + MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN * !params->scatter_fcs_en; 595 596 rq->xdpsq = &c->rq_xdpsq; 596 597 rq->stats = &c->priv->channel_stats[c->ix]->rq; 597 598 rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev); ··· 1013 1012 mlx5e_free_rx_descs(rq); 1014 1013 1015 1014 return mlx5e_rq_to_ready(rq, curr_state); 1016 - } 1017 - 1018 - static int mlx5e_modify_rq_scatter_fcs(struct mlx5e_rq *rq, bool enable) 1019 - { 1020 - struct mlx5_core_dev *mdev = rq->mdev; 1021 - 1022 - void *in; 1023 - void *rqc; 1024 - int inlen; 1025 - int err; 1026 - 1027 - inlen = MLX5_ST_SZ_BYTES(modify_rq_in); 1028 - in = kvzalloc(inlen, GFP_KERNEL); 1029 - if (!in) 1030 - return -ENOMEM; 1031 - 1032 - rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); 1033 - 1034 - MLX5_SET(modify_rq_in, in, rq_state, MLX5_RQC_STATE_RDY); 1035 - MLX5_SET64(modify_rq_in, in, modify_bitmask, 1036 - MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS); 1037 - MLX5_SET(rqc, rqc, scatter_fcs, enable); 1038 - MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY); 1039 - 1040 - err = mlx5_core_modify_rq(mdev, rq->rqn, in); 1041 - 1042 - kvfree(in); 1043 - 1044 - return err; 1045 1015 } 1046 1016 1047 1017 static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd) ··· 3286 3314 mlx5e_destroy_tises(priv); 3287 3315 } 3288 3316 3289 - static int mlx5e_modify_channels_scatter_fcs(struct mlx5e_channels *chs, bool enable) 3290 - { 3291 - int err = 0; 3292 - int i; 3293 - 3294 - for (i = 0; i < chs->num; i++) { 3295 - err = mlx5e_modify_rq_scatter_fcs(&chs->c[i]->rq, enable); 3296 - if (err) 3297 - return err; 3298 - } 3299 - 3300 - return 0; 3301 - } 3302 - 3303 3317 static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) 3304 3318 { 3305 3319 int err; ··· 3861 3903 return mlx5_set_ports_check(mdev, in, sizeof(in)); 3862 3904 } 3863 3905 3906 + static int mlx5e_set_rx_port_ts_wrap(struct mlx5e_priv *priv, void *ctx) 3907 + { 3908 + struct mlx5_core_dev *mdev = priv->mdev; 3909 + bool enable = *(bool *)ctx; 3910 + 3911 + return mlx5e_set_rx_port_ts(mdev, enable); 3912 + } 3913 + 3864 3914 static int set_feature_rx_fcs(struct net_device *netdev, bool enable) 3865 3915 { 3866 3916 struct mlx5e_priv *priv = netdev_priv(netdev); 3867 3917 struct mlx5e_channels *chs = &priv->channels; 3868 - struct mlx5_core_dev *mdev = priv->mdev; 3918 + struct mlx5e_params new_params; 3869 3919 int err; 3870 3920 3871 3921 mutex_lock(&priv->state_lock); 3872 3922 3873 - if (enable) { 3874 - err = mlx5e_set_rx_port_ts(mdev, false); 3875 - if (err) 3876 - goto out; 3877 - 3878 - chs->params.scatter_fcs_en = true; 3879 - err = mlx5e_modify_channels_scatter_fcs(chs, true); 3880 - if (err) { 3881 - chs->params.scatter_fcs_en = false; 3882 - mlx5e_set_rx_port_ts(mdev, true); 3883 - } 3884 - } else { 3885 - chs->params.scatter_fcs_en = false; 3886 - err = mlx5e_modify_channels_scatter_fcs(chs, false); 3887 - if (err) { 3888 - chs->params.scatter_fcs_en = true; 3889 - goto out; 3890 - } 3891 - err = mlx5e_set_rx_port_ts(mdev, true); 3892 - if (err) { 3893 - mlx5_core_warn(mdev, "Failed to set RX port timestamp %d\n", err); 3894 - err = 0; 3895 - } 3896 - } 3897 - 3898 - out: 3923 + new_params = chs->params; 3924 + new_params.scatter_fcs_en = enable; 3925 + err = mlx5e_safe_switch_params(priv, &new_params, mlx5e_set_rx_port_ts_wrap, 3926 + &new_params.scatter_fcs_en, true); 3899 3927 mutex_unlock(&priv->state_lock); 3900 3928 return err; 3901 3929 } ··· 4017 4073 features &= ~NETIF_F_GRO_HW; 4018 4074 if (netdev->features & NETIF_F_GRO_HW) 4019 4075 netdev_warn(netdev, "Disabling HW_GRO, not supported in switchdev mode\n"); 4076 + 4077 + features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; 4078 + if (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) 4079 + netdev_warn(netdev, "Disabling HW_VLAN CTAG FILTERING, not supported in switchdev mode\n"); 4020 4080 4021 4081 return features; 4022 4082 }
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
··· 1715 1715 struct mlx5_esw_bridge *bridge; 1716 1716 1717 1717 port = mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads); 1718 - if (!port || port->flags & MLX5_ESW_BRIDGE_PORT_FLAG_PEER) 1718 + if (!port) 1719 1719 return; 1720 1720 1721 1721 bridge = port->bridge;
+5 -8
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
··· 189 189 } 190 190 } 191 191 192 - static int mlx5i_get_speed_settings(u16 ib_link_width_oper, u16 ib_proto_oper) 192 + static u32 mlx5i_get_speed_settings(u16 ib_link_width_oper, u16 ib_proto_oper) 193 193 { 194 194 int rate, width; 195 195 196 196 rate = mlx5_ptys_rate_enum_to_int(ib_proto_oper); 197 197 if (rate < 0) 198 - return -EINVAL; 198 + return SPEED_UNKNOWN; 199 199 width = mlx5_ptys_width_enum_to_int(ib_link_width_oper); 200 200 if (width < 0) 201 - return -EINVAL; 201 + return SPEED_UNKNOWN; 202 202 203 203 return rate * width; 204 204 } ··· 221 221 ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); 222 222 223 223 speed = mlx5i_get_speed_settings(ib_link_width_oper, ib_proto_oper); 224 - if (speed < 0) 225 - return -EINVAL; 224 + link_ksettings->base.speed = speed; 225 + link_ksettings->base.duplex = speed == SPEED_UNKNOWN ? DUPLEX_UNKNOWN : DUPLEX_FULL; 226 226 227 - link_ksettings->base.duplex = DUPLEX_FULL; 228 227 link_ksettings->base.port = PORT_OTHER; 229 228 230 229 link_ksettings->base.autoneg = AUTONEG_DISABLE; 231 - 232 - link_ksettings->base.speed = speed; 233 230 234 231 return 0; 235 232 }
+7 -7
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 2110 2110 mlx5_core_verify_params(); 2111 2111 mlx5_register_debugfs(); 2112 2112 2113 - err = pci_register_driver(&mlx5_core_driver); 2113 + err = mlx5e_init(); 2114 2114 if (err) 2115 2115 goto err_debug; 2116 2116 ··· 2118 2118 if (err) 2119 2119 goto err_sf; 2120 2120 2121 - err = mlx5e_init(); 2121 + err = pci_register_driver(&mlx5_core_driver); 2122 2122 if (err) 2123 - goto err_en; 2123 + goto err_pci; 2124 2124 2125 2125 return 0; 2126 2126 2127 - err_en: 2127 + err_pci: 2128 2128 mlx5_sf_driver_unregister(); 2129 2129 err_sf: 2130 - pci_unregister_driver(&mlx5_core_driver); 2130 + mlx5e_cleanup(); 2131 2131 err_debug: 2132 2132 mlx5_unregister_debugfs(); 2133 2133 return err; ··· 2135 2135 2136 2136 static void __exit mlx5_cleanup(void) 2137 2137 { 2138 - mlx5e_cleanup(); 2139 - mlx5_sf_driver_unregister(); 2140 2138 pci_unregister_driver(&mlx5_core_driver); 2139 + mlx5_sf_driver_unregister(); 2140 + mlx5e_cleanup(); 2141 2141 mlx5_unregister_debugfs(); 2142 2142 } 2143 2143
+21 -16
drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
··· 74 74 return (u32)func_id | (ec_function << 16); 75 75 } 76 76 77 + static u16 func_id_to_type(struct mlx5_core_dev *dev, u16 func_id, bool ec_function) 78 + { 79 + if (!func_id) 80 + return mlx5_core_is_ecpf(dev) && !ec_function ? MLX5_HOST_PF : MLX5_PF; 81 + 82 + return func_id <= mlx5_core_max_vfs(dev) ? MLX5_VF : MLX5_SF; 83 + } 84 + 77 85 static struct rb_root *page_root_per_function(struct mlx5_core_dev *dev, u32 function) 78 86 { 79 87 struct rb_root *root; ··· 340 332 u32 out[MLX5_ST_SZ_DW(manage_pages_out)] = {0}; 341 333 int inlen = MLX5_ST_SZ_BYTES(manage_pages_in); 342 334 int notify_fail = event; 335 + u16 func_type; 343 336 u64 addr; 344 337 int err; 345 338 u32 *in; ··· 392 383 goto out_dropped; 393 384 } 394 385 386 + func_type = func_id_to_type(dev, func_id, ec_function); 387 + dev->priv.page_counters[func_type] += npages; 395 388 dev->priv.fw_pages += npages; 396 - if (func_id) 397 - dev->priv.vfs_pages += npages; 398 - else if (mlx5_core_is_ecpf(dev) && !ec_function) 399 - dev->priv.host_pf_pages += npages; 400 389 401 390 mlx5_core_dbg(dev, "npages %d, ec_function %d, func_id 0x%x, err %d\n", 402 391 npages, ec_function, func_id, err); ··· 421 414 struct rb_root *root; 422 415 struct rb_node *p; 423 416 int npages = 0; 417 + u16 func_type; 424 418 425 419 root = xa_load(&dev->priv.page_root_xa, function); 426 420 if (WARN_ON_ONCE(!root)) ··· 436 428 free_fwp(dev, fwp, fwp->free_count); 437 429 } 438 430 431 + func_type = func_id_to_type(dev, func_id, ec_function); 432 + dev->priv.page_counters[func_type] -= npages; 439 433 dev->priv.fw_pages -= npages; 440 - if (func_id) 441 - dev->priv.vfs_pages -= npages; 442 - else if (mlx5_core_is_ecpf(dev) && !ec_function) 443 - dev->priv.host_pf_pages -= npages; 444 434 445 435 mlx5_core_dbg(dev, "npages %d, ec_function %d, func_id 0x%x\n", 446 436 npages, ec_function, func_id); ··· 504 498 int outlen = MLX5_ST_SZ_BYTES(manage_pages_out); 505 499 u32 in[MLX5_ST_SZ_DW(manage_pages_in)] = {}; 506 500 int num_claimed; 501 + u16 func_type; 507 502 u32 *out; 508 503 int err; 509 504 int i; ··· 556 549 if (nclaimed) 557 550 *nclaimed = num_claimed; 558 551 552 + func_type = func_id_to_type(dev, func_id, ec_function); 553 + dev->priv.page_counters[func_type] -= num_claimed; 559 554 dev->priv.fw_pages -= num_claimed; 560 - if (func_id) 561 - dev->priv.vfs_pages -= num_claimed; 562 - else if (mlx5_core_is_ecpf(dev) && !ec_function) 563 - dev->priv.host_pf_pages -= num_claimed; 564 555 565 556 out_free: 566 557 kvfree(out); ··· 711 706 WARN(dev->priv.fw_pages, 712 707 "FW pages counter is %d after reclaiming all pages\n", 713 708 dev->priv.fw_pages); 714 - WARN(dev->priv.vfs_pages, 709 + WARN(dev->priv.page_counters[MLX5_VF], 715 710 "VFs FW pages counter is %d after reclaiming all pages\n", 716 - dev->priv.vfs_pages); 717 - WARN(dev->priv.host_pf_pages, 711 + dev->priv.page_counters[MLX5_VF]); 712 + WARN(dev->priv.page_counters[MLX5_HOST_PF], 718 713 "External host PF FW pages counter is %d after reclaiming all pages\n", 719 - dev->priv.host_pf_pages); 714 + dev->priv.page_counters[MLX5_HOST_PF]); 720 715 721 716 return 0; 722 717 }
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/sriov.c
··· 147 147 148 148 mlx5_eswitch_disable_sriov(dev->priv.eswitch, clear_vf); 149 149 150 - if (mlx5_wait_for_pages(dev, &dev->priv.vfs_pages)) 150 + if (mlx5_wait_for_pages(dev, &dev->priv.page_counters[MLX5_VF])) 151 151 mlx5_core_warn(dev, "timeout reclaiming VFs pages\n"); 152 152 } 153 153
+15 -10
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
··· 1138 1138 rule->flow_source)) 1139 1139 return 0; 1140 1140 1141 + mlx5dr_domain_nic_lock(nic_dmn); 1142 + 1141 1143 ret = mlx5dr_matcher_select_builders(matcher, 1142 1144 nic_matcher, 1143 1145 dr_rule_get_ipv(&param->outer), 1144 1146 dr_rule_get_ipv(&param->inner)); 1145 1147 if (ret) 1146 - return ret; 1148 + goto err_unlock; 1147 1149 1148 1150 hw_ste_arr_is_opt = nic_matcher->num_of_builders <= DR_RULE_MAX_STES_OPTIMIZED; 1149 1151 if (likely(hw_ste_arr_is_opt)) { ··· 1154 1152 hw_ste_arr = kzalloc((nic_matcher->num_of_builders + DR_ACTION_MAX_STES) * 1155 1153 DR_STE_SIZE, GFP_KERNEL); 1156 1154 1157 - if (!hw_ste_arr) 1158 - return -ENOMEM; 1155 + if (!hw_ste_arr) { 1156 + ret = -ENOMEM; 1157 + goto err_unlock; 1158 + } 1159 1159 } 1160 - 1161 - mlx5dr_domain_nic_lock(nic_dmn); 1162 1160 1163 1161 ret = mlx5dr_matcher_add_to_tbl_nic(dmn, nic_matcher); 1164 1162 if (ret) ··· 1225 1223 1226 1224 mlx5dr_domain_nic_unlock(nic_dmn); 1227 1225 1228 - goto out; 1226 + if (unlikely(!hw_ste_arr_is_opt)) 1227 + kfree(hw_ste_arr); 1228 + 1229 + return 0; 1229 1230 1230 1231 free_rule: 1231 1232 dr_rule_clean_rule_members(rule, nic_rule); ··· 1243 1238 mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher); 1244 1239 1245 1240 free_hw_ste: 1246 - mlx5dr_domain_nic_unlock(nic_dmn); 1247 - 1248 - out: 1249 - if (unlikely(!hw_ste_arr_is_opt)) 1241 + if (!hw_ste_arr_is_opt) 1250 1242 kfree(hw_ste_arr); 1243 + 1244 + err_unlock: 1245 + mlx5dr_domain_nic_unlock(nic_dmn); 1251 1246 1252 1247 return ret; 1253 1248 }
+10 -3
include/linux/mlx5/driver.h
··· 573 573 struct dentry *lag_debugfs; 574 574 }; 575 575 576 + enum mlx5_func_type { 577 + MLX5_PF, 578 + MLX5_VF, 579 + MLX5_SF, 580 + MLX5_HOST_PF, 581 + MLX5_FUNC_TYPE_NUM, 582 + }; 583 + 576 584 struct mlx5_ft_pool; 577 585 struct mlx5_priv { 578 586 /* IRQ table valid only for real pci devices PF or VF */ ··· 591 583 struct mlx5_nb pg_nb; 592 584 struct workqueue_struct *pg_wq; 593 585 struct xarray page_root_xa; 594 - u32 fw_pages; 595 586 atomic_t reg_pages; 596 587 struct list_head free_list; 597 - u32 vfs_pages; 598 - u32 host_pf_pages; 588 + u32 fw_pages; 589 + u32 page_counters[MLX5_FUNC_TYPE_NUM]; 599 590 u32 fw_pages_alloc_failed; 600 591 u32 give_pages_dropped; 601 592 u32 reclaim_pages_discard;