Skip to content

Commit

Permalink
RDMA/ocrdma: Move PD resource management to driver.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mitesh Ahuja authored and rolandd committed Feb 18, 2015
1 parent 978cb6a commit 9ba1377
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 2 deletions.
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct ocrdma_dev_attr {
u32 vendor_id;
u32 device_id;
u16 max_pd;
u16 max_dpp_pds;
u16 max_cq;
u16 max_cqe;
u16 max_qp;
Expand Down Expand Up @@ -171,6 +172,21 @@ struct ocrdma_stats {
struct ocrdma_dev *dev;
};

struct ocrdma_pd_resource_mgr {
u32 pd_norm_start;
u16 pd_norm_count;
u16 pd_norm_thrsh;
u16 max_normal_pd;
u32 pd_dpp_start;
u16 pd_dpp_count;
u16 pd_dpp_thrsh;
u16 max_dpp_pd;
u16 dpp_page_index;
unsigned long *pd_norm_bitmap;
unsigned long *pd_dpp_bitmap;
bool pd_prealloc_valid;
};

struct stats_mem {
struct ocrdma_mqe mqe;
void *va;
Expand Down Expand Up @@ -256,6 +272,7 @@ struct ocrdma_dev {
struct ocrdma_stats tx_dbg_stats;
struct ocrdma_stats rx_dbg_stats;
struct dentry *dir;
struct ocrdma_pd_resource_mgr *pd_mgr;
};

struct ocrdma_cq {
Expand Down
120 changes: 120 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
attr->max_pd =
(rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >>
OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT;
attr->max_dpp_pds =
(rsp->max_dpp_pds_credits & OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_MASK) >>
OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_OFFSET;
attr->max_qp =
(rsp->qp_srq_cq_ird_ord & OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK) >>
OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT;
Expand Down Expand Up @@ -1396,6 +1399,122 @@ int ocrdma_mbx_dealloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
return status;
}


static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev)
{
int status = -ENOMEM;
size_t pd_bitmap_size;
struct ocrdma_alloc_pd_range *cmd;
struct ocrdma_alloc_pd_range_rsp *rsp;

/* Pre allocate the DPP PDs */
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd));
if (!cmd)
return -ENOMEM;
cmd->pd_count = dev->attr.max_dpp_pds;
cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP;
status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
if (status)
goto mbx_err;
rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;

if ((rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) && rsp->pd_count) {
dev->pd_mgr->dpp_page_index = rsp->dpp_page_pdid >>
OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT;
dev->pd_mgr->pd_dpp_start = rsp->dpp_page_pdid &
OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
dev->pd_mgr->max_dpp_pd = rsp->pd_count;
pd_bitmap_size = BITS_TO_LONGS(rsp->pd_count) * sizeof(long);
dev->pd_mgr->pd_dpp_bitmap = kzalloc(pd_bitmap_size,
GFP_KERNEL);
}
kfree(cmd);

cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd));
if (!cmd)
return -ENOMEM;

cmd->pd_count = dev->attr.max_pd - dev->attr.max_dpp_pds;
status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
if (status)
goto mbx_err;
rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;
if (rsp->pd_count) {
dev->pd_mgr->pd_norm_start = rsp->dpp_page_pdid &
OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
dev->pd_mgr->max_normal_pd = rsp->pd_count;
pd_bitmap_size = BITS_TO_LONGS(rsp->pd_count) * sizeof(long);
dev->pd_mgr->pd_norm_bitmap = kzalloc(pd_bitmap_size,
GFP_KERNEL);
}

if (dev->pd_mgr->pd_norm_bitmap || dev->pd_mgr->pd_dpp_bitmap) {
/* Enable PD resource manager */
dev->pd_mgr->pd_prealloc_valid = true;
} else {
return -ENOMEM;
}
mbx_err:
kfree(cmd);
return status;
}

static void ocrdma_mbx_dealloc_pd_range(struct ocrdma_dev *dev)
{
struct ocrdma_dealloc_pd_range *cmd;

/* return normal PDs to firmware */
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_PD_RANGE, sizeof(*cmd));
if (!cmd)
goto mbx_err;

if (dev->pd_mgr->max_normal_pd) {
cmd->start_pd_id = dev->pd_mgr->pd_norm_start;
cmd->pd_count = dev->pd_mgr->max_normal_pd;
ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
}

if (dev->pd_mgr->max_dpp_pd) {
kfree(cmd);
/* return DPP PDs to firmware */
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_PD_RANGE,
sizeof(*cmd));
if (!cmd)
goto mbx_err;

cmd->start_pd_id = dev->pd_mgr->pd_dpp_start;
cmd->pd_count = dev->pd_mgr->max_dpp_pd;
ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
}
mbx_err:
kfree(cmd);
}

