[PATCH] IB/mthca: fix MTT allocation in mem-free mode
authorRoland Dreier <roland@topspin.com>
Sat, 16 Apr 2005 22:26:24 +0000 (15:26 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 16 Apr 2005 22:26:24 +0000 (15:26 -0700)
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>
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_cmd.h
drivers/infiniband/hw/mthca/mthca_dev.h
drivers/infiniband/hw/mthca/mthca_main.c
drivers/infiniband/hw/mthca/mthca_mr.c
drivers/infiniband/hw/mthca/mthca_profile.c

index 1bc1ce758165a7186fbc9255e1ef503c82d9c202..244d37c5bf6a45074d54033193d7eff60ec90108 100644 (file)
@@ -990,7 +990,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
                MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
                dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
                MTHCA_GET(size, outbox, QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET);
-               dev_lim->mtt_seg_sz = size;
                MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
                dev_lim->mpt_entry_sz = size;
                MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
@@ -1018,7 +1017,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
        } else {
                MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET);
                dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f);
-               dev_lim->mtt_seg_sz   = MTHCA_MTT_SEG_SIZE;
                dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
        }
 
index a8bc6aa36ff191dc84a2a1a2c3e7c17ac52e7897..a6da34dce8ef8f2ff011948f9b64f2dbe14f5343 100644 (file)
@@ -162,7 +162,6 @@ struct mthca_dev_lim {
        int cqc_entry_sz;
        int srq_entry_sz;
        int uar_scratch_entry_sz;
-       int mtt_seg_sz;
        int mpt_entry_sz;
        union {
                struct {
index 56b2bfb5adb1390c9b3d3d46753d5b2a8c1662b2..f437979e8967c8ed425de62012e0cce36d63a5fb 100644 (file)
@@ -121,7 +121,6 @@ struct mthca_limits {
        int      reserved_eqs;
        int      num_mpts;
        int      num_mtt_segs;
-       int      mtt_seg_size;
        int      reserved_mtts;
        int      reserved_mrws;
        int      reserved_uars;
index 144aed417faacf94d60ebff34067e71553c86bb4..7912b262a4cf81013f86dbc4ee575aaa04c95cf1 100644 (file)
@@ -390,7 +390,7 @@ static int __devinit mthca_init_icm(struct mthca_dev *mdev,
        }
 
        mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base,
-                                                        dev_lim->mtt_seg_sz,
+                                                        MTHCA_MTT_SEG_SIZE,
                                                         mdev->limits.num_mtt_segs,
                                                         mdev->limits.reserved_mtts, 1);
        if (!mdev->mr_table.mtt_table) {
index 66656379ea7b2f43fc0668bd9f2f9d5276d50fac..5cde296b4065d1e9a3317ccdaafe790cc797751a 100644 (file)
@@ -263,7 +263,7 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
                        goto err_out_mpt_free;
        }
 
-       for (i = dev->limits.mtt_seg_size / 8, mr->order = 0;
+       for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0;
             i < list_len;
             i <<= 1, ++mr->order)
                ; /* nothing */
@@ -286,7 +286,7 @@ int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
        mtt_entry = MAILBOX_ALIGN(mailbox);
 
        mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base +
-                                  mr->first_seg * dev->limits.mtt_seg_size);
+                                  mr->first_seg * MTHCA_MTT_SEG_SIZE);
        mtt_entry[1] = 0;
        for (i = 0; i < list_len; ++i)
                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,
        memset(&mpt_entry->lkey, 0,
               sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey));
        mpt_entry->mtt_seg   = cpu_to_be64(dev->mr_table.mtt_base +
-                                          mr->first_seg * dev->limits.mtt_seg_size);
+                                          mr->first_seg * MTHCA_MTT_SEG_SIZE);
 
        if (0) {
                mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
index 9ffe76e23a9e2a1a12093514bbdfc76b36871586..cfd6f70c8df3eef23b28e796ec19286cd276f3c5 100644 (file)
@@ -95,7 +95,7 @@ u64 mthca_make_profile(struct mthca_dev *dev,
        profile[MTHCA_RES_RDB].size  = MTHCA_RDB_ENTRY_SIZE;
        profile[MTHCA_RES_MCG].size  = MTHCA_MGM_ENTRY_SIZE;
        profile[MTHCA_RES_MPT].size  = dev_lim->mpt_entry_sz;
-       profile[MTHCA_RES_MTT].size  = dev_lim->mtt_seg_sz;
+       profile[MTHCA_RES_MTT].size  = MTHCA_MTT_SEG_SIZE;
        profile[MTHCA_RES_UAR].size  = dev_lim->uar_scratch_entry_sz;
        profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
        profile[MTHCA_RES_UARC].size = request->uarc_size;
@@ -229,10 +229,9 @@ u64 mthca_make_profile(struct mthca_dev *dev,
                        break;
                case MTHCA_RES_MTT:
                        dev->limits.num_mtt_segs = profile[i].num;
-                       dev->limits.mtt_seg_size = dev_lim->mtt_seg_sz;
                        dev->mr_table.mtt_base   = profile[i].start;
                        init_hca->mtt_base       = profile[i].start;
-                       init_hca->mtt_seg_sz     = ffs(dev_lim->mtt_seg_sz) - 7;
+                       init_hca->mtt_seg_sz     = ffs(MTHCA_MTT_SEG_SIZE) - 7;
                        break;
                case MTHCA_RES_UAR:
                        dev->limits.num_uars       = profile[i].num;