|
@@ -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;
|
|
|
-
|
|
|
- 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,
|
|
|
- GFP_KERNEL);
|
|
|
- if (!device->pkey_tbl_len || !device->gid_tbl_len)
|
|
|
+ int ret = -ENOMEM;
|
|
|
+ u8 start_port = rdma_start_port(device);
|
|
|
+ u8 end_port = rdma_end_port(device);
|
|
|
+ u8 port;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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->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;
|