void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev)
{
int status;

dev->pd_mgr = kzalloc(sizeof(struct ocrdma_pd_resource_mgr),
GFP_KERNEL);
if (!dev->pd_mgr) {
pr_err("%s(%d)Memory allocation failure.\n", __func__, dev->id);
return;
}
status = ocrdma_mbx_alloc_pd_range(dev);
if (status) {
pr_err("%s(%d) Unable to initialize PD pool, using default.\n",
__func__, dev->id);
}
}

static void ocrdma_free_pd_pool(struct ocrdma_dev *dev)
{
ocrdma_mbx_dealloc_pd_range(dev);
kfree(dev->pd_mgr->pd_norm_bitmap);
kfree(dev->pd_mgr->pd_dpp_bitmap);
kfree(dev->pd_mgr);
}

static int ocrdma_build_q_conf(u32 *num_entries, int entry_size,
int *num_pages, int *page_size)
{
Expand Down Expand Up @@ -2915,6 +3034,7 @@ int ocrdma_init_hw(struct ocrdma_dev *dev)

void ocrdma_cleanup_hw(struct ocrdma_dev *dev)
{
ocrdma_free_pd_pool(dev);
ocrdma_mbx_delete_ah_tbl(dev);

/* cleanup the eqs */
Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,7 @@ int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq);
int ocrdma_mbx_rdma_stats(struct ocrdma_dev *, bool reset);
char *port_speed_string(struct ocrdma_dev *dev);
void ocrdma_init_service_level(struct ocrdma_dev *);
void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev);
void ocrdma_free_pd_range(struct ocrdma_dev *dev);

#endif /* __OCRDMA_HW_H__ */
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ static int ocrdma_alloc_resources(struct ocrdma_dev *dev)
if (dev->stag_arr == NULL)
goto alloc_err;

ocrdma_alloc_pd_pool(dev);

spin_lock_init(&dev->av_tbl.lock);
spin_lock_init(&dev->flush_q_lock);
return 0;
Expand Down
33 changes: 33 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_sli.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ enum {
OCRDMA_CMD_DESTROY_RBQ = 26,

OCRDMA_CMD_GET_RDMA_STATS = 27,
OCRDMA_CMD_ALLOC_PD_RANGE = 28,
OCRDMA_CMD_DEALLOC_PD_RANGE = 29,

OCRDMA_CMD_MAX
};
Expand Down Expand Up @@ -1297,6 +1299,37 @@ struct ocrdma_dealloc_pd_rsp {
struct ocrdma_mbx_rsp rsp;
};

struct ocrdma_alloc_pd_range {
struct ocrdma_mqe_hdr hdr;
struct ocrdma_mbx_hdr req;
u32 enable_dpp_rsvd;
u32 pd_count;
};

struct ocrdma_alloc_pd_range_rsp {
struct ocrdma_mqe_hdr hdr;
struct ocrdma_mbx_rsp rsp;
u32 dpp_page_pdid;
u32 pd_count;
};

enum {
OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK = 0xFFFF,
};

struct ocrdma_dealloc_pd_range {
struct ocrdma_mqe_hdr hdr;
struct ocrdma_mbx_hdr req;
u32 start_pd_id;
u32 pd_count;
};

struct ocrdma_dealloc_pd_range_rsp {
struct ocrdma_mqe_hdr hdr;
struct ocrdma_mbx_hdr req;
u32 rsvd;
};

enum {
OCRDMA_ADDR_CHECK_ENABLE = 1,
OCRDMA_ADDR_CHECK_DISABLE = 0
Expand Down
12 changes: 12 additions & 0 deletions drivers/infiniband/hw/ocrdma/ocrdma_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ static void ocrdma_update_stats(struct ocrdma_dev *dev)
{
ulong now = jiffies, secs;
int status = 0;
struct ocrdma_rdma_stats_resp *rdma_stats =
(struct ocrdma_rdma_stats_resp *)dev->stats_mem.va;
struct ocrdma_rsrc_stats *rsrc_stats = &rdma_stats->act_rsrc_stats;

secs = jiffies_to_msecs(now - dev->last_stats_time) / 1000U;
if (secs) {
Expand All @@ -497,6 +500,15 @@ static void ocrdma_update_stats(struct ocrdma_dev *dev)
if (status)
pr_err("%s: stats mbox failed with status = %d\n",
__func__, status);
/* Update PD counters from PD resource manager */
if (dev->pd_mgr->pd_prealloc_valid) {
rsrc_stats->dpp_pds = dev->pd_mgr->pd_dpp_count;
rsrc_stats->non_dpp_pds = dev->pd_mgr->pd_norm_count;
/* Threshold stata*/
rsrc_stats = &rdma_stats->th_rsrc_stats;
rsrc_stats->dpp_pds = dev->pd_mgr->pd_dpp_thrsh;
rsrc_stats->non_dpp_pds = dev->pd_mgr->pd_norm_thrsh;
}
dev->last_stats_time = jiffies;
}
}
Expand Down
Loading

0 comments on commit 9ba1377

Please sign in to comment.