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 'net-mlx5-misc-changes-2025-11-17'

Tariq Toukan says:

====================
net/mlx5: misc changes 2025-11-17

This series contains misc enhancements to the mlx5 driver.
====================

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

+111 -51
+55
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
··· 181 181 static void cmd_free_index(struct mlx5_cmd *cmd, int idx) 182 182 { 183 183 lockdep_assert_held(&cmd->alloc_lock); 184 + cmd->ent_arr[idx] = NULL; 184 185 set_bit(idx, &cmd->vars.bitmask); 185 186 } 186 187 ··· 1201 1200 return err; 1202 1201 } 1203 1202 1203 + /* Check if all command slots are stalled (timed out and not recovered). 1204 + * returns true if all slots timed out on a recent command and have not been 1205 + * completed by FW yet. (stalled state) 1206 + * false otherwise (at least one slot is not stalled). 1207 + * 1208 + * In such odd situation "all_stalled", this serves as a protection mechanism 1209 + * to avoid blocking the kernel for long periods of time in case FW is not 1210 + * responding to commands. 1211 + */ 1212 + static bool mlx5_cmd_all_stalled(struct mlx5_core_dev *dev) 1213 + { 1214 + struct mlx5_cmd *cmd = &dev->cmd; 1215 + bool all_stalled = true; 1216 + unsigned long flags; 1217 + int i; 1218 + 1219 + spin_lock_irqsave(&cmd->alloc_lock, flags); 1220 + 1221 + /* at least one command slot is free */ 1222 + if (bitmap_weight(&cmd->vars.bitmask, cmd->vars.max_reg_cmds) > 0) { 1223 + all_stalled = false; 1224 + goto out; 1225 + } 1226 + 1227 + for_each_clear_bit(i, &cmd->vars.bitmask, cmd->vars.max_reg_cmds) { 1228 + struct mlx5_cmd_work_ent *ent = dev->cmd.ent_arr[i]; 1229 + 1230 + if (!test_bit(MLX5_CMD_ENT_STATE_TIMEDOUT, &ent->state)) { 1231 + all_stalled = false; 1232 + break; 1233 + } 1234 + } 1235 + out: 1236 + spin_unlock_irqrestore(&cmd->alloc_lock, flags); 1237 + 1238 + return all_stalled; 1239 + } 1240 + 1204 1241 /* Notes: 1205 1242 * 1. Callback functions may not sleep 1206 1243 * 2. page queue commands do not support asynchrous completion ··· 1268 1229 1269 1230 if (callback && page_queue) 1270 1231 return -EINVAL; 1232 + 1233 + if (!page_queue && mlx5_cmd_all_stalled(dev)) { 1234 + mlx5_core_err_rl(dev, 1235 + "All CMD slots are stalled, aborting command\n"); 1236 + /* there's no reason to wait and block the whole kernel if FW 1237 + * isn't currently responding to all slots, fail immediately 1238 + */ 1239 + return -EAGAIN; 1240 + } 1271 1241 1272 1242 ent = cmd_alloc_ent(cmd, in, out, uout, uout_size, 1273 1243 callback, context, page_queue); ··· 1747 1699 for (i = 0; i < (1 << cmd->vars.log_sz); i++) { 1748 1700 if (test_bit(i, &vector)) { 1749 1701 ent = cmd->ent_arr[i]; 1702 + 1703 + if (forced && ent->ret == -ETIMEDOUT) 1704 + set_bit(MLX5_CMD_ENT_STATE_TIMEDOUT, 1705 + &ent->state); 1706 + else if (!forced) /* real FW completion */ 1707 + clear_bit(MLX5_CMD_ENT_STATE_TIMEDOUT, 1708 + &ent->state); 1750 1709 1751 1710 /* if we already completed the command, ignore it */ 1752 1711 if (!test_and_clear_bit(MLX5_CMD_ENT_STATE_PENDING_COMP,
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
··· 54 54 55 55 if (!MLX5_GET(mtrc_cap, out, trace_to_memory)) { 56 56 mlx5_core_dbg(dev, "FWTracer: Device does not support logging traces to memory\n"); 57 - return -ENOTSUPP; 57 + return -EOPNOTSUPP; 58 58 } 59 59 60 60 tracer->trc_ver = MLX5_GET(mtrc_cap, out, trc_ver);
+15 -6
drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
··· 82 82 } 83 83 84 84 static void mlx5e_skb_cb_hwtstamp_tx(struct sk_buff *skb, 85 - struct mlx5e_ptp_cq_stats *cq_stats) 85 + struct mlx5e_ptpsq *ptpsq) 86 86 { 87 87 struct skb_shared_hwtstamps hwts = {}; 88 88 ktime_t diff; ··· 92 92 93 93 /* Maximal allowed diff is 1 / 128 second */ 94 94 if (diff > (NSEC_PER_SEC >> 7)) { 95 - cq_stats->abort++; 96 - cq_stats->abort_abs_diff_ns += diff; 95 + struct mlx5e_txqsq *sq = &ptpsq->txqsq; 96 + 97 + ptpsq->cq_stats->abort++; 98 + ptpsq->cq_stats->abort_abs_diff_ns += diff; 99 + if (diff > (NSEC_PER_SEC >> 1) && 100 + !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) { 101 + netdev_warn(sq->channel->netdev, 102 + "PTP TX timestamp difference between CQE and port exceeds threshold: %lld ns, recovering SQ %u\n", 103 + (s64)diff, sq->sqn); 104 + queue_work(sq->priv->wq, &ptpsq->report_unhealthy_work); 105 + } 97 106 return; 98 107 } 99 108 ··· 112 103 113 104 void mlx5e_skb_cb_hwtstamp_handler(struct sk_buff *skb, int hwtstamp_type, 114 105 ktime_t hwtstamp, 115 - struct mlx5e_ptp_cq_stats *cq_stats) 106 + struct mlx5e_ptpsq *ptpsq) 116 107 { 117 108 switch (hwtstamp_type) { 118 109 case (MLX5E_SKB_CB_CQE_HWTSTAMP): ··· 130 121 !mlx5e_skb_cb_get_hwts(skb)->port_hwtstamp) 131 122 return; 132 123 133 - mlx5e_skb_cb_hwtstamp_tx(skb, cq_stats); 124 + mlx5e_skb_cb_hwtstamp_tx(skb, ptpsq); 134 125 memset(skb->cb, 0, sizeof(struct mlx5e_skb_cb_hwtstamp)); 135 126 } 136 127 ··· 218 209 219 210 hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, get_cqe_ts(cqe)); 220 211 mlx5e_skb_cb_hwtstamp_handler(skb, MLX5E_SKB_CB_PORT_HWTSTAMP, 221 - hwtstamp, ptpsq->cq_stats); 212 + hwtstamp, ptpsq); 222 213 ptpsq->cq_stats->cqe++; 223 214 224 215 mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp);
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
··· 147 147 148 148 void mlx5e_skb_cb_hwtstamp_handler(struct sk_buff *skb, int hwtstamp_type, 149 149 ktime_t hwtstamp, 150 - struct mlx5e_ptp_cq_stats *cq_stats); 150 + struct mlx5e_ptpsq *ptpsq); 151 151 152 152 void mlx5e_skb_cb_hwtstamp_init(struct sk_buff *skb); 153 153 #endif /* __MLX5_EN_PTP_H__ */
+11 -8
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
··· 2027 2027 int size_read = 0; 2028 2028 u8 data[4] = {0}; 2029 2029 2030 - size_read = mlx5_query_module_eeprom(dev, 0, 2, data); 2030 + size_read = mlx5_query_module_eeprom(dev, 0, 2, data, NULL); 2031 2031 if (size_read < 2) 2032 2032 return -EIO; 2033 2033 ··· 2069 2069 struct mlx5_core_dev *mdev = priv->mdev; 2070 2070 int offset = ee->offset; 2071 2071 int size_read; 2072 + u8 status = 0; 2072 2073 int i = 0; 2073 2074 2074 2075 if (!ee->len) ··· 2079 2078 2080 2079 while (i < ee->len) { 2081 2080 size_read = mlx5_query_module_eeprom(mdev, offset, ee->len - i, 2082 - data + i); 2083 - 2081 + data + i, &status); 2084 2082 if (!size_read) 2085 2083 /* Done reading */ 2086 2084 return 0; 2087 2085 2088 2086 if (size_read < 0) { 2089 - netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n", 2090 - __func__, size_read); 2087 + netdev_err(netdev, 2088 + "%s: mlx5_query_eeprom failed:0x%x, status %u\n", 2089 + __func__, size_read, status); 2091 2090 return size_read; 2092 2091 } 2093 2092 ··· 2107 2106 struct mlx5_core_dev *mdev = priv->mdev; 2108 2107 u8 *data = page_data->data; 2109 2108 int size_read; 2109 + u8 status = 0; 2110 2110 int i = 0; 2111 2111 2112 2112 if (!page_data->length) ··· 2121 2119 query.page = page_data->page; 2122 2120 while (i < page_data->length) { 2123 2121 query.size = page_data->length - i; 2124 - size_read = mlx5_query_module_eeprom_by_page(mdev, &query, data + i); 2122 + size_read = mlx5_query_module_eeprom_by_page(mdev, &query, 2123 + data + i, &status); 2125 2124 2126 2125 /* Done reading, return how many bytes was read */ 2127 2126 if (!size_read) ··· 2131 2128 if (size_read < 0) { 2132 2129 NL_SET_ERR_MSG_FMT_MOD( 2133 2130 extack, 2134 - "Query module eeprom by page failed, read %u bytes, err %d", 2135 - i, size_read); 2131 + "Query module eeprom by page failed, read %u bytes, err %d, status %u", 2132 + i, size_read, status); 2136 2133 return size_read; 2137 2134 } 2138 2135
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
··· 704 704 num_tuples += ret; 705 705 break; 706 706 default: 707 - return -ENOTSUPP; 707 + return -EOPNOTSUPP; 708 708 } 709 709 if ((fs->flow_type & FLOW_EXT)) { 710 710 ret = validate_vlan(fs);
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
··· 755 755 hwts.hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, ts); 756 756 if (sq->ptpsq) { 757 757 mlx5e_skb_cb_hwtstamp_handler(skb, MLX5E_SKB_CB_CQE_HWTSTAMP, 758 - hwts.hwtstamp, sq->ptpsq->cq_stats); 758 + hwts.hwtstamp, sq->ptpsq); 759 759 } else { 760 760 skb_tstamp_tx(skb, &hwts); 761 761 sq->stats->timestamps++;
-7
drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
··· 341 341 if (max_guarantee) 342 342 return max_t(u32, max_guarantee / fw_max_bw_share, 1); 343 343 344 - /* If nodes max min_rate divider is 0 but their parent has bw_share 345 - * configured, then set bw_share for nodes to minimal value. 346 - */ 347 - 348 - if (parent && parent->bw_share) 349 - return 1; 350 - 351 344 /* If the node nodes has min_rate configured, a divider of 0 sets all 352 345 * nodes' bw_share to 0, effectively disabling min guarantees. 353 346 */
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c
··· 211 211 max_num_qps = MLX5_CAP_FPGA(mdev, shell_caps.max_num_qps); 212 212 if (!max_num_qps) { 213 213 mlx5_fpga_err(fdev, "FPGA reports 0 QPs in SHELL_CAPS\n"); 214 - err = -ENOTSUPP; 214 + err = -EOPNOTSUPP; 215 215 goto out; 216 216 } 217 217
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
··· 149 149 struct mlx5_vxlan *vxlan; 150 150 151 151 if (!MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) || !mlx5_core_is_pf(mdev)) 152 - return ERR_PTR(-ENOTSUPP); 152 + return ERR_PTR(-EOPNOTSUPP); 153 153 154 154 vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); 155 155 if (!vxlan)
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
··· 357 357 void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported, 358 358 bool *enabled); 359 359 int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, 360 - u16 offset, u16 size, u8 *data); 360 + u16 offset, u16 size, u8 *data, u8 *status); 361 361 int 362 362 mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev, 363 363 struct mlx5_module_eeprom_query_params *params, 364 - u8 *data); 364 + u8 *data, u8 *status); 365 365 366 366 int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out); 367 367 int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
+17 -18
drivers/net/ethernet/mellanox/mlx5/core/port.c
··· 289 289 } 290 290 291 291 static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num, 292 - u8 *module_id) 292 + u8 *module_id, u8 *status) 293 293 { 294 294 u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {}; 295 295 u32 out[MLX5_ST_SZ_DW(mcia_reg)]; 296 - int err, status; 296 + int err; 297 297 u8 *ptr; 298 298 299 299 MLX5_SET(mcia_reg, in, i2c_device_address, MLX5_I2C_ADDR_LOW); ··· 308 308 if (err) 309 309 return err; 310 310 311 - status = MLX5_GET(mcia_reg, out, status); 312 - if (status) { 313 - mlx5_core_err(dev, "query_mcia_reg failed: status: 0x%x\n", 314 - status); 311 + if (MLX5_GET(mcia_reg, out, status)) { 312 + if (status) 313 + *status = MLX5_GET(mcia_reg, out, status); 315 314 return -EIO; 316 315 } 316 + 317 317 ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); 318 318 319 319 *module_id = ptr[0]; ··· 370 370 } 371 371 372 372 static int mlx5_query_mcia(struct mlx5_core_dev *dev, 373 - struct mlx5_module_eeprom_query_params *params, u8 *data) 373 + struct mlx5_module_eeprom_query_params *params, 374 + u8 *data, u8 *status) 374 375 { 375 376 u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {}; 376 377 u32 out[MLX5_ST_SZ_DW(mcia_reg)]; 377 - int status, err; 378 378 void *ptr; 379 379 u16 size; 380 + int err; 380 381 381 382 size = min_t(int, params->size, mlx5_mcia_max_bytes(dev)); 382 383 ··· 393 392 if (err) 394 393 return err; 395 394 396 - status = MLX5_GET(mcia_reg, out, status); 397 - if (status) { 398 - mlx5_core_err(dev, "query_mcia_reg failed: status: 0x%x\n", 399 - status); 395 + *status = MLX5_GET(mcia_reg, out, status); 396 + if (*status) 400 397 return -EIO; 401 - } 402 398 403 399 ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); 404 400 memcpy(data, ptr, size); ··· 404 406 } 405 407 406 408 int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, 407 - u16 offset, u16 size, u8 *data) 409 + u16 offset, u16 size, u8 *data, u8 *status) 408 410 { 409 411 struct mlx5_module_eeprom_query_params query = {0}; 410 412 u8 module_id; ··· 414 416 if (err) 415 417 return err; 416 418 417 - err = mlx5_query_module_id(dev, query.module_number, &module_id); 419 + err = mlx5_query_module_id(dev, query.module_number, &module_id, 420 + status); 418 421 if (err) 419 422 return err; 420 423 ··· 440 441 query.size = size; 441 442 query.offset = offset; 442 443 443 - return mlx5_query_mcia(dev, &query, data); 444 + return mlx5_query_mcia(dev, &query, data, status); 444 445 } 445 446 446 447 int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev, 447 448 struct mlx5_module_eeprom_query_params *params, 448 - u8 *data) 449 + u8 *data, u8 *status) 449 450 { 450 451 int err; 451 452 ··· 459 460 return -EINVAL; 460 461 } 461 462 462 - return mlx5_query_mcia(dev, params, data); 463 + return mlx5_query_mcia(dev, params, data, status); 463 464 } 464 465 465 466 static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
+4 -4
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c
··· 410 410 switch (dmn->type) { 411 411 case MLX5DR_DOMAIN_TYPE_NIC_RX: 412 412 if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, rx)) 413 - return -ENOTSUPP; 413 + return -EOPNOTSUPP; 414 414 415 415 dmn->info.supp_sw_steering = true; 416 416 dmn->info.rx.type = DR_DOMAIN_NIC_TYPE_RX; ··· 419 419 break; 420 420 case MLX5DR_DOMAIN_TYPE_NIC_TX: 421 421 if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, tx)) 422 - return -ENOTSUPP; 422 + return -EOPNOTSUPP; 423 423 424 424 dmn->info.supp_sw_steering = true; 425 425 dmn->info.tx.type = DR_DOMAIN_NIC_TYPE_TX; ··· 428 428 break; 429 429 case MLX5DR_DOMAIN_TYPE_FDB: 430 430 if (!dmn->info.caps.eswitch_manager) 431 - return -ENOTSUPP; 431 + return -EOPNOTSUPP; 432 432 433 433 if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, fdb)) 434 - return -ENOTSUPP; 434 + return -EOPNOTSUPP; 435 435 436 436 dmn->info.rx.type = DR_DOMAIN_NIC_TYPE_RX; 437 437 dmn->info.tx.type = DR_DOMAIN_NIC_TYPE_TX;
+1
include/linux/mlx5/driver.h
··· 819 819 820 820 enum { 821 821 MLX5_CMD_ENT_STATE_PENDING_COMP, 822 + MLX5_CMD_ENT_STATE_TIMEDOUT, 822 823 }; 823 824 824 825 struct mlx5_cmd_work_ent {