Commit 0afd2209 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma updates from Jason Gunthorpe:
 "Lighter that normal, but the now usual collection of driver fixes and
  small improvements:

   - Small fixes and minor improvements to cxgb4, bnxt_re, rxe, srp,
     efa, cxgb4

   - Update mlx4 to use the new umem APIs, avoiding direct use of
     scatterlist

   - Support ROCEv2 in erdma

   - Remove various uncalled functions, constify bin_attribute

   - Provide core infrastructure to catch netdev events and route them
     to drivers, consolidating duplicated driver code

   - Fix rare race condition crashes in mlx5 ODP flows"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (63 commits)
  RDMA/mlx5: Fix implicit ODP use after free
  RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
  RDMA/qib: Constify 'struct bin_attribute'
  RDMA/hfi1: Constify 'struct bin_attribute'
  RDMA/rxe: Fix the warning "__rxe_cleanup+0x12c/0x170 [rdma_rxe]"
  RDMA/cxgb4: Notify rdma stack for IB_EVENT_QP_LAST_WQE_REACHED event
  RDMA/bnxt_re: Allocate dev_attr information dynamically
  RDMA/bnxt_re: Pass the context for ulp_irq_stop
  RDMA/bnxt_re: Add support to handle DCB_CONFIG_CHANGE event
  RDMA/bnxt_re: Query firmware defaults of CC params during probe
  RDMA/bnxt_re: Add Async event handling support
  bnxt_en: Add ULP call to notify async events
  RDMA/mlx5: Fix indirect mkey ODP page count
  MAINTAINERS: Update the bnxt_re maintainers
  RDMA/hns: Clean up the legacy CONFIG_INFINIBAND_HNS
  RDMA/rtrs: Add missing deinit() call
  RDMA/efa: Align interrupt related fields to same type
  RDMA/bnxt_re: Fix to drop reference to the mmap entry in case of error
  RDMA/mlx5: Fix link status down event for MPV
  RDMA/erdma: Support create_ah/destroy_ah in non-sleepable contexts
  ...
parents aa44198a d3d93041
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4800,6 +4800,7 @@ F: drivers/scsi/mpi3mr/
BROADCOM NETXTREME-E ROCE DRIVER
M:	Selvin Xavier <selvin.xavier@broadcom.com>
M:	Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
L:	linux-rdma@vger.kernel.org
S:	Supported
W:	http://www.broadcom.com
+0 −35
Original line number Diff line number Diff line
@@ -1127,41 +1127,6 @@ int ib_find_cached_pkey(struct ib_device *device, u32 port_num,
}
EXPORT_SYMBOL(ib_find_cached_pkey);

int ib_find_exact_cached_pkey(struct ib_device *device, u32 port_num,
			      u16 pkey, u16 *index)
{
	struct ib_pkey_cache *cache;
	unsigned long flags;
	int i;
	int ret = -ENOENT;

	if (!rdma_is_port_valid(device, port_num))
		return -EINVAL;

	read_lock_irqsave(&device->cache_lock, flags);

	cache = device->port_data[port_num].cache.pkey;
	if (!cache) {
		ret = -EINVAL;
		goto err;
	}

	*index = -1;

	for (i = 0; i < cache->table_len; ++i)
		if (cache->table[i] == pkey) {
			*index = i;
			ret = 0;
			break;
		}

err:
	read_unlock_irqrestore(&device->cache_lock, flags);

	return ret;
}
EXPORT_SYMBOL(ib_find_exact_cached_pkey);

