]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/infiniband/hw/mthca/mthca_provider.c
IB/mthca: Make all device methods truly reentrant
[linux-2.6.git] / drivers / infiniband / hw / mthca / mthca_provider.c
index 8f89ba7c9147ee2c034d0db05aa940bd8f646aad..230ae21db8fd3c15a2c8664443987efec352912e 100644 (file)
@@ -793,18 +793,24 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda
        if (entries < 1 || entries > dev->limits.max_cqes)
                return -EINVAL;
 
+       mutex_lock(&cq->mutex);
+
        entries = roundup_pow_of_two(entries + 1);
-       if (entries == ibcq->cqe + 1)
-               return 0;
+       if (entries == ibcq->cqe + 1) {
+               ret = 0;
+               goto out;
+       }
 
        if (cq->is_kernel) {
                ret = mthca_alloc_resize_buf(dev, cq, entries);
                if (ret)
-                       return ret;
+                       goto out;
                lkey = cq->resize_buf->buf.mr.ibmr.lkey;
        } else {
-               if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
-                       return -EFAULT;
+               if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
+                       ret = -EFAULT;
+                       goto out;
+               }
                lkey = ucmd.lkey;
        }
 
@@ -821,7 +827,7 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda
                        cq->resize_buf = NULL;
                        spin_unlock_irq(&cq->lock);
                }
-               return ret;
+               goto out;
        }
 
        if (cq->is_kernel) {
@@ -848,7 +854,10 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda
        } else
                ibcq->cqe = entries - 1;
 
-       return 0;
+out:
+       mutex_unlock(&cq->mutex);
+
+       return ret;
 }
 
 static int mthca_destroy_cq(struct ib_cq *cq)