diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2006-08-25 14:24:27 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-09-22 18:22:27 -0400 |
commit | c27fef26271d352b5546c33239edeb0dcb4fc0cc (patch) | |
tree | 3dc284784c4218c80d7806c05324be1599d6c6c6 /drivers/infiniband | |
parent | eb9dc6f48dc7537ce53163109625bd992150e0cf (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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.c | 34 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.h | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs_mcast.c | 5 |
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; |