Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ba1377d authored by Mitesh Ahuja's avatar Mitesh Ahuja Committed by Roland Dreier
Browse files

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: default avatarMitesh Ahuja <mitesh.ahuja@emulex.com>
Signed-off-by: default avatarDevesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: default avatarSelvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 978cb6a4
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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 {
+120 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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)
{
@@ -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 */
+2 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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;
+33 −0
Original line number Diff line number Diff line
@@ -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
};
@@ -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
Loading