Commit b1df2a07 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Jason Gunthorpe:
 "A number of driver bug fixes and a few recent regressions:

   - Several bug fixes for bnxt_re. Crashing, incorrect data reported,
     and corruption on new HW

   - Memory leak and crash in rxe

   - Fix sysfs corruption in rxe if the netdev name is too long

   - Fix a crash on error unwind in the new cq_pool code

   - Fix kobject panics in rtrs by working device lifetime properly

   - Fix a data corruption bug in iser target related to misaligned
     buffers"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  IB/isert: Fix unaligned immediate-data handling
  RDMA/rtrs-srv: Set .release function for rtrs srv device during device init
  RDMA/bnxt_re: Remove set but not used variable 'qplib_ctx'
  RDMA/core: Fix reported speed and width
  RDMA/core: Fix unsafe linked list traversal after failing to allocate CQ
  RDMA/bnxt_re: Remove the qp from list only if the qp destroy succeeds
  RDMA/bnxt_re: Fix driver crash on unaligned PSN entry address
  RDMA/bnxt_re: Restrict the max_gids to 256
  RDMA/bnxt_re: Static NQ depth allocation
  RDMA/bnxt_re: Fix the qp table indexing
  RDMA/bnxt_re: Do not report transparent vlan from QP1
  RDMA/mlx4: Read pkey table length instead of hardcoded value
  RDMA/rxe: Fix panic when calling kmem_cache_create()
  RDMA/rxe: Fix memleak in rxe_mem_init_user
  RDMA/rxe: Fix the parent sysfs read when the interface has 15 chars
  RDMA/rtrs-srv: Replace device_register with device_initialize and device_add
