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

Commit 7738613e authored by Ira Weiny's avatar Ira Weiny Committed by Doug Ledford
Browse files

IB/core: Add per port immutable struct to ib_device



As of commit 5eb620c8 "IB/core: Add helpers for uncached GID and P_Key
searches"; pkey_tbl_len and gid_tbl_len are immutable data which are stored in
the ib_device.

The per port core capability flags to be added later are also immutable data to
be stored in the ib_device object.

In preparation for this create a structure for per port immutable data and
place the pkey and gid table lengths within this structure.

"get_port_immutable" is added as a mandatory device function to allow the
drivers to fill in this data.

Signed-off-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 26c45428
Loading
Loading
Loading
Loading
+28 −35
Original line number Diff line number Diff line
@@ -93,7 +93,8 @@ static int ib_device_check_mandatory(struct ib_device *device)
		IB_MANDATORY_FUNC(poll_cq),
		IB_MANDATORY_FUNC(req_notify_cq),
		IB_MANDATORY_FUNC(get_dma_mr),
		IB_MANDATORY_FUNC(dereg_mr)
		IB_MANDATORY_FUNC(dereg_mr),
		IB_MANDATORY_FUNC(get_port_immutable)
	};
	int i;

@@ -211,42 +212,38 @@ static int add_client_context(struct ib_device *device, struct ib_client *client
	return 0;
}

