tree 0b7945bffcadef91219f94025b100bd9c9196dd8
parent 943e2abff1314dcedeee6081071f8dfff8e9223f
author Roland Dreier <[EMAIL PROTECTED]> Tue Apr 12 08:26:40 2005
committer Linus Torvalds <[EMAIL PROTECTED]> Tue Apr 12 08:26:40 2005

[PATCH] IB/mthca: map MPT/MTT context in mem-free mode

In mem-free mode, when allocating memory regions, make sure that the HCA has
context memory mapped to cover the virtual space used for the MPT and MTTs
being used.

Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>

 mthca_main.c    |    2 -
 mthca_memfree.c |   32 ++++++++++++++++++++++
 mthca_memfree.h |    4 ++
 mthca_mr.c      |   79 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 4 files changed, 105 insertions(+), 12 deletions(-)

Index: drivers/infiniband/hw/mthca/mthca_main.c
===================================================================
--- 
8887c04bd471d3c84b77358f2721da6c490cacfa/drivers/infiniband/hw/mthca/mthca_main.c
  (mode:100644 sha1:22c4cd1edcbaa3368dd2949876447aafc56272d4)
+++ 
0b7945bffcadef91219f94025b100bd9c9196dd8/drivers/infiniband/hw/mthca/mthca_main.c
  (mode:100644 sha1:a8c6db860cf329711994815f7aaa914606ccbd67)
@@ -390,7 +390,7 @@
        }
 
        mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, 
init_hca->mtt_base,
-                                                        init_hca->mtt_seg_sz,
+                                                        dev_lim->mtt_seg_sz,
                                                         
mdev->limits.num_mtt_segs,
                                                         
mdev->limits.reserved_mtts, 1);
        if (!mdev->mr_table.mtt_table) {
Index: drivers/infiniband/hw/mthca/mthca_memfree.c
===================================================================
--- 
8887c04bd471d3c84b77358f2721da6c490cacfa/drivers/infiniband/hw/mthca/mthca_memfree.c
  (mode:100644 sha1:119c90ec791989569a04392864fee176d4d1448a)
+++ 
0b7945bffcadef91219f94025b100bd9c9196dd8/drivers/infiniband/hw/mthca/mthca_memfree.c
  (mode:100644 sha1:4f60d62437c3e78885297ed2872491ee558ab328)
@@ -192,6 +192,38 @@
        up(&table->mutex);
 }
 
+int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
+                         int start, int end)
+{
+       int inc = MTHCA_TABLE_CHUNK_SIZE / table->obj_size;
+       int i, err;
+
+       for (i = start; i <= end; i += inc) {
+               err = mthca_table_get(dev, table, i);
+               if (err)
+                       goto fail;
+       }
+
+       return 0;
+
+fail:
+       while (i > start) {
+               i -= inc;
+               mthca_table_put(dev, table, i);
+       }
+
+       return err;
+}
+
+void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table 
*table,
+                          int start, int end)
+{
+       int i;
+
+       for (i = start; i <= end; i += MTHCA_TABLE_CHUNK_SIZE / table->obj_size)
+               mthca_table_put(dev, table, i);
+}
+
 struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
                                              u64 virt, int obj_size,
                                              int nobj, int reserved,
Index: drivers/infiniband/hw/mthca/mthca_memfree.h
===================================================================
--- 
8887c04bd471d3c84b77358f2721da6c490cacfa/drivers/infiniband/hw/mthca/mthca_memfree.h
  (mode:100644 sha1:cbb8650ef971ab80f68a179cad42f74efa509d6e)
+++ 
0b7945bffcadef91219f94025b100bd9c9196dd8/drivers/infiniband/hw/mthca/mthca_memfree.h
  (mode:100644 sha1:6dfc0ba9e4d539ac3abc1371e15060bf739e19f6)
@@ -85,6 +85,10 @@
 void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table 
*table);
 int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int 
obj);
 void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int 
obj);
+int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
+                         int start, int end);
+void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table 
*table,
+                          int start, int end);
 
 static inline void mthca_icm_first(struct mthca_icm *icm,
                                   struct mthca_icm_iter *iter)
Index: drivers/infiniband/hw/mthca/mthca_mr.c
===================================================================
--- 
8887c04bd471d3c84b77358f2721da6c490cacfa/drivers/infiniband/hw/mthca/mthca_mr.c 
 (mode:100644 sha1:9b67447e9aa0c5c08e699ae5e36c071212149478)
+++ 
0b7945bffcadef91219f94025b100bd9c9196dd8/drivers/infiniband/hw/mthca/mthca_mr.c 
 (mode:100644 sha1:b42fabbce0157aa3f79212d0bba6e54a862cf253)
