Commit 41ceb5e8 authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5-fixes-2019-02-13' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2019-02-13

This series introduces some fixes to mlx5 driver.
For more information please see tag log below.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2fdeee25 407e17b1
...@@ -1583,6 +1583,24 @@ void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) ...@@ -1583,6 +1583,24 @@ void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags); spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags);
} }
void mlx5_cmd_flush(struct mlx5_core_dev *dev)
{
struct mlx5_cmd *cmd = &dev->cmd;
int i;
for (i = 0; i < cmd->max_reg_cmds; i++)
while (down_trylock(&cmd->sem))
mlx5_cmd_trigger_completions(dev);
while (down_trylock(&cmd->pages_sem))
mlx5_cmd_trigger_completions(dev);
/* Unlock cmdif */
up(&cmd->pages_sem);
for (i = 0; i < cmd->max_reg_cmds; i++)
up(&cmd->sem);
}
static int status_to_err(u8 status) static int status_to_err(u8 status)
{ {
return status ? -1 : 0; /* TBD more meaningful codes */ return status ? -1 : 0; /* TBD more meaningful codes */
......
...@@ -657,6 +657,7 @@ struct mlx5e_channel_stats { ...@@ -657,6 +657,7 @@ struct mlx5e_channel_stats {
enum { enum {
MLX5E_STATE_OPENED, MLX5E_STATE_OPENED,
MLX5E_STATE_DESTROYING, MLX5E_STATE_DESTROYING,
MLX5E_STATE_XDP_TX_ENABLED,
}; };
struct mlx5e_rqt { struct mlx5e_rqt {
......
...@@ -365,7 +365,8 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, ...@@ -365,7 +365,8 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
int sq_num; int sq_num;
int i; int i;
if (unlikely(!test_bit(MLX5E_STATE_OPENED, &priv->state))) /* this flag is sufficient, no need to test internal sq state */
if (unlikely(!mlx5e_xdp_tx_is_enabled(priv)))
return -ENETDOWN; return -ENETDOWN;
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
...@@ -378,9 +379,6 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, ...@@ -378,9 +379,6 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
sq = &priv->channels.c[sq_num]->xdpsq; sq = &priv->channels.c[sq_num]->xdpsq;
if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
return -ENETDOWN;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
struct xdp_frame *xdpf = frames[i]; struct xdp_frame *xdpf = frames[i];
struct mlx5e_xdp_info xdpi; struct mlx5e_xdp_info xdpi;
......
...@@ -50,6 +50,23 @@ void mlx5e_xdp_rx_poll_complete(struct mlx5e_rq *rq); ...@@ -50,6 +50,23 @@ void mlx5e_xdp_rx_poll_complete(struct mlx5e_rq *rq);
int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
u32 flags); u32 flags);
static inline void mlx5e_xdp_tx_enable(struct mlx5e_priv *priv)
{
set_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state);
}
static inline void mlx5e_xdp_tx_disable(struct mlx5e_priv *priv)
{
clear_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state);
/* let other device's napi(s) see our new state */
synchronize_rcu();
}
static inline bool mlx5e_xdp_tx_is_enabled(struct mlx5e_priv *priv)
{
return test_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state);
}
static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_xdpsq *sq) static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_xdpsq *sq)
{ {
if (sq->doorbell_cseg) { if (sq->doorbell_cseg) {
......
...@@ -354,9 +354,6 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv, ...@@ -354,9 +354,6 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
new_channels.params = priv->channels.params; new_channels.params = priv->channels.params;
new_channels.params.num_channels = count; new_channels.params.num_channels = count;
if (!netif_is_rxfh_configured(priv->netdev))
mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
MLX5E_INDIR_RQT_SIZE, count);
if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
priv->channels.params = new_channels.params; priv->channels.params = new_channels.params;
...@@ -372,6 +369,10 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv, ...@@ -372,6 +369,10 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
if (arfs_enabled) if (arfs_enabled)
mlx5e_arfs_disable(priv); mlx5e_arfs_disable(priv);
if (!netif_is_rxfh_configured(priv->netdev))
mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
MLX5E_INDIR_RQT_SIZE, count);
/* Switch to new channels, set new parameters and close old ones */ /* Switch to new channels, set new parameters and close old ones */
mlx5e_switch_priv_channels(priv, &new_channels, NULL); mlx5e_switch_priv_channels(priv, &new_channels, NULL);
......
...@@ -2938,6 +2938,7 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv) ...@@ -2938,6 +2938,7 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
mlx5e_build_tx2sq_maps(priv); mlx5e_build_tx2sq_maps(priv);
mlx5e_activate_channels(&priv->channels); mlx5e_activate_channels(&priv->channels);
mlx5e_xdp_tx_enable(priv);
netif_tx_start_all_queues(priv->netdev); netif_tx_start_all_queues(priv->netdev);
if (mlx5e_is_vport_rep(priv)) if (mlx5e_is_vport_rep(priv))
...@@ -2959,6 +2960,7 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv) ...@@ -2959,6 +2960,7 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
*/ */
netif_tx_stop_all_queues(priv->netdev); netif_tx_stop_all_queues(priv->netdev);
netif_tx_disable(priv->netdev); netif_tx_disable(priv->netdev);
mlx5e_xdp_tx_disable(priv);
mlx5e_deactivate_channels(&priv->channels); mlx5e_deactivate_channels(&priv->channels);
} }
......
...@@ -211,11 +211,10 @@ static int port_module(struct notifier_block *nb, unsigned long type, void *data ...@@ -211,11 +211,10 @@ static int port_module(struct notifier_block *nb, unsigned long type, void *data
enum port_module_event_status_type module_status; enum port_module_event_status_type module_status;
enum port_module_event_error_type error_type; enum port_module_event_error_type error_type;
struct mlx5_eqe_port_module *module_event_eqe; struct mlx5_eqe_port_module *module_event_eqe;
const char *status_str, *error_str; const char *status_str;
u8 module_num; u8 module_num;
module_event_eqe = &eqe->data.port_module; module_event_eqe = &eqe->data.port_module;
module_num = module_event_eqe->module;
module_status = module_event_eqe->module_status & module_status = module_event_eqe->module_status &
PORT_MODULE_EVENT_MODULE_STATUS_MASK; PORT_MODULE_EVENT_MODULE_STATUS_MASK;
error_type = module_event_eqe->error_type & error_type = module_event_eqe->error_type &
...@@ -223,25 +222,27 @@ static int port_module(struct notifier_block *nb, unsigned long type, void *data ...@@ -223,25 +222,27 @@ static int port_module(struct notifier_block *nb, unsigned long type, void *data
if (module_status < MLX5_MODULE_STATUS_NUM) if (module_status < MLX5_MODULE_STATUS_NUM)
events->pme_stats.status_counters[module_status]++; events->pme_stats.status_counters[module_status]++;
status_str = mlx5_pme_status_to_string(module_status);
if (module_status == MLX5_MODULE_STATUS_ERROR) { if (module_status == MLX5_MODULE_STATUS_ERROR)
if (error_type < MLX5_MODULE_EVENT_ERROR_NUM) if (error_type < MLX5_MODULE_EVENT_ERROR_NUM)
events->pme_stats.error_counters[error_type]++; events->pme_stats.error_counters[error_type]++;
error_str = mlx5_pme_error_to_string(error_type);
}
if (!printk_ratelimit()) if (!printk_ratelimit())
return NOTIFY_OK; return NOTIFY_OK;
if (module_status == MLX5_MODULE_STATUS_ERROR) module_num = module_event_eqe->module;
status_str = mlx5_pme_status_to_string(module_status);
if (module_status == MLX5_MODULE_STATUS_ERROR) {
const char *error_str = mlx5_pme_error_to_string(error_type);
mlx5_core_err(events->dev, mlx5_core_err(events->dev,
"Port module event[error]: module %u, %s, %s\n", "Port module event[error]: module %u, %s, %s\n",
module_num, status_str, error_str); module_num, status_str, error_str);
else } else {
mlx5_core_info(events->dev, mlx5_core_info(events->dev,
"Port module event: module %u, %s\n", "Port module event: module %u, %s\n",
module_num, status_str); module_num, status_str);
}
return NOTIFY_OK; return NOTIFY_OK;
} }
......
...@@ -103,7 +103,7 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force) ...@@ -103,7 +103,7 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force)
mlx5_core_err(dev, "start\n"); mlx5_core_err(dev, "start\n");
if (pci_channel_offline(dev->pdev) || in_fatal(dev) || force) { if (pci_channel_offline(dev->pdev) || in_fatal(dev) || force) {
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
mlx5_cmd_trigger_completions(dev); mlx5_cmd_flush(dev);
} }
mlx5_notifier_call_chain(dev->priv.events, MLX5_DEV_EVENT_SYS_ERROR, (void *)1); mlx5_notifier_call_chain(dev->priv.events, MLX5_DEV_EVENT_SYS_ERROR, (void *)1);
......
...@@ -126,6 +126,7 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev, ...@@ -126,6 +126,7 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
struct ptp_system_timestamp *sts); struct ptp_system_timestamp *sts);
void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev); void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev);
void mlx5_cmd_flush(struct mlx5_core_dev *dev);
int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev); int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev);
void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev); void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment