aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@pathscale.com>2006-08-25 14:24:27 -0400
committerRoland Dreier <rolandd@cisco.com>2006-09-22 18:22:27 -0400
commitc27fef26271d352b5546c33239edeb0dcb4fc0cc (patch)
tree3dc284784c4218c80d7806c05324be1599d6c6c6
parenteb9dc6f48dc7537ce53163109625bd992150e0cf (diff)
IB/ipath: lock resource limit counters correctly
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c34
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs_mcast.c5
3 files changed, 38 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index a2b4c70192d8..5b8ee65c6cd3 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -776,18 +776,22 @@ static struct ib_pd *ipath_alloc_pd(struct ib_device *ibdev,
776 * we allow allocations of more than we report for this value. 776 * we allow allocations of more than we report for this value.
777 */ 777 */
778 778
779 if (dev->n_pds_allocated == ib_ipath_max_pds) { 779 pd = kmalloc(sizeof *pd, GFP_KERNEL);
780 if (!pd) {
780 ret = ERR_PTR(-ENOMEM); 781 ret = ERR_PTR(-ENOMEM);
781 goto bail; 782 goto bail;
782 } 783 }
783 784
784 pd = kmalloc(sizeof *pd, GFP_KERNEL); 785 spin_lock(&dev->n_pds_lock);
785 if (!pd) { 786 if (dev->n_pds_allocated == ib_ipath_max_pds) {
787 spin_unlock(&dev->n_pds_lock);
788 kfree(pd);
786 ret = ERR_PTR(-ENOMEM); 789 ret = ERR_PTR(-ENOMEM);
787 goto bail; 790 goto bail;
788 } 791 }
789 792
790 dev->n_pds_allocated++; 793 dev->n_pds_allocated++;
794 spin_unlock(&dev->n_pds_lock);
791 795
792 /* ib_alloc_pd() will initialize pd->ibpd. */ 796 /* ib_alloc_pd() will initialize pd->ibpd. */
793 pd->user = udata != NULL; 797 pd->user = udata != NULL;
@@ -803,7 +807,9 @@ static int ipath_dealloc_pd(struct ib_pd *ibpd)
803 struct ipath_pd *pd = to_ipd(ibpd); 807 struct ipath_pd *pd = to_ipd(ibpd);
804 struct ipath_ibdev *dev = to_idev(ibpd->device); 808 struct ipath_ibdev *dev = to_idev(ibpd->device);
805 809
810 spin_lock(&dev->n_pds_lock);
806 dev->n_pds_allocated--; 811 dev->n_pds_allocated--;
812 spin_unlock(&dev->n_pds_lock);
807 813
808 kfree(pd); 814 kfree(pd);
809 815
@@ -824,11 +830,6 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
824 struct ib_ah *ret; 830 struct ib_ah *ret;
825 struct ipath_ibdev *dev = to_idev(pd->device); 831 struct ipath_ibdev *dev = to_idev(pd->device);
826 832
827 if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
828 ret = ERR_PTR(-ENOMEM);
829 goto bail;
830 }
831
832 /* A multicast address requires a GRH (see ch. 8.4.1). */ 833 /* A multicast address requires a GRH (see ch. 8.4.1). */
833 if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE && 834 if (ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
834 ah_attr->dlid != IPATH_PERMISSIVE_LID && 835 ah_attr->dlid != IPATH_PERMISSIVE_LID &&
@@ -854,7 +855,16 @@ static struct ib_ah *ipath_create_ah(struct ib_pd *pd,
854 goto bail; 855 goto bail;
855 } 856 }
856 857
858 spin_lock(&dev->n_ahs_lock);
859 if (dev->n_ahs_allocated == ib_ipath_max_ahs) {
860 spin_unlock(&dev->n_ahs_lock);
861 kfree(ah);
862 ret = ERR_PTR(-ENOMEM);
863 goto bail;
864 }
865
857 dev->n_ahs_allocated++; 866 dev->n_ahs_allocated++;
867 spin_unlock(&dev->n_ahs_lock);
858 868
859 /* ib_create_ah() will initialize ah->ibah. */ 869 /* ib_create_ah() will initialize ah->ibah. */
860 ah->attr = *ah_attr; 870 ah->attr = *ah_attr;
@@ -876,7 +886,9 @@ static int ipath_destroy_ah(struct ib_ah *ibah)
876 struct ipath_ibdev *dev = to_idev(ibah->device); 886 struct ipath_ibdev *dev = to_idev(ibah->device);
877 struct ipath_ah *ah = to_iah(ibah); 887 struct ipath_ah *ah = to_iah(ibah);
878 888
889 spin_lock(&dev->n_ahs_lock);
879 dev->n_ahs_allocated--; 890 dev->n_ahs_allocated--;
891 spin_unlock(&dev->n_ahs_lock);
880 892
881 kfree(ah); 893 kfree(ah);
882 894
@@ -963,6 +975,12 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
963 dev = &idev->ibdev; 975 dev = &idev->ibdev;
964 976
965 /* Only need to initialize non-zero fields. */ 977 /* Only need to initialize non-zero fields. */
978 spin_lock_init(&idev->n_pds_lock);
979 spin_lock_init(&idev->n_ahs_lock);
980 spin_lock_init(&idev->n_cqs_lock);
981 spin_lock_init(&idev->n_srqs_lock);
982 spin_lock_init(&idev->n_mcast_grps_lock);
983
966 spin_lock_init(&idev->qp_table.lock); 984 spin_lock_init(&idev->qp_table.lock);
967 spin_lock_init(&idev->lk_table.lock); 985 spin_lock_init(&idev->lk_table.lock);
968 idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE); 986 idev->sm_lid = __constant_be16_to_cpu(IB_LID_PERMISSIVE);
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 7d2ba72609f7..a9baa9101432 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -434,11 +434,18 @@ struct ipath_ibdev {
434 __be64 sys_image_guid; /* in network order */ 434 __be64 sys_image_guid; /* in network order */
435 __be64 gid_prefix; /* in network order */ 435 __be64 gid_prefix; /* in network order */
436 __be64 mkey; 436 __be64 mkey;
437
437 u32 n_pds_allocated; /* number of PDs allocated for device */ 438 u32 n_pds_allocated; /* number of PDs allocated for device */
439 spinlock_t n_pds_lock;
438 u32 n_ahs_allocated; /* number of AHs allocated for device */ 440 u32 n_ahs_allocated; /* number of AHs allocated for device */
441 spinlock_t n_ahs_lock;
439 u32 n_cqs_allocated; /* number of CQs allocated for device */ 442 u32 n_cqs_allocated; /* number of CQs allocated for device */
443 spinlock_t n_cqs_lock;
440 u32 n_srqs_allocated; /* number of SRQs allocated for device */ 444 u32 n_srqs_allocated; /* number of SRQs allocated for device */
445 spinlock_t n_srqs_lock;
441 u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ 446 u32 n_mcast_grps_allocated; /* number of mcast groups allocated */
447 spinlock_t n_mcast_grps_lock;
448
442 u64 ipath_sword; /* total dwords sent (sample result) */ 449 u64 ipath_sword; /* total dwords sent (sample result) */
443 u64 ipath_rword; /* total dwords received (sample result) */ 450 u64 ipath_rword; /* total dwords received (sample result) */
444 u64 ipath_spkts; /* total packets sent (sample result) */ 451 u64 ipath_spkts; /* total packets sent (sample result) */
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
index ee0e1d96d723..cb35679e4a18 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
@@ -207,12 +207,15 @@ static int ipath_mcast_add(struct ipath_ibdev *dev,
207 goto bail; 207 goto bail;
208 } 208 }
209 209
210 spin_lock(&dev->n_mcast_grps_lock);
210 if (dev->n_mcast_grps_allocated == ib_ipath_max_mcast_grps) { 211 if (dev->n_mcast_grps_allocated == ib_ipath_max_mcast_grps) {
212 spin_unlock(&dev->n_mcast_grps_lock);
211 ret = ENOMEM; 213 ret = ENOMEM;
212 goto bail; 214 goto bail;
213 } 215 }
214 216
215 dev->n_mcast_grps_allocated++; 217 dev->n_mcast_grps_allocated++;
218 spin_unlock(&dev->n_mcast_grps_lock);
216 219
217 list_add_tail_rcu(&mqp->list, &mcast->qp_list); 220 list_add_tail_rcu(&mqp->list, &mcast->qp_list);
218 221
@@ -343,7 +346,9 @@ int ipath_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
343 atomic_dec(&mcast->refcount); 346 atomic_dec(&mcast->refcount);
344 wait_event(mcast->wait, !atomic_read(&mcast->refcount)); 347 wait_event(mcast->wait, !atomic_read(&mcast->refcount));
345 ipath_mcast_free(mcast); 348 ipath_mcast_free(mcast);
349 spin_lock(&dev->n_mcast_grps_lock);
346 dev->n_mcast_grps_allocated--; 350 dev->n_mcast_grps_allocated--;
351 spin_unlock(&dev->n_mcast_grps_lock);
347 } 352 }
348 353
349 ret = 0; 354 ret = 0;