The following patch supercedes the patch for mthca_mcg that I sent previously.
Unfortunately the patch has got relatively big, and it's somewhat hard
to split it up to smaller chunks.

---

Multicast group management fixes:
. Dont leak mailbox memory in error handling on multicast group operations
. Free AMGM indices at detach and in attach error handling
. Fix amount to shift for aligning next_gid_index in mailbox:
  it starts at bit 6, not bit 5
. Allocate AMGM index after end of MGM table, in the range
  num_mgms to multicast table size - 1. Add some BUG_ON checks
  to catch cases where the index falls in the MGM hash area.
. Initialize the list of QPs in a newly-allocated group from AMGM to 0
  This is necessary since when a group is moved from AMGM to MGM
  (in the case where the MGM entry has been emptied of QPs), the AMGM
  entry is not reset to 0 (and we dont want an extra command to do that).

Signed-off-by: Jack Morgenstein <[EMAIL PROTECTED]>
Signed-off-by: Michael S. Tsirkin <[EMAIL PROTECTED]>

Index: latest/drivers/infiniband/hw/mthca/mthca_mcg.c
===================================================================
--- latest.orig/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ latest/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -109,7 +109,8 @@ static int find_mgm(struct mthca_dev *de
                        goto out;
                if (status) {
                        mthca_err(dev, "READ_MGM returned status %02x\n", 
status);
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto out;
                }
 
                if (!memcmp(mgm->gid, zero_gid, 16)) {
@@ -124,7 +125,7 @@ static int find_mgm(struct mthca_dev *de
                        goto out;
 
                *prev = *index;
-               *index = be32_to_cpu(mgm->next_gid_index) >> 5;
+               *index = be32_to_cpu(mgm->next_gid_index) >> 6;
        } while (*index);
 
        *index = -1;
@@ -151,8 +152,10 @@ int mthca_multicast_attach(struct ib_qp 
                return PTR_ERR(mailbox);
        mgm = mailbox->buf;
 
-       if (down_interruptible(&dev->mcg_table.sem))
-               return -EINTR;
+       if (down_interruptible(&dev->mcg_table.sem)) {
+               err = -EINTR;
+               goto err_sem;
+       }
 
        err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
        if (err)
@@ -179,9 +182,8 @@ int mthca_multicast_attach(struct ib_qp 
                        err = -EINVAL;
                        goto out;
                }
-
+               memset(mgm, 0, sizeof *mgm);
                memcpy(mgm->gid, gid->raw, 16);
-               mgm->next_gid_index = 0;
        }
 
        for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
@@ -207,6 +209,7 @@ int mthca_multicast_attach(struct ib_qp 
        if (status) {
                mthca_err(dev, "WRITE_MGM returned status %02x\n", status);
                err = -EINVAL;
+               goto out;
        }
 
        if (!link)
@@ -221,7 +224,7 @@ int mthca_multicast_attach(struct ib_qp 
                goto out;
        }
 
-       mgm->next_gid_index = cpu_to_be32(index << 5);
+       mgm->next_gid_index = cpu_to_be32(index << 6);
 
        err = mthca_WRITE_MGM(dev, prev, mailbox, &status);
        if (err)
@@ -232,7 +235,12 @@ int mthca_multicast_attach(struct ib_qp 
        }
 
  out:
+       if (err && link && index != -1) {
+               BUG_ON(index < dev->limits.num_mgms);
+               mthca_free(&dev->mcg_table.alloc, index);
+       }
        up(&dev->mcg_table.sem);
+ err_sem:
        mthca_free_mailbox(dev, mailbox);
        return err;
 }
@@ -253,8 +261,10 @@ int mthca_multicast_detach(struct ib_qp 
                return PTR_ERR(mailbox);
        mgm = mailbox->buf;
 
-       if (down_interruptible(&dev->mcg_table.sem))
-               return -EINTR;
+       if (down_interruptible(&dev->mcg_table.sem)) {
+               err = -EINTR;
+               goto err_sem;
+       }
 
        err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
        if (err)
@@ -303,13 +313,11 @@ int mthca_multicast_detach(struct ib_qp 
        if (i != 1)
                goto out;
 
-       goto out;
-
        if (prev == -1) {
                /* Remove entry from MGM */
-               if (be32_to_cpu(mgm->next_gid_index) >> 5) {
-                       err = mthca_READ_MGM(dev,
-                                            be32_to_cpu(mgm->next_gid_index) 
>> 5,
+               int amgm_index_to_free = be32_to_cpu(mgm->next_gid_index) >> 6;
+               if (amgm_index_to_free) {
+                       err = mthca_READ_MGM(dev, amgm_index_to_free,
                                             mailbox, &status);
                        if (err)
                                goto out;
@@ -330,9 +338,13 @@ int mthca_multicast_detach(struct ib_qp 
                        err = -EINVAL;
                        goto out;
                }
+               if (amgm_index_to_free) {
+                       BUG_ON(amgm_index_to_free < dev->limits.num_mgms);
+                       mthca_free(&dev->mcg_table.alloc, amgm_index_to_free);
+               }
        } else {
                /* Remove entry from AMGM */
-               index = be32_to_cpu(mgm->next_gid_index) >> 5;
+               int curr_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
                err = mthca_READ_MGM(dev, prev, mailbox, &status);
                if (err)
                        goto out;
@@ -342,7 +354,7 @@ int mthca_multicast_detach(struct ib_qp 
                        goto out;
                }
 
-               mgm->next_gid_index = cpu_to_be32(index << 5);
+               mgm->next_gid_index = cpu_to_be32(curr_next_index << 6);
 
                err = mthca_WRITE_MGM(dev, prev, mailbox, &status);
                if (err)
@@ -352,10 +364,13 @@ int mthca_multicast_detach(struct ib_qp 
                        err = -EINVAL;
                        goto out;
                }
+               BUG_ON(index < dev->limits.num_mgms);
+               mthca_free(&dev->mcg_table.alloc, index);
        }
 
  out:
        up(&dev->mcg_table.sem);
+ err_sem:
        mthca_free_mailbox(dev, mailbox);
        return err;
 }
@@ -363,11 +378,12 @@ int mthca_multicast_detach(struct ib_qp 
 int __devinit mthca_init_mcg_table(struct mthca_dev *dev)
 {
        int err;
+       int table_size = dev->limits.num_mgms + dev->limits.num_amgms;
 
        err = mthca_alloc_init(&dev->mcg_table.alloc,
-                              dev->limits.num_amgms,
-                              dev->limits.num_amgms - 1,
-                              0);
+                              table_size,
+                              table_size - 1,
+                              dev->limits.num_mgms);
        if (err)
                return err;
 


-- 
MST
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to