IB/mthca: Merge MR and FMR space on 64-bit systems
authorMichael S. Tsirkin <mst@mellanox.co.il>
Sat, 10 Feb 2007 21:13:12 +0000 (23:13 +0200)
committerRoland Dreier <rolandd@cisco.com>
Tue, 13 Feb 2007 00:16:29 +0000 (16:16 -0800)
For Tavor, we currently reserve separate MPT and MTT space for FMRs to
avoid abusing the vmalloc space on 32 bit kernels. No such problem
exists on 64 bit kernels so let's not do it there.

This way we have a shared pool for MR and FMR resources, used on
demand.  This will also make it possible to write MTTs for regular
regions directly from driver.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/mthca/mthca_mr.c
drivers/infiniband/hw/mthca/mthca_profile.c

index 7d08f2038aff3582e00da35081a3d8e4f22bf7d7..958c6d5b6bc0c02affb5f47083f950f3eb4b4d70 100644 (file)
@@ -765,7 +765,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
 int mthca_init_mr_table(struct mthca_dev *dev)
 {
        unsigned long addr;
-       int err, i;
+       int mpts, mtts, err, i;
 
        err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
                               dev->limits.num_mpts,
@@ -799,13 +799,21 @@ int mthca_init_mr_table(struct mthca_dev *dev)
                        err = -EINVAL;
                        goto err_fmr_mpt;
                }
+               mpts = mtts = 1 << i;
+       } else {
+               mpts = dev->limits.num_mtt_segs;
+               mtts = dev->limits.num_mpts;
+       }
+
+       if (!mthca_is_memfree(dev) &&
+           (dev->mthca_flags & MTHCA_FLAG_FMR)) {
 
                addr = pci_resource_start(dev->pdev, 4) +
                        ((pci_resource_len(dev->pdev, 4) - 1) &
                         dev->mr_table.mpt_base);
 
                dev->mr_table.tavor_fmr.mpt_base =
-                       ioremap(addr, (1 << i) * sizeof(struct mthca_mpt_entry));
+                       ioremap(addr, mpts * sizeof(struct mthca_mpt_entry));
 
                if (!dev->mr_table.tavor_fmr.mpt_base) {
                        mthca_warn(dev, "MPT ioremap for FMR failed.\n");
@@ -818,19 +826,21 @@ int mthca_init_mr_table(struct mthca_dev *dev)
                         dev->mr_table.mtt_base);
 
                dev->mr_table.tavor_fmr.mtt_base =
-                       ioremap(addr, (1 << i) * MTHCA_MTT_SEG_SIZE);
+                       ioremap(addr, mtts * MTHCA_MTT_SEG_SIZE);
                if (!dev->mr_table.tavor_fmr.mtt_base) {
                        mthca_warn(dev, "MTT ioremap for FMR failed.\n");
                        err = -ENOMEM;
                        goto err_fmr_mtt;
                }
+       }
 
-               err = mthca_buddy_init(&dev->mr_table.tavor_fmr.mtt_buddy, i);
+       if (dev->limits.fmr_reserved_mtts) {
+               err = mthca_buddy_init(&dev->mr_table.tavor_fmr.mtt_buddy, fls(mtts - 1));
                if (err)
                        goto err_fmr_mtt_buddy;
 
                /* Prevent regular MRs from using FMR keys */
-               err = mthca_buddy_alloc(&dev->mr_table.mtt_buddy, i);
+               err = mthca_buddy_alloc(&dev->mr_table.mtt_buddy, fls(mtts - 1));
                if (err)
                        goto err_reserve_fmr;
 
index 58d44aa3c30297a6920c8b292a27cb458b1a7763..26bf86d1cfcd693cf29cdc19bd9704ec916b65de 100644 (file)
@@ -277,7 +277,7 @@ u64 mthca_make_profile(struct mthca_dev *dev,
         * out of the MR pool. They don't use additional memory, but
         * we assign them as part of the HCA profile anyway.
         */
-       if (mthca_is_memfree(dev))
+       if (mthca_is_memfree(dev) || BITS_PER_LONG == 64)
                dev->limits.fmr_reserved_mtts = 0;
        else
                dev->limits.fmr_reserved_mtts = request->fmr_reserved_mtts;