mlx5: convert to generic pci_alloc_irq_vectors

Now that we have a generic code to allocate an array
of irq vectors and even correctly spread their affinity,
correctly handle cpu hotplug events and more, were much
better off using it.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Sagi Grimberg 2017-07-13 11:09:38 +03:00 коммит произвёл Doug Ledford
Родитель 520eccdfe1
Коммит 78249c4215
7 изменённых файлов: 20 добавлений и 36 удалений

Просмотреть файл

@ -397,7 +397,7 @@ static void mlx5e_enable_async_events(struct mlx5e_priv *priv)
static void mlx5e_disable_async_events(struct mlx5e_priv *priv) static void mlx5e_disable_async_events(struct mlx5e_priv *priv)
{ {
clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLED, &priv->state); clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLED, &priv->state);
synchronize_irq(mlx5_get_msix_vec(priv->mdev, MLX5_EQ_VEC_ASYNC)); synchronize_irq(pci_irq_vector(priv->mdev->pdev, MLX5_EQ_VEC_ASYNC));
} }
static inline int mlx5e_get_wqe_mtt_sz(void) static inline int mlx5e_get_wqe_mtt_sz(void)

Просмотреть файл

@ -585,7 +585,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
name, pci_name(dev->pdev)); name, pci_name(dev->pdev));
eq->eqn = MLX5_GET(create_eq_out, out, eq_number); eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
eq->irqn = priv->msix_arr[vecidx].vector; eq->irqn = pci_irq_vector(dev->pdev, vecidx);
eq->dev = dev; eq->dev = dev;
eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET; eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET;
err = request_irq(eq->irqn, handler, 0, err = request_irq(eq->irqn, handler, 0,
@ -620,7 +620,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
return 0; return 0;
err_irq: err_irq:
free_irq(priv->msix_arr[vecidx].vector, eq); free_irq(eq->irqn, eq);
err_eq: err_eq:
mlx5_cmd_destroy_eq(dev, eq->eqn); mlx5_cmd_destroy_eq(dev, eq->eqn);
@ -661,11 +661,6 @@ int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
} }
EXPORT_SYMBOL_GPL(mlx5_destroy_unmap_eq); EXPORT_SYMBOL_GPL(mlx5_destroy_unmap_eq);
u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx)
{
return dev->priv.msix_arr[MLX5_EQ_VEC_ASYNC].vector;
}
int mlx5_eq_init(struct mlx5_core_dev *dev) int mlx5_eq_init(struct mlx5_core_dev *dev)
{ {
int err; int err;

Просмотреть файл

@ -1585,7 +1585,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num)
/* Mark this vport as disabled to discard new events */ /* Mark this vport as disabled to discard new events */
vport->enabled = false; vport->enabled = false;
synchronize_irq(mlx5_get_msix_vec(esw->dev, MLX5_EQ_VEC_ASYNC)); synchronize_irq(pci_irq_vector(esw->dev->pdev, MLX5_EQ_VEC_ASYNC));
/* Wait for current already scheduled events to complete */ /* Wait for current already scheduled events to complete */
flush_workqueue(esw->work_queue); flush_workqueue(esw->work_queue);
/* Disable events from this vport */ /* Disable events from this vport */

Просмотреть файл

@ -81,7 +81,7 @@ static void trigger_cmd_completions(struct mlx5_core_dev *dev)
u64 vector; u64 vector;
/* wait for pending handlers to complete */ /* wait for pending handlers to complete */
synchronize_irq(dev->priv.msix_arr[MLX5_EQ_VEC_CMD].vector); synchronize_irq(pci_irq_vector(dev->pdev, MLX5_EQ_VEC_CMD));
spin_lock_irqsave(&dev->cmd.alloc_lock, flags); spin_lock_irqsave(&dev->cmd.alloc_lock, flags);
vector = ~dev->cmd.bitmask & ((1ul << (1 << dev->cmd.log_sz)) - 1); vector = ~dev->cmd.bitmask & ((1ul << (1 << dev->cmd.log_sz)) - 1);
if (!vector) if (!vector)

Просмотреть файл

@ -312,13 +312,12 @@ static void release_bar(struct pci_dev *pdev)
pci_release_regions(pdev); pci_release_regions(pdev);
} }
static int mlx5_enable_msix(struct mlx5_core_dev *dev) static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
{ {
struct mlx5_priv *priv = &dev->priv; struct mlx5_priv *priv = &dev->priv;
struct mlx5_eq_table *table = &priv->eq_table; struct mlx5_eq_table *table = &priv->eq_table;
int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq); int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq);
int nvec; int nvec;
int i;
nvec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() + nvec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() +
MLX5_EQ_VEC_COMP_BASE; MLX5_EQ_VEC_COMP_BASE;
@ -326,17 +325,13 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev)
if (nvec <= MLX5_EQ_VEC_COMP_BASE) if (nvec <= MLX5_EQ_VEC_COMP_BASE)
return -ENOMEM; return -ENOMEM;
priv->msix_arr = kcalloc(nvec, sizeof(*priv->msix_arr), GFP_KERNEL);
priv->irq_info = kcalloc(nvec, sizeof(*priv->irq_info), GFP_KERNEL); priv->irq_info = kcalloc(nvec, sizeof(*priv->irq_info), GFP_KERNEL);
if (!priv->msix_arr || !priv->irq_info) if (!priv->irq_info)
goto err_free_msix; goto err_free_msix;
for (i = 0; i < nvec; i++) nvec = pci_alloc_irq_vectors(dev->pdev,
priv->msix_arr[i].entry = i; MLX5_EQ_VEC_COMP_BASE + 1, nvec,
PCI_IRQ_MSIX);
nvec = pci_enable_msix_range(dev->pdev, priv->msix_arr,
MLX5_EQ_VEC_COMP_BASE + 1, nvec);
if (nvec < 0) if (nvec < 0)
return nvec; return nvec;
@ -346,17 +341,15 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev)
err_free_msix: err_free_msix:
kfree(priv->irq_info); kfree(priv->irq_info);
kfree(priv->msix_arr);
return -ENOMEM; return -ENOMEM;
} }
static void mlx5_disable_msix(struct mlx5_core_dev *dev) static void mlx5_free_irq_vectors(struct mlx5_core_dev *dev)
{ {
struct mlx5_priv *priv = &dev->priv; struct mlx5_priv *priv = &dev->priv;
pci_disable_msix(dev->pdev); pci_free_irq_vectors(dev->pdev);
kfree(priv->irq_info); kfree(priv->irq_info);
kfree(priv->msix_arr);
} }
struct mlx5_reg_host_endianness { struct mlx5_reg_host_endianness {
@ -615,8 +608,7 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
{ {
struct mlx5_priv *priv = &mdev->priv; struct mlx5_priv *priv = &mdev->priv;
struct msix_entry *msix = priv->msix_arr; int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
@ -636,8 +628,7 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
{ {
struct mlx5_priv *priv = &mdev->priv; struct mlx5_priv *priv = &mdev->priv;
struct msix_entry *msix = priv->msix_arr; int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
irq_set_affinity_hint(irq, NULL); irq_set_affinity_hint(irq, NULL);
free_cpumask_var(priv->irq_info[i].mask); free_cpumask_var(priv->irq_info[i].mask);
@ -760,8 +751,8 @@ static int alloc_comp_eqs(struct mlx5_core_dev *dev)
} }
#ifdef CONFIG_RFS_ACCEL #ifdef CONFIG_RFS_ACCEL
irq_cpu_rmap_add(dev->rmap, irq_cpu_rmap_add(dev->rmap, pci_irq_vector(dev->pdev,
dev->priv.msix_arr[i + MLX5_EQ_VEC_COMP_BASE].vector); MLX5_EQ_VEC_COMP_BASE + i));
#endif #endif
snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i); snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i);
err = mlx5_create_map_eq(dev, eq, err = mlx5_create_map_eq(dev, eq,
@ -1119,9 +1110,9 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
goto err_stop_poll; goto err_stop_poll;
} }
err = mlx5_enable_msix(dev); err = mlx5_alloc_irq_vectors(dev);
if (err) { if (err) {
dev_err(&pdev->dev, "enable msix failed\n"); dev_err(&pdev->dev, "alloc irq vectors failed\n");
goto err_cleanup_once; goto err_cleanup_once;
} }
@ -1220,7 +1211,7 @@ err_put_uars:
mlx5_put_uars_page(dev, priv->uar); mlx5_put_uars_page(dev, priv->uar);
err_disable_msix: err_disable_msix:
mlx5_disable_msix(dev); mlx5_free_irq_vectors(dev);
err_cleanup_once: err_cleanup_once:
if (boot) if (boot)
@ -1287,7 +1278,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
free_comp_eqs(dev); free_comp_eqs(dev);
mlx5_stop_eqs(dev); mlx5_stop_eqs(dev);
mlx5_put_uars_page(dev, priv->uar); mlx5_put_uars_page(dev, priv->uar);
mlx5_disable_msix(dev); mlx5_free_irq_vectors(dev);
if (cleanup) if (cleanup)
mlx5_cleanup_once(dev); mlx5_cleanup_once(dev);
mlx5_stop_health_poll(dev); mlx5_stop_health_poll(dev);

Просмотреть файл

@ -110,7 +110,6 @@ int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
u32 element_id); u32 element_id);
int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev); int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev); u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev);
u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx);
struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn); struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn);
void mlx5_cq_tasklet_cb(unsigned long data); void mlx5_cq_tasklet_cb(unsigned long data);

Просмотреть файл

@ -597,7 +597,6 @@ struct mlx5_port_module_event_stats {
struct mlx5_priv { struct mlx5_priv {
char name[MLX5_MAX_NAME_LEN]; char name[MLX5_MAX_NAME_LEN];
struct mlx5_eq_table eq_table; struct mlx5_eq_table eq_table;
struct msix_entry *msix_arr;
struct mlx5_irq_info *irq_info; struct mlx5_irq_info *irq_info;
/* pages stuff */ /* pages stuff */