aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <roland@topspin.com>2005-04-16 18:26:24 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:26:24 -0400
commit44ea66879d5638cfed5b5ecf628badfd8ec26f36 (patch)
tree987bb5368a8e4a058cffc2eef4752d7cca4335e5
parentddb934e0eead2feadc7467b1f7bf9c81aa241232 (diff)
[PATCH] IB/mthca: fix MTT allocation in mem-free mode
Fix bug in MTT allocation in mem-free mode. I misunderstood the MTT size value returned by the firmware -- it is really the size of a single MTT entry, since mem-free mode does not segment the MTT as the original firmware did. This meant that our MTT addresses ended up being off by a factor of 8. This meant that our MTT allocations might overlap, and so we could overwrite and corrupt earlier memory regions when writing new MTT entries. We fix this by always using our 64-byte MTT segment size. This allows some simplification of the code as well, since there's no reason to put the MTT segment size in a variable -- we can always use our enum value directly. Signed-off-by: Roland Dreier <roland@topspin.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_profile.c5
6 files changed, 6 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 1bc1ce758165..244d37c5bf6a 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -990,7 +990,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
990 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); 990 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
991 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg); 991 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
992 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET); 992 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET);
993 dev_lim->mtt_seg_sz = size;
994 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET); 993 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
995 dev_lim->mpt_entry_sz = size; 994 dev_lim->mpt_entry_sz = size;
996 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET); 995 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
@@ -1018,7 +1017,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1018 } else { 1017 } else {
1019 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET); 1018 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET);
1020 dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f); 1019 dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f);
1021 dev_lim->mtt_seg_sz = MTHCA_MTT_SEG_SIZE;
1022 dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; 1020 dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
1023 } 1021 }
1024 1022
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
index a8bc6aa36ff1..a6da34dce8ef 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -162,7 +162,6 @@ struct mthca_dev_lim {
162 int cqc_entry_sz; 162 int cqc_entry_sz;
163 int srq_entry_sz; 163 int srq_entry_sz;
164 int uar_scratch_entry_sz; 164 int uar_scratch_entry_sz;
165 int mtt_seg_sz;
166 int mpt_entry_sz; 165 int mpt_entry_sz;
167 union { 166 union {
168 struct { 167 struct {
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 56b2bfb5adb1..f437979e8967 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -121,7 +121,6 @@ struct mthca_limits {
121 int reserved_eqs; 121 int reserved_eqs;
122 int num_mpts; 122 int num_mpts;
123 int num_mtt_segs; 123 int num_mtt_segs;
124 int mtt_seg_size;
125 int reserved_mtts; 124 int reserved_mtts;
126 int reserved_mrws; 125 int reserved_mrws;
127 int reserved_uars; 126 int reserved_uars;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 144aed417faa..7912b262a4cf 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -390,7 +390,7 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev,
390 } 390 }
391 391
392 mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base, 392 mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base,
393 dev_lim->mtt_seg_sz, 393 MTHCA_MTT_SEG_SIZE,
394 mdev->limits.num_mtt_segs, 394 mdev->limits.num_mtt_segs,
395 mdev->limits.reserved_mtts, 1); 395 mdev->limits.reserved_mtts, 1);
396 if (!mdev->mr_table.mtt_table) { 396 if (!mdev->mr_table.mtt_table) {
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 66656379ea7b..5cde296b4065 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -263,7 +263,7 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
263 goto err_out_mpt_free; 263 goto err_out_mpt_free;
264 } 264 }
265 265
266 for (i = dev->limits.mtt_seg_size / 8, mr->order = 0; 266 for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0;
267 i < list_len; 267 i < list_len;
268 i <<= 1, ++mr->order) 268 i <<= 1, ++mr->order)
269 ; /* nothing */ 269 ; /* nothing */
@@ -286,7 +286,7 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
286 mtt_entry = MAILBOX_ALIGN(mailbox); 286 mtt_entry = MAILBOX_ALIGN(mailbox);
287 287
288 mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base + 288 mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base +
289 mr->first_seg * dev->limits.mtt_seg_size); 289 mr->first_seg * MTHCA_MTT_SEG_SIZE);
290 mtt_entry[1] = 0; 290 mtt_entry[1] = 0;
291 for (i = 0; i < list_len; ++i) 291 for (i = 0; i < list_len; ++i)
292 mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] | 292 mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] |
@@ -330,7 +330,7 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
330 memset(&mpt_entry->lkey, 0, 330 memset(&mpt_entry->lkey, 0,
331 sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey)); 331 sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey));
332 mpt_entry->mtt_seg = cpu_to_be64(dev->mr_table.mtt_base + 332 mpt_entry->mtt_seg = cpu_to_be64(dev->mr_table.mtt_base +
333 mr->first_seg * dev->limits.mtt_seg_size); 333 mr->first_seg * MTHCA_MTT_SEG_SIZE);
334 334
335 if (0) { 335 if (0) {
336 mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey); 336 mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
index 9ffe76e23a9e..cfd6f70c8df3 100644
--- a/drivers/infiniband/hw/mthca/mthca_profile.c
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c
@@ -95,7 +95,7 @@ u64 mthca_make_profile(struct mthca_dev *dev,
95 profile[MTHCA_RES_RDB].size = MTHCA_RDB_ENTRY_SIZE; 95 profile[MTHCA_RES_RDB].size = MTHCA_RDB_ENTRY_SIZE;
96 profile[MTHCA_RES_MCG].size = MTHCA_MGM_ENTRY_SIZE; 96 profile[MTHCA_RES_MCG].size = MTHCA_MGM_ENTRY_SIZE;
97 profile[MTHCA_RES_MPT].size = dev_lim->mpt_entry_sz; 97 profile[MTHCA_RES_MPT].size = dev_lim->mpt_entry_sz;
98 profile[MTHCA_RES_MTT].size = dev_lim->mtt_seg_sz; 98 profile[MTHCA_RES_MTT].size = MTHCA_MTT_SEG_SIZE;
99 profile[MTHCA_RES_UAR].size = dev_lim->uar_scratch_entry_sz; 99 profile[MTHCA_RES_UAR].size = dev_lim->uar_scratch_entry_sz;
100 profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE; 100 profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
101 profile[MTHCA_RES_UARC].size = request->uarc_size; 101 profile[MTHCA_RES_UARC].size = request->uarc_size;
@@ -229,10 +229,9 @@ u64 mthca_make_profile(struct mthca_dev *dev,
229 break; 229 break;
230 case MTHCA_RES_MTT: 230 case MTHCA_RES_MTT:
231 dev->limits.num_mtt_segs = profile[i].num; 231 dev->limits.num_mtt_segs = profile[i].num;
232 dev->limits.mtt_seg_size = dev_lim->mtt_seg_sz;
233 dev->mr_table.mtt_base = profile[i].start; 232 dev->mr_table.mtt_base = profile[i].start;
234 init_hca->mtt_base = profile[i].start; 233 init_hca->mtt_base = profile[i].start;
235 init_hca->mtt_seg_sz = ffs(dev_lim->mtt_seg_sz) - 7; 234 init_hca->mtt_seg_sz = ffs(MTHCA_MTT_SEG_SIZE) - 7;
236 break; 235 break;
237 case MTHCA_RES_UAR: 236 case MTHCA_RES_UAR:
238 dev->limits.num_uars = profile[i].num; 237 dev->limits.num_uars = profile[i].num;