summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRoland Dreier <roland@eddore.topspincom.com>2005-08-19 10:36:11 -0700
committerRoland Dreier <rolandd@cisco.com>2005-08-26 20:37:37 -0700
commitd20a40192868082eff6fec729b311cb8463b4a21 (patch)
treedae3cac48c76da789215cb9067559a7b721cbc5f /drivers/infiniband
parentc04bc3d1f417a8a90eef9ab46523dfd44858b28d (diff)
[PATCH] IB/mthca: Handle context tables smaller than our chunk size
When creating a table in context memory where the table is smaller than our chunk size, we don't want to allocate and map a full chunk. Instead, allocate just enough memory to cover the table. This can be pretty simple because all tables are a power-of-2 size, so either the table is a multiple of the chunk size, or it's smaller than one chunk. Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index fba0a53ba6e..1827400f189 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -286,6 +286,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
{
struct mthca_icm_table *table;
int num_icm;
+ unsigned chunk_size;
int i;
u8 status;
@@ -306,7 +307,11 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
table->icm[i] = NULL;
for (i = 0; i * MTHCA_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
- table->icm[i] = mthca_alloc_icm(dev, MTHCA_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
+ chunk_size = MTHCA_TABLE_CHUNK_SIZE;
+ if ((i + 1) * MTHCA_TABLE_CHUNK_SIZE > nobj * obj_size)
+ chunk_size = nobj * obj_size - i * MTHCA_TABLE_CHUNK_SIZE;
+
+ table->icm[i] = mthca_alloc_icm(dev, chunk_size >> PAGE_SHIFT,
(use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
__GFP_NOWARN);
if (!table->icm[i])