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

Commit 32a024b9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Jason Gunthorpe:
 "A few regression and bug fixes for the patches merged in the last
  cycle:

   - hns fixes a subtle crash from the ib core SGL rework

   - hfi1 fixes various error handling, oops and protocol errors

   - bnxt_re fixes a regression where nvmeof doesn't work on some
     configurations

   - mlx5 fixes a serious 'use after free' bug in how MR caching is
     handled

   - some edge case crashers in the new statistic core code

   - more siw static checker fixups"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  IB/mlx5: Fix RSS Toeplitz setup to be aligned with the HW specification
  IB/counters: Always initialize the port counter object
  IB/core: Fix querying total rdma stats
  IB/mlx5: Prevent concurrent MR updates during invalidation
  IB/mlx5: Fix clean_mr() to work in the expected order
  IB/mlx5: Move MRs to a kernel PD when freeing them to the MR cache
  IB/mlx5: Use direct mkey destroy command upon UMR unreg failure
  IB/mlx5: Fix unreg_umr to ignore the mkey state
  RDMA/siw: Remove set but not used variables 'rv'
  IB/mlx5: Replace kfree with kvfree
  RDMA/bnxt_re: Honor vlan_id in GID entry comparison
  IB/hfi1: Drop all TID RDMA READ RESP packets after r_next_psn
  IB/hfi1: Field not zero-ed when allocating TID flow memory
  IB/hfi1: Unreserve a flushed OPFN request
  IB/hfi1: Check for error on call to alloc_rsm_map_table
  RDMA/hns: Fix sg offset non-zero issue
  RDMA/siw: Fix error return code in siw_init_module()
parents 515f12b9 b7165bd0
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -393,6 +393,9 @@ u64 rdma_counter_get_hwstat_value(struct ib_device *dev, u8 port, u32 index)
	u64 sum;

	port_counter = &dev->port_data[port].port_counter;
	if (!port_counter->hstats)
		return 0;

	sum = get_running_counters_hwstat_sum(dev, port, index);
	sum += port_counter->hstats->value[index];

