Commit 0794d601 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Implement common IO buffers between NVME and SCSI

Currently, both NVME and SCSI get their IO buffers from separate
pools. XRI's are associated 1:1 with IO buffers, so XRI's are also split
between protocols.

Eliminate the independent pools and use a single pool. Each buffer
structure now has a common section and a protocol section. Per protocol
routines for SGL initialization are removed and replaced by common
routines. Initialization of the buffers is only done on the common area.
All other fields, which are protocol specific, are initialized when the
buffer is allocated for use in the per-protocol allocation routine.

In the past, the SCSI side allocated IO buffers as part of slave_alloc
calls until the maximum XRIs for SCSI was reached. As all XRIs are now
common and may be used for either protocol, allocation for everything is
done as part of adapter initialization and the scsi side has no action in
slave alloc.

As XRI's are no longer split, the lpfc_xri_split module parameter is
removed.

Adapters based on SLI3 will continue to use the older scsi_buf_list_get/put
routines.  All SLI4 adapters utilize the new IO buffer scheme
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e960f5ab
......@@ -617,8 +617,6 @@ struct lpfc_ras_fwlog {
struct lpfc_hba {
/* SCSI interface function jump table entries */
int (*lpfc_new_scsi_buf)
(struct lpfc_vport *, int);
struct lpfc_scsi_buf * (*lpfc_get_scsi_buf)
(struct lpfc_hba *, struct lpfc_nodelist *);
int (*lpfc_scsi_prep_dma_buf)
......@@ -875,7 +873,6 @@ struct lpfc_hba {
uint32_t cfg_enable_fc4_type;
uint32_t cfg_enable_bbcr; /* Enable BB Credit Recovery */
uint32_t cfg_enable_dpp; /* Enable Direct Packet Push */
uint32_t cfg_xri_split;
#define LPFC_ENABLE_FCP 1
#define LPFC_ENABLE_NVME 2
#define LPFC_ENABLE_BOTH 3
......@@ -970,13 +967,13 @@ struct lpfc_hba {
struct list_head lpfc_scsi_buf_list_get;
struct list_head lpfc_scsi_buf_list_put;
uint32_t total_scsi_bufs;
spinlock_t nvme_buf_list_get_lock; /* NVME buf alloc list lock */
spinlock_t nvme_buf_list_put_lock; /* NVME buf free list lock */
struct list_head lpfc_nvme_buf_list_get;
struct list_head lpfc_nvme_buf_list_put;
uint32_t total_nvme_bufs;
uint32_t get_nvme_bufs;
uint32_t put_nvme_bufs;
spinlock_t common_buf_list_get_lock; /* Common buf alloc list lock */
spinlock_t common_buf_list_put_lock; /* Common buf free list lock */
struct list_head lpfc_common_buf_list_get;
struct list_head lpfc_common_buf_list_put;
uint32_t total_common_bufs;
uint32_t get_common_bufs;
uint32_t put_common_bufs;
struct list_head lpfc_iocb_list;
uint32_t total_iocbq_bufs;
struct list_head active_rrq_list;
......
......@@ -334,11 +334,10 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
rcu_read_lock();
scnprintf(tmp, sizeof(tmp),
"XRI Dist lpfc%d Total %d NVME %d SCSI %d ELS %d\n",
"XRI Dist lpfc%d Total %d IO %d ELS %d\n",
phba->brd_no,
phba->sli4_hba.max_cfg_param.max_xri,
phba->sli4_hba.nvme_xri_max,
phba->sli4_hba.scsi_xri_max,
phba->sli4_hba.common_xri_max,
lpfc_sli4_get_els_iocb_cnt(phba));
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done;
......@@ -3730,22 +3729,6 @@ LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_FCP,
LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH,
"Enable FC4 Protocol support - FCP / NVME");
/*
* lpfc_xri_split: Defines the division of XRI resources between SCSI and NVME
* This parameter is only used if:
* lpfc_enable_fc4_type is 3 - register both FCP and NVME and
* port is not configured for NVMET.
*
* ELS/CT always get 10% of XRIs, up to a maximum of 250
* The remaining XRIs get split up based on lpfc_xri_split per port:
*
* Supported Values are in percentages
* the xri_split value is the percentage the SCSI port will get. The remaining
* percentage will go to NVME.
*/
LPFC_ATTR_R(xri_split, 50, 10, 90,
"Percentage of FCP XRI resources versus NVME");
/*
# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
# deluged with LOTS of information.
......@@ -5704,7 +5687,6 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_nodev_tmo,
&dev_attr_lpfc_devloss_tmo,
&dev_attr_lpfc_enable_fc4_type,
&dev_attr_lpfc_xri_split,
&dev_attr_lpfc_fcp_class,
&dev_attr_lpfc_use_adisc,
&dev_attr_lpfc_first_burst_size,
......@@ -6865,7 +6847,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
phba->cfg_soft_wwnn = 0L;
phba->cfg_soft_wwpn = 0L;
lpfc_xri_split_init(phba, lpfc_xri_split);
lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
......
......@@ -520,8 +520,10 @@ int lpfc_sli4_read_config(struct lpfc_hba *);
void lpfc_sli4_node_prep(struct lpfc_hba *);
int lpfc_sli4_els_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_nvme_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_common_sgl_update(struct lpfc_hba *phba);
int lpfc_sli4_post_common_sgl_list(struct lpfc_hba *phba,
struct list_head *blist, int xricnt);
int lpfc_new_common_buf(struct lpfc_hba *phba, int num_to_alloc);
void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *);
uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *);
int lpfc_sli4_request_firmware_update(struct lpfc_hba *, uint8_t);
......
This diff is collapsed.
This diff is collapsed.
......@@ -77,7 +77,15 @@ struct lpfc_nvme_rport {
};
struct lpfc_nvme_buf {
/* Common fields */
struct list_head list;
void *data;
dma_addr_t dma_handle;
dma_addr_t dma_phys_sgl;
struct sli4_sge *dma_sgl;
struct lpfc_iocbq cur_iocbq;
/* NVME specific fields */
struct nvmefc_fcp_req *nvmeCmd;
struct lpfc_nodelist *ndlp;
......@@ -87,36 +95,19 @@ struct lpfc_nvme_buf {
#define LPFC_SBUF_XBUSY 0x1 /* SLI4 hba reported XB on WCQE cmpl */
#define LPFC_BUMP_QDEPTH 0x2 /* bumped queue depth counter */
uint16_t exch_busy; /* SLI4 hba reported XB on complete WCQE */
uint16_t status; /* From IOCB Word 7- ulpStatus */
uint16_t cpu;
uint16_t qidx;
uint16_t sqid;
uint16_t status; /* From IOCB Word 7- ulpStatus */
uint32_t result; /* From IOCB Word 4. */
uint32_t seg_cnt; /* Number of scatter-gather segments returned by
* dma_map_sg. The driver needs this for calls
* to dma_unmap_sg.
*/
dma_addr_t nonsg_phys; /* Non scatter-gather physical address. */
/*
* data and dma_handle are the kernel virtual and bus address of the
* dma-able buffer containing the fcp_cmd, fcp_rsp and a scatter
* gather bde list that supports the sg_tablesize value.
*/
void *data;
dma_addr_t dma_handle;
struct sli4_sge *nvme_sgl;
dma_addr_t dma_phys_sgl;
/* cur_iocbq has phys of the dma-able buffer.
* Iotag is in here
*/
struct lpfc_iocbq cur_iocbq;
wait_queue_head_t *waitq;
unsigned long start_time;
uint16_t qidx;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
uint64_t ts_cmd_start;
uint64_t ts_last_cmd;
......
This diff is collapsed.
......@@ -131,7 +131,15 @@ struct lpfc_scsicmd_bkt {
};
struct lpfc_scsi_buf {
/* Common fields */
struct list_head list;
void *data;
dma_addr_t dma_handle;
dma_addr_t dma_phys_sgl;
struct ulp_bde64 *dma_sgl;
struct lpfc_iocbq cur_iocbq;
/* SCSI specific fields */
struct scsi_cmnd *pCmd;
struct lpfc_rport_data *rdata;
struct lpfc_nodelist *ndlp;
......@@ -139,9 +147,10 @@ struct lpfc_scsi_buf {
uint32_t timeout;
uint16_t flags; /* TBD convert exch_busy to flags */
#define LPFC_SBUF_XBUSY 0x1 /* SLI4 hba reported XB on WCQE cmpl */
#define LPFC_SBUF_BUMP_QDEPTH 0x8 /* bumped queue depth counter */
#define LPFC_SBUF_XBUSY 0x1 /* SLI4 hba reported XB on WCQE cmpl */
#define LPFC_SBUF_BUMP_QDEPTH 0x2 /* bumped queue depth counter */
uint16_t exch_busy; /* SLI4 hba reported XB on complete WCQE */
uint16_t cpu;
uint16_t status; /* From IOCB Word 7- ulpStatus */
uint32_t result; /* From IOCB Word 4. */
......@@ -150,27 +159,13 @@ struct lpfc_scsi_buf {
* to dma_unmap_sg. */
uint32_t prot_seg_cnt; /* seg_cnt's counterpart for protection data */
dma_addr_t nonsg_phys; /* Non scatter-gather physical address. */
/*
* data and dma_handle are the kernel virtual and bus address of the
* dma-able buffer containing the fcp_cmd, fcp_rsp and a scatter
* gather bde list that supports the sg_tablesize value.
*/
void *data;
dma_addr_t dma_handle;
struct fcp_cmnd *fcp_cmnd;
struct fcp_rsp *fcp_rsp;
struct ulp_bde64 *fcp_bpl;
dma_addr_t dma_phys_bpl;
/* cur_iocbq has phys of the dma-able buffer.
* Iotag is in here
*/
struct lpfc_iocbq cur_iocbq;
uint16_t cpu;
wait_queue_head_t *waitq;
unsigned long start_time;
......
This diff is collapsed.
......@@ -41,6 +41,9 @@
#define LPFC_FCP_IO_CHAN_DEF 4
#define LPFC_NVME_IO_CHAN_DEF 0
/* Common buffer size to accomidate SCSI and NVME IO buffers */
#define LPFC_COMMON_IO_BUF_SZ 768
/* Number of channels used for Flash Optimized Fabric (FOF) operations */
#define LPFC_FOF_IO_CHAN_NUM 1
......@@ -663,12 +666,9 @@ struct lpfc_sli4_hba {
uint16_t rpi_hdrs_in_use; /* must post rpi hdrs if set. */
uint16_t next_xri; /* last_xri - max_cfg_param.xri_base = used */
uint16_t next_rpi;
uint16_t nvme_xri_max;
uint16_t nvme_xri_cnt;
uint16_t nvme_xri_start;
uint16_t scsi_xri_max;
uint16_t scsi_xri_cnt;
uint16_t scsi_xri_start;
uint16_t common_xri_max;
uint16_t common_xri_cnt;
uint16_t common_xri_start;
uint16_t els_xri_cnt;
uint16_t nvmet_xri_cnt;
uint16_t nvmet_io_wait_cnt;
......@@ -843,12 +843,10 @@ int lpfc_rq_destroy(struct lpfc_hba *, struct lpfc_queue *,
int lpfc_sli4_queue_setup(struct lpfc_hba *);
void lpfc_sli4_queue_unset(struct lpfc_hba *);
int lpfc_sli4_post_sgl(struct lpfc_hba *, dma_addr_t, dma_addr_t, uint16_t);
int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *);
int lpfc_repost_nvme_sgl_list(struct lpfc_hba *phba);
int lpfc_repost_common_sgl_list(struct lpfc_hba *phba);
uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *);
void lpfc_sli4_free_xri(struct lpfc_hba *, int);
int lpfc_sli4_post_async_mbox(struct lpfc_hba *);
int lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *, struct list_head *, int);
struct lpfc_cq_event *__lpfc_sli4_cq_event_alloc(struct lpfc_hba *);
struct lpfc_cq_event *lpfc_sli4_cq_event_alloc(struct lpfc_hba *);
void __lpfc_sli4_cq_event_release(struct lpfc_hba *, struct lpfc_cq_event *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment