Skip to content

Commit

Permalink
RDMA/device: Consolidate ib_device per_port data into one place
Browse files Browse the repository at this point in the history
There is no reason to have three allocations of per-port data. Combine
them together and make the lifetime for all the per-port data match the
struct ib_device.

Following patches will require more port-specific data, now there is a
good place to put it.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
  • Loading branch information
Jason Gunthorpe committed Feb 19, 2019
1 parent ea1075e commit 8ceb135
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 94 deletions.
4 changes: 2 additions & 2 deletions drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,8 +881,8 @@ static int _gid_table_setup_one(struct ib_device *ib_dev)
for (port = 0; port < ib_dev->phys_port_cnt; port++) {
u8 rdma_port = port + rdma_start_port(ib_dev);

table = alloc_gid_table(
ib_dev->port_immutable[rdma_port].gid_tbl_len);
table = alloc_gid_table(
ib_dev->port_data[rdma_port].immutable.gid_tbl_len);
if (!table)
goto rollback_table_setup;

Expand Down
70 changes: 22 additions & 48 deletions drivers/infiniband/core/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,7 @@ static void ib_device_release(struct device *device)
WARN_ON(refcount_read(&dev->refcount));
ib_cache_release_one(dev);
ib_security_release_port_pkey_list(dev);
kfree(dev->port_pkey_list);
kfree(dev->port_immutable);
kfree(dev->port_data);
xa_destroy(&dev->client_data);
kfree(dev);
}
Expand Down Expand Up @@ -468,27 +467,31 @@ static int verify_immutable(const struct ib_device *dev, u8 port)
rdma_max_mad_size(dev, port) != 0);
}

static int read_port_immutable(struct ib_device *device)
static int setup_port_data(struct ib_device *device)
{
unsigned int port;
int ret;

/**
* device->port_immutable is indexed directly by the port number to make
/*
* device->port_data 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.
* Therefore port_data is declared as a 1 based array with potential
* empty slots at the beginning.
*/
device->port_immutable =
kcalloc(rdma_end_port(device) + 1,
sizeof(*device->port_immutable), GFP_KERNEL);
if (!device->port_immutable)
device->port_data = kcalloc(rdma_end_port(device) + 1,
sizeof(*device->port_data), GFP_KERNEL);
if (!device->port_data)
return -ENOMEM;

rdma_for_each_port (device, port) {
ret = device->ops.get_port_immutable(
device, port, &device->port_immutable[port]);
struct ib_port_data *pdata = &device->port_data[port];

spin_lock_init(&pdata->pkey_list_lock);
INIT_LIST_HEAD(&pdata->pkey_list);

ret = device->ops.get_port_immutable(device, port,
&pdata->immutable);
if (ret)
return ret;

Expand All @@ -507,30 +510,6 @@ void ib_get_device_fw_str(struct ib_device *dev, char *str)
}
EXPORT_SYMBOL(ib_get_device_fw_str);

static int setup_port_pkey_list(struct ib_device *device)
{
int i;

/**
* device->port_pkey_list is indexed directly by the port number,
* Therefore it is declared as a 1 based array with potential empty
* slots at the beginning.
*/
device->port_pkey_list = kcalloc(rdma_end_port(device) + 1,
sizeof(*device->port_pkey_list),
GFP_KERNEL);

if (!device->port_pkey_list)
return -ENOMEM;

for (i = 0; i < (rdma_end_port(device) + 1); i++) {
spin_lock_init(&device->port_pkey_list[i].list_lock);
INIT_LIST_HEAD(&device->port_pkey_list[i].pkey_list);
}

return 0;
}

static void ib_policy_change_task(struct work_struct *work)
{
struct ib_device *dev;
Expand Down Expand Up @@ -668,10 +647,9 @@ static int setup_device(struct ib_device *device)
if (ret)
return ret;

ret = read_port_immutable(device);
ret = setup_port_data(device);
if (ret) {
dev_warn(&device->dev,
"Couldn't create per port immutable data\n");
dev_warn(&device->dev, "Couldn't create per-port data\n");
return ret;
}

Expand All @@ -683,12 +661,6 @@ static int setup_device(struct ib_device *device)
return ret;
}

ret = setup_port_pkey_list(device);
if (ret) {
dev_warn(&device->dev, "Couldn't create per port_pkey_list\n");
return ret;
}

return 0;
}