static int read_port_table_lengths(struct ib_device *device)
static int read_port_immutable(struct ib_device *device)
{
	struct ib_port_attr *tprops = NULL;
	int num_ports, ret = -ENOMEM;
	u8 port_index;
	int ret = -ENOMEM;
	u8 start_port = rdma_start_port(device);
	u8 end_port = rdma_end_port(device);
	u8 port;

	tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
	if (!tprops)
		goto out;

	num_ports = rdma_end_port(device) - rdma_start_port(device) + 1;

	device->pkey_tbl_len = kmalloc(sizeof *device->pkey_tbl_len * num_ports,
				       GFP_KERNEL);
	device->gid_tbl_len = kmalloc(sizeof *device->gid_tbl_len * num_ports,
	/**
	 * device->port_immutable is indexed directly by the port number to make
	 * access to this data as efficient as possible.
	 *
	 * Therefore port_immutable is declared as a 1 based array with
	 * potential empty slots at the beginning.
	 */
	device->port_immutable = kzalloc(sizeof(*device->port_immutable)
					 * (end_port + 1),
					 GFP_KERNEL);
	if (!device->pkey_tbl_len || !device->gid_tbl_len)
	if (!device->port_immutable)
		goto err;

	for (port_index = 0; port_index < num_ports; ++port_index) {
		ret = ib_query_port(device, port_index + rdma_start_port(device),
					tprops);
	for (port = start_port; port <= end_port; ++port) {
		ret = device->get_port_immutable(device, port,
						 &device->port_immutable[port]);
		if (ret)
			goto err;
		device->pkey_tbl_len[port_index] = tprops->pkey_tbl_len;
		device->gid_tbl_len[port_index]  = tprops->gid_tbl_len;
	}

	ret = 0;
	goto out;

err:
	kfree(device->gid_tbl_len);
	kfree(device->pkey_tbl_len);
	kfree(device->port_immutable);
out:
	kfree(tprops);
	return ret;
}

@@ -283,9 +280,9 @@ int ib_register_device(struct ib_device *device,
	spin_lock_init(&device->event_handler_lock);
	spin_lock_init(&device->client_data_lock);

	ret = read_port_table_lengths(device);
	ret = read_port_immutable(device);
	if (ret) {
		printk(KERN_WARNING "Couldn't create table lengths cache for device %s\n",
		printk(KERN_WARNING "Couldn't create per port immutable data %s\n",
		       device->name);
		goto out;
	}
@@ -294,8 +291,7 @@ int ib_register_device(struct ib_device *device,
	if (ret) {
		printk(KERN_WARNING "Couldn't register device %s with driver model\n",
		       device->name);
		kfree(device->gid_tbl_len);
		kfree(device->pkey_tbl_len);
		kfree(device->port_immutable);
		goto out;
	}

@@ -337,9 +333,6 @@ void ib_unregister_device(struct ib_device *device)

	list_del(&device->core_list);

	kfree(device->gid_tbl_len);
	kfree(device->pkey_tbl_len);

	mutex_unlock(&device_mutex);

	ib_device_unregister_sysfs(device);
@@ -666,7 +659,7 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid,
	int ret, port, i;

	for (port = rdma_start_port(device); port <= rdma_end_port(device); ++port) {
		for (i = 0; i < device->gid_tbl_len[port - rdma_start_port(device)]; ++i) {
		for (i = 0; i < device->port_immutable[port].gid_tbl_len; ++i) {
			ret = ib_query_gid(device, port, i, &tmp_gid);
			if (ret)
				return ret;
@@ -698,7 +691,7 @@ int ib_find_pkey(struct ib_device *device,
	u16 tmp_pkey;
	int partial_ix = -1;

	for (i = 0; i < device->pkey_tbl_len[port_num - rdma_start_port(device)]; ++i) {
	for (i = 0; i < device->port_immutable[port_num].pkey_tbl_len; ++i) {
		ret = ib_query_pkey(device, port_num, i, &tmp_pkey);
		if (ret)
			return ret;
+1 −0
Original line number Diff line number Diff line
@@ -456,6 +456,7 @@ static void ib_device_release(struct device *device)
{
	struct ib_device *dev = container_of(device, struct ib_device, dev);

	kfree(dev->port_immutable);
	kfree(dev);
}

+17 −0
Original line number Diff line number Diff line
@@ -763,6 +763,22 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
	return netdev;
}

static int c2_port_immutable(struct ib_device *ibdev, u8 port_num,
			     struct ib_port_immutable *immutable)
{
	struct ib_port_attr attr;
	int err;

	err = c2_query_port(ibdev, port_num, &attr);
	if (err)
		return err;

	immutable->pkey_tbl_len = attr.pkey_tbl_len;
	immutable->gid_tbl_len = attr.gid_tbl_len;

	return 0;
}

int c2_register_device(struct c2_dev *dev)
{
	int ret = -ENOMEM;
@@ -827,6 +843,7 @@ int c2_register_device(struct c2_dev *dev)
	dev->ibdev.reg_phys_mr = c2_reg_phys_mr;
	dev->ibdev.reg_user_mr = c2_reg_user_mr;
	dev->ibdev.dereg_mr = c2_dereg_mr;
	dev->ibdev.get_port_immutable = c2_port_immutable;

	dev->ibdev.alloc_fmr = NULL;
	dev->ibdev.unmap_fmr = NULL;
+17 −0
Original line number Diff line number Diff line
@@ -1349,6 +1349,22 @@ static struct device_attribute *iwch_class_attributes[] = {
	&dev_attr_board_id,
};

static int iwch_port_immutable(struct ib_device *ibdev, u8 port_num,
			       struct ib_port_immutable *immutable)
{
	struct ib_port_attr attr;
	int err;

	err = iwch_query_port(ibdev, port_num, &attr);
	if (err)
		return err;

	immutable->pkey_tbl_len = attr.pkey_tbl_len;
	immutable->gid_tbl_len = attr.gid_tbl_len;

	return 0;
}

int iwch_register_device(struct iwch_dev *dev)
{
	int ret;
@@ -1427,6 +1443,7 @@ int iwch_register_device(struct iwch_dev *dev)
	dev->ibdev.post_recv = iwch_post_receive;
	dev->ibdev.get_protocol_stats = iwch_get_mib;
	dev->ibdev.uverbs_abi_ver = IWCH_UVERBS_ABI_VERSION;
	dev->ibdev.get_port_immutable = iwch_port_immutable;

	dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
	if (!dev->ibdev.iwcm)
+17 −0
Original line number Diff line number Diff line
@@ -471,6 +471,22 @@ static struct device_attribute *c4iw_class_attributes[] = {
	&dev_attr_board_id,
};

static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num,
			       struct ib_port_immutable *immutable)
{
	struct ib_port_attr attr;
	int err;

	err = c4iw_query_port(ibdev, port_num, &attr);
	if (err)
		return err;

	immutable->pkey_tbl_len = attr.pkey_tbl_len;
	immutable->gid_tbl_len = attr.gid_tbl_len;

	return 0;
}

int c4iw_register_device(struct c4iw_dev *dev)
{
	int ret;
@@ -549,6 +565,7 @@ int c4iw_register_device(struct c4iw_dev *dev)
	dev->ibdev.post_recv = c4iw_post_receive;
	dev->ibdev.get_protocol_stats = c4iw_get_mib;
	dev->ibdev.uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION;
	dev->ibdev.get_port_immutable = c4iw_port_immutable;

	dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
	if (!dev->ibdev.iwcm)
Loading