int ib_get_cached_lmc(struct ib_device *device, u32 port_num, u8 *lmc)
{
	unsigned long flags;
+92 −24
Original line number Diff line number Diff line
@@ -209,23 +209,6 @@ static void __ibdev_printk(const char *level, const struct ib_device *ibdev,
		printk("%s(NULL ib_device): %pV", level, vaf);
}

void ibdev_printk(const char *level, const struct ib_device *ibdev,
		  const char *format, ...)
{
	struct va_format vaf;
	va_list args;

	va_start(args, format);

	vaf.fmt = format;
	vaf.va = &args;

	__ibdev_printk(level, ibdev, &vaf);

	va_end(args);
}
EXPORT_SYMBOL(ibdev_printk);

#define define_ibdev_printk_level(func, level)                  \
void func(const struct ib_device *ibdev, const char *fmt, ...)  \
{                                                               \
@@ -2295,6 +2278,33 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,
}
EXPORT_SYMBOL(ib_device_get_netdev);

/**
 * ib_query_netdev_port - Query the port number of a net_device
 * associated with an ibdev
 * @ibdev: IB device
 * @ndev: Network device
 * @port: IB port the net_device is connected to
 */
int ib_query_netdev_port(struct ib_device *ibdev, struct net_device *ndev,
			 u32 *port)
{
	struct net_device *ib_ndev;
	u32 port_num;

	rdma_for_each_port(ibdev, port_num) {
		ib_ndev = ib_device_get_netdev(ibdev, port_num);
		if (ndev == ib_ndev) {
			*port = port_num;
			dev_put(ib_ndev);
			return 0;
		}
		dev_put(ib_ndev);
	}

	return -ENOENT;
}
EXPORT_SYMBOL(ib_query_netdev_port);

/**
 * ib_device_get_by_netdev - Find an IB device associated with a netdev
 * @ndev: netdev to locate
@@ -2761,6 +2771,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
	SET_DEVICE_OP(dev_ops, set_vf_guid);
	SET_DEVICE_OP(dev_ops, set_vf_link_state);
	SET_DEVICE_OP(dev_ops, ufile_hw_cleanup);
	SET_DEVICE_OP(dev_ops, report_port_event);

	SET_OBJ_SIZE(dev_ops, ib_ah);
	SET_OBJ_SIZE(dev_ops, ib_counters);
@@ -2854,11 +2865,62 @@ static const struct rdma_nl_cbs ibnl_ls_cb_table[RDMA_NL_LS_NUM_OPS] = {
	},
};

void ib_dispatch_port_state_event(struct ib_device *ibdev, struct net_device *ndev)
{
	enum ib_port_state curr_state;
	struct ib_event ibevent = {};
	u32 port;

	if (ib_query_netdev_port(ibdev, ndev, &port))
		return;

	curr_state = ib_get_curr_port_state(ndev);

	write_lock_irq(&ibdev->cache_lock);
	if (ibdev->port_data[port].cache.last_port_state == curr_state) {
		write_unlock_irq(&ibdev->cache_lock);
		return;
	}
	ibdev->port_data[port].cache.last_port_state = curr_state;
	write_unlock_irq(&ibdev->cache_lock);

	ibevent.event = (curr_state == IB_PORT_DOWN) ?
					IB_EVENT_PORT_ERR : IB_EVENT_PORT_ACTIVE;
	ibevent.device = ibdev;
	ibevent.element.port_num = port;
	ib_dispatch_event(&ibevent);
}
EXPORT_SYMBOL(ib_dispatch_port_state_event);

static void handle_port_event(struct net_device *ndev, unsigned long event)
{
	struct ib_device *ibdev;

	/* Currently, link events in bonding scenarios are still
	 * reported by drivers that support bonding.
	 */
	if (netif_is_lag_master(ndev) || netif_is_lag_port(ndev))
		return;

	ibdev = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
	if (!ibdev)
		return;

	if (ibdev->ops.report_port_event) {
		ibdev->ops.report_port_event(ibdev, ndev, event);
		goto put_ibdev;
	}

	ib_dispatch_port_state_event(ibdev, ndev);

put_ibdev:
	ib_device_put(ibdev);
};