Expand Down Expand Up @@ -1221,7 +1193,8 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid,
if (!rdma_protocol_ib(device, port))
continue;

for (i = 0; i < device->port_immutable[port].gid_tbl_len; ++i) {
for (i = 0; i < device->port_data[port].immutable.gid_tbl_len;
++i) {
ret = rdma_query_gid(device, port, i, &tmp_gid);
if (ret)
return ret;
Expand Down Expand Up @@ -1253,7 +1226,8 @@ int ib_find_pkey(struct ib_device *device,
u16 tmp_pkey;
int partial_ix = -1;

for (i = 0; i < device->port_immutable[port_num].pkey_tbl_len; ++i) {
for (i = 0; i < device->port_data[port_num].immutable.pkey_tbl_len;
++i) {
ret = ib_query_pkey(device, port_num, i, &tmp_pkey);
if (ret)
return ret;
Expand Down
24 changes: 11 additions & 13 deletions drivers/infiniband/core/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,15 @@ static struct pkey_index_qp_list *get_pkey_idx_qp_list(struct ib_port_pkey *pp)
struct pkey_index_qp_list *tmp_pkey;
struct ib_device *dev = pp->sec->dev;

spin_lock(&dev->port_pkey_list[pp->port_num].list_lock);
list_for_each_entry(tmp_pkey,
&dev->port_pkey_list[pp->port_num].pkey_list,
pkey_index_list) {
spin_lock(&dev->port_data[pp->port_num].pkey_list_lock);
list_for_each_entry (tmp_pkey, &dev->port_data[pp->port_num].pkey_list,
pkey_index_list) {
if (tmp_pkey->pkey_index == pp->pkey_index) {
pkey = tmp_pkey;
break;
}
}
spin_unlock(&dev->port_pkey_list[pp->port_num].list_lock);
spin_unlock(&dev->port_data[pp->port_num].pkey_list_lock);
return pkey;
}

Expand Down Expand Up @@ -263,12 +262,12 @@ static int port_pkey_list_insert(struct ib_port_pkey *pp)
if (!pkey)
return -ENOMEM;

spin_lock(&dev->port_pkey_list[port_num].list_lock);
spin_lock(&dev->port_data[port_num].pkey_list_lock);
/* Check for the PKey again. A racing process may
* have created it.
*/
list_for_each_entry(tmp_pkey,
&dev->port_pkey_list[port_num].pkey_list,
&dev->port_data[port_num].pkey_list,
pkey_index_list) {
if (tmp_pkey->pkey_index == pp->pkey_index) {
kfree(pkey);
Expand All @@ -283,9 +282,9 @@ static int port_pkey_list_insert(struct ib_port_pkey *pp)
spin_lock_init(&pkey->qp_list_lock);
INIT_LIST_HEAD(&pkey->qp_list);
list_add(&pkey->pkey_index_list,
&dev->port_pkey_list[port_num].pkey_list);
&dev->port_data[port_num].pkey_list);
}
spin_unlock(&dev->port_pkey_list[port_num].list_lock);
spin_unlock(&dev->port_data[port_num].pkey_list_lock);
}

spin_lock(&pkey->qp_list_lock);
Expand Down Expand Up @@ -551,9 +550,8 @@ void ib_security_cache_change(struct ib_device *device,
{
struct pkey_index_qp_list *pkey;

list_for_each_entry(pkey,
&device->port_pkey_list[port_num].pkey_list,
pkey_index_list) {
list_for_each_entry (pkey, &device->port_data[port_num].pkey_list,
pkey_index_list) {
check_pkey_qps(pkey,
device,
port_num,
Expand All @@ -569,7 +567,7 @@ void ib_security_release_port_pkey_list(struct ib_device *device)
rdma_for_each_port (device, i) {
list_for_each_entry_safe(pkey,
tmp_pkey,
&device->port_pkey_list[i].pkey_list,
&device->port_data[i].pkey_list,
pkey_index_list) {
list_del(&pkey->pkey_index_list);
kfree(pkey);
Expand Down
Loading

0 comments on commit 8ceb135

Please sign in to comment.