Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

IB/ipath: lock resource limit counters correctly

parent eb9dc6f4
Loading
Loading
Loading
Loading
+26 −8
Original line number Original line Diff line number Diff line
@@ -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)
	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,
	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,
		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)
	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)
	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);
+7 −0
Original line number Original line Diff line number Diff line
@@ -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) */
+5 −0
Original line number Original line Diff line number Diff line
@@ -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)
		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;