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

Merge tag 'mlx5-updates-2017-06-16' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox mlx5 updates and cleanups 2017-06-16

mlx5-updates-2017-06-16

This series provide some updates and cleanups for mlx5 core and netdevice
driver.

From Eli Cohen, add a missing event string.
From Or Gerlitz, some checkpatch cleanups.
From Moni, Disalbe HW level LAG when SRIOV is enabled.
From Tariq, A code reuse cleanup in aRFS flow.
From Itay Aveksis, Typo fix.
From Gal Pressman, ethtool statistics updates and "update stats" deferred work optimizations.
From Majd Dibbiny, Fast unload support on kernel shutdown.
====================

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

+227 -124
+1 -1
drivers/infiniband/hw/mlx5/main.c
··· 439 439 u8 atomic_operations = MLX5_CAP_ATOMIC(dev->mdev, atomic_operations); 440 440 u8 atomic_size_qp = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_qp); 441 441 u8 atomic_req_8B_endianness_mode = 442 - MLX5_CAP_ATOMIC(dev->mdev, atomic_req_8B_endianess_mode); 442 + MLX5_CAP_ATOMIC(dev->mdev, atomic_req_8B_endianness_mode); 443 443 444 444 /* Check if HW supports 8 bytes standard atomic operations and capable 445 445 * of host endianness respond
-1
drivers/net/ethernet/mellanox/mlx5/core/alloc.c
··· 274 274 } 275 275 EXPORT_SYMBOL_GPL(mlx5_db_free); 276 276 277 - 278 277 void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas) 279 278 { 280 279 u64 addr;
+25 -11
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
··· 217 217 kfree(ent); 218 218 } 219 219 220 - 221 220 static int verify_signature(struct mlx5_cmd_work_ent *ent) 222 221 { 223 222 struct mlx5_cmd_mailbox *next = ent->out->next; ··· 785 786 struct mlx5_cmd_layout *lay; 786 787 struct semaphore *sem; 787 788 unsigned long flags; 789 + bool poll_cmd = ent->polling; 790 + 788 791 789 792 sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; 790 793 down(sem); ··· 847 846 iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell); 848 847 mmiowb(); 849 848 /* if not in polling don't use ent after this point */ 850 - if (cmd->mode == CMD_MODE_POLLING) { 849 + if (cmd->mode == CMD_MODE_POLLING || poll_cmd) { 851 850 poll_timeout(ent); 852 851 /* make sure we read the descriptor after ownership is SW */ 853 852 rmb(); ··· 875 874 case MLX5_CMD_DELIVERY_STAT_IN_LENGTH_ERR: 876 875 return "command input length error"; 877 876 case MLX5_CMD_DELIVERY_STAT_OUT_LENGTH_ERR: 878 - return "command ouput length error"; 877 + return "command output length error"; 879 878 case MLX5_CMD_DELIVERY_STAT_RES_FLD_NOT_CLR_ERR: 880 879 return "reserved fields not cleared"; 881 880 case MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR: ··· 891 890 struct mlx5_cmd *cmd = &dev->cmd; 892 891 int err; 893 892 894 - if (cmd->mode == CMD_MODE_POLLING) { 893 + if (cmd->mode == CMD_MODE_POLLING || ent->polling) { 895 894 wait_for_completion(&ent->done); 896 895 } else if (!wait_for_completion_timeout(&ent->done, timeout)) { 897 896 ent->ret = -ETIMEDOUT; ··· 919 918 struct mlx5_cmd_msg *out, void *uout, int uout_size, 920 919 mlx5_cmd_cbk_t callback, 921 920 void *context, int page_queue, u8 *status, 922 - u8 token) 921 + u8 token, bool force_polling) 923 922 { 924 923 struct mlx5_cmd *cmd = &dev->cmd; 925 924 struct mlx5_cmd_work_ent *ent; ··· 937 936 return PTR_ERR(ent); 938 937 939 938 ent->token = token; 939 + ent->polling = force_polling; 940 940 941 941 if (!callback) 942 942 init_completion(&ent->done); ··· 1002 1000 1003 1001 return err ? err : count; 1004 1002 } 1005 - 1006 1003 1007 1004 static const struct file_operations fops = { 1008 1005 .owner = THIS_MODULE, ··· 1154 1153 } 1155 1154 1156 1155 static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev, 1157 - struct mlx5_cmd_msg *msg) 1156 + struct mlx5_cmd_msg *msg) 1158 1157 { 1159 1158 struct mlx5_cmd_mailbox *head = msg->next; 1160 1159 struct mlx5_cmd_mailbox *next; ··· 1538 1537 } 1539 1538 1540 1539 static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, 1541 - int out_size, mlx5_cmd_cbk_t callback, void *context) 1540 + int out_size, mlx5_cmd_cbk_t callback, void *context, 1541 + bool force_polling) 1542 1542 { 1543 1543 struct mlx5_cmd_msg *inb; 1544 1544 struct mlx5_cmd_msg *outb; ··· 1584 1582 } 1585 1583 1586 1584 err = mlx5_cmd_invoke(dev, inb, outb, out, out_size, callback, context, 1587 - pages_queue, &status, token); 1585 + pages_queue, &status, token, force_polling); 1588 1586 if (err) 1589 1587 goto out_out; 1590 1588 ··· 1612 1610 { 1613 1611 int err; 1614 1612 1615 - err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL); 1613 + err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false); 1616 1614 return err ? : mlx5_cmd_check(dev, in, out); 1617 1615 } 1618 1616 EXPORT_SYMBOL(mlx5_cmd_exec); ··· 1621 1619 void *out, int out_size, mlx5_cmd_cbk_t callback, 1622 1620 void *context) 1623 1621 { 1624 - return cmd_exec(dev, in, in_size, out, out_size, callback, context); 1622 + return cmd_exec(dev, in, in_size, out, out_size, callback, context, 1623 + false); 1625 1624 } 1626 1625 EXPORT_SYMBOL(mlx5_cmd_exec_cb); 1626 + 1627 + int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size, 1628 + void *out, int out_size) 1629 + { 1630 + int err; 1631 + 1632 + err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true); 1633 + 1634 + return err ? : mlx5_cmd_check(dev, in, out); 1635 + } 1636 + EXPORT_SYMBOL(mlx5_cmd_exec_polling); 1627 1637 1628 1638 static void destroy_msg_cache(struct mlx5_core_dev *dev) 1629 1639 {
-3
drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
··· 168 168 return ret; 169 169 } 170 170 171 - 172 171 static ssize_t average_write(struct file *filp, const char __user *buf, 173 172 size_t count, loff_t *pos) 174 173 { ··· 465 466 return -EINVAL; 466 467 } 467 468 468 - 469 469 if (is_str) 470 470 ret = snprintf(tbuf, sizeof(tbuf), "%s\n", (const char *)(unsigned long)field); 471 471 else ··· 559 561 if (qp->dbg) 560 562 rem_res_tree(qp->dbg); 561 563 } 562 - 563 564 564 565 int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq) 565 566 {
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en.h
··· 822 822 void mlx5e_rx_am_work(struct work_struct *work); 823 823 struct mlx5e_cq_moder mlx5e_am_get_def_profile(u8 rx_cq_period_mode); 824 824 825 - void mlx5e_update_stats(struct mlx5e_priv *priv); 825 + void mlx5e_update_stats(struct mlx5e_priv *priv, bool full); 826 826 827 827 int mlx5e_create_flow_steering(struct mlx5e_priv *priv); 828 828 void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv);
+7 -14
drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
··· 178 178 struct mlx5_flow_destination dest; 179 179 MLX5_DECLARE_FLOW_ACT(flow_act); 180 180 struct mlx5_flow_spec *spec; 181 + enum mlx5e_traffic_types tt; 181 182 int err = 0; 182 183 183 184 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); ··· 188 187 } 189 188 190 189 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; 191 - switch (type) { 192 - case ARFS_IPV4_TCP: 193 - dest.tir_num = tir[MLX5E_TT_IPV4_TCP].tirn; 194 - break; 195 - case ARFS_IPV4_UDP: 196 - dest.tir_num = tir[MLX5E_TT_IPV4_UDP].tirn; 197 - break; 198 - case ARFS_IPV6_TCP: 199 - dest.tir_num = tir[MLX5E_TT_IPV6_TCP].tirn; 200 - break; 201 - case ARFS_IPV6_UDP: 202 - dest.tir_num = tir[MLX5E_TT_IPV6_UDP].tirn; 203 - break; 204 - default: 190 + tt = arfs_get_tt(type); 191 + if (tt == -EINVAL) { 192 + netdev_err(priv->netdev, "%s: bad arfs_type: %d\n", 193 + __func__, type); 205 194 err = -EINVAL; 206 195 goto out; 207 196 } 197 + 198 + dest.tir_num = tir[tt].tirn; 208 199 209 200 arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, spec, 210 201 &flow_act,
-1
drivers/net/ethernet/mellanox/mlx5/core/en_common.c
··· 145 145 int inlen; 146 146 void *in; 147 147 148 - 149 148 inlen = MLX5_ST_SZ_BYTES(modify_tir_in); 150 149 in = kvzalloc(inlen, GFP_KERNEL); 151 150 if (!in)
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
··· 311 311 312 312 mutex_lock(&priv->state_lock); 313 313 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 314 - mlx5e_update_stats(priv); 314 + mlx5e_update_stats(priv, true); 315 315 channels = &priv->channels; 316 316 mutex_unlock(&priv->state_lock); 317 317
-1
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
··· 170 170 171 171 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 172 172 173 - 174 173 switch (rule_type) { 175 174 case MLX5E_VLAN_RULE_TYPE_UNTAGGED: 176 175 rule_p = &priv->fs.vlan.untagged_rule;
+27 -25
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 124 124 u8 port_state; 125 125 126 126 port_state = mlx5_query_vport_state(mdev, 127 - MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT, 0); 127 + MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT, 128 + 0); 128 129 129 130 if (port_state == VPORT_STATE_UP) { 130 131 netdev_info(priv->netdev, "Link up\n"); ··· 244 243 mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen); 245 244 } 246 245 247 - static void mlx5e_update_pport_counters(struct mlx5e_priv *priv) 246 + static void mlx5e_update_pport_counters(struct mlx5e_priv *priv, bool full) 248 247 { 249 248 struct mlx5e_pport_stats *pstats = &priv->stats.pport; 250 249 struct mlx5_core_dev *mdev = priv->mdev; 250 + u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0}; 251 251 int sz = MLX5_ST_SZ_BYTES(ppcnt_reg); 252 252 int prio; 253 253 void *out; 254 - u32 *in; 255 - 256 - in = kvzalloc(sz, GFP_KERNEL); 257 - if (!in) 258 - return; 259 254 260 255 MLX5_SET(ppcnt_reg, in, local_port, 1); 261 256 262 257 out = pstats->IEEE_802_3_counters; 263 258 MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP); 264 259 mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0); 260 + 261 + if (!full) 262 + return; 265 263 266 264 out = pstats->RFC_2863_counters; 267 265 MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP); ··· 287 287 mlx5_core_access_reg(mdev, in, sz, out, sz, 288 288 MLX5_REG_PPCNT, 0, 0); 289 289 } 290 - 291 - kvfree(in); 292 290 } 293 291 294 292 static void mlx5e_update_q_counter(struct mlx5e_priv *priv) 295 293 { 296 294 struct mlx5e_qcounter_stats *qcnt = &priv->stats.qcnt; 295 + u32 out[MLX5_ST_SZ_DW(query_q_counter_out)]; 296 + int err; 297 297 298 298 if (!priv->q_counter) 299 299 return; 300 300 301 - mlx5_core_query_out_of_buffer(priv->mdev, priv->q_counter, 302 - &qcnt->rx_out_of_buffer); 301 + err = mlx5_core_query_q_counter(priv->mdev, priv->q_counter, 0, out, sizeof(out)); 302 + if (err) 303 + return; 304 + 305 + qcnt->rx_out_of_buffer = MLX5_GET(query_q_counter_out, out, out_of_buffer); 303 306 } 304 307 305 308 static void mlx5e_update_pcie_counters(struct mlx5e_priv *priv) 306 309 { 307 310 struct mlx5e_pcie_stats *pcie_stats = &priv->stats.pcie; 308 311 struct mlx5_core_dev *mdev = priv->mdev; 312 + u32 in[MLX5_ST_SZ_DW(mpcnt_reg)] = {0}; 309 313 int sz = MLX5_ST_SZ_BYTES(mpcnt_reg); 310 314 void *out; 311 - u32 *in; 312 315 313 316 if (!MLX5_CAP_MCAM_FEATURE(mdev, pcie_performance_group)) 314 - return; 315 - 316 - in = kvzalloc(sz, GFP_KERNEL); 317 - if (!in) 318 317 return; 319 318 320 319 out = pcie_stats->pcie_perf_counters; 321 320 MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP); 322 321 mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0); 323 - 324 - kvfree(in); 325 322 } 326 323 327 - void mlx5e_update_stats(struct mlx5e_priv *priv) 324 + void mlx5e_update_stats(struct mlx5e_priv *priv, bool full) 328 325 { 329 - mlx5e_update_pcie_counters(priv); 330 - mlx5e_update_pport_counters(priv); 326 + if (full) 327 + mlx5e_update_pcie_counters(priv); 328 + mlx5e_update_pport_counters(priv, full); 331 329 mlx5e_update_vport_counters(priv); 332 330 mlx5e_update_q_counter(priv); 333 331 mlx5e_update_sw_counters(priv); 332 + } 333 + 334 + static void mlx5e_update_ndo_stats(struct mlx5e_priv *priv) 335 + { 336 + mlx5e_update_stats(priv, false); 334 337 } 335 338 336 339 void mlx5e_update_stats_work(struct work_struct *work) ··· 3070 3067 */ 3071 3068 stats->multicast = 3072 3069 VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); 3073 - 3074 3070 } 3075 3071 3076 3072 static void mlx5e_set_rx_mode(struct net_device *dev) ··· 3729 3727 if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable)) 3730 3728 mlx5_core_warn(mdev, "Self loop back prevention is not supported\n"); 3731 3729 if (!MLX5_CAP_GEN(mdev, cq_moderation)) 3732 - mlx5_core_warn(mdev, "CQ modiration is not supported\n"); 3730 + mlx5_core_warn(mdev, "CQ moderation is not supported\n"); 3733 3731 3734 3732 return 0; 3735 3733 } ··· 3862 3860 /* set CQE compression */ 3863 3861 params->rx_cqe_compress_def = false; 3864 3862 if (MLX5_CAP_GEN(mdev, cqe_compression) && 3865 - MLX5_CAP_GEN(mdev, vport_group_manager)) 3863 + MLX5_CAP_GEN(mdev, vport_group_manager)) 3866 3864 params->rx_cqe_compress_def = cqe_compress_heuristic(link_speed, pci_bw); 3867 3865 3868 3866 MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def); ··· 4213 4211 .cleanup_tx = mlx5e_cleanup_nic_tx, 4214 4212 .enable = mlx5e_nic_enable, 4215 4213 .disable = mlx5e_nic_disable, 4216 - .update_stats = mlx5e_update_stats, 4214 + .update_stats = mlx5e_update_ndo_stats, 4217 4215 .max_nch = mlx5e_get_max_num_channels, 4218 4216 .rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe, 4219 4217 .rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
-1
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
··· 1019 1019 mlx5e_destroy_netdev(netdev_priv(netdev)); 1020 1020 kfree(rpriv); 1021 1021 return err; 1022 - 1023 1022 } 1024 1023 1025 1024 static void
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
··· 268 268 }; 269 269 270 270 static const struct counter_desc pport_phy_statistical_stats_desc[] = { 271 - { "rx_symbol_errors_phy", PPORT_PHY_STATISTICAL_OFF(phy_symbol_errors) }, 271 + { "rx_pcs_symbol_err_phy", PPORT_PHY_STATISTICAL_OFF(phy_symbol_errors) }, 272 272 { "rx_corrected_bits_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits) }, 273 273 }; 274 274
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
··· 245 245 int fsz = skb_frag_size(frag); 246 246 247 247 dma_addr = skb_frag_dma_map(sq->pdev, frag, 0, fsz, 248 - DMA_TO_DEVICE); 248 + DMA_TO_DEVICE); 249 249 if (unlikely(dma_mapping_error(sq->pdev, dma_addr))) 250 250 return -ENOMEM; 251 251
+3 -3
drivers/net/ethernet/mellanox/mlx5/core/eq.c
··· 157 157 return "MLX5_EVENT_TYPE_PAGE_FAULT"; 158 158 case MLX5_EVENT_TYPE_PPS_EVENT: 159 159 return "MLX5_EVENT_TYPE_PPS_EVENT"; 160 + case MLX5_EVENT_TYPE_NIC_VPORT_CHANGE: 161 + return "MLX5_EVENT_TYPE_NIC_VPORT_CHANGE"; 160 162 case MLX5_EVENT_TYPE_FPGA_ERROR: 161 163 return "MLX5_EVENT_TYPE_FPGA_ERROR"; 162 164 default: ··· 191 189 { 192 190 __be32 __iomem *addr = eq->doorbell + (arm ? 0 : 2); 193 191 u32 val = (eq->cons_index & 0xffffff) | (eq->eqn << 24); 194 - __raw_writel((__force u32) cpu_to_be32(val), addr); 192 + __raw_writel((__force u32)cpu_to_be32(val), addr); 195 193 /* We still want ordering, just not swabbing, so add a barrier */ 196 194 mb(); 197 195 } ··· 677 675 return err; 678 676 } 679 677 680 - 681 678 void mlx5_eq_cleanup(struct mlx5_core_dev *dev) 682 679 { 683 680 mlx5_eq_debugfs_cleanup(dev); ··· 687 686 struct mlx5_eq_table *table = &dev->priv.eq_table; 688 687 u64 async_event_mask = MLX5_ASYNC_EVENT_MASK; 689 688 int err; 690 - 691 689 692 690 if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH && 693 691 MLX5_CAP_GEN(dev, vport_group_manager) &&
-1
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 1217 1217 "vport[%d] configure ingress rules failed, illegal mac with spoofchk\n", 1218 1218 vport->vport); 1219 1219 return -EPERM; 1220 - 1221 1220 } 1222 1221 1223 1222 esw_vport_cleanup_ingress_rules(esw, vport);
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
··· 691 691 692 692 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 693 693 flow_rule = mlx5_add_flow_rules(esw->offloads.ft_offloads, spec, 694 - &flow_act, &dest, 1); 694 + &flow_act, &dest, 1); 695 695 if (IS_ERR(flow_rule)) { 696 696 esw_warn(esw->dev, "fs offloads: Failed to add vport rx rule err %ld\n", PTR_ERR(flow_rule)); 697 697 goto out; ··· 1093 1093 if (err) { 1094 1094 esw_warn(esw->dev, "Failed re-creating fast FDB table, err %d\n", err); 1095 1095 esw->offloads.encap = !encap; 1096 - (void) esw_create_offloads_fast_fdb_table(esw); 1096 + (void)esw_create_offloads_fast_fdb_table(esw); 1097 1097 } 1098 1098 return err; 1099 1099 }
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
··· 104 104 size_t arr_sz; 105 105 long *caps; 106 106 }; 107 + 107 108 static struct init_tree_node { 108 109 enum fs_node_type type; 109 110 struct init_tree_node *children; ··· 1859 1858 1860 1859 static int init_root_ns(struct mlx5_flow_steering *steering) 1861 1860 { 1862 - 1863 1861 steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); 1864 1862 if (!steering->root_ns) 1865 1863 goto cleanup;
+28
drivers/net/ethernet/mellanox/mlx5/core/fw.c
··· 195 195 MLX5_SET(teardown_hca_in, in, opcode, MLX5_CMD_OP_TEARDOWN_HCA); 196 196 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 197 197 } 198 + 199 + int mlx5_cmd_force_teardown_hca(struct mlx5_core_dev *dev) 200 + { 201 + u32 out[MLX5_ST_SZ_DW(teardown_hca_out)] = {0}; 202 + u32 in[MLX5_ST_SZ_DW(teardown_hca_in)] = {0}; 203 + int force_state; 204 + int ret; 205 + 206 + if (!MLX5_CAP_GEN(dev, force_teardown)) { 207 + mlx5_core_dbg(dev, "force teardown is not supported in the firmware\n"); 208 + return -EOPNOTSUPP; 209 + } 210 + 211 + MLX5_SET(teardown_hca_in, in, opcode, MLX5_CMD_OP_TEARDOWN_HCA); 212 + MLX5_SET(teardown_hca_in, in, profile, MLX5_TEARDOWN_HCA_IN_PROFILE_FORCE_CLOSE); 213 + 214 + ret = mlx5_cmd_exec_polling(dev, in, sizeof(in), out, sizeof(out)); 215 + if (ret) 216 + return ret; 217 + 218 + force_state = MLX5_GET(teardown_hca_out, out, force_state); 219 + if (force_state == MLX5_TEARDOWN_HCA_OUT_FORCE_STATE_FAIL) { 220 + mlx5_core_err(dev, "teardown with force mode failed\n"); 221 + return -EIO; 222 + } 223 + 224 + return 0; 225 + }
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/health.c
··· 111 111 return 0; 112 112 } 113 113 114 - void mlx5_enter_error_state(struct mlx5_core_dev *dev) 114 + void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force) 115 115 { 116 116 mutex_lock(&dev->intf_state_mutex); 117 117 if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) 118 118 goto unlock; 119 119 120 120 mlx5_core_err(dev, "start\n"); 121 - if (pci_channel_offline(dev->pdev) || in_fatal(dev)) { 121 + if (pci_channel_offline(dev->pdev) || in_fatal(dev) || force) { 122 122 dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; 123 123 trigger_cmd_completions(dev); 124 124 }
+61 -10
drivers/net/ethernet/mellanox/mlx5/core/lag.c
··· 61 61 struct lag_tracker tracker; 62 62 struct delayed_work bond_work; 63 63 struct notifier_block nb; 64 + 65 + /* Admin state. Allow lag only if allowed is true 66 + * even if network conditions for lag were met 67 + */ 68 + bool allowed; 64 69 }; 65 70 66 71 /* General purpose, use for short periods of time. ··· 219 214 struct lag_tracker tracker; 220 215 u8 v2p_port1, v2p_port2; 221 216 int i, err; 217 + bool do_bond; 222 218 223 219 if (!dev0 || !dev1) 224 220 return; ··· 228 222 tracker = ldev->tracker; 229 223 mutex_unlock(&lag_mutex); 230 224 231 - if (tracker.is_bonded && !mlx5_lag_is_bonded(ldev)) { 232 - if (mlx5_sriov_is_enabled(dev0) || 233 - mlx5_sriov_is_enabled(dev1)) { 234 - mlx5_core_warn(dev0, "LAG is not supported with SRIOV"); 235 - return; 236 - } 225 + do_bond = tracker.is_bonded && ldev->allowed; 237 226 227 + if (do_bond && !mlx5_lag_is_bonded(ldev)) { 238 228 for (i = 0; i < MLX5_MAX_PORTS; i++) 239 229 mlx5_remove_dev_by_protocol(ldev->pf[i].dev, 240 230 MLX5_INTERFACE_PROTOCOL_IB); ··· 239 237 240 238 mlx5_add_dev_by_protocol(dev0, MLX5_INTERFACE_PROTOCOL_IB); 241 239 mlx5_nic_vport_enable_roce(dev1); 242 - } else if (tracker.is_bonded && mlx5_lag_is_bonded(ldev)) { 240 + } else if (do_bond && mlx5_lag_is_bonded(ldev)) { 243 241 mlx5_infer_tx_affinity_mapping(&tracker, &v2p_port1, 244 242 &v2p_port2); 245 243 ··· 254 252 "Failed to modify LAG (%d)\n", 255 253 err); 256 254 } 257 - } else if (!tracker.is_bonded && mlx5_lag_is_bonded(ldev)) { 255 + } else if (!do_bond && mlx5_lag_is_bonded(ldev)) { 258 256 mlx5_remove_dev_by_protocol(dev0, MLX5_INTERFACE_PROTOCOL_IB); 259 257 mlx5_nic_vport_disable_roce(dev1); 260 258 ··· 413 411 return NOTIFY_DONE; 414 412 } 415 413 414 + static bool mlx5_lag_check_prereq(struct mlx5_lag *ldev) 415 + { 416 + if ((ldev->pf[0].dev && mlx5_sriov_is_enabled(ldev->pf[0].dev)) || 417 + (ldev->pf[1].dev && mlx5_sriov_is_enabled(ldev->pf[1].dev))) 418 + return false; 419 + else 420 + return true; 421 + } 422 + 416 423 static struct mlx5_lag *mlx5_lag_dev_alloc(void) 417 424 { 418 425 struct mlx5_lag *ldev; ··· 431 420 return NULL; 432 421 433 422 INIT_DELAYED_WORK(&ldev->bond_work, mlx5_do_bond_work); 423 + ldev->allowed = mlx5_lag_check_prereq(ldev); 434 424 435 425 return ldev; 436 426 } ··· 456 444 ldev->tracker.netdev_state[fn].link_up = 0; 457 445 ldev->tracker.netdev_state[fn].tx_enabled = 0; 458 446 447 + ldev->allowed = mlx5_lag_check_prereq(ldev); 459 448 dev->priv.lag = ldev; 449 + 460 450 mutex_unlock(&lag_mutex); 461 451 } 462 452 ··· 478 464 memset(&ldev->pf[i], 0, sizeof(*ldev->pf)); 479 465 480 466 dev->priv.lag = NULL; 467 + ldev->allowed = mlx5_lag_check_prereq(ldev); 481 468 mutex_unlock(&lag_mutex); 482 469 } 483 - 484 470 485 471 /* Must be called with intf_mutex held */ 486 472 void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev) ··· 557 543 } 558 544 EXPORT_SYMBOL(mlx5_lag_is_active); 559 545 546 + static int mlx5_lag_set_state(struct mlx5_core_dev *dev, bool allow) 547 + { 548 + struct mlx5_lag *ldev; 549 + int ret = 0; 550 + bool lag_active; 551 + 552 + mlx5_dev_list_lock(); 553 + 554 + ldev = mlx5_lag_dev_get(dev); 555 + if (!ldev) { 556 + ret = -ENODEV; 557 + goto unlock; 558 + } 559 + lag_active = mlx5_lag_is_bonded(ldev); 560 + if (!mlx5_lag_check_prereq(ldev) && allow) { 561 + ret = -EINVAL; 562 + goto unlock; 563 + } 564 + if (ldev->allowed == allow) 565 + goto unlock; 566 + ldev->allowed = allow; 567 + if ((lag_active && !allow) || allow) 568 + mlx5_do_bond(ldev); 569 + unlock: 570 + mlx5_dev_list_unlock(); 571 + return ret; 572 + } 573 + 574 + int mlx5_lag_forbid(struct mlx5_core_dev *dev) 575 + { 576 + return mlx5_lag_set_state(dev, false); 577 + } 578 + 579 + int mlx5_lag_allow(struct mlx5_core_dev *dev) 580 + { 581 + return mlx5_lag_set_state(dev, true); 582 + } 583 + 560 584 struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev) 561 585 { 562 586 struct net_device *ndev = NULL; ··· 638 586 /* If bonded, we do not add an IB device for PF1. */ 639 587 return false; 640 588 } 641 -
+35 -8
drivers/net/ethernet/mellanox/mlx5/core/main.c
··· 356 356 kfree(priv->msix_arr); 357 357 } 358 358 359 - struct mlx5_reg_host_endianess { 359 + struct mlx5_reg_host_endianness { 360 360 u8 he; 361 361 u8 rsvd[15]; 362 362 }; 363 - 364 363 365 364 #define CAP_MASK(pos, size) ((u64)((1 << (size)) - 1) << (pos)) 366 365 ··· 474 475 475 476 req_endianness = 476 477 MLX5_CAP_ATOMIC(dev, 477 - supported_atomic_req_8B_endianess_mode_1); 478 + supported_atomic_req_8B_endianness_mode_1); 478 479 479 480 if (req_endianness != MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS) 480 481 return 0; ··· 486 487 set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability); 487 488 488 489 /* Set requestor to host endianness */ 489 - MLX5_SET(atomic_caps, set_hca_cap, atomic_req_8B_endianess_mode, 490 + MLX5_SET(atomic_caps, set_hca_cap, atomic_req_8B_endianness_mode, 490 491 MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS); 491 492 492 493 err = set_caps(dev, set_ctx, set_sz, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC); ··· 561 562 562 563 static int set_hca_ctrl(struct mlx5_core_dev *dev) 563 564 { 564 - struct mlx5_reg_host_endianess he_in; 565 - struct mlx5_reg_host_endianess he_out; 565 + struct mlx5_reg_host_endianness he_in; 566 + struct mlx5_reg_host_endianness he_out; 566 567 int err; 567 568 568 569 if (!mlx5_core_is_pf(dev)) ··· 1418 1419 1419 1420 dev_info(&pdev->dev, "%s was called\n", __func__); 1420 1421 1421 - mlx5_enter_error_state(dev); 1422 + mlx5_enter_error_state(dev, false); 1422 1423 mlx5_unload_one(dev, priv, false); 1423 1424 /* In case of kernel call drain the health wq */ 1424 1425 if (state) { ··· 1505 1506 .resume = mlx5_pci_resume 1506 1507 }; 1507 1508 1509 + static int mlx5_try_fast_unload(struct mlx5_core_dev *dev) 1510 + { 1511 + int ret; 1512 + 1513 + if (!MLX5_CAP_GEN(dev, force_teardown)) { 1514 + mlx5_core_dbg(dev, "force teardown is not supported in the firmware\n"); 1515 + return -EOPNOTSUPP; 1516 + } 1517 + 1518 + if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { 1519 + mlx5_core_dbg(dev, "Device in internal error state, giving up\n"); 1520 + return -EAGAIN; 1521 + } 1522 + 1523 + ret = mlx5_cmd_force_teardown_hca(dev); 1524 + if (ret) { 1525 + mlx5_core_dbg(dev, "Firmware couldn't do fast unload error: %d\n", ret); 1526 + return ret; 1527 + } 1528 + 1529 + mlx5_enter_error_state(dev, true); 1530 + 1531 + return 0; 1532 + } 1533 + 1508 1534 static void shutdown(struct pci_dev *pdev) 1509 1535 { 1510 1536 struct mlx5_core_dev *dev = pci_get_drvdata(pdev); 1511 1537 struct mlx5_priv *priv = &dev->priv; 1538 + int err; 1512 1539 1513 1540 dev_info(&pdev->dev, "Shutdown was called\n"); 1514 1541 /* Notify mlx5 clients that the kernel is being shut down */ 1515 1542 set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state); 1516 - mlx5_unload_one(dev, priv, false); 1543 + err = mlx5_try_fast_unload(dev); 1544 + if (err) 1545 + mlx5_unload_one(dev, priv, false); 1517 1546 mlx5_pci_disable_device(dev); 1518 1547 } 1519 1548
+5 -1
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
··· 83 83 int mlx5_query_board_id(struct mlx5_core_dev *dev); 84 84 int mlx5_cmd_init_hca(struct mlx5_core_dev *dev); 85 85 int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev); 86 + int mlx5_cmd_force_teardown_hca(struct mlx5_core_dev *dev); 86 87 void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event, 87 88 unsigned long param); 88 89 void mlx5_core_page_fault(struct mlx5_core_dev *dev, 89 90 struct mlx5_pagefault *pfault); 90 91 void mlx5_port_module_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe); 91 - void mlx5_enter_error_state(struct mlx5_core_dev *dev); 92 + void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force); 92 93 void mlx5_disable_device(struct mlx5_core_dev *dev); 93 94 void mlx5_recover_device(struct mlx5_core_dev *dev); 94 95 int mlx5_sriov_init(struct mlx5_core_dev *dev); ··· 167 166 (MLX5_CAP_GEN(dev, num_lag_ports) > 1) && 168 167 MLX5_CAP_GEN(dev, lag_master); 169 168 } 169 + 170 + int mlx5_lag_allow(struct mlx5_core_dev *dev); 171 + int mlx5_lag_forbid(struct mlx5_core_dev *dev); 170 172 171 173 #endif /* __MLX5_CORE_H__ */
-1
drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
··· 403 403 for (i = 0; i < num_claimed; i++) 404 404 free_4k(dev, MLX5_GET64(manage_pages_out, out, pas[i])); 405 405 406 - 407 406 if (nclaimed) 408 407 *nclaimed = num_claimed; 409 408
-21
drivers/net/ethernet/mellanox/mlx5/core/qp.c
··· 30 30 * SOFTWARE. 31 31 */ 32 32 33 - 34 33 #include <linux/gfp.h> 35 34 #include <linux/export.h> 36 35 #include <linux/mlx5/cmd.h> ··· 518 519 return mlx5_cmd_exec(dev, in, sizeof(in), out, out_size); 519 520 } 520 521 EXPORT_SYMBOL_GPL(mlx5_core_query_q_counter); 521 - 522 - int mlx5_core_query_out_of_buffer(struct mlx5_core_dev *dev, u16 counter_id, 523 - u32 *out_of_buffer) 524 - { 525 - int outlen = MLX5_ST_SZ_BYTES(query_q_counter_out); 526 - void *out; 527 - int err; 528 - 529 - out = kvzalloc(outlen, GFP_KERNEL); 530 - if (!out) 531 - return -ENOMEM; 532 - 533 - err = mlx5_core_query_q_counter(dev, counter_id, 0, out, outlen); 534 - if (!err) 535 - *out_of_buffer = MLX5_GET(query_q_counter_out, out, 536 - out_of_buffer); 537 - 538 - kfree(out); 539 - return err; 540 - }
+10 -5
drivers/net/ethernet/mellanox/mlx5/core/sriov.c
··· 175 175 if (!mlx5_core_is_pf(dev)) 176 176 return -EPERM; 177 177 178 - if (num_vfs && mlx5_lag_is_active(dev)) { 179 - mlx5_core_warn(dev, "can't turn sriov on while LAG is active"); 180 - return -EINVAL; 178 + if (num_vfs) { 179 + int ret; 180 + 181 + ret = mlx5_lag_forbid(dev); 182 + if (ret && (ret != -ENODEV)) 183 + return ret; 181 184 } 182 185 183 - if (num_vfs) 186 + if (num_vfs) { 184 187 err = mlx5_sriov_enable(pdev, num_vfs); 185 - else 188 + } else { 186 189 mlx5_sriov_disable(pdev); 190 + mlx5_lag_allow(dev); 191 + } 187 192 188 193 return err ? err : num_vfs; 189 194 }
+3
include/linux/mlx5/driver.h
··· 817 817 u64 ts1; 818 818 u64 ts2; 819 819 u16 op; 820 + bool polling; 820 821 }; 821 822 822 823 struct mlx5_pas { ··· 916 915 int mlx5_cmd_exec_cb(struct mlx5_core_dev *dev, void *in, int in_size, 917 916 void *out, int out_size, mlx5_cmd_cbk_t callback, 918 917 void *context); 918 + int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size, 919 + void *out, int out_size); 919 920 void mlx5_cmd_mbox_status(void *out, u8 *status, u32 *syndrome); 920 921 921 922 int mlx5_core_get_caps(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type);
+13 -5
include/linux/mlx5/mlx5_ifc.h
··· 661 661 struct mlx5_ifc_atomic_caps_bits { 662 662 u8 reserved_at_0[0x40]; 663 663 664 - u8 atomic_req_8B_endianess_mode[0x2]; 664 + u8 atomic_req_8B_endianness_mode[0x2]; 665 665 u8 reserved_at_42[0x4]; 666 - u8 supported_atomic_req_8B_endianess_mode_1[0x1]; 666 + u8 supported_atomic_req_8B_endianness_mode_1[0x1]; 667 667 668 668 u8 reserved_at_47[0x19]; 669 669 ··· 801 801 u8 max_indirection[0x8]; 802 802 u8 fixed_buffer_size[0x1]; 803 803 u8 log_max_mrw_sz[0x7]; 804 - u8 reserved_at_110[0x2]; 804 + u8 force_teardown[0x1]; 805 + u8 reserved_at_111[0x1]; 805 806 u8 log_max_bsf_list_size[0x6]; 806 807 u8 umr_extended_translation_offset[0x1]; 807 808 u8 null_mkey[0x1]; ··· 3095 3094 u8 reserved_at_10[0x10]; 3096 3095 }; 3097 3096 3097 + enum { 3098 + MLX5_TEARDOWN_HCA_OUT_FORCE_STATE_SUCCESS = 0x0, 3099 + MLX5_TEARDOWN_HCA_OUT_FORCE_STATE_FAIL = 0x1, 3100 + }; 3101 + 3098 3102 struct mlx5_ifc_teardown_hca_out_bits { 3099 3103 u8 status[0x8]; 3100 3104 u8 reserved_at_8[0x18]; 3101 3105 3102 3106 u8 syndrome[0x20]; 3103 3107 3104 - u8 reserved_at_40[0x40]; 3108 + u8 reserved_at_40[0x3f]; 3109 + 3110 + u8 force_state[0x1]; 3105 3111 }; 3106 3112 3107 3113 enum { 3108 3114 MLX5_TEARDOWN_HCA_IN_PROFILE_GRACEFUL_CLOSE = 0x0, 3109 - MLX5_TEARDOWN_HCA_IN_PROFILE_PANIC_CLOSE = 0x1, 3115 + MLX5_TEARDOWN_HCA_IN_PROFILE_FORCE_CLOSE = 0x1, 3110 3116 }; 3111 3117 3112 3118 struct mlx5_ifc_teardown_hca_in_bits {
-2
include/linux/mlx5/qp.h
··· 569 569 int mlx5_core_dealloc_q_counter(struct mlx5_core_dev *dev, u16 counter_id); 570 570 int mlx5_core_query_q_counter(struct mlx5_core_dev *dev, u16 counter_id, 571 571 int reset, void *out, int out_size); 572 - int mlx5_core_query_out_of_buffer(struct mlx5_core_dev *dev, u16 counter_id, 573 - u32 *out_of_buffer); 574 572 575 573 static inline const char *mlx5_qp_type_str(int type) 576 574 {