diff options
author | Eli Cohen <eli@mellanox.co.il> | 2009-05-27 17:36:16 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-05-27 17:36:16 -0400 |
commit | c1f67a88bf62fac0f4151c007b361199c2cd1988 (patch) | |
tree | 5bb527966e1a6cd2a3c06f6df70199df948e3817 /drivers/infiniband/hw/mthca | |
parent | 210af919c949a7d6bd330916ef376cec2907d81e (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/hw/mthca')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_dev.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 17 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mr.c | 16 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_profile.c | 4 |
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); | |||
125 | MODULE_PARM_DESC(fmr_reserved_mtts, | 125 | MODULE_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 | ||
128 | static int log_mtts_per_seg = ilog2(MTHCA_MTT_SEG_SIZE / 8); | ||
129 | module_param_named(log_mtts_per_seg, log_mtts_per_seg, int, 0444); | ||
130 | MODULE_PARM_DESC(log_mtts_per_seg, "Log2 number of MTT entries per segment (1-5)"); | ||
131 | |||
128 | static char mthca_version[] __devinitdata = | 132 | static 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 | ||
1320 | static int __init mthca_init(void) | 1331 | static 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; |