tree 97984c9e04c31a5d2055e4bcac16bb11c923eca1
parent 79b61dceafce696d72661d23a02393566b1899ab
author Roland Dreier <[EMAIL PROTECTED]> Sun, 17 Apr 2005 05:26:13 -0700
committer Linus Torvalds <[EMAIL PROTECTED]> Sun, 17 Apr 2005 05:26:13 -0700
[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]>
infiniband/hw/mthca/mthca_main.c | 2
infiniband/hw/mthca/mthca_memfree.c | 32 ++++++++++++++
infiniband/hw/mthca/mthca_memfree.h | 4 +
infiniband/hw/mthca/mthca_mr.c | 79 ++++++++++++++++++++++++++++++------
4 files changed, 105 insertions(+), 12 deletions(-)
Index: drivers/infiniband/hw/mthca/mthca_main.c
===================================================================
---
642e71bca35c7e77ac55a8e810144a722e13f531/drivers/infiniband/hw/mthca/mthca_main.c
(mode:100644 sha1:9e782bc1c38de4cc7187718277adff127c2709b8)
+++
97984c9e04c31a5d2055e4bcac16bb11c923eca1/drivers/infiniband/hw/mthca/mthca_main.c
(mode:100644 sha1:8bd2e3af016dd6328e2938bda0bd37a65bdd2830)
@@ -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
===================================================================
---
642e71bca35c7e77ac55a8e810144a722e13f531/drivers/infiniband/hw/mthca/mthca_memfree.c
(mode:100644 sha1:7730b59606160e3804ad530686f194ec1c3f9afd)
+++
97984c9e04c31a5d2055e4bcac16bb11c923eca1/drivers/infiniband/hw/mthca/mthca_memfree.c
(mode:100644 sha1:a70a1c712b4bc2aa873d1bc0e7e63c46ef4fbf66)
@@ -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
===================================================================
---
642e71bca35c7e77ac55a8e810144a722e13f531/drivers/infiniband/hw/mthca/mthca_memfree.h
(mode:100644 sha1:a8fa97e140f5faa4ad73b191a5dfb38589f20f35)
+++
97984c9e04c31a5d2055e4bcac16bb11c923eca1/drivers/infiniband/hw/mthca/mthca_memfree.h
(mode:100644 sha1:ef72e430250acae35e4b7d09969a03da20734493)
@@ -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
===================================================================
---
642e71bca35c7e77ac55a8e810144a722e13f531/drivers/infiniband/hw/mthca/mthca_mr.c
(mode:100644 sha1:80a0cd97881b7405267525efcff05db363550591)
+++
97984c9e04c31a5d2055e4bcac16bb11c923eca1/drivers/infiniband/hw/mthca/mthca_mr.c
(mode:100644 sha1:5eb6e07f35bb2fdbd83c910df56bb70193d0dc76)
@@ -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