mlx5-fixes-2022-07-06
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAmLGFrwACgkQSD+KveBX +j6frQf9Hb1Qg4+gzRuhC35GgZ72HTWSWmECnQKx98puSSYrtTMGUUUgrJTf0O5V Jxrm7bWG4/D5ykfWcXWJm7bQZNgnYia9vC8YAWJpHd7zzCcecQBU8qhRH371eMfp wUs8rsNxIOJyhLvmQ+bLO/7Njb3cPrahnurWAoLVspjpR4nzbrVOjPAznjMHeXur OIiVgr0DPbYf/DaacKgiymlE6z+qziBuu2gohv21008EvW2ymzlqU33eGO1pKblt icOlx6wcEgbyrJmdy6gd9eCO/qd+z7EIUYfbcTSDdrVpOpH4HQjXMLEgKBZqCTq4 lkQpJIamFRSgsAJb8sF58b/RhcQofA== =DOa+ -----END PGP SIGNATURE----- Merge tag 'mlx5-fixes-2022-07-06' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5 fixes 2022-07-06 This series provides bug fixes to mlx5 driver. * tag 'mlx5-fixes-2022-07-06' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux: net/mlx5e: Ring the TX doorbell on DMA errors net/mlx5e: Fix capability check for updating vnic env counters net/mlx5e: CT: Use own workqueue instead of mlx5e priv net/mlx5: Lag, correct get the port select mode str net/mlx5e: Fix enabling sriov while tc nic rules are offloaded net/mlx5e: kTLS, Fix build time constant test in RX net/mlx5e: kTLS, Fix build time constant test in TX net/mlx5: Lag, decouple FDB selection and shared FDB net/mlx5: TC, allow offload from uplink to other PF's VF ==================== Link: https://lore.kernel.org/r/20220706231309.38579-1-saeed@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
fe5235aef8
@ -76,6 +76,7 @@ struct mlx5_tc_ct_priv {
|
||||
struct mlx5_ct_fs *fs;
|
||||
struct mlx5_ct_fs_ops *fs_ops;
|
||||
spinlock_t ht_lock; /* protects ft entries */
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
struct mlx5_tc_ct_debugfs debugfs;
|
||||
};
|
||||
@ -941,14 +942,11 @@ static void mlx5_tc_ct_entry_del_work(struct work_struct *work)
|
||||
static void
|
||||
__mlx5_tc_ct_entry_put(struct mlx5_ct_entry *entry)
|
||||
{
|
||||
struct mlx5e_priv *priv;
|
||||
|
||||
if (!refcount_dec_and_test(&entry->refcnt))
|
||||
return;
|
||||
|
||||
priv = netdev_priv(entry->ct_priv->netdev);
|
||||
INIT_WORK(&entry->work, mlx5_tc_ct_entry_del_work);
|
||||
queue_work(priv->wq, &entry->work);
|
||||
queue_work(entry->ct_priv->wq, &entry->work);
|
||||
}
|
||||
|
||||
static struct mlx5_ct_counter *
|
||||
@ -1759,19 +1757,16 @@ mlx5_tc_ct_flush_ft_entry(void *ptr, void *arg)
|
||||
static void
|
||||
mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
|
||||
{
|
||||
struct mlx5e_priv *priv;
|
||||
|
||||
if (!refcount_dec_and_test(&ft->refcount))
|
||||
return;
|
||||
|
||||
flush_workqueue(ct_priv->wq);
|
||||
nf_flow_table_offload_del_cb(ft->nf_ft,
|
||||
mlx5_tc_ct_block_flow_offload, ft);
|
||||
rhashtable_remove_fast(&ct_priv->zone_ht, &ft->node, zone_params);
|
||||
rhashtable_free_and_destroy(&ft->ct_entries_ht,
|
||||
mlx5_tc_ct_flush_ft_entry,
|
||||
ct_priv);
|
||||
priv = netdev_priv(ct_priv->netdev);
|
||||
flush_workqueue(priv->wq);
|
||||
mlx5_tc_ct_free_pre_ct_tables(ft);
|
||||
mapping_remove(ct_priv->zone_mapping, ft->zone_restore_id);
|
||||
kfree(ft);
|
||||
@ -2176,6 +2171,12 @@ mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
|
||||
if (rhashtable_init(&ct_priv->ct_tuples_nat_ht, &tuples_nat_ht_params))
|
||||
goto err_ct_tuples_nat_ht;
|
||||
|
||||
ct_priv->wq = alloc_ordered_workqueue("mlx5e_ct_priv_wq", 0);
|
||||
if (!ct_priv->wq) {
|
||||
err = -ENOMEM;
|
||||
goto err_wq;
|
||||
}
|
||||
|
||||
err = mlx5_tc_ct_fs_init(ct_priv);
|
||||
if (err)
|
||||
goto err_init_fs;
|
||||
@ -2184,6 +2185,8 @@ mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
|
||||
return ct_priv;
|
||||
|
||||
err_init_fs:
|
||||
destroy_workqueue(ct_priv->wq);
|
||||
err_wq:
|
||||
rhashtable_destroy(&ct_priv->ct_tuples_nat_ht);
|
||||
err_ct_tuples_nat_ht:
|
||||
rhashtable_destroy(&ct_priv->ct_tuples_ht);
|
||||
@ -2213,6 +2216,7 @@ mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
|
||||
if (!ct_priv)
|
||||
return;
|
||||
|
||||
destroy_workqueue(ct_priv->wq);
|
||||
mlx5_ct_tc_remove_dbgfs(ct_priv);
|
||||
chains = ct_priv->chains;
|
||||
|
||||
|
@ -231,8 +231,7 @@ mlx5e_set_ktls_rx_priv_ctx(struct tls_context *tls_ctx,
|
||||
struct mlx5e_ktls_offload_context_rx **ctx =
|
||||
__tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_RX);
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct mlx5e_ktls_offload_context_rx *) >
|
||||
TLS_OFFLOAD_CONTEXT_SIZE_RX);
|
||||
BUILD_BUG_ON(sizeof(priv_rx) > TLS_DRIVER_STATE_SIZE_RX);
|
||||
|
||||
*ctx = priv_rx;
|
||||
}
|
||||
|
@ -68,8 +68,7 @@ mlx5e_set_ktls_tx_priv_ctx(struct tls_context *tls_ctx,
|
||||
struct mlx5e_ktls_offload_context_tx **ctx =
|
||||
__tls_driver_ctx(tls_ctx, TLS_OFFLOAD_CTX_DIR_TX);
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct mlx5e_ktls_offload_context_tx *) >
|
||||
TLS_OFFLOAD_CONTEXT_SIZE_TX);
|
||||
BUILD_BUG_ON(sizeof(priv_tx) > TLS_DRIVER_STATE_SIZE_TX);
|
||||
|
||||
*ctx = priv_tx;
|
||||
}
|
||||
|
@ -688,7 +688,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(vnic_env)
|
||||
u32 in[MLX5_ST_SZ_DW(query_vnic_env_in)] = {};
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
|
||||
if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
|
||||
if (!mlx5e_stats_grp_vnic_env_num_stats(priv))
|
||||
return;
|
||||
|
||||
MLX5_SET(query_vnic_env_in, in, opcode, MLX5_CMD_OP_QUERY_VNIC_ENV);
|
||||
|
@ -3793,7 +3793,7 @@ static bool is_lag_dev(struct mlx5e_priv *priv,
|
||||
|
||||
static bool is_multiport_eligible(struct mlx5e_priv *priv, struct net_device *out_dev)
|
||||
{
|
||||
if (mlx5e_eswitch_uplink_rep(out_dev) &&
|
||||
if (same_hw_reps(priv, out_dev) &&
|
||||
MLX5_CAP_PORT_SELECTION(priv->mdev, port_select_flow_table) &&
|
||||
MLX5_CAP_GEN(priv->mdev, create_lag_when_not_master_up))
|
||||
return true;
|
||||
|
@ -341,6 +341,26 @@ static void mlx5e_tx_check_stop(struct mlx5e_txqsq *sq)
|
||||
}
|
||||
}
|
||||
|
||||
static void mlx5e_tx_flush(struct mlx5e_txqsq *sq)
|
||||
{
|
||||
struct mlx5e_tx_wqe_info *wi;
|
||||
struct mlx5e_tx_wqe *wqe;
|
||||
u16 pi;
|
||||
|
||||
/* Must not be called when a MPWQE session is active but empty. */
|
||||
mlx5e_tx_mpwqe_ensure_complete(sq);
|
||||
|
||||
pi = mlx5_wq_cyc_ctr2ix(&sq->wq, sq->pc);
|
||||
wi = &sq->db.wqe_info[pi];
|
||||
|
||||
*wi = (struct mlx5e_tx_wqe_info) {
|
||||
.num_wqebbs = 1,
|
||||
};
|
||||
|
||||
wqe = mlx5e_post_nop(&sq->wq, sq->sqn, &sq->pc);
|
||||
mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, &wqe->ctrl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
const struct mlx5e_tx_attr *attr,
|
||||
@ -459,6 +479,7 @@ mlx5e_sq_xmit_wqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
err_drop:
|
||||
stats->dropped++;
|
||||
dev_kfree_skb_any(skb);
|
||||
mlx5e_tx_flush(sq);
|
||||
}
|
||||
|
||||
static bool mlx5e_tx_skb_supports_mpwqe(struct sk_buff *skb, struct mlx5e_tx_attr *attr)
|
||||
@ -560,6 +581,13 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
struct mlx5_wqe_ctrl_seg *cseg;
|
||||
struct mlx5e_xmit_data txd;
|
||||
|
||||
txd.data = skb->data;
|
||||
txd.len = skb->len;
|
||||
|
||||
txd.dma_addr = dma_map_single(sq->pdev, txd.data, txd.len, DMA_TO_DEVICE);
|
||||
if (unlikely(dma_mapping_error(sq->pdev, txd.dma_addr)))
|
||||
goto err_unmap;
|
||||
|
||||
if (!mlx5e_tx_mpwqe_session_is_active(sq)) {
|
||||
mlx5e_tx_mpwqe_session_start(sq, eseg);
|
||||
} else if (!mlx5e_tx_mpwqe_same_eseg(sq, eseg)) {
|
||||
@ -569,18 +597,9 @@ mlx5e_sq_xmit_mpwqe(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
|
||||
sq->stats->xmit_more += xmit_more;
|
||||
|
||||
txd.data = skb->data;
|
||||
txd.len = skb->len;
|
||||
|
||||
txd.dma_addr = dma_map_single(sq->pdev, txd.data, txd.len, DMA_TO_DEVICE);
|
||||
if (unlikely(dma_mapping_error(sq->pdev, txd.dma_addr)))
|
||||
goto err_unmap;
|
||||
mlx5e_dma_push(sq, txd.dma_addr, txd.len, MLX5E_DMA_MAP_SINGLE);
|
||||
|
||||
mlx5e_skb_fifo_push(&sq->db.skb_fifo, skb);
|
||||
|
||||
mlx5e_tx_mpwqe_add_dseg(sq, &txd);
|
||||
|
||||
mlx5e_tx_skb_update_hwts_flags(skb);
|
||||
|
||||
if (unlikely(mlx5e_tx_mpwqe_is_full(&sq->mpwqe, sq->max_sq_mpw_wqebbs))) {
|
||||
@ -602,6 +621,7 @@ err_unmap:
|
||||
mlx5e_dma_unmap_wqe_err(sq, 1);
|
||||
sq->stats->dropped++;
|
||||
dev_kfree_skb_any(skb);
|
||||
mlx5e_tx_flush(sq);
|
||||
}
|
||||
|
||||
void mlx5e_tx_mpwqe_ensure_complete(struct mlx5e_txqsq *sq)
|
||||
@ -1006,5 +1026,6 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb,
|
||||
err_drop:
|
||||
stats->dropped++;
|
||||
dev_kfree_skb_any(skb);
|
||||
mlx5e_tx_flush(sq);
|
||||
}
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mlx5_core.h"
|
||||
#include "eswitch.h"
|
||||
#include "fs_core.h"
|
||||
#include "fs_ft_pool.h"
|
||||
#include "esw/qos.h"
|
||||
|
||||
enum {
|
||||
@ -95,8 +96,7 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw)
|
||||
if (!flow_group_in)
|
||||
return -ENOMEM;
|
||||
|
||||
table_size = BIT(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
|
||||
ft_attr.max_fte = table_size;
|
||||
ft_attr.max_fte = POOL_NEXT_SIZE;
|
||||
ft_attr.prio = LEGACY_FDB_PRIO;
|
||||
fdb = mlx5_create_flow_table(root_ns, &ft_attr);
|
||||
if (IS_ERR(fdb)) {
|
||||
@ -105,6 +105,7 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw)
|
||||
goto out;
|
||||
}
|
||||
esw->fdb_table.legacy.fdb = fdb;
|
||||
table_size = fdb->max_fte;
|
||||
|
||||
/* Addresses group : Full match unicast/multicast addresses */
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
|
||||
|
@ -44,7 +44,7 @@ static int port_sel_mode_show(struct seq_file *file, void *priv)
|
||||
ldev = dev->priv.lag;
|
||||
mutex_lock(&ldev->lock);
|
||||
if (__mlx5_lag_is_active(ldev))
|
||||
mode = mlx5_get_str_port_sel_mode(ldev);
|
||||
mode = mlx5_get_str_port_sel_mode(ldev->mode, ldev->mode_flags);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
mutex_unlock(&ldev->lock);
|
||||
@ -72,6 +72,7 @@ static int state_show(struct seq_file *file, void *priv)
|
||||
static int flags_show(struct seq_file *file, void *priv)
|
||||
{
|
||||
struct mlx5_core_dev *dev = file->private;
|
||||
bool fdb_sel_mode_native;
|
||||
struct mlx5_lag *ldev;
|
||||
bool shared_fdb;
|
||||
bool lag_active;
|
||||
@ -79,14 +80,21 @@ static int flags_show(struct seq_file *file, void *priv)
|
||||
ldev = dev->priv.lag;
|
||||
mutex_lock(&ldev->lock);
|
||||
lag_active = __mlx5_lag_is_active(ldev);
|
||||
if (lag_active)
|
||||
shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
|
||||
if (!lag_active)
|
||||
goto unlock;
|
||||
|
||||
shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
|
||||
fdb_sel_mode_native = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
|
||||
&ldev->mode_flags);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&ldev->lock);
|
||||
if (!lag_active)
|
||||
return -EINVAL;
|
||||
|
||||
seq_printf(file, "%s:%s\n", "shared_fdb", shared_fdb ? "on" : "off");
|
||||
seq_printf(file, "%s:%s\n", "fdb_selection_mode",
|
||||
fdb_sel_mode_native ? "native" : "affinity");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -68,14 +68,15 @@ static int get_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
|
||||
static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, u8 *ports, int mode,
|
||||
unsigned long flags)
|
||||
{
|
||||
bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags);
|
||||
bool fdb_sel_mode = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
|
||||
&flags);
|
||||
int port_sel_mode = get_port_sel_mode(mode, flags);
|
||||
u32 in[MLX5_ST_SZ_DW(create_lag_in)] = {};
|
||||
void *lag_ctx;
|
||||
|
||||
lag_ctx = MLX5_ADDR_OF(create_lag_in, in, ctx);
|
||||
MLX5_SET(create_lag_in, in, opcode, MLX5_CMD_OP_CREATE_LAG);
|
||||
MLX5_SET(lagc, lag_ctx, fdb_selection_mode, shared_fdb);
|
||||
MLX5_SET(lagc, lag_ctx, fdb_selection_mode, fdb_sel_mode);
|
||||
if (port_sel_mode == MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY) {
|
||||
MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, ports[0]);
|
||||
MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, ports[1]);
|
||||
@ -471,8 +472,13 @@ static int mlx5_lag_set_flags(struct mlx5_lag *ldev, enum mlx5_lag_mode mode,
|
||||
bool roce_lag = mode == MLX5_LAG_MODE_ROCE;
|
||||
|
||||
*flags = 0;
|
||||
if (shared_fdb)
|
||||
if (shared_fdb) {
|
||||
set_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, flags);
|
||||
set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
|
||||
}
|
||||
|
||||
if (mode == MLX5_LAG_MODE_MPESW)
|
||||
set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
|
||||
|
||||
if (roce_lag)
|
||||
return mlx5_lag_set_port_sel_mode_roce(ldev, flags);
|
||||
@ -481,9 +487,9 @@ static int mlx5_lag_set_flags(struct mlx5_lag *ldev, enum mlx5_lag_mode mode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *mlx5_get_str_port_sel_mode(struct mlx5_lag *ldev)
|
||||
char *mlx5_get_str_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
|
||||
{
|
||||
int port_sel_mode = get_port_sel_mode(ldev->mode, ldev->mode_flags);
|
||||
int port_sel_mode = get_port_sel_mode(mode, flags);
|
||||
|
||||
switch (port_sel_mode) {
|
||||
case MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY: return "queue_affinity";
|
||||
@ -507,7 +513,7 @@ static int mlx5_create_lag(struct mlx5_lag *ldev,
|
||||
if (tracker)
|
||||
mlx5_lag_print_mapping(dev0, ldev, tracker, flags);
|
||||
mlx5_core_info(dev0, "shared_fdb:%d mode:%s\n",
|
||||
shared_fdb, mlx5_get_str_port_sel_mode(ldev));
|
||||
shared_fdb, mlx5_get_str_port_sel_mode(mode, flags));
|
||||
|
||||
err = mlx5_cmd_create_lag(dev0, ldev->v2p_map, mode, flags);
|
||||
if (err) {
|
||||
|
@ -24,6 +24,7 @@ enum {
|
||||
enum {
|
||||
MLX5_LAG_MODE_FLAG_HASH_BASED,
|
||||
MLX5_LAG_MODE_FLAG_SHARED_FDB,
|
||||
MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
|
||||
};
|
||||
|
||||
enum mlx5_lag_mode {
|
||||
@ -114,7 +115,7 @@ bool mlx5_shared_fdb_supported(struct mlx5_lag *ldev);
|
||||
void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev);
|
||||
int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev);
|
||||
|
||||
char *mlx5_get_str_port_sel_mode(struct mlx5_lag *ldev);
|
||||
char *mlx5_get_str_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags);
|
||||
void mlx5_infer_tx_enabled(struct lag_tracker *tracker, u8 num_ports,
|
||||
u8 *ports, int *num_enabled);
|
||||
|
||||
|
@ -41,7 +41,6 @@ void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev)
|
||||
int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_lag *ldev = dev->priv.lag;
|
||||
bool shared_fdb;
|
||||
int err = 0;
|
||||
|
||||
if (!ldev)
|
||||
@ -55,8 +54,8 @@ int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
shared_fdb = mlx5_shared_fdb_supported(ldev);
|
||||
err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, shared_fdb);
|
||||
|
||||
err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false);
|
||||
if (err)
|
||||
mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user