From aa0401aeaa3e5d859bbd15b0c5c325b5ace725c9 Mon Sep 17 00:00:00 2001 From: Mukesh Kacker Date: Tue, 22 Dec 2015 19:49:49 -0800 Subject: [PATCH] ib_uverbs: Allocate pd in a lazy manner to conserve resources For usnic devices devices where the maximum number of pd resources are limited (usnic devices), its a waste to allocate this resource on device initialization. We delay the allocation to first use. Orabug: 22378991 Signed-off-by: Mukesh Kacker Reviewed-by: Santosh Shilimkar --- drivers/infiniband/core/uverbs_cmd.c | 22 +++++++++++++++++++++- drivers/infiniband/core/uverbs_main.c | 23 +++++++++++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 9ef2f493f0d1..4c82ee16be9a 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1594,7 +1594,27 @@ ssize_t ib_uverbs_reg_mr_relaxed(struct ib_uverbs_file *file, (ufmr_pool1_blocksize + PAGE_SIZE) >> PAGE_SHIFT; int pool2pages = (ufmr_pool2_blocksize + PAGE_SIZE) >> PAGE_SHIFT; - struct ib_pd *pool_pd = file->device->ib_dev->relaxed_pd; + struct ib_pd *pool_pd = NULL; + + /* + * If not already allocated, we do (lazy) + * pd allocation for usnic node type devices! + */ + if (file->device && + file->device->ib_dev && + file->device->ib_dev->relaxed_pd == NULL && + (file->device->ib_dev->node_type == RDMA_NODE_USNIC || + file->device->ib_dev->node_type == RDMA_NODE_USNIC_UDP)) { + file->device->ib_dev->relaxed_pd = + ib_alloc_pd(file->device->ib_dev); + if (IS_ERR(file->device->ib_dev->relaxed_pd)) { + ret = PTR_ERR(file->device->ib_dev->relaxed_pd); + file->device->ib_dev->relaxed_pd = NULL; + goto err_put; + } + } + + pool_pd = file->device->ib_dev->relaxed_pd; /* Create pool for 8kb buffers */ ret = create_fmr_pool(pool_pd, pool1pages, ufmr_pool1_nelems, diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index b2a8bd749170..17db86f5d11c 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -1053,10 +1053,18 @@ static void ib_uverbs_add_one(struct ib_device *device) if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version)) goto err_class; - device->relaxed_pd = ib_alloc_pd(device); - if (IS_ERR(device->relaxed_pd)) { - device->relaxed_pd = NULL; - goto err_class; + device->relaxed_pd = NULL; + /* + * Allocate pd if not a usnic device node + * (For usnic devices we do lazy allocation of pd) + */ + if (device->node_type != RDMA_NODE_USNIC && + device->node_type != RDMA_NODE_USNIC_UDP) { + device->relaxed_pd = ib_alloc_pd(device); + if (IS_ERR(device->relaxed_pd)) { + device->relaxed_pd = NULL; + goto err_class; + } } ib_set_client_data(device, &uverbs_client, uverbs_dev); @@ -1097,8 +1105,11 @@ static void ib_uverbs_remove_one(struct ib_device *device) kfree(pos); } - ret = ib_dealloc_pd(device->relaxed_pd); - device->relaxed_pd = NULL; + /* free pd if allocated! */ + if (device->relaxed_pd) { + ret = ib_dealloc_pd(device->relaxed_pd); + device->relaxed_pd = NULL; + } dev_set_drvdata(uverbs_dev->dev, NULL); device_destroy(uverbs_class, uverbs_dev->cdev.dev); -- 2.50.1