aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
diff options
context:
space:
mode:
authorMitesh Ahuja <mitesh.ahuja@emulex.com>2014-12-18 14:12:57 +0530
committerRoland Dreier <roland@purestorage.com>2015-02-18 08:30:59 -0800
commit9ba1377daa51ff97815fcfb15c26621c7393d1c0 (patch)
tree1c62545f561167f55b660443ebf931fec0ba8b8f /drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
parentRDMA/ocrdma: Increase the GID table size. (diff)
downloadlinux-dev-9ba1377daa51ff97815fcfb15c26621c7393d1c0.tar.xz
linux-dev-9ba1377daa51ff97815fcfb15c26621c7393d1c0.zip
RDMA/ocrdma: Move PD resource management to driver.
Move PD allocation and deallocation from firmware to driver. At driver load time all the PDs will be requested from firmware and their management will be handled by driver to reduce mailbox commands overhead at runtime. Signed-off-by: Mitesh Ahuja <mitesh.ahuja@emulex.com> Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com> Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to '')
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c114
1 files changed, 112 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index fb8d8c4dfbb9..4593f9d8ad25 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -253,6 +253,107 @@ static bool ocrdma_search_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr,
return found;
}
+
+static u16 _ocrdma_pd_mgr_get_bitmap(struct ocrdma_dev *dev, bool dpp_pool)
+{
+ u16 pd_bitmap_idx = 0;
+ const unsigned long *pd_bitmap;
+
+ if (dpp_pool) {
+ pd_bitmap = dev->pd_mgr->pd_dpp_bitmap;
+ pd_bitmap_idx = find_first_zero_bit(pd_bitmap,
+ dev->pd_mgr->max_dpp_pd);
+ __set_bit(pd_bitmap_idx, dev->pd_mgr->pd_dpp_bitmap);
+ dev->pd_mgr->pd_dpp_count++;
+ if (dev->pd_mgr->pd_dpp_count > dev->pd_mgr->pd_dpp_thrsh)
+ dev->pd_mgr->pd_dpp_thrsh = dev->pd_mgr->pd_dpp_count;
+ } else {
+ pd_bitmap = dev->pd_mgr->pd_norm_bitmap;
+ pd_bitmap_idx = find_first_zero_bit(pd_bitmap,
+ dev->pd_mgr->max_normal_pd);
+ __set_bit(pd_bitmap_idx, dev->pd_mgr->pd_norm_bitmap);
+ dev->pd_mgr->pd_norm_count++;
+ if (dev->pd_mgr->pd_norm_count > dev->pd_mgr->pd_norm_thrsh)
+ dev->pd_mgr->pd_norm_thrsh = dev->pd_mgr->pd_norm_count;
+ }
+ return pd_bitmap_idx;
+}
+
+static int _ocrdma_pd_mgr_put_bitmap(struct ocrdma_dev *dev, u16 pd_id,
+ bool dpp_pool)
+{
+ u16 pd_count;
+ u16 pd_bit_index;
+
+ pd_count = dpp_pool ? dev->pd_mgr->pd_dpp_count :
+ dev->pd_mgr->pd_norm_count;
+ if (pd_count == 0)
+ return -EINVAL;
+
+ if (dpp_pool) {
+ pd_bit_index = pd_id - dev->pd_mgr->pd_dpp_start;
+ if (pd_bit_index >= dev->pd_mgr->max_dpp_pd) {
+ return -EINVAL;
+ } else {
+ __clear_bit(pd_bit_index, dev->pd_mgr->pd_dpp_bitmap);
+ dev->pd_mgr->pd_dpp_count--;
+ }
+ } else {
+ pd_bit_index = pd_id - dev->pd_mgr->pd_norm_start;
+ if (pd_bit_index >= dev->pd_mgr->max_normal_pd) {
+ return -EINVAL;
+ } else {
+ __clear_bit(pd_bit_index, dev->pd_mgr->pd_norm_bitmap);
+ dev->pd_mgr->pd_norm_count--;
+ }
+ }
+
+ return 0;
+}
+
+static u8 ocrdma_put_pd_num(struct ocrdma_dev *dev, u16 pd_id,
+ bool dpp_pool)
+{
+ int status;
+
+ mutex_lock(&dev->dev_lock);
+ status = _ocrdma_pd_mgr_put_bitmap(dev, pd_id, dpp_pool);
+ mutex_unlock(&dev->dev_lock);
+ return status;
+}
+
+static int ocrdma_get_pd_num(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
+{
+ u16 pd_idx = 0;
+ int status = 0;
+
+ mutex_lock(&dev->dev_lock);
+ if (pd->dpp_enabled) {
+ /* try allocating DPP PD, if not available then normal PD */
+ if (dev->pd_mgr->pd_dpp_count < dev->pd_mgr->max_dpp_pd) {
+ pd_idx = _ocrdma_pd_mgr_get_bitmap(dev, true);
+ pd->id = dev->pd_mgr->pd_dpp_start + pd_idx;
+ pd->dpp_page = dev->pd_mgr->dpp_page_index + pd_idx;
+ } else if (dev->pd_mgr->pd_norm_count <
+ dev->pd_mgr->max_normal_pd) {
+ pd_idx = _ocrdma_pd_mgr_get_bitmap(dev, false);
+ pd->id = dev->pd_mgr->pd_norm_start + pd_idx;
+ pd->dpp_enabled = false;
+ } else {
+ status = -EINVAL;
+ }
+ } else {
+ if (dev->pd_mgr->pd_norm_count < dev->pd_mgr->max_normal_pd) {
+ pd_idx = _ocrdma_pd_mgr_get_bitmap(dev, false);
+ pd->id = dev->pd_mgr->pd_norm_start + pd_idx;
+ } else {
+ status = -EINVAL;
+ }
+ }
+ mutex_unlock(&dev->dev_lock);
+ return status;
+}
+
static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
struct ocrdma_ucontext *uctx,
struct ib_udata *udata)
@@ -272,6 +373,11 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
dev->attr.wqe_size) : 0;
}
+ if (dev->pd_mgr->pd_prealloc_valid) {
+ status = ocrdma_get_pd_num(dev, pd);
+ return (status == 0) ? pd : ERR_PTR(status);
+ }
+
retry:
status = ocrdma_mbx_alloc_pd(dev, pd);
if (status) {
@@ -299,7 +405,11 @@ static int _ocrdma_dealloc_pd(struct ocrdma_dev *dev,
{
int status = 0;
- status = ocrdma_mbx_dealloc_pd(dev, pd);
+ if (dev->pd_mgr->pd_prealloc_valid)
+ status = ocrdma_put_pd_num(dev, pd->id, pd->dpp_enabled);
+ else
+ status = ocrdma_mbx_dealloc_pd(dev, pd);
+
kfree(pd);
return status;
}
@@ -569,7 +679,7 @@ err:
if (is_uctx_pd) {
ocrdma_release_ucontext_pd(uctx);
} else {
- status = ocrdma_mbx_dealloc_pd(dev, pd);
+ status = _ocrdma_dealloc_pd(dev, pd);
kfree(pd);
}
exit: