mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
mlx5-fixes-2023-05-22
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAmRsUT8ACgkQSD+KveBX +j61Zwf9GyvzrD29Lmu0/BTsLAnf7GAyJi/SMzXJ09Tp1dAYSWmF2DE3fzKvNoQ/ VT2udSKbZ96b2N9SGF396KZaV8gHxg23IAzILia1JDPd4Pn7YaNymAIWGU7vn+Tq ErG7atPVnJV5R1H6SwO2KpOClG7jOjUPMF87uDCl2g+IpYNgjKa9hcnt5bguztC2 KBW/sV7BCYVWOUrmlSe1hH2Fn4djhga3i4JBIzjp55Dz1voIu5SHsT13Ou2/UuiC 1RDqBTJ9WvnviAxICbI96TLMJTFnDo9HFGHPIQRhZ6k25PIuWX6GLMKaceVlfCd+ BZvRG+PNOsDR9a9tFCjMBfx7KE0bMw== =dwjN -----END PGP SIGNATURE----- Merge tag 'mlx5-fixes-2023-05-22' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5-fixes-2023-05-22 This series provides bug fixes for the mlx5 driver. Please pull and let me know if there is any problem. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ba46c96db9
@ -1920,9 +1920,10 @@ static void mlx5_cmd_err_trace(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod
|
||||
static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
|
||||
u32 syndrome, int err)
|
||||
{
|
||||
const char *namep = mlx5_command_str(opcode);
|
||||
struct mlx5_cmd_stats *stats;
|
||||
|
||||
if (!err)
|
||||
if (!err || !(strcmp(namep, "unknown command opcode")))
|
||||
return;
|
||||
|
||||
stats = &dev->cmd.stats[opcode];
|
||||
|
@ -175,6 +175,8 @@ static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget)
|
||||
/* ensure cq space is freed before enabling more cqes */
|
||||
wmb();
|
||||
|
||||
mlx5e_txqsq_wake(&ptpsq->txqsq);
|
||||
|
||||
return work_done == budget;
|
||||
}
|
||||
|
||||
|
@ -1369,11 +1369,13 @@ static void mlx5e_invalidate_encap(struct mlx5e_priv *priv,
|
||||
struct mlx5e_tc_flow *flow;
|
||||
|
||||
list_for_each_entry(flow, encap_flows, tmp_list) {
|
||||
struct mlx5_flow_attr *attr = flow->attr;
|
||||
struct mlx5_esw_flow_attr *esw_attr;
|
||||
struct mlx5_flow_attr *attr;
|
||||
|
||||
if (!mlx5e_is_offloaded_flow(flow))
|
||||
continue;
|
||||
|
||||
attr = mlx5e_tc_get_encap_attr(flow);
|
||||
esw_attr = attr->esw_attr;
|
||||
|
||||
if (flow_flag_test(flow, SLOW))
|
||||
|
@ -193,6 +193,8 @@ static inline u16 mlx5e_txqsq_get_next_pi(struct mlx5e_txqsq *sq, u16 size)
|
||||
return pi;
|
||||
}
|
||||
|
||||
void mlx5e_txqsq_wake(struct mlx5e_txqsq *sq);
|
||||
|
||||
static inline u16 mlx5e_shampo_get_cqe_header_index(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
|
||||
{
|
||||
return be16_to_cpu(cqe->shampo.header_entry_index) & (rq->mpwqe.shampo->hd_per_wq - 1);
|
||||
|
@ -1665,11 +1665,9 @@ bool mlx5e_tc_is_vf_tunnel(struct net_device *out_dev, struct net_device *route_
|
||||
int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *route_dev, u16 *vport)
|
||||
{
|
||||
struct mlx5e_priv *out_priv, *route_priv;
|
||||
struct mlx5_devcom *devcom = NULL;
|
||||
struct mlx5_core_dev *route_mdev;
|
||||
struct mlx5_eswitch *esw;
|
||||
u16 vhca_id;
|
||||
int err;
|
||||
|
||||
out_priv = netdev_priv(out_dev);
|
||||
esw = out_priv->mdev->priv.eswitch;
|
||||
@ -1678,6 +1676,9 @@ int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *ro
|
||||
|
||||
vhca_id = MLX5_CAP_GEN(route_mdev, vhca_id);
|
||||
if (mlx5_lag_is_active(out_priv->mdev)) {
|
||||
struct mlx5_devcom *devcom;
|
||||
int err;
|
||||
|
||||
/* In lag case we may get devices from different eswitch instances.
|
||||
* If we failed to get vport num, it means, mostly, that we on the wrong
|
||||
* eswitch.
|
||||
@ -1686,16 +1687,16 @@ int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *ro
|
||||
if (err != -ENOENT)
|
||||
return err;
|
||||
|
||||
rcu_read_lock();
|
||||
devcom = out_priv->mdev->priv.devcom;
|
||||
esw = mlx5_devcom_get_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
|
||||
if (!esw)
|
||||
return -ENODEV;
|
||||
esw = mlx5_devcom_get_peer_data_rcu(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
|
||||
err = esw ? mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport) : -ENODEV;
|
||||
rcu_read_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport);
|
||||
if (devcom)
|
||||
mlx5_devcom_release_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
|
||||
return err;
|
||||
return mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -5301,6 +5302,8 @@ int mlx5e_tc_esw_init(struct mlx5_rep_uplink_priv *uplink_priv)
|
||||
goto err_action_counter;
|
||||
}
|
||||
|
||||
mlx5_esw_offloads_devcom_init(esw);
|
||||
|
||||
return 0;
|
||||
|
||||
err_action_counter:
|
||||
@ -5329,7 +5332,7 @@ void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv)
|
||||
priv = netdev_priv(rpriv->netdev);
|
||||
esw = priv->mdev->priv.eswitch;
|
||||
|
||||
mlx5e_tc_clean_fdb_peer_flows(esw);
|
||||
mlx5_esw_offloads_devcom_cleanup(esw);
|
||||
|
||||
mlx5e_tc_tun_cleanup(uplink_priv->encap);
|
||||
|
||||
@ -5643,22 +5646,43 @@ bool mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb)
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
static struct mapping_ctx *
|
||||
mlx5e_get_priv_obj_mapping(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_tc_table *tc;
|
||||
struct mlx5_eswitch *esw;
|
||||
struct mapping_ctx *ctx;
|
||||
|
||||
if (is_mdev_switchdev_mode(priv->mdev)) {
|
||||
esw = priv->mdev->priv.eswitch;
|
||||
ctx = esw->offloads.reg_c0_obj_pool;
|
||||
} else {
|
||||
tc = mlx5e_fs_get_tc(priv->fs);
|
||||
ctx = tc->mapping;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int mlx5e_tc_action_miss_mapping_get(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr,
|
||||
u64 act_miss_cookie, u32 *act_miss_mapping)
|
||||
{
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct mlx5_mapped_obj mapped_obj = {};
|
||||
struct mlx5_eswitch *esw;
|
||||
struct mapping_ctx *ctx;
|
||||
int err;
|
||||
|
||||
ctx = esw->offloads.reg_c0_obj_pool;
|
||||
|
||||
ctx = mlx5e_get_priv_obj_mapping(priv);
|
||||
mapped_obj.type = MLX5_MAPPED_OBJ_ACT_MISS;
|
||||
mapped_obj.act_miss_cookie = act_miss_cookie;
|
||||
err = mapping_add(ctx, &mapped_obj, act_miss_mapping);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!is_mdev_switchdev_mode(priv->mdev))
|
||||
return 0;
|
||||
|
||||
esw = priv->mdev->priv.eswitch;
|
||||
attr->act_id_restore_rule = esw_add_restore_rule(esw, *act_miss_mapping);
|
||||
if (IS_ERR(attr->act_id_restore_rule))
|
||||
goto err_rule;
|
||||
@ -5673,10 +5697,9 @@ int mlx5e_tc_action_miss_mapping_get(struct mlx5e_priv *priv, struct mlx5_flow_a
|
||||
void mlx5e_tc_action_miss_mapping_put(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr,
|
||||
u32 act_miss_mapping)
|
||||
{
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct mapping_ctx *ctx;
|
||||
struct mapping_ctx *ctx = mlx5e_get_priv_obj_mapping(priv);
|
||||
|
||||
ctx = esw->offloads.reg_c0_obj_pool;
|
||||
mlx5_del_flow_rules(attr->act_id_restore_rule);
|
||||
if (is_mdev_switchdev_mode(priv->mdev))
|
||||
mlx5_del_flow_rules(attr->act_id_restore_rule);
|
||||
mapping_remove(ctx, act_miss_mapping);
|
||||
}
|
||||
|
@ -762,6 +762,17 @@ static void mlx5e_tx_wi_consume_fifo_skbs(struct mlx5e_txqsq *sq, struct mlx5e_t
|
||||
}
|
||||
}
|
||||
|
||||
void mlx5e_txqsq_wake(struct mlx5e_txqsq *sq)
|
||||
{
|
||||
if (netif_tx_queue_stopped(sq->txq) &&
|
||||
mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) &&
|
||||
mlx5e_ptpsq_fifo_has_room(sq) &&
|
||||
!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) {
|
||||
netif_tx_wake_queue(sq->txq);
|
||||
sq->stats->wake++;
|
||||
}
|
||||
}
|
||||
|
||||
bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
|
||||
{
|
||||
struct mlx5e_sq_stats *stats;
|
||||
@ -861,13 +872,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
|
||||
|
||||
netdev_tx_completed_queue(sq->txq, npkts, nbytes);
|
||||
|
||||
if (netif_tx_queue_stopped(sq->txq) &&
|
||||
mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) &&
|
||||
mlx5e_ptpsq_fifo_has_room(sq) &&
|
||||
!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) {
|
||||
netif_tx_wake_queue(sq->txq);
|
||||
stats->wake++;
|
||||
}
|
||||
mlx5e_txqsq_wake(sq);
|
||||
|
||||
return (i == MLX5E_TX_CQ_POLL_BUDGET);
|
||||
}
|
||||
|
@ -1104,7 +1104,7 @@ void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev)
|
||||
struct mlx5_eq_table *table = dev->priv.eq_table;
|
||||
|
||||
mutex_lock(&table->lock); /* sync with create/destroy_async_eq */
|
||||
mlx5_irq_table_destroy(dev);
|
||||
mlx5_irq_table_free_irqs(dev);
|
||||
mutex_unlock(&table->lock);
|
||||
}
|
||||
|
||||
|
@ -342,6 +342,7 @@ struct mlx5_eswitch {
|
||||
u32 large_group_num;
|
||||
} params;
|
||||
struct blocking_notifier_head n_head;
|
||||
bool paired[MLX5_MAX_PORTS];
|
||||
};
|
||||
|
||||
void esw_offloads_disable(struct mlx5_eswitch *esw);
|
||||
@ -369,6 +370,8 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs);
|
||||
void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf);
|
||||
void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw);
|
||||
void mlx5_eswitch_disable(struct mlx5_eswitch *esw);
|
||||
void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw);
|
||||
void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw);
|
||||
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
|
||||
u16 vport, const u8 *mac);
|
||||
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
|
||||
@ -767,6 +770,8 @@ static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {}
|
||||
static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { return 0; }
|
||||
static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw, bool clear_vf) {}
|
||||
static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw) {}
|
||||
static inline void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw) {}
|
||||
static inline void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw) {}
|
||||
static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; }
|
||||
static inline
|
||||
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; }
|
||||
|
@ -2742,6 +2742,9 @@ static int mlx5_esw_offloads_devcom_event(int event,
|
||||
mlx5_eswitch_vport_match_metadata_enabled(peer_esw))
|
||||
break;
|
||||
|
||||
if (esw->paired[mlx5_get_dev_index(peer_esw->dev)])
|
||||
break;
|
||||
|
||||
err = mlx5_esw_offloads_set_ns_peer(esw, peer_esw, true);
|
||||
if (err)
|
||||
goto err_out;
|
||||
@ -2753,14 +2756,18 @@ static int mlx5_esw_offloads_devcom_event(int event,
|
||||
if (err)
|
||||
goto err_pair;
|
||||
|
||||
esw->paired[mlx5_get_dev_index(peer_esw->dev)] = true;
|
||||
peer_esw->paired[mlx5_get_dev_index(esw->dev)] = true;
|
||||
mlx5_devcom_set_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS, true);
|
||||
break;
|
||||
|
||||
case ESW_OFFLOADS_DEVCOM_UNPAIR:
|
||||
if (!mlx5_devcom_is_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS))
|
||||
if (!esw->paired[mlx5_get_dev_index(peer_esw->dev)])
|
||||
break;
|
||||
|
||||
mlx5_devcom_set_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS, false);
|
||||
esw->paired[mlx5_get_dev_index(peer_esw->dev)] = false;
|
||||
peer_esw->paired[mlx5_get_dev_index(esw->dev)] = false;
|
||||
mlx5_esw_offloads_unpair(peer_esw);
|
||||
mlx5_esw_offloads_unpair(esw);
|
||||
mlx5_esw_offloads_set_ns_peer(esw, peer_esw, false);
|
||||
@ -2779,7 +2786,7 @@ static int mlx5_esw_offloads_devcom_event(int event,
|
||||
return err;
|
||||
}
|
||||
|
||||
static void esw_offloads_devcom_init(struct mlx5_eswitch *esw)
|
||||
void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw)
|
||||
{
|
||||
struct mlx5_devcom *devcom = esw->dev->priv.devcom;
|
||||
|
||||
@ -2802,7 +2809,7 @@ static void esw_offloads_devcom_init(struct mlx5_eswitch *esw)
|
||||
ESW_OFFLOADS_DEVCOM_PAIR, esw);
|
||||
}
|
||||
|
||||
static void esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw)
|
||||
void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw)
|
||||
{
|
||||
struct mlx5_devcom *devcom = esw->dev->priv.devcom;
|
||||
|
||||
@ -3250,8 +3257,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
|
||||
if (err)
|
||||
goto err_vports;
|
||||
|
||||
esw_offloads_devcom_init(esw);
|
||||
|
||||
return 0;
|
||||
|
||||
err_vports:
|
||||
@ -3292,7 +3297,6 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw,
|
||||
|
||||
void esw_offloads_disable(struct mlx5_eswitch *esw)
|
||||
{
|
||||
esw_offloads_devcom_cleanup(esw);
|
||||
mlx5_eswitch_disable_pf_vf_vports(esw);
|
||||
esw_offloads_unload_rep(esw, MLX5_VPORT_UPLINK);
|
||||
esw_set_passing_vport_metadata(esw, false);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <linux/mlx5/vport.h>
|
||||
#include "lib/devcom.h"
|
||||
#include "mlx5_core.h"
|
||||
|
||||
static LIST_HEAD(devcom_list);
|
||||
|
||||
@ -13,7 +14,7 @@ static LIST_HEAD(devcom_list);
|
||||
|
||||
struct mlx5_devcom_component {
|
||||
struct {
|
||||
void *data;
|
||||
void __rcu *data;
|
||||
} device[MLX5_DEVCOM_PORTS_SUPPORTED];
|
||||
|
||||
mlx5_devcom_event_handler_t handler;
|
||||
@ -77,6 +78,7 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
||||
if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
|
||||
return NULL;
|
||||
|
||||
mlx5_dev_list_lock();
|
||||
sguid0 = mlx5_query_nic_system_image_guid(dev);
|
||||
list_for_each_entry(iter, &devcom_list, list) {
|
||||
struct mlx5_core_dev *tmp_dev = NULL;
|
||||
@ -102,8 +104,10 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
||||
|
||||
if (!priv) {
|
||||
priv = mlx5_devcom_list_alloc();
|
||||
if (!priv)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (!priv) {
|
||||
devcom = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
new_priv = true;
|
||||
@ -112,13 +116,16 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
|
||||
priv->devs[idx] = dev;
|
||||
devcom = mlx5_devcom_alloc(priv, idx);
|
||||
if (!devcom) {
|
||||
kfree(priv);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (new_priv)
|
||||
kfree(priv);
|
||||
devcom = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (new_priv)
|
||||
list_add(&priv->list, &devcom_list);
|
||||
|
||||
out:
|
||||
mlx5_dev_list_unlock();
|
||||
return devcom;
|
||||
}
|
||||
|
||||
@ -131,6 +138,7 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
|
||||
if (IS_ERR_OR_NULL(devcom))
|
||||
return;
|
||||
|
||||
mlx5_dev_list_lock();
|
||||
priv = devcom->priv;
|
||||
priv->devs[devcom->idx] = NULL;
|
||||
|
||||
@ -141,10 +149,12 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
|
||||
break;
|
||||
|
||||
if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
list_del(&priv->list);
|
||||
kfree(priv);
|
||||
out:
|
||||
mlx5_dev_list_unlock();
|
||||
}
|
||||
|
||||
void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
|
||||
@ -162,7 +172,7 @@ void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
|
||||
comp = &devcom->priv->components[id];
|
||||
down_write(&comp->sem);
|
||||
comp->handler = handler;
|
||||
comp->device[devcom->idx].data = data;
|
||||
rcu_assign_pointer(comp->device[devcom->idx].data, data);
|
||||
up_write(&comp->sem);
|
||||
}
|
||||
|
||||
@ -176,8 +186,9 @@ void mlx5_devcom_unregister_component(struct mlx5_devcom *devcom,
|
||||
|
||||
comp = &devcom->priv->components[id];
|
||||
down_write(&comp->sem);
|
||||
comp->device[devcom->idx].data = NULL;
|
||||
RCU_INIT_POINTER(comp->device[devcom->idx].data, NULL);
|
||||
up_write(&comp->sem);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
int mlx5_devcom_send_event(struct mlx5_devcom *devcom,
|
||||
@ -193,12 +204,15 @@ int mlx5_devcom_send_event(struct mlx5_devcom *devcom,
|
||||
|
||||
comp = &devcom->priv->components[id];
|
||||
down_write(&comp->sem);
|
||||
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
|
||||
if (i != devcom->idx && comp->device[i].data) {
|
||||
err = comp->handler(event, comp->device[i].data,
|
||||
event_data);
|
||||
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) {
|
||||
void *data = rcu_dereference_protected(comp->device[i].data,
|
||||
lockdep_is_held(&comp->sem));
|
||||
|
||||
if (i != devcom->idx && data) {
|
||||
err = comp->handler(event, data, event_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
up_write(&comp->sem);
|
||||
return err;
|
||||
@ -213,7 +227,7 @@ void mlx5_devcom_set_paired(struct mlx5_devcom *devcom,
|
||||
comp = &devcom->priv->components[id];
|
||||
WARN_ON(!rwsem_is_locked(&comp->sem));
|
||||
|
||||
comp->paired = paired;
|
||||
WRITE_ONCE(comp->paired, paired);
|
||||
}
|
||||
|
||||
bool mlx5_devcom_is_paired(struct mlx5_devcom *devcom,
|
||||
@ -222,7 +236,7 @@ bool mlx5_devcom_is_paired(struct mlx5_devcom *devcom,
|
||||
if (IS_ERR_OR_NULL(devcom))
|
||||
return false;
|
||||
|
||||
return devcom->priv->components[id].paired;
|
||||
return READ_ONCE(devcom->priv->components[id].paired);
|
||||
}
|
||||
|
||||
void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
|
||||
@ -236,7 +250,7 @@ void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
|
||||
|
||||
comp = &devcom->priv->components[id];
|
||||
down_read(&comp->sem);
|
||||
if (!comp->paired) {
|
||||
if (!READ_ONCE(comp->paired)) {
|
||||
up_read(&comp->sem);
|
||||
return NULL;
|
||||
}
|
||||
@ -245,7 +259,29 @@ void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
|
||||
if (i != devcom->idx)
|
||||
break;
|
||||
|
||||
return comp->device[i].data;
|
||||
return rcu_dereference_protected(comp->device[i].data, lockdep_is_held(&comp->sem));
|
||||
}
|
||||
|
||||
void *mlx5_devcom_get_peer_data_rcu(struct mlx5_devcom *devcom, enum mlx5_devcom_components id)
|
||||
{
|
||||
struct mlx5_devcom_component *comp;
|
||||
int i;
|
||||
|
||||
if (IS_ERR_OR_NULL(devcom))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
|
||||
if (i != devcom->idx)
|
||||
break;
|
||||
|
||||
comp = &devcom->priv->components[id];
|
||||
/* This can change concurrently, however 'data' pointer will remain
|
||||
* valid for the duration of RCU read section.
|
||||
*/
|
||||
if (!READ_ONCE(comp->paired))
|
||||
return NULL;
|
||||
|
||||
return rcu_dereference(comp->device[i].data);
|
||||
}
|
||||
|
||||
void mlx5_devcom_release_peer_data(struct mlx5_devcom *devcom,
|
||||
|
@ -41,6 +41,7 @@ bool mlx5_devcom_is_paired(struct mlx5_devcom *devcom,
|
||||
|
||||
void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
|
||||
enum mlx5_devcom_components id);
|
||||
void *mlx5_devcom_get_peer_data_rcu(struct mlx5_devcom *devcom, enum mlx5_devcom_components id);
|
||||
void mlx5_devcom_release_peer_data(struct mlx5_devcom *devcom,
|
||||
enum mlx5_devcom_components id);
|
||||
|
||||
|
@ -1049,7 +1049,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev)
|
||||
|
||||
dev->dm = mlx5_dm_create(dev);
|
||||
if (IS_ERR(dev->dm))
|
||||
mlx5_core_warn(dev, "Failed to init device memory%d\n", err);
|
||||
mlx5_core_warn(dev, "Failed to init device memory %ld\n", PTR_ERR(dev->dm));
|
||||
|
||||
dev->tracer = mlx5_fw_tracer_create(dev);
|
||||
dev->hv_vhca = mlx5_hv_vhca_create(dev);
|
||||
|
@ -15,6 +15,7 @@ int mlx5_irq_table_init(struct mlx5_core_dev *dev);
|
||||
void mlx5_irq_table_cleanup(struct mlx5_core_dev *dev);
|
||||
int mlx5_irq_table_create(struct mlx5_core_dev *dev);
|
||||
void mlx5_irq_table_destroy(struct mlx5_core_dev *dev);
|
||||
void mlx5_irq_table_free_irqs(struct mlx5_core_dev *dev);
|
||||
int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table);
|
||||
int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table);
|
||||
struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev);
|
||||
|
@ -32,6 +32,7 @@ struct mlx5_irq {
|
||||
struct mlx5_irq_pool *pool;
|
||||
int refcount;
|
||||
struct msi_map map;
|
||||
u32 pool_index;
|
||||
};
|
||||
|
||||
struct mlx5_irq_table {
|
||||
@ -132,7 +133,7 @@ static void irq_release(struct mlx5_irq *irq)
|
||||
struct cpu_rmap *rmap;
|
||||
#endif
|
||||
|
||||
xa_erase(&pool->irqs, irq->map.index);
|
||||
xa_erase(&pool->irqs, irq->pool_index);
|
||||
/* free_irq requires that affinity_hint and rmap will be cleared before
|
||||
* calling it. To satisfy this requirement, we call
|
||||
* irq_cpu_rmap_remove() to remove the notifier
|
||||
@ -276,11 +277,11 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i,
|
||||
}
|
||||
irq->pool = pool;
|
||||
irq->refcount = 1;
|
||||
irq->map.index = i;
|
||||
err = xa_err(xa_store(&pool->irqs, irq->map.index, irq, GFP_KERNEL));
|
||||
irq->pool_index = i;
|
||||
err = xa_err(xa_store(&pool->irqs, irq->pool_index, irq, GFP_KERNEL));
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "Failed to alloc xa entry for irq(%u). err = %d\n",
|
||||
irq->map.index, err);
|
||||
irq->pool_index, err);
|
||||
goto err_xa;
|
||||
}
|
||||
return irq;
|
||||
@ -567,7 +568,7 @@ int mlx5_irqs_request_vectors(struct mlx5_core_dev *dev, u16 *cpus, int nirqs,
|
||||
struct mlx5_irq *irq;
|
||||
int i;
|
||||
|
||||
af_desc.is_managed = 1;
|
||||
af_desc.is_managed = false;
|
||||
for (i = 0; i < nirqs; i++) {
|
||||
cpumask_set_cpu(cpus[i], &af_desc.mask);
|
||||
irq = mlx5_irq_request(dev, i + 1, &af_desc, rmap);
|
||||
@ -691,6 +692,24 @@ static void irq_pools_destroy(struct mlx5_irq_table *table)
|
||||
irq_pool_free(table->pcif_pool);
|
||||
}
|
||||
|
||||
static void mlx5_irq_pool_free_irqs(struct mlx5_irq_pool *pool)
|
||||
{
|
||||
struct mlx5_irq *irq;
|
||||
unsigned long index;
|
||||
|
||||
xa_for_each(&pool->irqs, index, irq)
|
||||
free_irq(irq->map.virq, &irq->nh);
|
||||
}
|
||||
|
||||
static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table)
|
||||
{
|
||||
if (table->sf_ctrl_pool) {
|
||||
mlx5_irq_pool_free_irqs(table->sf_comp_pool);
|
||||
mlx5_irq_pool_free_irqs(table->sf_ctrl_pool);
|
||||
}
|
||||
mlx5_irq_pool_free_irqs(table->pcif_pool);
|
||||
}
|
||||
|
||||
/* irq_table API */
|
||||
|
||||
int mlx5_irq_table_init(struct mlx5_core_dev *dev)
|
||||
@ -774,6 +793,17 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev)
|
||||
pci_free_irq_vectors(dev->pdev);
|
||||
}
|
||||
|
||||
void mlx5_irq_table_free_irqs(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_irq_table *table = dev->priv.irq_table;
|
||||
|
||||
if (mlx5_core_is_sf(dev))
|
||||
return;
|
||||
|
||||
mlx5_irq_pools_free_irqs(table);
|
||||
pci_free_irq_vectors(dev->pdev);
|
||||
}
|
||||
|
||||
int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table)
|
||||
{
|
||||
if (table->sf_comp_pool)
|
||||
|
@ -117,6 +117,8 @@ int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
|
||||
caps->gvmi = MLX5_CAP_GEN(mdev, vhca_id);
|
||||
caps->flex_protocols = MLX5_CAP_GEN(mdev, flex_parser_protocols);
|
||||
caps->sw_format_ver = MLX5_CAP_GEN(mdev, steering_format_version);
|
||||
caps->roce_caps.fl_rc_qp_when_roce_disabled =
|
||||
MLX5_CAP_GEN(mdev, fl_rc_qp_when_roce_disabled);
|
||||
|
||||
if (MLX5_CAP_GEN(mdev, roce)) {
|
||||
err = dr_cmd_query_nic_vport_roce_en(mdev, 0, &roce_en);
|
||||
@ -124,7 +126,7 @@ int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
|
||||
return err;
|
||||
|
||||
caps->roce_caps.roce_en = roce_en;
|
||||
caps->roce_caps.fl_rc_qp_when_roce_disabled =
|
||||
caps->roce_caps.fl_rc_qp_when_roce_disabled |=
|
||||
MLX5_CAP_ROCE(mdev, fl_rc_qp_when_roce_disabled);
|
||||
caps->roce_caps.fl_rc_qp_when_roce_enabled =
|
||||
MLX5_CAP_ROCE(mdev, fl_rc_qp_when_roce_enabled);
|
||||
|
@ -15,7 +15,8 @@ static u32 dr_ste_crc32_calc(const void *input_data, size_t length)
|
||||
{
|
||||
u32 crc = crc32(0, input_data, length);
|
||||
|
||||
return (__force u32)htonl(crc);
|
||||
return (__force u32)((crc >> 24) & 0xff) | ((crc << 8) & 0xff0000) |
|
||||
((crc >> 8) & 0xff00) | ((crc << 24) & 0xff000000);
|
||||
}
|
||||
|
||||
bool mlx5dr_ste_supp_ttl_cs_recalc(struct mlx5dr_cmd_caps *caps)
|
||||
|
@ -1705,7 +1705,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
|
||||
u8 rc[0x1];
|
||||
|
||||
u8 uar_4k[0x1];
|
||||
u8 reserved_at_241[0x9];
|
||||
u8 reserved_at_241[0x7];
|
||||
u8 fl_rc_qp_when_roce_disabled[0x1];
|
||||
u8 regexp_params[0x1];
|
||||
u8 uar_sz[0x6];
|
||||
u8 port_selection_cap[0x1];
|
||||
u8 reserved_at_248[0x1];
|
||||
|
Loading…
Reference in New Issue
Block a user