aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorEli Cohen <eli@mellanox.co.il>2009-05-27 17:36:16 -0400
committerRoland Dreier <rolandd@cisco.com>2009-05-27 17:36:16 -0400
commitc1f67a88bf62fac0f4151c007b361199c2cd1988 (patch)
tree5bb527966e1a6cd2a3c06f6df70199df948e3817 /drivers/infiniband
parent210af919c949a7d6bd330916ef376cec2907d81e (diff)
IB/mthca: Add module parameter for number of MTTs per segment
The current MTT allocator uses kmalloc() to allocate a buffer for its buddy allocator, and thus is limited in the amount of MTT segments that it can control. As a result, the size of memory that can be registered is limited too. This patch uses a module parameter to control the number of MTT entries that each segment represents, allowing more memory to be registered with the same number of segments. Signed-off-by: Eli Cohen <eli@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c17
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.c4
5 files changed, 26 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 6d55f9d748f6..8c2ed994d540 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1059,7 +1059,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1059 MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_MTT_OFFSET); 1059 MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_MTT_OFFSET);
1060 if (mthca_is_memfree(dev)) 1060 if (mthca_is_memfree(dev))
1061 dev_lim->reserved_mtts = ALIGN((1 << (field >> 4)) * sizeof(u64), 1061 dev_lim->reserved_mtts = ALIGN((1 << (field >> 4)) * sizeof(u64),
1062 MTHCA_MTT_SEG_SIZE) / MTHCA_MTT_SEG_SIZE; 1062 dev->limits.mtt_seg_size) / dev->limits.mtt_seg_size;
1063 else 1063 else
1064 dev_lim->reserved_mtts = 1 << (field >> 4); 1064 dev_lim->reserved_mtts = 1 << (field >> 4);
1065 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_MRW_SZ_OFFSET); 1065 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_MRW_SZ_OFFSET);
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 252590116df5..9ef611f6dd36 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -159,6 +159,7 @@ struct mthca_limits {
159 int reserved_eqs; 159 int reserved_eqs;
160 int num_mpts; 160 int num_mpts;
161 int num_mtt_segs; 161 int num_mtt_segs;
162 int mtt_seg_size;
162 int fmr_reserved_mtts; 163 int fmr_reserved_mtts;
163 int reserved_mtts; 164 int reserved_mtts;
164 int reserved_mrws; 165 int reserved_mrws;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 1d83cf7caf38..13da9f1d24c0 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -125,6 +125,10 @@ module_param_named(fmr_reserved_mtts, hca_profile.fmr_reserved_mtts, int, 0444);
125MODULE_PARM_DESC(fmr_reserved_mtts, 125MODULE_PARM_DESC(fmr_reserved_mtts,
126 "number of memory translation table segments reserved for FMR"); 126 "number of memory translation table segments reserved for FMR");
127 127
128static int log_mtts_per_seg = ilog2(MTHCA_MTT_SEG_SIZE / 8);
129module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444);
130MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-5)");
131
128static char mthca_version[] __devinitdata = 132static char mthca_version[] __devinitdata =
129 DRV_NAME ": Mellanox InfiniBand HCA driver v" 133 DRV_NAME ": Mellanox InfiniBand HCA driver v"
130 DRV_VERSION " (" DRV_RELDATE ")\n"; 134 DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -162,6 +166,7 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim)
162 int err; 166 int err;
163 u8 status; 167 u8 status;
164 168
169 mdev->limits.mtt_seg_size = (1 << log_mtts_per_seg) * 8;
165 err = mthca_QUERY_DEV_LIM(mdev, dev_lim, &status); 170 err = mthca_QUERY_DEV_LIM(mdev, dev_lim, &status);
166 if (err) { 171 if (err) {
167 mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n"); 172 mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n");
@@ -460,11 +465,11 @@ static int mthca_init_icm(struct mthca_dev *mdev,
460 } 465 }
461 466
462 /* CPU writes to non-reserved MTTs, while HCA might DMA to reserved mtts */ 467 /* CPU writes to non-reserved MTTs, while HCA might DMA to reserved mtts */
463 mdev->limits.reserved_mtts = ALIGN(mdev->limits.reserved_mtts * MTHCA_MTT_SEG_SIZE, 468 mdev->limits.reserved_mtts = ALIGN(mdev->limits.reserved_mtts * mdev->limits.mtt_seg_size,
464 dma_get_cache_alignment()) / MTHCA_MTT_SEG_SIZE; 469 dma_get_cache_alignment()) / mdev->limits.mtt_seg_size;
465 470
466 mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base, 471 mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base,
467 MTHCA_MTT_SEG_SIZE, 472 mdev->limits.mtt_seg_size,
468 mdev->limits.num_mtt_segs, 473 mdev->limits.num_mtt_segs,
469 mdev->limits.reserved_mtts, 474 mdev->limits.reserved_mtts,
470 1, 0); 475 1, 0);
@@ -1315,6 +1320,12 @@ static void __init mthca_validate_profile(void)
1315 printk(KERN_WARNING PFX "Corrected fmr_reserved_mtts to %d.\n", 1320 printk(KERN_WARNING PFX "Corrected fmr_reserved_mtts to %d.\n",
1316 hca_profile.fmr_reserved_mtts); 1321 hca_profile.fmr_reserved_mtts);
1317 } 1322 }
1323
1324 if ((log_mtts_per_seg < 1) || (log_mtts_per_seg > 5)) {
1325 printk(KERN_WARNING PFX "bad log_mtts_per_seg (%d). Using default - %d\n",
1326 log_mtts_per_seg, ilog2(MTHCA_MTT_SEG_SIZE / 8));
1327 log_mtts_per_seg = ilog2(MTHCA_MTT_SEG_SIZE / 8);
1328 }
1318} 1329}
1319 1330
1320static int __init mthca_init(void) 1331static int __init mthca_init(void)
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 882e6b735915..d606edf10858 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -220,7 +220,7 @@ static struct mthca_mtt *__mthca_alloc_mtt(struct mthca_dev *dev, int size,
220 220
221 mtt->buddy = buddy; 221 mtt->buddy = buddy;
222 mtt->order = 0; 222 mtt->order = 0;
223 for (i = MTHCA_MTT_SEG_SIZE / 8; i < size; i <<= 1) 223 for (i = dev->limits.mtt_seg_size / 8; i < size; i <<= 1)
224 ++mtt->order; 224 ++mtt->order;
225 225
226 mtt->first_seg = mthca_alloc_mtt_range(dev, mtt->order, buddy); 226 mtt->first_seg = mthca_alloc_mtt_range(dev, mtt->order, buddy);
@@ -267,7 +267,7 @@ static int __mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt,
267 267
268 while (list_len > 0) { 268 while (list_len > 0) {
269 mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base + 269 mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base +
270 mtt->first_seg * MTHCA_MTT_SEG_SIZE + 270 mtt->first_seg * dev->limits.mtt_seg_size +
271 start_index * 8); 271 start_index * 8);
272 mtt_entry[1] = 0; 272 mtt_entry[1] = 0;
273 for (i = 0; i < list_len && i < MTHCA_MAILBOX_SIZE / 8 - 2; ++i) 273 for (i = 0; i < list_len && i < MTHCA_MAILBOX_SIZE / 8 - 2; ++i)
@@ -326,7 +326,7 @@ static void mthca_tavor_write_mtt_seg(struct mthca_dev *dev,
326 u64 __iomem *mtts; 326 u64 __iomem *mtts;
327 int i; 327 int i;
328 328
329 mtts = dev->mr_table.tavor_fmr.mtt_base + mtt->first_seg * MTHCA_MTT_SEG_SIZE + 329 mtts = dev->mr_table.tavor_fmr.mtt_base + mtt->first_seg * dev->limits.mtt_seg_size +
330 start_index * sizeof (u64); 330 start_index * sizeof (u64);
331 for (i = 0; i < list_len; ++i) 331 for (i = 0; i < list_len; ++i)
332 mthca_write64_raw(cpu_to_be64(buffer_list[i] | MTHCA_MTT_FLAG_PRESENT), 332 mthca_write64_raw(cpu_to_be64(buffer_list[i] | MTHCA_MTT_FLAG_PRESENT),
@@ -345,10 +345,10 @@ static void mthca_arbel_write_mtt_seg(struct mthca_dev *dev,
345 /* For Arbel, all MTTs must fit in the same page. */ 345 /* For Arbel, all MTTs must fit in the same page. */
346 BUG_ON(s / PAGE_SIZE != (s + list_len * sizeof(u64) - 1) / PAGE_SIZE); 346 BUG_ON(s / PAGE_SIZE != (s + list_len * sizeof(u64) - 1) / PAGE_SIZE);
347 /* Require full segments */ 347 /* Require full segments */
348 BUG_ON(s % MTHCA_MTT_SEG_SIZE); 348 BUG_ON(s % dev->limits.mtt_seg_size);
349 349
350 mtts = mthca_table_find(dev->mr_table.mtt_table, mtt->first_seg + 350 mtts = mthca_table_find(dev->mr_table.mtt_table, mtt->first_seg +
351 s / MTHCA_MTT_SEG_SIZE, &dma_handle); 351 s / dev->limits.mtt_seg_size, &dma_handle);
352 352
353 BUG_ON(!mtts); 353 BUG_ON(!mtts);
354 354
@@ -479,7 +479,7 @@ int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
479 if (mr->mtt) 479 if (mr->mtt)
480 mpt_entry->mtt_seg = 480 mpt_entry->mtt_seg =
481 cpu_to_be64(dev->mr_table.mtt_base + 481 cpu_to_be64(dev->mr_table.mtt_base +
482 mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE); 482 mr->mtt->first_seg * dev->limits.mtt_seg_size);
483 483
484 if (0) { 484 if (0) {
485 mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey); 485 mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
@@ -626,7 +626,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
626 goto err_out_table; 626 goto err_out_table;
627 } 627 }
628 628
629 mtt_seg = mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE; 629 mtt_seg = mr->mtt->first_seg * dev->limits.mtt_seg_size;
630 630
631 if (mthca_is_memfree(dev)) { 631 if (mthca_is_memfree(dev)) {
632 mr->mem.arbel.mtts = mthca_table_find(dev->mr_table.mtt_table, 632 mr->mem.arbel.mtts = mthca_table_find(dev->mr_table.mtt_table,
@@ -908,7 +908,7 @@ int mthca_init_mr_table(struct mthca_dev *dev)
908 dev->mr_table.mtt_base); 908 dev->mr_table.mtt_base);
909 909
910 dev->mr_table.tavor_fmr.mtt_base = 910 dev->mr_table.tavor_fmr.mtt_base =
911 ioremap(addr, mtts * MTHCA_MTT_SEG_SIZE); 911 ioremap(addr, mtts * dev->limits.mtt_seg_size);
912 if (!dev->mr_table.tavor_fmr.mtt_base) { 912 if (!dev->mr_table.tavor_fmr.mtt_base) {
913 mthca_warn(dev, "MTT ioremap for FMR failed.\n"); 913 mthca_warn(dev, "MTT ioremap for FMR failed.\n");
914 err = -ENOMEM; 914 err = -ENOMEM;
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
index d168c2540611..8edb28a9a0e7 100644
--- a/drivers/infiniband/hw/mthca/mthca_profile.c
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c
@@ -94,7 +94,7 @@ s64 mthca_make_profile(struct mthca_dev *dev,
94 profile[MTHCA_RES_RDB].size = MTHCA_RDB_ENTRY_SIZE; 94 profile[MTHCA_RES_RDB].size = MTHCA_RDB_ENTRY_SIZE;
95 profile[MTHCA_RES_MCG].size = MTHCA_MGM_ENTRY_SIZE; 95 profile[MTHCA_RES_MCG].size = MTHCA_MGM_ENTRY_SIZE;
96 profile[MTHCA_RES_MPT].size = dev_lim->mpt_entry_sz; 96 profile[MTHCA_RES_MPT].size = dev_lim->mpt_entry_sz;
97 profile[MTHCA_RES_MTT].size = MTHCA_MTT_SEG_SIZE; 97 profile[MTHCA_RES_MTT].size = dev->limits.mtt_seg_size;
98 profile[MTHCA_RES_UAR].size = dev_lim->uar_scratch_entry_sz; 98 profile[MTHCA_RES_UAR].size = dev_lim->uar_scratch_entry_sz;
99 profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE; 99 profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
100 profile[MTHCA_RES_UARC].size = request->uarc_size; 100 profile[MTHCA_RES_UARC].size = request->uarc_size;
@@ -232,7 +232,7 @@ s64 mthca_make_profile(struct mthca_dev *dev,
232 dev->limits.num_mtt_segs = profile[i].num; 232 dev->limits.num_mtt_segs = profile[i].num;
233 dev->mr_table.mtt_base = profile[i].start; 233 dev->mr_table.mtt_base = profile[i].start;
234 init_hca->mtt_base = profile[i].start; 234 init_hca->mtt_base = profile[i].start;
235 init_hca->mtt_seg_sz = ffs(MTHCA_MTT_SEG_SIZE) - 7; 235 init_hca->mtt_seg_sz = ffs(dev->limits.mtt_seg_size) - 7;
236 break; 236 break;
237 case MTHCA_RES_UAR: 237 case MTHCA_RES_UAR:
238 dev->limits.num_uars = profile[i].num; 238 dev->limits.num_uars = profile[i].num;