mlx5-fixes-2021-06-09
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAmDBWrYACgkQSD+KveBX +j5XVQf+O2K9crkScr9sjDOF7WWDTKTXHsCWK2BqEKMtgdRcaYE/RK+v6cqVtwaI yObg4qnLDPt6AkmcSPSPPhPVzYKTxidryafMWCxkS5toqzC+bKQIUvhK1oP0QSFY 7rSTeC+u93/yCizNXaYbRKBVnlRr8w32ON5H92NGjMbVN7PLbPhQluzoLYoT3Zbj 3zQYnhHzV7sh6U/av5yCFl2iEls4JT5OfC6KbtiYohULdQ+Ggj9NjFQ49u+YOQo1 dPGyjEq6xzm4Fe2trq63h8hrKkc99Sbq+Lv5lF7io82xGrUb6JtK7SKYruF+kZ2U gZ9bHpUJC/bq1C8jLuGFGLoFzcBqYw== =fUUd -----END PGP SIGNATURE----- Merge tag 'mlx5-fixes-2021-06-09' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5-fixes-2021-06-09 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
388fa7f13d
@ -64,6 +64,8 @@ struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev)
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
struct devlink_port *port;
|
||||
|
||||
if (!netif_device_present(dev))
|
||||
return NULL;
|
||||
port = mlx5e_devlink_get_dl_port(priv);
|
||||
if (port->registered)
|
||||
return port;
|
||||
|
@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
// Copyright (c) 2020 Mellanox Technologies
|
||||
|
||||
#include <linux/ptp_classify.h>
|
||||
#include "en/ptp.h"
|
||||
#include "en/txrx.h"
|
||||
#include "en/params.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "en.h"
|
||||
#include "en_stats.h"
|
||||
#include <linux/ptp_classify.h>
|
||||
|
||||
struct mlx5e_ptpsq {
|
||||
struct mlx5e_txqsq txqsq;
|
||||
@ -43,6 +44,27 @@ struct mlx5e_ptp {
|
||||
DECLARE_BITMAP(state, MLX5E_PTP_STATE_NUM_STATES);
|
||||
};
|
||||
|
||||
static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
|
||||
{
|
||||
struct flow_keys fk;
|
||||
|
||||
if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
|
||||
return false;
|
||||
|
||||
if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
|
||||
return false;
|
||||
|
||||
if (fk.basic.n_proto == htons(ETH_P_1588))
|
||||
return true;
|
||||
|
||||
if (fk.basic.n_proto != htons(ETH_P_IP) &&
|
||||
fk.basic.n_proto != htons(ETH_P_IPV6))
|
||||
return false;
|
||||
|
||||
return (fk.basic.ip_proto == IPPROTO_UDP &&
|
||||
fk.ports.dst == htons(PTP_EV_PORT));
|
||||
}
|
||||
|
||||
int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
|
||||
u8 lag_port, struct mlx5e_ptp **cp);
|
||||
void mlx5e_ptp_close(struct mlx5e_ptp *c);
|
||||
|
@ -129,10 +129,9 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
|
||||
work);
|
||||
struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;
|
||||
struct neighbour *n = update_work->n;
|
||||
struct mlx5e_encap_entry *e = NULL;
|
||||
bool neigh_connected, same_dev;
|
||||
struct mlx5e_encap_entry *e;
|
||||
unsigned char ha[ETH_ALEN];
|
||||
struct mlx5e_priv *priv;
|
||||
u8 nud_state, dead;
|
||||
|
||||
rtnl_lock();
|
||||
@ -156,14 +155,12 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
|
||||
if (!same_dev)
|
||||
goto out;
|
||||
|
||||
list_for_each_entry(e, &nhe->encap_list, encap_list) {
|
||||
if (!mlx5e_encap_take(e))
|
||||
continue;
|
||||
/* mlx5e_get_next_init_encap() releases previous encap before returning
|
||||
* the next one.
|
||||
*/
|
||||
while ((e = mlx5e_get_next_init_encap(nhe, e)) != NULL)
|
||||
mlx5e_rep_update_flows(netdev_priv(e->out_dev), e, neigh_connected, ha);
|
||||
|
||||
priv = netdev_priv(e->out_dev);
|
||||
mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
|
||||
mlx5e_encap_put(priv, e);
|
||||
}
|
||||
out:
|
||||
rtnl_unlock();
|
||||
mlx5e_release_neigh_update_work(update_work);
|
||||
|
@ -94,13 +94,9 @@ void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
/* wait for encap to be fully initialized */
|
||||
wait_for_completion(&e->res_ready);
|
||||
|
||||
mutex_lock(&esw->offloads.encap_tbl_lock);
|
||||
encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
|
||||
if (e->compl_result < 0 || (encap_connected == neigh_connected &&
|
||||
ether_addr_equal(e->h_dest, ha)))
|
||||
if (encap_connected == neigh_connected && ether_addr_equal(e->h_dest, ha))
|
||||
goto unlock;
|
||||
|
||||
mlx5e_take_all_encap_flows(e, &flow_list);
|
||||
|
@ -251,9 +251,12 @@ static void mlx5e_take_all_route_decap_flows(struct mlx5e_route_entry *r,
|
||||
mlx5e_take_tmp_flow(flow, flow_list, 0);
|
||||
}
|
||||
|
||||
typedef bool (match_cb)(struct mlx5e_encap_entry *);
|
||||
|
||||
static struct mlx5e_encap_entry *
|
||||
mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||
struct mlx5e_encap_entry *e)
|
||||
mlx5e_get_next_matching_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||
struct mlx5e_encap_entry *e,
|
||||
match_cb match)
|
||||
{
|
||||
struct mlx5e_encap_entry *next = NULL;
|
||||
|
||||
@ -288,7 +291,7 @@ retry:
|
||||
/* wait for encap to be fully initialized */
|
||||
wait_for_completion(&next->res_ready);
|
||||
/* continue searching if encap entry is not in valid state after completion */
|
||||
if (!(next->flags & MLX5_ENCAP_ENTRY_VALID)) {
|
||||
if (!match(next)) {
|
||||
e = next;
|
||||
goto retry;
|
||||
}
|
||||
@ -296,6 +299,30 @@ retry:
|
||||
return next;
|
||||
}
|
||||
|
||||
static bool mlx5e_encap_valid(struct mlx5e_encap_entry *e)
|
||||
{
|
||||
return e->flags & MLX5_ENCAP_ENTRY_VALID;
|
||||
}
|
||||
|
||||
static struct mlx5e_encap_entry *
|
||||
mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||
struct mlx5e_encap_entry *e)
|
||||
{
|
||||
return mlx5e_get_next_matching_encap(nhe, e, mlx5e_encap_valid);
|
||||
}
|
||||
|
||||
static bool mlx5e_encap_initialized(struct mlx5e_encap_entry *e)
|
||||
{
|
||||
return e->compl_result >= 0;
|
||||
}
|
||||
|
||||
struct mlx5e_encap_entry *
|
||||
mlx5e_get_next_init_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||
struct mlx5e_encap_entry *e)
|
||||
{
|
||||
return mlx5e_get_next_matching_encap(nhe, e, mlx5e_encap_initialized);
|
||||
}
|
||||
|
||||
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
|
||||
{
|
||||
struct mlx5e_neigh *m_neigh = &nhe->m_neigh;
|
||||
|
@ -532,9 +532,6 @@ void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
struct net_device *netdev = priv->netdev;
|
||||
|
||||
if (!priv->ipsec)
|
||||
return;
|
||||
|
||||
if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) ||
|
||||
!MLX5_CAP_ETH(mdev, swp)) {
|
||||
mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n");
|
||||
|
@ -356,7 +356,7 @@ err:
|
||||
|
||||
int mlx5e_arfs_create_tables(struct mlx5e_priv *priv)
|
||||
{
|
||||
int err = 0;
|
||||
int err = -ENOMEM;
|
||||
int i;
|
||||
|
||||
if (!(priv->netdev->hw_features & NETIF_F_NTUPLE))
|
||||
|
@ -2705,8 +2705,6 @@ static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
|
||||
nch = priv->channels.params.num_channels;
|
||||
ntc = priv->channels.params.num_tc;
|
||||
num_rxqs = nch * priv->profile->rq_groups;
|
||||
if (priv->channels.params.ptp_rx)
|
||||
num_rxqs++;
|
||||
|
||||
mlx5e_netdev_set_tcs(netdev, nch, ntc);
|
||||
|
||||
@ -4824,22 +4822,15 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
|
||||
}
|
||||
|
||||
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
|
||||
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
}
|
||||
|
||||
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
|
||||
netdev->hw_features |= NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM;
|
||||
netdev->gso_partial_features |= NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM;
|
||||
netdev->hw_features |= NETIF_F_GSO_GRE;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_GRE;
|
||||
netdev->gso_partial_features |= NETIF_F_GSO_GRE;
|
||||
}
|
||||
|
||||
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) {
|
||||
|
@ -4765,7 +4765,7 @@ static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
|
||||
list_for_each_entry_safe(hpe, tmp, &init_wait_list, dead_peer_wait_list) {
|
||||
wait_for_completion(&hpe->res_ready);
|
||||
if (!IS_ERR_OR_NULL(hpe->hp) && hpe->peer_vhca_id == peer_vhca_id)
|
||||
hpe->hp->pair->peer_gone = true;
|
||||
mlx5_core_hairpin_clear_dead_peer(hpe->hp->pair);
|
||||
|
||||
mlx5e_hairpin_put(priv, hpe);
|
||||
}
|
||||
|
@ -178,6 +178,9 @@ void mlx5e_take_all_encap_flows(struct mlx5e_encap_entry *e, struct list_head *f
|
||||
void mlx5e_put_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list);
|
||||
|
||||
struct mlx5e_neigh_hash_entry;
|
||||
struct mlx5e_encap_entry *
|
||||
mlx5e_get_next_init_encap(struct mlx5e_neigh_hash_entry *nhe,
|
||||
struct mlx5e_encap_entry *e);
|
||||
void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe);
|
||||
|
||||
void mlx5e_tc_reoffload_flows_work(struct work_struct *work);
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/ptp_classify.h>
|
||||
#include <net/geneve.h>
|
||||
#include <net/dsfield.h>
|
||||
#include "en.h"
|
||||
@ -67,24 +66,6 @@ static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool mlx5e_use_ptpsq(struct sk_buff *skb)
|
||||
{
|
||||
struct flow_keys fk;
|
||||
|
||||
if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
|
||||
return false;
|
||||
|
||||
if (fk.basic.n_proto == htons(ETH_P_1588))
|
||||
return true;
|
||||
|
||||
if (fk.basic.n_proto != htons(ETH_P_IP) &&
|
||||
fk.basic.n_proto != htons(ETH_P_IPV6))
|
||||
return false;
|
||||
|
||||
return (fk.basic.ip_proto == IPPROTO_UDP &&
|
||||
fk.ports.dst == htons(PTP_EV_PORT));
|
||||
}
|
||||
|
||||
static u16 mlx5e_select_ptpsq(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
@ -145,9 +126,9 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
ptp_channel = READ_ONCE(priv->channels.ptp);
|
||||
if (unlikely(ptp_channel) &&
|
||||
test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
|
||||
mlx5e_use_ptpsq(skb))
|
||||
if (unlikely(ptp_channel &&
|
||||
test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state) &&
|
||||
mlx5e_use_ptpsq(skb)))
|
||||
return mlx5e_select_ptpsq(dev, skb);
|
||||
|
||||
txq_ix = netdev_pick_tx(dev, skb, NULL);
|
||||
|
@ -136,7 +136,7 @@ static int mlx5_eq_comp_int(struct notifier_block *nb,
|
||||
|
||||
eqe = next_eqe_sw(eq);
|
||||
if (!eqe)
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
do {
|
||||
struct mlx5_core_cq *cq;
|
||||
@ -161,6 +161,8 @@ static int mlx5_eq_comp_int(struct notifier_block *nb,
|
||||
++eq->cons_index;
|
||||
|
||||
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
|
||||
|
||||
out:
|
||||
eq_update_ci(eq, 1);
|
||||
|
||||
if (cqn != -1)
|
||||
@ -248,9 +250,9 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
|
||||
++eq->cons_index;
|
||||
|
||||
} while ((++num_eqes < MLX5_EQ_POLLING_BUDGET) && (eqe = next_eqe_sw(eq)));
|
||||
eq_update_ci(eq, 1);
|
||||
|
||||
out:
|
||||
eq_update_ci(eq, 1);
|
||||
mlx5_eq_async_int_unlock(eq_async, recovery, &flags);
|
||||
|
||||
return unlikely(recovery) ? num_eqes : 0;
|
||||
|
@ -156,6 +156,9 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!MLX5_CAP_GEN(dev, roce))
|
||||
return;
|
||||
|
||||
err = mlx5_nic_vport_enable_roce(dev);
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
|
||||
|
@ -124,10 +124,11 @@ int mlx5dr_action_destroy(struct mlx5dr_action *action);
|
||||
static inline bool
|
||||
mlx5dr_is_supported(struct mlx5_core_dev *dev)
|
||||
{
|
||||
return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) ||
|
||||
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) &&
|
||||
(MLX5_CAP_GEN(dev, steering_format_version) <=
|
||||
MLX5_STEERING_FORMAT_CONNECTX_6DX));
|
||||
return MLX5_CAP_GEN(dev, roce) &&
|
||||
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) ||
|
||||
(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) &&
|
||||
(MLX5_CAP_GEN(dev, steering_format_version) <=
|
||||
MLX5_STEERING_FORMAT_CONNECTX_6DX)));
|
||||
}
|
||||
|
||||
/* buddy functions & structure */
|
||||
|
@ -424,6 +424,15 @@ err_modify_sq:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlx5_hairpin_unpair_peer_sq(struct mlx5_hairpin *hp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hp->num_channels; i++)
|
||||
mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY,
|
||||
MLX5_SQC_STATE_RST, 0, 0);
|
||||
}
|
||||
|
||||
static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
|
||||
{
|
||||
int i;
|
||||
@ -432,13 +441,9 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
|
||||
for (i = 0; i < hp->num_channels; i++)
|
||||
mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn[i], MLX5_RQC_STATE_RDY,
|
||||
MLX5_RQC_STATE_RST, 0, 0);
|
||||
|
||||
/* unset peer SQs */
|
||||
if (hp->peer_gone)
|
||||
return;
|
||||
for (i = 0; i < hp->num_channels; i++)
|
||||
mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY,
|
||||
MLX5_SQC_STATE_RST, 0, 0);
|
||||
if (!hp->peer_gone)
|
||||
mlx5_hairpin_unpair_peer_sq(hp);
|
||||
}
|
||||
|
||||
struct mlx5_hairpin *
|
||||
@ -485,3 +490,16 @@ void mlx5_core_hairpin_destroy(struct mlx5_hairpin *hp)
|
||||
mlx5_hairpin_destroy_queues(hp);
|
||||
kfree(hp);
|
||||
}
|
||||
|
||||
void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp)
|
||||
{
|
||||
int i;
|
||||
|
||||
mlx5_hairpin_unpair_peer_sq(hp);
|
||||
|
||||
/* destroy peer SQ */
|
||||
for (i = 0; i < hp->num_channels; i++)
|
||||
mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]);
|
||||
|
||||
hp->peer_gone = true;
|
||||
}
|
||||
|
@ -85,4 +85,5 @@ mlx5_core_hairpin_create(struct mlx5_core_dev *func_mdev,
|
||||
struct mlx5_hairpin_params *params);
|
||||
|
||||
void mlx5_core_hairpin_destroy(struct mlx5_hairpin *pair);
|
||||
void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp);
|
||||
#endif /* __TRANSOBJ_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user