@@ -38,6 +38,7 @@
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
+#include "mthca_memfree.h"
 
 /*
  * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
@@ -71,7 +72,7 @@
  * through the bitmaps)
  */
 
-static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order)
+static u32 __mthca_alloc_mtt(struct mthca_dev *dev, int order)
 {
        int o;
        int m;
@@ -105,7 +106,7 @@
        return seg;
 }
 
-static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order)
+static void __mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order)
 {
        seg >>= order;
 
@@ -122,6 +123,32 @@
        spin_unlock(&dev->mr_table.mpt_alloc.lock);
 }
 
+static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order)
+{
+       u32 seg = __mthca_alloc_mtt(dev, order);
+
+       if (seg == -1)
+               return -1;
+
+       if (dev->hca_type == ARBEL_NATIVE)
+               if (mthca_table_get_range(dev, dev->mr_table.mtt_table, seg,
+                                         seg + (1 << order) - 1)) {
+                       __mthca_free_mtt(dev, seg, order);
+                       seg = -1;
+               }
+
+       return seg;
+}
+
+static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order)
+{
+       __mthca_free_mtt(dev, seg, order);
+
+       if (dev->hca_type == ARBEL_NATIVE)
+               mthca_table_put_range(dev, dev->mr_table.mtt_table, seg,
+                                     seg + (1 << order) - 1);
+}
+
 static inline u32 hw_index_to_key(struct mthca_dev *dev, u32 ind)
 {
        if (dev->hca_type == ARBEL_NATIVE)
@@ -141,7 +168,7 @@
 int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
                           u32 access, struct mthca_mr *mr)
 {
-       void *mailbox;
+       void *mailbox = NULL;
        struct mthca_mpt_entry *mpt_entry;
        u32 key;
        int err;
@@ -155,11 +182,17 @@
                return -ENOMEM;
        mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
 
+       if (dev->hca_type == ARBEL_NATIVE) {
+               err = mthca_table_get(dev, dev->mr_table.mpt_table, key);
+               if (err)
+                       goto err_out_mpt_free;
+       }
+
        mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA,
                          GFP_KERNEL);
        if (!mailbox) {
-               mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_out_table;
        }
        mpt_entry = MAILBOX_ALIGN(mailbox);
 
@@ -180,16 +213,27 @@
        err = mthca_SW2HW_MPT(dev, mpt_entry,
                              key & (dev->limits.num_mpts - 1),
                              &status);
-       if (err)
+       if (err) {
                mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
-       else if (status) {
+               goto err_out_table;
+       } else if (status) {
                mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
                           status);
                err = -EINVAL;
+               goto err_out_table;
        }
 
        kfree(mailbox);
        return err;
+
+err_out_table:
+       if (dev->hca_type == ARBEL_NATIVE)
+               mthca_table_put(dev, dev->mr_table.mpt_table, key);
+
+err_out_mpt_free:
+       mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
+       kfree(mailbox);
+       return err;
 }
 
 int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
@@ -213,6 +257,12 @@
                return -ENOMEM;
        mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
 
+       if (dev->hca_type == ARBEL_NATIVE) {
+               err = mthca_table_get(dev, dev->mr_table.mpt_table, key);
+               if (err)
+                       goto err_out_mpt_free;
+       }
+
        for (i = dev->limits.mtt_seg_size / 8, mr->order = 0;
             i < list_len;
             i <<= 1, ++mr->order)
@@ -220,7 +270,7 @@
 
        mr->first_seg = mthca_alloc_mtt(dev, mr->order);
        if (mr->first_seg == -1)
-               goto err_out_mpt_free;
+               goto err_out_table;
 
        /*
         * If list_len is odd, we add one more dummy entry for
@@ -307,13 +357,17 @@
        kfree(mailbox);
        return err;
 
- err_out_mailbox_free:
+err_out_mailbox_free:
        kfree(mailbox);
 
- err_out_free_mtt:
+err_out_free_mtt:
        mthca_free_mtt(dev, mr->first_seg, mr->order);
 
- err_out_mpt_free:
+err_out_table:
+       if (dev->hca_type == ARBEL_NATIVE)
+               mthca_table_put(dev, dev->mr_table.mpt_table, key);
+
+err_out_mpt_free:
        mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
        return err;
 }
@@ -338,6 +392,9 @@
        if (mr->order >= 0)
                mthca_free_mtt(dev, mr->first_seg, mr->order);
 
+       if (dev->hca_type == ARBEL_NATIVE)
+               mthca_table_put(dev, dev->mr_table.mpt_table,
+                               key_to_hw_index(dev, mr->ibmr.lkey));
        mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, 
mr->ibmr.lkey));
 }
 
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to