Skip to content

Commit

Permalink
IB/core: Add per port immutable struct to ib_device
Browse files Browse the repository at this point in the history
As of commit 5eb620c "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: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Ira Weiny authored and Doug Ledford committed May 20, 2015
1 parent 26c4542 commit 7738613
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 37 deletions.
63 changes: 28 additions & 35 deletions drivers/infiniband/core/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/infiniband/core/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/amso1100/c2_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/cxgb3/iwch_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/cxgb4/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/ehca/ehca_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,22 @@ static int init_node_guid(struct ehca_shca *shca)
return ret;
}

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

err = ehca_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;
}

static int ehca_init_device(struct ehca_shca *shca)
{
int ret;
Expand Down Expand Up @@ -511,6 +527,7 @@ static int ehca_init_device(struct ehca_shca *shca)
shca->ib_device.process_mad = ehca_process_mad;
shca->ib_device.mmap = ehca_mmap;
shca->ib_device.dma_ops = &ehca_dma_mapping_ops;
shca->ib_device.get_port_immutable = ehca_port_immutable;

if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
shca->ib_device.uverbs_cmd_mask |=
Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/ipath/ipath_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,22 @@ static int disable_timer(struct ipath_devdata *dd)
return 0;
}

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

err = ipath_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;
}

/**
* ipath_register_ib_device - register our device with the infiniband core
* @dd: the device data structure
Expand Down Expand Up @@ -2186,6 +2202,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
dev->process_mad = ipath_process_mad;
dev->mmap = ipath_mmap;
dev->dma_ops = &ipath_dma_mapping_ops;
dev->get_port_immutable = ipath_port_immutable;

snprintf(dev->node_desc, sizeof(dev->node_desc),
IPATH_IDSTR " %s", init_utsname()->nodename);
Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2123,6 +2123,22 @@ static void mlx4_ib_free_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev)
kfree(ibdev->eq_table);
}

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

err = mlx4_ib_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;
}

static void *mlx4_ib_add(struct mlx4_dev *dev)
{
struct mlx4_ib_dev *ibdev;
Expand Down Expand Up @@ -2251,6 +2267,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
ibdev->ib_dev.attach_mcast = mlx4_ib_mcg_attach;
ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach;
ibdev->ib_dev.process_mad = mlx4_ib_process_mad;
ibdev->ib_dev.get_port_immutable = mlx4_port_immutable;

if (!mlx4_is_slave(ibdev->dev)) {
ibdev->ib_dev.alloc_fmr = mlx4_ib_fmr_alloc;
Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/mlx5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,22 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
mlx5_ib_dealloc_pd(devr->p0);
}

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

err = mlx5_ib_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;
}

static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
{
struct mlx5_ib_dev *dev;
Expand Down Expand Up @@ -1292,6 +1308,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list;
dev->ib_dev.free_fast_reg_page_list = mlx5_ib_free_fast_reg_page_list;
dev->ib_dev.check_mr_status = mlx5_ib_check_mr_status;
dev->ib_dev.get_port_immutable = mlx5_port_immutable;

mlx5_ib_internal_query_odp_caps(dev);

Expand Down
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/mthca/mthca_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,22 @@ static int mthca_init_node_data(struct mthca_dev *dev)
return err;
}

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

err = mthca_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 mthca_register_device(struct mthca_dev *dev)
{
int ret;
Expand Down Expand Up @@ -1330,6 +1346,7 @@ int mthca_register_device(struct mthca_dev *dev)
dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr;
dev->ib_dev.reg_user_mr = mthca_reg_user_mr;
dev->ib_dev.dereg_mr = mthca_dereg_mr;
dev->ib_dev.get_port_immutable = mthca_port_immutable;

if (dev->mthca_flags & MTHCA_FLAG_FMR) {
dev->ib_dev.alloc_fmr = mthca_alloc_fmr;
Expand Down
Loading

0 comments on commit 7738613

Please sign in to comment.