Commit c27fef26 authored by Bryan O'Sullivan's avatar Bryan O'Sullivan Committed by Roland Dreier

IB/ipath: lock resource limit counters correctly

Signed-off-by: default avatarBryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent eb9dc6f4
...@@ -776,18 +776,22 @@ static struct ib_pd *ipath_alloc_pd(struct ib_device *ibdev, ...@@ -776,18 +776,22 @@ static struct ib_pd *ipath_alloc_pd(struct ib_device *ibdev,
* we allow allocations of more than we report for this value. * we allow allocations of more than we report for this value.
*/ */
if (dev->n_pds_allocated == ib_ipath_max_pds) { pd = kmalloc(sizeof *pd, GFP_KERNEL);
if (!pd) {
ret = ERR_PTR(-ENOMEM); ret = ERR_PTR(-ENOMEM);
goto bail; goto bail;
} }
pd = kmalloc(sizeof *pd, GFP_KERNEL); spin_lock(&dev->n_pds_lock);
if (!pd) { if (dev->n_pds_allocated == ib_ipath_max_pds) {
spin_unlock(&dev->n_pds_lock);
kfree(pd);
ret = ERR_PTR(-ENOMEM); ret = ERR_PTR(-ENOMEM);
goto bail; goto bail;
} }
dev->n_pds_allocated++; dev->n_pds_allocated++;
spin_unlock(&dev->n_pds_lock);
/* ib_alloc_pd() will initialize pd->ibpd. */ /* ib_alloc_pd() will initialize pd->ibpd. */
pd->user = udata != NULL; pd->user = udata != NULL;
...@@ -803,7 +807,9 @@ static int ipath_dealloc_pd(struct ib_pd *ibpd) ...@@ -803,7 +807,9 @@ static int ipath_dealloc_pd(struct ib_pd *ibpd)
struct ipath_pd *pd = to_ipd(ibpd); struct ipath_pd *pd = to_ipd(ibpd);
struct ipath_ibdev *dev = to_idev(ibpd->device); struct ipath_ibdev *dev = to_idev(ibpd->device);
spin_lock(&dev->n_pds_lock);
dev->n_pds_allocated--; dev->n_pds_allocated--;
spin_unlock(&dev->n_pds_lock);
kfree(pd); kfree(pd);
...@@ -824,11 +830,6 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd, ...@@ -824,11 +830,6 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
struct ib_ah *ret; struct ib_ah *ret;
struct ipath_ibdev *dev = to_idev(pd->device); struct ipath_ibdev *dev = to_idev(pd->device);
if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
ret = ERR_PTR(-ENOMEM);
goto bail;
}
/* A multicast address requires a GRH (see ch. 8.4.1). */ /* A multicast address requires a GRH (see ch. 8.4.1). */
if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
ah_attr->dlid != IPATH_PERMISSIVE_LID && ah_attr->dlid != IPATH_PERMISSIVE_LID &&
...@@ -854,7 +855,16 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd, ...@@ -854,7 +855,16 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
goto bail; goto bail;
} }
spin_lock(&dev->n_ahs_lock);
if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
spin_unlock(&dev->n_ahs_lock);
kfree(ah);
ret = ERR_PTR(-ENOMEM);
goto bail;
}
dev->n_ahs_allocated++; dev->n_ahs_allocated++;
spin_unlock(&dev->n_ahs_lock);
/* ib_create_ah() will initialize ah->ibah. */ /* ib_create_ah() will initialize ah->ibah. */
ah->attr = *ah_attr; ah->attr = *ah_attr;
...@@ -876,7 +886,9 @@ static int ipath_destroy_ah(struct ib_ah *ibah) ...@@ -876,7 +886,9 @@ static int ipath_destroy_ah(struct ib_ah *ibah)
struct ipath_ibdev *dev = to_idev(ibah->device); struct ipath_ibdev *dev = to_idev(ibah->device);
struct ipath_ah *ah = to_iah(ibah); struct ipath_ah *ah = to_iah(ibah);
spin_lock(&dev->n_ahs_lock);
dev->n_ahs_allocated--; dev->n_ahs_allocated--;
spin_unlock(&dev->n_ahs_lock);
kfree(ah); kfree(ah);
...@@ -963,6 +975,12 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd) ...@@ -963,6 +975,12 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
dev = &idev->ibdev; dev = &idev->ibdev;
/* Only need to initialize non-zero fields. */ /* Only need to initialize non-zero fields. */
spin_lock_init(&idev->n_pds_lock);
spin_lock_init(&idev->n_ahs_lock);
spin_lock_init(&idev->n_cqs_lock);
spin_lock_init(&idev->n_srqs_lock);
spin_lock_init(&idev->n_mcast_grps_lock);
spin_lock_init(&idev->qp_table.lock); spin_lock_init(&idev->qp_table.lock);
spin_lock_init(&idev->lk_table.lock); spin_lock_init(&idev->lk_table.lock);
idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE); idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE);
......
...@@ -434,11 +434,18 @@ struct ipath_ibdev { ...@@ -434,11 +434,18 @@ struct ipath_ibdev {
__be64 sys_image_guid; /* in network order */ __be64 sys_image_guid; /* in network order */
__be64 gid_prefix; /* in network order */ __be64 gid_prefix; /* in network order */
__be64 mkey; __be64 mkey;
u32 n_pds_allocated; /* number of PDs allocated for device */ u32 n_pds_allocated; /* number of PDs allocated for device */
spinlock_t n_pds_lock;
u32 n_ahs_allocated; /* number of AHs allocated for device */ u32 n_ahs_allocated; /* number of AHs allocated for device */
spinlock_t n_ahs_lock;
u32 n_cqs_allocated; /* number of CQs allocated for device */ u32 n_cqs_allocated; /* number of CQs allocated for device */
spinlock_t n_cqs_lock;
u32 n_srqs_allocated; /* number of SRQs allocated for device */ u32 n_srqs_allocated; /* number of SRQs allocated for device */
spinlock_t n_srqs_lock;
u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ u32 n_mcast_grps_allocated; /* number of mcast groups allocated */
spinlock_t n_mcast_grps_lock;
u64 ipath_sword; /* total dwords sent (sample result) */ u64 ipath_sword; /* total dwords sent (sample result) */
u64 ipath_rword; /* total dwords received (sample result) */ u64 ipath_rword; /* total dwords received (sample result) */
u64 ipath_spkts; /* total packets sent (sample result) */ u64 ipath_spkts; /* total packets sent (sample result) */
......
...@@ -207,12 +207,15 @@ static int ipath_mcast_add(struct ipath_ibdev *dev, ...@@ -207,12 +207,15 @@ static int ipath_mcast_add(struct ipath_ibdev *dev,
goto bail; goto bail;
} }
spin_lock(&dev->n_mcast_grps_lock);
if (dev->n_mcast_grps_allocated == ib_ipath_max_mcast_grps) { if (dev->n_mcast_grps_allocated == ib_ipath_max_mcast_grps) {
spin_unlock(&dev->n_mcast_grps_lock);
ret = ENOMEM; ret = ENOMEM;
goto bail; goto bail;
} }
dev->n_mcast_grps_allocated++; dev->n_mcast_grps_allocated++;
spin_unlock(&dev->n_mcast_grps_lock);
list_add_tail_rcu(&mqp->list, &mcast->qp_list); list_add_tail_rcu(&mqp->list, &mcast->qp_list);
...@@ -343,7 +346,9 @@ int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) ...@@ -343,7 +346,9 @@ int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
atomic_dec(&mcast->refcount); atomic_dec(&mcast->refcount);
wait_event(mcast->wait, !atomic_read(&mcast->refcount)); wait_event(mcast->wait, !atomic_read(&mcast->refcount));
ipath_mcast_free(mcast); ipath_mcast_free(mcast);
spin_lock(&dev->n_mcast_grps_lock);
dev->n_mcast_grps_allocated--; dev->n_mcast_grps_allocated--;
spin_unlock(&dev->n_mcast_grps_lock);
} }
ret = 0; ret = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment