Commit 2d74524c authored by Shay Drory's avatar Shay Drory Committed by Saeed Mahameed

net/mlx5: Moving rmap logic to EQs

IRQs are being simplified in order to ease their sharing and any feature
specific object will be moved to upper layer.
Hence we move rmap object into eq_table.
Signed-off-by: default avatarShay Drory <shayd@nvidia.com>
Reviewed-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent e8abebb3
...@@ -58,6 +58,9 @@ struct mlx5_eq_table { ...@@ -58,6 +58,9 @@ struct mlx5_eq_table {
struct mutex lock; /* sync async eqs creations */ struct mutex lock; /* sync async eqs creations */
int num_comp_eqs; int num_comp_eqs;
struct mlx5_irq_table *irq_table; struct mlx5_irq_table *irq_table;
#ifdef CONFIG_RFS_ACCEL
struct cpu_rmap *rmap;
#endif
}; };
#define MLX5_ASYNC_EVENT_MASK ((1ull << MLX5_EVENT_TYPE_PATH_MIG) | \ #define MLX5_ASYNC_EVENT_MASK ((1ull << MLX5_EVENT_TYPE_PATH_MIG) | \
...@@ -899,7 +902,7 @@ EXPORT_SYMBOL(mlx5_comp_irq_get_affinity_mask); ...@@ -899,7 +902,7 @@ EXPORT_SYMBOL(mlx5_comp_irq_get_affinity_mask);
#ifdef CONFIG_RFS_ACCEL #ifdef CONFIG_RFS_ACCEL
struct cpu_rmap *mlx5_eq_table_get_rmap(struct mlx5_core_dev *dev) struct cpu_rmap *mlx5_eq_table_get_rmap(struct mlx5_core_dev *dev)
{ {
return mlx5_irq_get_rmap(dev->priv.eq_table->irq_table); return dev->priv.eq_table->rmap;
} }
#endif #endif
...@@ -916,12 +919,57 @@ struct mlx5_eq_comp *mlx5_eqn2comp_eq(struct mlx5_core_dev *dev, int eqn) ...@@ -916,12 +919,57 @@ struct mlx5_eq_comp *mlx5_eqn2comp_eq(struct mlx5_core_dev *dev, int eqn)
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
static void clear_rmap(struct mlx5_core_dev *dev)
{
#ifdef CONFIG_RFS_ACCEL
struct mlx5_eq_table *eq_table = dev->priv.eq_table;
free_irq_cpu_rmap(eq_table->rmap);
#endif
}
static int set_rmap(struct mlx5_core_dev *mdev)
{
int err = 0;
#ifdef CONFIG_RFS_ACCEL
struct mlx5_eq_table *eq_table = mdev->priv.eq_table;
int vecidx;
eq_table->rmap = alloc_irq_cpu_rmap(eq_table->num_comp_eqs);
if (!eq_table->rmap) {
err = -ENOMEM;
mlx5_core_err(mdev, "Failed to allocate cpu_rmap. err %d", err);
goto err_out;
}
vecidx = MLX5_IRQ_VEC_COMP_BASE;
for (; vecidx < eq_table->num_comp_eqs + MLX5_IRQ_VEC_COMP_BASE;
vecidx++) {
err = irq_cpu_rmap_add(eq_table->rmap,
pci_irq_vector(mdev->pdev, vecidx));
if (err) {
mlx5_core_err(mdev, "irq_cpu_rmap_add failed. err %d",
err);
goto err_irq_cpu_rmap_add;
}
}
return 0;
err_irq_cpu_rmap_add:
clear_rmap(mdev);
err_out:
#endif
return err;
}
/* This function should only be called after mlx5_cmd_force_teardown_hca */ /* This function should only be called after mlx5_cmd_force_teardown_hca */
void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev) void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev)
{ {
struct mlx5_eq_table *table = dev->priv.eq_table; struct mlx5_eq_table *table = dev->priv.eq_table;
mutex_lock(&table->lock); /* sync with create/destroy_async_eq */ mutex_lock(&table->lock); /* sync with create/destroy_async_eq */
if (!mlx5_core_is_sf(dev))
clear_rmap(dev);
mlx5_irq_table_destroy(dev); mlx5_irq_table_destroy(dev);
mutex_unlock(&table->lock); mutex_unlock(&table->lock);
} }
...@@ -951,6 +999,18 @@ int mlx5_eq_table_create(struct mlx5_core_dev *dev) ...@@ -951,6 +999,18 @@ int mlx5_eq_table_create(struct mlx5_core_dev *dev)
goto err_async_eqs; goto err_async_eqs;
} }
if (!mlx5_core_is_sf(dev)) {
/* rmap is a mapping between irq number and queue number.
* each irq can be assign only to a single rmap.
* since SFs share IRQs, rmap mapping cannot function correctly
* for irqs that are shared for different core/netdev RX rings.
* Hence we don't allow netdev rmap for SFs
*/
err = set_rmap(dev);
if (err)
goto err_rmap;
}
err = create_comp_eqs(dev); err = create_comp_eqs(dev);
if (err) { if (err) {
mlx5_core_err(dev, "Failed to create completion EQs\n"); mlx5_core_err(dev, "Failed to create completion EQs\n");
...@@ -959,6 +1019,9 @@ int mlx5_eq_table_create(struct mlx5_core_dev *dev) ...@@ -959,6 +1019,9 @@ int mlx5_eq_table_create(struct mlx5_core_dev *dev)
return 0; return 0;
err_comp_eqs: err_comp_eqs:
if (!mlx5_core_is_sf(dev))
clear_rmap(dev);
err_rmap:
destroy_async_eqs(dev); destroy_async_eqs(dev);
err_async_eqs: err_async_eqs:
return err; return err;
...@@ -966,6 +1029,8 @@ int mlx5_eq_table_create(struct mlx5_core_dev *dev) ...@@ -966,6 +1029,8 @@ int mlx5_eq_table_create(struct mlx5_core_dev *dev)
void mlx5_eq_table_destroy(struct mlx5_core_dev *dev) void mlx5_eq_table_destroy(struct mlx5_core_dev *dev)
{ {
if (!mlx5_core_is_sf(dev))
clear_rmap(dev);
destroy_comp_eqs(dev); destroy_comp_eqs(dev);
destroy_async_eqs(dev); destroy_async_eqs(dev);
} }
......
...@@ -12,7 +12,6 @@ int mlx5_irq_table_init(struct mlx5_core_dev *dev); ...@@ -12,7 +12,6 @@ int mlx5_irq_table_init(struct mlx5_core_dev *dev);
void mlx5_irq_table_cleanup(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); int mlx5_irq_table_create(struct mlx5_core_dev *dev);
void mlx5_irq_table_destroy(struct mlx5_core_dev *dev); void mlx5_irq_table_destroy(struct mlx5_core_dev *dev);
struct cpu_rmap *mlx5_irq_get_rmap(struct mlx5_irq_table *table);
int mlx5_irq_get_num_comp(struct mlx5_irq_table *table); int mlx5_irq_get_num_comp(struct mlx5_irq_table *table);
struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev); struct mlx5_irq_table *mlx5_irq_table_get(struct mlx5_core_dev *dev);
......
...@@ -24,9 +24,6 @@ struct mlx5_irq { ...@@ -24,9 +24,6 @@ struct mlx5_irq {
struct mlx5_irq_table { struct mlx5_irq_table {
struct mlx5_irq *irq; struct mlx5_irq *irq;
int nvec; int nvec;
#ifdef CONFIG_RFS_ACCEL
struct cpu_rmap *rmap;
#endif
}; };
int mlx5_irq_table_init(struct mlx5_core_dev *dev) int mlx5_irq_table_init(struct mlx5_core_dev *dev)
...@@ -159,8 +156,6 @@ static void irq_release(struct kref *kref) ...@@ -159,8 +156,6 @@ static void irq_release(struct kref *kref)
*/ */
irq_set_affinity_hint(irq->irqn, NULL); irq_set_affinity_hint(irq->irqn, NULL);
free_cpumask_var(irq->mask); free_cpumask_var(irq->mask);
/* this line is releasing this irq from the rmap */
irq_set_affinity_notifier(irq->irqn, NULL);
free_irq(irq->irqn, &irq->nh); free_irq(irq->irqn, &irq->nh);
} }
...@@ -210,10 +205,11 @@ static void irq_set_name(char *name, int vecidx) ...@@ -210,10 +205,11 @@ static void irq_set_name(char *name, int vecidx)
static int irq_request(struct mlx5_core_dev *dev, int i) static int irq_request(struct mlx5_core_dev *dev, int i)
{ {
struct mlx5_irq *irq = mlx5_irq_get(dev, i);
char name[MLX5_MAX_IRQ_NAME]; char name[MLX5_MAX_IRQ_NAME];
struct mlx5_irq *irq;
int err; int err;
irq = mlx5_irq_get(dev, i);
irq->irqn = pci_irq_vector(dev->pdev, i); irq->irqn = pci_irq_vector(dev->pdev, i);
irq_set_name(name, i); irq_set_name(name, i);
ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh); ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh);
...@@ -223,15 +219,22 @@ static int irq_request(struct mlx5_core_dev *dev, int i) ...@@ -223,15 +219,22 @@ static int irq_request(struct mlx5_core_dev *dev, int i)
&irq->nh); &irq->nh);
if (err) { if (err) {
mlx5_core_err(dev, "Failed to request irq. err = %d\n", err); mlx5_core_err(dev, "Failed to request irq. err = %d\n", err);
return err; goto err_req_irq;
} }
if (!zalloc_cpumask_var(&irq->mask, GFP_KERNEL)) { if (!zalloc_cpumask_var(&irq->mask, GFP_KERNEL)) {
mlx5_core_warn(dev, "zalloc_cpumask_var failed\n"); mlx5_core_warn(dev, "zalloc_cpumask_var failed\n");
free_irq(irq->irqn, &irq->nh); err = -ENOMEM;
return -ENOMEM; goto err_cpumask;
} }
kref_init(&irq->kref); kref_init(&irq->kref);
return 0; return 0;
err_cpumask:
free_irq(irq->irqn, &irq->nh);
err_req_irq:
if (i != 0)
irq_set_affinity_notifier(irq->irqn, NULL);
return err;
} }
/** /**
...@@ -271,63 +274,12 @@ struct mlx5_irq *mlx5_irq_request(struct mlx5_core_dev *dev, int vecidx, ...@@ -271,63 +274,12 @@ struct mlx5_irq *mlx5_irq_request(struct mlx5_core_dev *dev, int vecidx,
return irq; return irq;
} }
static void irq_clear_rmap(struct mlx5_core_dev *dev)
{
#ifdef CONFIG_RFS_ACCEL
struct mlx5_irq_table *irq_table = dev->priv.irq_table;
free_irq_cpu_rmap(irq_table->rmap);
#endif
}
static int irq_set_rmap(struct mlx5_core_dev *mdev)
{
int err = 0;
#ifdef CONFIG_RFS_ACCEL
struct mlx5_irq_table *irq_table = mdev->priv.irq_table;
int num_affinity_vec;
int vecidx;
num_affinity_vec = mlx5_irq_get_num_comp(irq_table);
irq_table->rmap = alloc_irq_cpu_rmap(num_affinity_vec);
if (!irq_table->rmap) {
err = -ENOMEM;
mlx5_core_err(mdev, "Failed to allocate cpu_rmap. err %d", err);
goto err_out;
}
vecidx = MLX5_IRQ_VEC_COMP_BASE;
for (; vecidx < irq_table->nvec; vecidx++) {
err = irq_cpu_rmap_add(irq_table->rmap,
pci_irq_vector(mdev->pdev, vecidx));
if (err) {
mlx5_core_err(mdev, "irq_cpu_rmap_add failed. err %d",
err);
goto err_irq_cpu_rmap_add;
}
}
return 0;
err_irq_cpu_rmap_add:
irq_clear_rmap(mdev);
err_out:
#endif
return err;
}
struct cpumask * struct cpumask *
mlx5_irq_get_affinity_mask(struct mlx5_irq_table *irq_table, int vecidx) mlx5_irq_get_affinity_mask(struct mlx5_irq_table *irq_table, int vecidx)
{ {
return irq_table->irq[vecidx].mask; return irq_table->irq[vecidx].mask;
} }
#ifdef CONFIG_RFS_ACCEL
struct cpu_rmap *mlx5_irq_get_rmap(struct mlx5_irq_table *irq_table)
{
return irq_table->rmap;
}
#endif
int mlx5_irq_table_create(struct mlx5_core_dev *dev) int mlx5_irq_table_create(struct mlx5_core_dev *dev)
{ {
struct mlx5_priv *priv = &dev->priv; struct mlx5_priv *priv = &dev->priv;
...@@ -360,24 +312,13 @@ int mlx5_irq_table_create(struct mlx5_core_dev *dev) ...@@ -360,24 +312,13 @@ int mlx5_irq_table_create(struct mlx5_core_dev *dev)
table->nvec = nvec; table->nvec = nvec;
err = irq_set_rmap(dev);
if (err)
goto err_set_rmap;
return 0; return 0;
err_set_rmap:
pci_free_irq_vectors(dev->pdev);
err_free_irq: err_free_irq:
kfree(table->irq); kfree(table->irq);
return err; return err;
} }
static void irq_table_clear_rmap(struct mlx5_irq_table *table)
{
cpu_rmap_put(table->rmap);
}
void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) void mlx5_irq_table_destroy(struct mlx5_core_dev *dev)
{ {
struct mlx5_irq_table *table = dev->priv.irq_table; struct mlx5_irq_table *table = dev->priv.irq_table;
...@@ -385,7 +326,6 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) ...@@ -385,7 +326,6 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev)
if (mlx5_core_is_sf(dev)) if (mlx5_core_is_sf(dev))
return; return;
irq_table_clear_rmap(table);
pci_free_irq_vectors(dev->pdev); pci_free_irq_vectors(dev->pdev);
kfree(table->irq); kfree(table->irq);
} }
......
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