static int ib_netdevice_event(struct notifier_block *this,
			      unsigned long event, void *ptr)
{
	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
	struct net_device *ib_ndev;
	struct ib_device *ibdev;
	u32 port;

@@ -2868,15 +2930,21 @@ static int ib_netdevice_event(struct notifier_block *this,
		if (!ibdev)
			return NOTIFY_DONE;

		rdma_for_each_port(ibdev, port) {
			ib_ndev = ib_device_get_netdev(ibdev, port);
			if (ndev == ib_ndev)
				rdma_nl_notify_event(ibdev, port,
						     RDMA_NETDEV_RENAME_EVENT);
			dev_put(ib_ndev);
		if (ib_query_netdev_port(ibdev, ndev, &port)) {
			ib_device_put(ibdev);
			break;
		}

		rdma_nl_notify_event(ibdev, port, RDMA_NETDEV_RENAME_EVENT);
		ib_device_put(ibdev);
		break;

	case NETDEV_UP:
	case NETDEV_CHANGE:
	case NETDEV_DOWN:
		handle_port_event(ndev, event);
		break;

	default:
		break;
	}
+0 −83
Original line number Diff line number Diff line
@@ -462,86 +462,3 @@ int ib_ud_header_pack(struct ib_ud_header *header,
	return len;
}
EXPORT_SYMBOL(ib_ud_header_pack);

/**
 * ib_ud_header_unpack - Unpack UD header struct from wire format
 * @header:UD header struct
 * @buf:Buffer to pack into
 *
 * ib_ud_header_pack() unpacks the UD header structure @header from wire
 * format in the buffer @buf.
 */
int ib_ud_header_unpack(void                *buf,
			struct ib_ud_header *header)
{
	ib_unpack(lrh_table, ARRAY_SIZE(lrh_table),
		  buf, &header->lrh);
	buf += IB_LRH_BYTES;

	if (header->lrh.link_version != 0) {
		pr_warn("Invalid LRH.link_version %u\n",
			header->lrh.link_version);
		return -EINVAL;
	}

	switch (header->lrh.link_next_header) {
	case IB_LNH_IBA_LOCAL:
		header->grh_present = 0;
		break;

	case IB_LNH_IBA_GLOBAL:
		header->grh_present = 1;
		ib_unpack(grh_table, ARRAY_SIZE(grh_table),
			  buf, &header->grh);
		buf += IB_GRH_BYTES;

		if (header->grh.ip_version != 6) {
			pr_warn("Invalid GRH.ip_version %u\n",
				header->grh.ip_version);
			return -EINVAL;
		}
		if (header->grh.next_header != 0x1b) {
			pr_warn("Invalid GRH.next_header 0x%02x\n",
				header->grh.next_header);
			return -EINVAL;
		}
		break;

	default:
		pr_warn("Invalid LRH.link_next_header %u\n",
			header->lrh.link_next_header);
		return -EINVAL;
	}

	ib_unpack(bth_table, ARRAY_SIZE(bth_table),
		  buf, &header->bth);
	buf += IB_BTH_BYTES;

	switch (header->bth.opcode) {
	case IB_OPCODE_UD_SEND_ONLY:
		header->immediate_present = 0;
		break;
	case IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE:
		header->immediate_present = 1;
		break;
	default:
		pr_warn("Invalid BTH.opcode 0x%02x\n", header->bth.opcode);
		return -EINVAL;
	}

	if (header->bth.transport_header_version != 0) {
		pr_warn("Invalid BTH.transport_header_version %u\n",
			header->bth.transport_header_version);
		return -EINVAL;
	}

	ib_unpack(deth_table, ARRAY_SIZE(deth_table),
		  buf, &header->deth);
	buf += IB_DETH_BYTES;

	if (header->immediate_present)
		memcpy(&header->immediate_data, buf, sizeof header->immediate_data);

	return 0;
}
EXPORT_SYMBOL(ib_ud_header_unpack);
+0 −42
Original line number Diff line number Diff line
@@ -171,45 +171,3 @@ void ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
	__ib_copy_path_rec_to_user(dst, src);
}
EXPORT_SYMBOL(ib_copy_path_rec_to_user);

void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
				struct ib_user_path_rec *src)
{
	u32 slid, dlid;

	memset(dst, 0, sizeof(*dst));
	if ((ib_is_opa_gid((union ib_gid *)src->sgid)) ||
	    (ib_is_opa_gid((union ib_gid *)src->dgid))) {
		dst->rec_type = SA_PATH_REC_TYPE_OPA;
		slid = opa_get_lid_from_gid((union ib_gid *)src->sgid);
		dlid = opa_get_lid_from_gid((union ib_gid *)src->dgid);
	} else {
		dst->rec_type = SA_PATH_REC_TYPE_IB;
		slid = ntohs(src->slid);
		dlid = ntohs(src->dlid);
	}
	memcpy(dst->dgid.raw, src->dgid, sizeof dst->dgid);
	memcpy(dst->sgid.raw, src->sgid, sizeof dst->sgid);

	sa_path_set_dlid(dst, dlid);
	sa_path_set_slid(dst, slid);
	sa_path_set_raw_traffic(dst, src->raw_traffic);
	dst->flow_label		= src->flow_label;
	dst->hop_limit		= src->hop_limit;
	dst->traffic_class	= src->traffic_class;
	dst->reversible		= src->reversible;
	dst->numb_path		= src->numb_path;
	dst->pkey		= src->pkey;
	dst->sl			= src->sl;
	dst->mtu_selector	= src->mtu_selector;
	dst->mtu		= src->mtu;
	dst->rate_selector	= src->rate_selector;
	dst->rate		= src->rate;
	dst->packet_life_time	= src->packet_life_time;
	dst->preference		= src->preference;
	dst->packet_life_time_selector = src->packet_life_time_selector;

	/* TODO: No need to set this */
	sa_path_set_dmac_zero(dst);
}
EXPORT_SYMBOL(ib_copy_path_rec_from_user);
Loading