Commit 17d85f33 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Jason Gunthorpe:

 - Memory leak in bnxt GSI qp path

 - Failure in irdma registering large MRs

 - Failure to clean out the right CQ table entry in irdma

 - Invalid vf_id in some cases

 - Incorrect error unwind in EFA CQ create

 - hns doesn't use the optimal cq/qp relationships for it's HW banks

 - hns reports the wrong SGE size to userspace for its QPs

 - Corruption of the hns work queue entries in some cases

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  MAINTAINERS: Update irdma maintainers
  RDMA/irdma: Fix vf_id size to u16 to avoid overflow
  RDMA/hns: Remove an extra blank line
  RDMA/hns: Fix wrong WQE data when QP wraps around
  RDMA/hns: Fix the modification of max_send_sge
  RDMA/hns: Fix recv CQ and QP cache affinity
  RDMA/uverbs: Fix umem release in UVERBS_METHOD_CQ_CREATE
  RDMA/irdma: Set irdma_cq cq_num field during CQ create
  RDMA/irdma: Fix SD index calculation
  RDMA/bnxt_re: Fix a potential memory leak in destroy_gsi_sqp
parents c9cfc122 b8126205
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12521,6 +12521,7 @@ F: include/linux/avf/virtchnl.h
F:	include/linux/net/intel/*/
INTEL ETHERNET PROTOCOL DRIVER FOR RDMA
M:	Krzysztof Czurylo <krzysztof.czurylo@intel.com>
M:	Tatyana Nikolova <tatyana.e.nikolova@intel.com>
L:	linux-rdma@vger.kernel.org
S:	Supported
+1 −0
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
	return ret;

err_free:
	ib_umem_release(umem);
	rdma_restrack_put(&cq->res);
	kfree(cq);
err_event_file:
+3 −8
Original line number Diff line number Diff line
@@ -913,7 +913,7 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp,
	spin_unlock_irqrestore(&qp->scq->cq_lock, flags);
}

static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
static void bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
{
	struct bnxt_re_qp *gsi_sqp;
	struct bnxt_re_ah *gsi_sah;
@@ -933,10 +933,9 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)

	ibdev_dbg(&rdev->ibdev, "Destroy the shadow QP\n");
	rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp);
	if (rc) {
	if (rc)
		ibdev_err(&rdev->ibdev, "Destroy Shadow QP failed");
		goto fail;
	}

	bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);

	/* remove from active qp list */
@@ -951,10 +950,6 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
	rdev->gsi_ctx.gsi_sqp = NULL;
	rdev->gsi_ctx.gsi_sah = NULL;
	rdev->gsi_ctx.sqp_tbl = NULL;

	return 0;
fail:
	return rc;
}

static void bnxt_re_del_unique_gid(struct bnxt_re_dev *rdev)
+7 −9
Original line number Diff line number Diff line
@@ -1216,13 +1216,13 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
		if (umem->length < cq->size) {
			ibdev_dbg(&dev->ibdev, "External memory too small\n");
			err = -EINVAL;
			goto err_free_mem;
			goto err_out;
		}

		if (!ib_umem_is_contiguous(umem)) {
			ibdev_dbg(&dev->ibdev, "Non contiguous CQ unsupported\n");
			err = -EINVAL;
			goto err_free_mem;
			goto err_out;
		}

		cq->cpu_addr = NULL;
@@ -1251,7 +1251,7 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,

	err = efa_com_create_cq(&dev->edev, &params, &result);
	if (err)
		goto err_free_mem;
		goto err_free_mapped;

	resp.db_off = result.db_off;
	resp.cq_idx = result.cq_idx;
@@ -1299,12 +1299,10 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
	efa_cq_user_mmap_entries_remove(cq);
err_destroy_cq:
	efa_destroy_cq_idx(dev, cq->cq_idx);
err_free_mem:
	if (umem)
		ib_umem_release(umem);
	else
		efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size, DMA_FROM_DEVICE);

err_free_mapped:
	if (!umem)
		efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size,
				DMA_FROM_DEVICE);
err_out:
	atomic64_inc(&dev->stats.create_cq_err);
	return err;
+55 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
 * SOFTWARE.
 */

#include <linux/pci.h>
#include <rdma/ib_umem.h>
#include <rdma/uverbs_ioctl.h>
#include "hns_roce_device.h"
@@ -37,6 +38,43 @@
#include "hns_roce_hem.h"
#include "hns_roce_common.h"

void hns_roce_put_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(uctx->ibucontext.device);
	struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;

	if (hr_dev->pci_dev->revision < PCI_REVISION_ID_HIP09)
		return;

	mutex_lock(&cq_table->bank_mutex);
	cq_table->ctx_num[uctx->cq_bank_id]--;
	mutex_unlock(&cq_table->bank_mutex);
}

void hns_roce_get_cq_bankid_for_uctx(struct hns_roce_ucontext *uctx)
{
	struct hns_roce_dev *hr_dev = to_hr_dev(uctx->ibucontext.device);
	struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
	u32 least_load = cq_table->ctx_num[0];
	u8 bankid = 0;
	u8 i;

	if (hr_dev->pci_dev->revision < PCI_REVISION_ID_HIP09)
		return;

	mutex_lock(&cq_table->bank_mutex);
	for (i = 1; i < HNS_ROCE_CQ_BANK_NUM; i++) {
		if (cq_table->ctx_num[i] < least_load) {
			least_load = cq_table->ctx_num[i];
			bankid = i;
		}
	}
	cq_table->ctx_num[bankid]++;
	mutex_unlock(&cq_table->bank_mutex);

	uctx->cq_bank_id = bankid;
}

static u8 get_least_load_bankid_for_cq(struct hns_roce_bank *bank)
{
	u32 least_load = bank[0].inuse;
@@ -55,7 +93,21 @@ static u8 get_least_load_bankid_for_cq(struct hns_roce_bank *bank)
	return bankid;
}

static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
static u8 select_cq_bankid(struct hns_roce_dev *hr_dev,
			   struct hns_roce_bank *bank, struct ib_udata *udata)
{
	struct hns_roce_ucontext *uctx = udata ?
		rdma_udata_to_drv_context(udata, struct hns_roce_ucontext,
					  ibucontext) : NULL;

	if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
		return uctx ? uctx->cq_bank_id : 0;

	return get_least_load_bankid_for_cq(bank);
}

static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq,
		     struct ib_udata *udata)
{
	struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
	struct hns_roce_bank *bank;
@@ -63,7 +115,7 @@ static int alloc_cqn(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
	int id;

	mutex_lock(&cq_table->bank_mutex);
	bankid = get_least_load_bankid_for_cq(cq_table->bank);
	bankid = select_cq_bankid(hr_dev, cq_table->bank, udata);
	bank = &cq_table->bank[bankid];

	id = ida_alloc_range(&bank->ida, bank->min, bank->max, GFP_KERNEL);
@@ -396,7 +448,7 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
		goto err_cq_buf;
	}

	ret = alloc_cqn(hr_dev, hr_cq);
	ret = alloc_cqn(hr_dev, hr_cq, udata);
	if (ret) {
		ibdev_err(ibdev, "failed to alloc CQN, ret = %d.\n", ret);
		goto err_cq_db;
Loading