@@ -594,7 +597,7 @@ void rdma_counter_init(struct ib_device *dev)
	struct rdma_port_counter *port_counter;
	u32 port;

	if (!dev->ops.alloc_hw_stats || !dev->port_data)
	if (!dev->port_data)
		return;

	rdma_for_each_port(dev, port) {
@@ -602,6 +605,9 @@ void rdma_counter_init(struct ib_device *dev)
		port_counter->mode.mode = RDMA_COUNTER_MODE_NONE;
		mutex_init(&port_counter->lock);

		if (!dev->ops.alloc_hw_stats)
			continue;

		port_counter->hstats = dev->ops.alloc_hw_stats(dev, port);
		if (!port_counter->hstats)
			goto fail;
@@ -624,9 +630,6 @@ void rdma_counter_release(struct ib_device *dev)
	struct rdma_port_counter *port_counter;
	u32 port;

	if (!dev->ops.alloc_hw_stats)
		return;

	rdma_for_each_port(dev, port) {
		port_counter = &dev->port_data[port].port_counter;
		kfree(port_counter->hstats);
+5 −2
Original line number Diff line number Diff line
@@ -308,6 +308,7 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
	struct bnxt_re_dev *rdev = to_bnxt_re_dev(attr->device, ibdev);
	struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
	struct bnxt_qplib_gid *gid_to_del;
	u16 vlan_id = 0xFFFF;

	/* Delete the entry from the hardware */
	ctx = *context;
@@ -317,7 +318,8 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
	if (sgid_tbl && sgid_tbl->active) {
		if (ctx->idx >= sgid_tbl->max)
			return -EINVAL;
		gid_to_del = &sgid_tbl->tbl[ctx->idx];
		gid_to_del = &sgid_tbl->tbl[ctx->idx].gid;
		vlan_id = sgid_tbl->tbl[ctx->idx].vlan_id;
		/* DEL_GID is called in WQ context(netdevice_event_work_handler)
		 * or via the ib_unregister_device path. In the former case QP1
		 * may not be destroyed yet, in which case just return as FW
@@ -335,7 +337,8 @@ int bnxt_re_del_gid(const struct ib_gid_attr *attr, void **context)
		}
		ctx->refcnt--;
		if (!ctx->refcnt) {
			rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del, true);
			rc = bnxt_qplib_del_sgid(sgid_tbl, gid_to_del,
						 vlan_id,  true);
			if (rc) {
				dev_err(rdev_to_dev(rdev),
					"Failed to remove GID: %#x", rc);
+9 −4
Original line number Diff line number Diff line
@@ -488,7 +488,7 @@ static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res *res,
				     struct bnxt_qplib_sgid_tbl *sgid_tbl,
				     u16 max)
{
	sgid_tbl->tbl = kcalloc(max, sizeof(struct bnxt_qplib_gid), GFP_KERNEL);
	sgid_tbl->tbl = kcalloc(max, sizeof(*sgid_tbl->tbl), GFP_KERNEL);
	if (!sgid_tbl->tbl)
		return -ENOMEM;

@@ -526,9 +526,10 @@ static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
	for (i = 0; i < sgid_tbl->max; i++) {
		if (memcmp(&sgid_tbl->tbl[i], &bnxt_qplib_gid_zero,
			   sizeof(bnxt_qplib_gid_zero)))
			bnxt_qplib_del_sgid(sgid_tbl, &sgid_tbl->tbl[i], true);
			bnxt_qplib_del_sgid(sgid_tbl, &sgid_tbl->tbl[i].gid,
					    sgid_tbl->tbl[i].vlan_id, true);
	}
	memset(sgid_tbl->tbl, 0, sizeof(struct bnxt_qplib_gid) * sgid_tbl->max);
	memset(sgid_tbl->tbl, 0, sizeof(*sgid_tbl->tbl) * sgid_tbl->max);
	memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
	memset(sgid_tbl->vlan, 0, sizeof(u8) * sgid_tbl->max);
	sgid_tbl->active = 0;
@@ -537,7 +538,11 @@ static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
static void bnxt_qplib_init_sgid_tbl(struct bnxt_qplib_sgid_tbl *sgid_tbl,
				     struct net_device *netdev)
{
	memset(sgid_tbl->tbl, 0, sizeof(struct bnxt_qplib_gid) * sgid_tbl->max);
	u32 i;

	for (i = 0; i < sgid_tbl->max; i++)
		sgid_tbl->tbl[i].vlan_id = 0xffff;

	memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
}

+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ struct bnxt_qplib_pd_tbl {
};

struct bnxt_qplib_sgid_tbl {
	struct bnxt_qplib_gid		*tbl;
	struct bnxt_qplib_gid_info	*tbl;
	u16				*hw_id;
	u16				max;
	u16				active;
+9 −5
Original line number Diff line number Diff line
@@ -213,12 +213,12 @@ int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
			index, sgid_tbl->max);
		return -EINVAL;
	}
	memcpy(gid, &sgid_tbl->tbl[index], sizeof(*gid));
	memcpy(gid, &sgid_tbl->tbl[index].gid, sizeof(*gid));
	return 0;
}

int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
			struct bnxt_qplib_gid *gid, bool update)
			struct bnxt_qplib_gid *gid, u16 vlan_id, bool update)
{
	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
						   struct bnxt_qplib_res,
@@ -236,7 +236,8 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
		return -ENOMEM;
	}
	for (index = 0; index < sgid_tbl->max; index++) {
		if (!memcmp(&sgid_tbl->tbl[index], gid, sizeof(*gid)))
		if (!memcmp(&sgid_tbl->tbl[index].gid, gid, sizeof(*gid)) &&
		    vlan_id == sgid_tbl->tbl[index].vlan_id)
			break;
	}
	if (index == sgid_tbl->max) {
@@ -262,8 +263,9 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
		if (rc)
			return rc;
	}
	memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
	memcpy(&sgid_tbl->tbl[index].gid, &bnxt_qplib_gid_zero,
	       sizeof(bnxt_qplib_gid_zero));
	sgid_tbl->tbl[index].vlan_id = 0xFFFF;
	sgid_tbl->vlan[index] = 0;
	sgid_tbl->active--;
	dev_dbg(&res->pdev->dev,
@@ -296,7 +298,8 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
	}
	free_idx = sgid_tbl->max;
	for (i = 0; i < sgid_tbl->max; i++) {
		if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid))) {
		if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid)) &&
		    sgid_tbl->tbl[i].vlan_id == vlan_id) {
			dev_dbg(&res->pdev->dev,
				"SGID entry already exist in entry %d!\n", i);
			*index = i;
@@ -351,6 +354,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
	}
	/* Add GID to the sgid_tbl */
	memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
	sgid_tbl->tbl[free_idx].vlan_id = vlan_id;
	sgid_tbl->active++;
	if (vlan_id != 0xFFFF)
		sgid_tbl->vlan[free_idx] = 1;
Loading