diff options
author | Roland Dreier <rolandd@cisco.com> | 2009-09-05 23:24:49 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-09-05 23:24:49 -0400 |
commit | fa0681d2129732027355d6b7083dd8932b9b799d (patch) | |
tree | 0730a4ccab5f7c5b4da772b76e6e709839ffe643 /drivers/net/mlx4/main.c | |
parent | 338a8fad27908f64a0d249cc9f5c7d4ddb7e5684 (diff) |
mlx4_core: Allocate and map sufficient ICM memory for EQ context
The current implementation allocates a single host page for EQ context
memory, which was OK when we only allocated a few EQs. However, since
we now allocate an EQ for each CPU core, this patch removes the
hard-coded limit (which we exceed with 4 KB pages and 128 byte EQ
context entries with 32 CPUs) and uses the same ICM table code as all
other context tables, which ends up simplifying the code quite a bit
while fixing the problem.
This problem was actually hit in practice on a dual-socket Nehalem box
with 16 real hardware threads and sufficiently odd ACPI tables that it
shows on boot
SMP: Allowing 32 CPUs, 16 hotplug CPUs
so num_possible_cpus() ends up 32, and mlx4 ends up creating 33 MSI-X
interrupts and 33 EQs. This mlx4 bug means that mlx4 can't even
initialize at all on this quite mainstream system.
Cc: <stable@kernel.org>
Reported-by: Eli Cohen <eli@mellanox.co.il>
Tested-by: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/net/mlx4/main.c')
-rw-r--r-- | drivers/net/mlx4/main.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 5c1afe0d73e8..528f89b2cde3 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -525,7 +525,10 @@ static int mlx4_init_icm(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap, | |||
525 | goto err_unmap_aux; | 525 | goto err_unmap_aux; |
526 | } | 526 | } |
527 | 527 | ||
528 | err = mlx4_map_eq_icm(dev, init_hca->eqc_base); | 528 | err = mlx4_init_icm_table(dev, &priv->eq_table.table, |
529 | init_hca->eqc_base, dev_cap->eqc_entry_sz, | ||
530 | dev->caps.num_eqs, dev->caps.num_eqs, | ||
531 | 0, 0); | ||
529 | if (err) { | 532 | if (err) { |
530 | mlx4_err(dev, "Failed to map EQ context memory, aborting.\n"); | 533 | mlx4_err(dev, "Failed to map EQ context memory, aborting.\n"); |
531 | goto err_unmap_cmpt; | 534 | goto err_unmap_cmpt; |
@@ -668,7 +671,7 @@ err_unmap_mtt: | |||
668 | mlx4_cleanup_icm_table(dev, &priv->mr_table.mtt_table); | 671 | mlx4_cleanup_icm_table(dev, &priv->mr_table.mtt_table); |
669 | 672 | ||
670 | err_unmap_eq: | 673 | err_unmap_eq: |
671 | mlx4_unmap_eq_icm(dev); | 674 | mlx4_cleanup_icm_table(dev, &priv->eq_table.table); |
672 | 675 | ||
673 | err_unmap_cmpt: | 676 | err_unmap_cmpt: |
674 | mlx4_cleanup_icm_table(dev, &priv->eq_table.cmpt_table); | 677 | mlx4_cleanup_icm_table(dev, &priv->eq_table.cmpt_table); |
@@ -698,11 +701,11 @@ static void mlx4_free_icms(struct mlx4_dev *dev) | |||
698 | mlx4_cleanup_icm_table(dev, &priv->qp_table.qp_table); | 701 | mlx4_cleanup_icm_table(dev, &priv->qp_table.qp_table); |
699 | mlx4_cleanup_icm_table(dev, &priv->mr_table.dmpt_table); | 702 | mlx4_cleanup_icm_table(dev, &priv->mr_table.dmpt_table); |
700 | mlx4_cleanup_icm_table(dev, &priv->mr_table.mtt_table); | 703 | mlx4_cleanup_icm_table(dev, &priv->mr_table.mtt_table); |
704 | mlx4_cleanup_icm_table(dev, &priv->eq_table.table); | ||
701 | mlx4_cleanup_icm_table(dev, &priv->eq_table.cmpt_table); | 705 | mlx4_cleanup_icm_table(dev, &priv->eq_table.cmpt_table); |
702 | mlx4_cleanup_icm_table(dev, &priv->cq_table.cmpt_table); | 706 | mlx4_cleanup_icm_table(dev, &priv->cq_table.cmpt_table); |
703 | mlx4_cleanup_icm_table(dev, &priv->srq_table.cmpt_table); | 707 | mlx4_cleanup_icm_table(dev, &priv->srq_table.cmpt_table); |
704 | mlx4_cleanup_icm_table(dev, &priv->qp_table.cmpt_table); | 708 | mlx4_cleanup_icm_table(dev, &priv->qp_table.cmpt_table); |
705 | mlx4_unmap_eq_icm(dev); | ||
706 | 709 | ||
707 | mlx4_UNMAP_ICM_AUX(dev); | 710 | mlx4_UNMAP_ICM_AUX(dev); |
708 | mlx4_free_icm(dev, priv->fw.aux_icm, 0); | 711 | mlx4_free_icm(dev, priv->fw.aux_icm, 0); |