parents 40249c69 0b089c1e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ static int ib_alloc_cqs(struct ib_device *dev, unsigned int nr_cqes,
{
	LIST_HEAD(tmp_list);
	unsigned int nr_cqs, i;
	struct ib_cq *cq;
	struct ib_cq *cq, *n;
	int ret;

	if (poll_ctx > IB_POLL_LAST_POOL_TYPE) {
@@ -412,7 +412,7 @@ static int ib_alloc_cqs(struct ib_device *dev, unsigned int nr_cqes,
	return 0;

out_free_cqs:
	list_for_each_entry(cq, &tmp_list, pool_entry) {
	list_for_each_entry_safe(cq, n, &tmp_list, pool_entry) {
		cq->shared = false;
		ib_free_cq(cq);
	}
+1 −1
Original line number Diff line number Diff line
@@ -1801,7 +1801,7 @@ int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u8 *speed, u8 *width)

	dev_put(netdev);

	if (!rc) {
	if (!rc && lksettings.base.speed != (u32)SPEED_UNKNOWN) {
		netdev_speed = lksettings.base.speed;
	} else {
		netdev_speed = SPEED_1000;
+29 −14
Original line number Diff line number Diff line
@@ -752,12 +752,6 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
	gsi_sqp = rdev->gsi_ctx.gsi_sqp;
	gsi_sah = rdev->gsi_ctx.gsi_sah;

	/* remove from active qp list */
	mutex_lock(&rdev->qp_lock);
	list_del(&gsi_sqp->list);
	mutex_unlock(&rdev->qp_lock);
	atomic_dec(&rdev->qp_count);

	ibdev_dbg(&rdev->ibdev, "Destroy the shadow AH\n");
	bnxt_qplib_destroy_ah(&rdev->qplib_res,
			      &gsi_sah->qplib_ah,
@@ -772,6 +766,12 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
	}
	bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp);

	/* remove from active qp list */
	mutex_lock(&rdev->qp_lock);
	list_del(&gsi_sqp->list);
	mutex_unlock(&rdev->qp_lock);
	atomic_dec(&rdev->qp_count);

	kfree(rdev->gsi_ctx.sqp_tbl);
	kfree(gsi_sah);
	kfree(gsi_sqp);
@@ -792,11 +792,6 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
	unsigned int flags;
	int rc;

	mutex_lock(&rdev->qp_lock);
	list_del(&qp->list);
	mutex_unlock(&rdev->qp_lock);
	atomic_dec(&rdev->qp_count);

	bnxt_qplib_flush_cqn_wq(&qp->qplib_qp);

	rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp);
@@ -819,6 +814,11 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
			goto sh_fail;
	}

	mutex_lock(&rdev->qp_lock);
	list_del(&qp->list);
	mutex_unlock(&rdev->qp_lock);
	atomic_dec(&rdev->qp_count);

	ib_umem_release(qp->rumem);
	ib_umem_release(qp->sumem);

@@ -3264,6 +3264,19 @@ static void bnxt_re_process_res_rawqp1_wc(struct ib_wc *wc,
	wc->wc_flags |= IB_WC_GRH;
}

static bool bnxt_re_check_if_vlan_valid(struct bnxt_re_dev *rdev,
					u16 vlan_id)
{
	/*
	 * Check if the vlan is configured in the host.  If not configured, it
	 * can be a transparent VLAN. So dont report the vlan id.
	 */
	if (!__vlan_find_dev_deep_rcu(rdev->netdev,
				      htons(ETH_P_8021Q), vlan_id))
		return false;
	return true;
}

static bool bnxt_re_is_vlan_pkt(struct bnxt_qplib_cqe *orig_cqe,
				u16 *vid, u8 *sl)
{
@@ -3332,10 +3345,12 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp,
	wc->src_qp = orig_cqe->src_qp;
	memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
	if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
		if (bnxt_re_check_if_vlan_valid(rdev, vlan_id)) {
			wc->vlan_id = vlan_id;
			wc->sl = sl;
			wc->wc_flags |= IB_WC_WITH_VLAN;
		}
	}
	wc->port_num = 1;
	wc->vendor_err = orig_cqe->status;

+1 −4
Original line number Diff line number Diff line
@@ -1009,7 +1009,6 @@ static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
{
	struct bnxt_re_ring_attr rattr = {};
	struct bnxt_qplib_ctx *qplib_ctx;
	int num_vec_created = 0;
	int rc = 0, i;
	u8 type;
@@ -1032,13 +1031,11 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
	if (rc)
		goto dealloc_res;

	qplib_ctx = &rdev->qplib_ctx;
	for (i = 0; i < rdev->num_msix - 1; i++) {
		struct bnxt_qplib_nq *nq;

		nq = &rdev->nq[i];
		nq->hwq.max_elements = (qplib_ctx->cq_count +
					qplib_ctx->srqc_count + 2);
		nq->hwq.max_elements = BNXT_QPLIB_NQE_MAX_CNT;
		rc = bnxt_qplib_alloc_nq(&rdev->qplib_res, &rdev->nq[i]);
		if (rc) {
			ibdev_err(&rdev->ibdev, "Alloc Failed NQ%d rc:%#x",
+16 −10
Original line number Diff line number Diff line
@@ -818,6 +818,7 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
	u16 cmd_flags = 0;
	u32 qp_flags = 0;
	u8 pg_sz_lvl;
	u32 tbl_indx;
	int rc;

	RCFW_CMD_PREP(req, CREATE_QP1, cmd_flags);
@@ -907,8 +908,9 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
		rq->dbinfo.db = qp->dpi->dbr;
		rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
	}
	rcfw->qp_tbl[qp->id].qp_id = qp->id;
	rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
	tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
	rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
	rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;

	return 0;

@@ -935,10 +937,10 @@ static void bnxt_qplib_init_psn_ptr(struct bnxt_qplib_qp *qp, int size)

	sq = &qp->sq;
	hwq = &sq->hwq;
	/* First psn entry */
	fpsne = (u64)bnxt_qplib_get_qe(hwq, hwq->depth, &psn_pg);
	if (!IS_ALIGNED(fpsne, PAGE_SIZE))
		indx_pad = ALIGN(fpsne, PAGE_SIZE) / size;

		indx_pad = (fpsne & ~PAGE_MASK) / size;
	hwq->pad_pgofft = indx_pad;
	hwq->pad_pg = (u64 *)psn_pg;
	hwq->pad_stride = size;
@@ -959,6 +961,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
	u16 cmd_flags = 0;
	u32 qp_flags = 0;
	u8 pg_sz_lvl;
	u32 tbl_indx;
	u16 nsge;

	RCFW_CMD_PREP(req, CREATE_QP, cmd_flags);
@@ -1111,8 +1114,9 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
		rq->dbinfo.db = qp->dpi->dbr;
		rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
	}
	rcfw->qp_tbl[qp->id].qp_id = qp->id;
	rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
	tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
	rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
	rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;

	return 0;
fail:
@@ -1457,10 +1461,12 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
	struct cmdq_destroy_qp req;
	struct creq_destroy_qp_resp resp;
	u16 cmd_flags = 0;
	u32 tbl_indx;
	int rc;

	rcfw->qp_tbl[qp->id].qp_id = BNXT_QPLIB_QP_ID_INVALID;
	rcfw->qp_tbl[qp->id].qp_handle = NULL;
	tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
	rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID;
	rcfw->qp_tbl[tbl_indx].qp_handle = NULL;

	RCFW_CMD_PREP(req, DESTROY_QP, cmd_flags);

@@ -1468,8 +1474,8 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res,
	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
					  (void *)&resp, NULL, 0);
	if (rc) {
		rcfw->qp_tbl[qp->id].qp_id = qp->id;
		rcfw->qp_tbl[qp->id].qp_handle = qp;
		rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
		rcfw->qp_tbl[tbl_indx].qp_handle = qp;
		return rc;
	}

Loading