mbox series

[00/10] qla2xxx driver misc features

Message ID 20230801114057.27039-1-njavali@marvell.com
Headers show
Series qla2xxx driver misc features | expand

Message

Nilesh Javali Aug. 1, 2023, 11:40 a.m. UTC
Martin,

Please apply the qla2xxx driver miscellaneous features and
bug fixes to the scsi tree at your earliest convenience.

Thanks,
Nilesh

Bikash Hazarika (2):
  qla2xxx: Add logs for SFP temperature monitoring
  qla2xxx: Observed call trace in smp_processor_id()

Manish Rangankar (2):
  qla2xxx: Add NVMe Disconnect support
  qla2xxx: Remove unsupported ql2xenabledif option.

Nilesh Javali (3):
  qla2xxx: fix smatch warn for qla_init_iocb_limit
  Revert "scsi: qla2xxx: Fix buffer overrun"
  qla2xxx: Update version to 10.02.09.100-k

Quinn Tran (3):
  qla2xxx: Flush mailbox commands on chip reset
  qla2xxx: Fix fw resource tracking
  qla2xxx: Error code did not return to upper layer

 drivers/scsi/qla2xxx/qla_attr.c    |   2 -
 drivers/scsi/qla2xxx/qla_dbg.c     |   7 +-
 drivers/scsi/qla2xxx/qla_dbg.h     |   1 +
 drivers/scsi/qla2xxx/qla_def.h     |  46 +++-
 drivers/scsi/qla2xxx/qla_dfs.c     |  10 +
 drivers/scsi/qla2xxx/qla_gbl.h     |  14 +-
 drivers/scsi/qla2xxx/qla_init.c    |  22 +-
 drivers/scsi/qla2xxx/qla_inline.h  |  59 ++++-
 drivers/scsi/qla2xxx/qla_iocb.c    |  28 +-
 drivers/scsi/qla2xxx/qla_isr.c     | 170 +++++++++++-
 drivers/scsi/qla2xxx/qla_mbx.c     |   4 -
 drivers/scsi/qla2xxx/qla_nvme.c    | 404 ++++++++++++++++++++++++++++-
 drivers/scsi/qla2xxx/qla_nvme.h    |  17 +-
 drivers/scsi/qla2xxx/qla_os.c      |  39 ++-
 drivers/scsi/qla2xxx/qla_target.c  |   2 +-
 drivers/scsi/qla2xxx/qla_version.h |   6 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |   4 +-
 include/linux/nvme-fc-driver.h     |   6 +-
 18 files changed, 778 insertions(+), 63 deletions(-)


base-commit: 7e9609d2daea0ebe4add444b26b76479ecfda504

Comments

Himanshu Madhani Aug. 2, 2023, 7:51 p.m. UTC | #1
On 8/1/23 04:40, Nilesh Javali wrote:
> From: Quinn Tran <qutran@marvell.com>
> 
> The storage was not draining io's and the work load
> is not spread out across different CPU's evenly. This led to
> FW resource counters getting over run on the busy CPU. This
> overrun prevented error recovery from happening in a timely
> manner.
> 
> By switching the counter to atomic, it allows the count to
> be little more accurate to prevent the overrun.
> 
> Cc: stable@vger.kernel.org
> Fixes: da7c21b72aa8 ("scsi: qla2xxx: Fix command flush during TMF")
> Signed-off-by: Quinn Tran <qutran@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> ---
>   drivers/scsi/qla2xxx/qla_def.h    | 11 ++++++
>   drivers/scsi/qla2xxx/qla_dfs.c    | 10 ++++++
>   drivers/scsi/qla2xxx/qla_init.c   |  8 +++++
>   drivers/scsi/qla2xxx/qla_inline.h | 57 ++++++++++++++++++++++++++++++-
>   drivers/scsi/qla2xxx/qla_os.c     |  5 +--
>   5 files changed, 88 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
> index 5882e61141e6..b5ec15bbce99 100644
> --- a/drivers/scsi/qla2xxx/qla_def.h
> +++ b/drivers/scsi/qla2xxx/qla_def.h
> @@ -3770,6 +3770,16 @@ struct qla_fw_resources {
>   	u16 pad;
>   };
>   
> +struct qla_fw_res {
> +	u16      iocb_total;
> +	u16      iocb_limit;
> +	atomic_t iocb_used;
> +
> +	u16      exch_total;
> +	u16      exch_limit;
> +	atomic_t exch_used;
> +};
> +
>   #define QLA_IOCB_PCT_LIMIT 95
>   
>   struct  qla_buf_pool {
> @@ -4829,6 +4839,7 @@ struct qla_hw_data {
>   	u8 edif_post_stop_cnt_down;
>   	struct qla_vp_map *vp_map;
>   	struct qla_nvme_fc_rjt lsrjt;
> +	struct qla_fw_res fwres ____cacheline_aligned;
>   };
>   
>   #define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
> diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
> index 1925cc6897b6..f060e593685d 100644
> --- a/drivers/scsi/qla2xxx/qla_dfs.c
> +++ b/drivers/scsi/qla2xxx/qla_dfs.c
> @@ -276,6 +276,16 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
>   
>   		seq_printf(s, "estimate exchange used[%d] high water limit [%d] n",
>   			   exch_used, ha->base_qpair->fwres.exch_limit);
> +
> +		if (ql2xenforce_iocb_limit == 2) {
> +			iocbs_used = atomic_read(&ha->fwres.iocb_used);
> +			exch_used  = atomic_read(&ha->fwres.exch_used);
> +			seq_printf(s, "        estimate iocb2 used [%d] high water limit [%d]\n",
> +					iocbs_used, ha->fwres.iocb_limit);
> +
> +			seq_printf(s, "        estimate exchange2 used[%d] high water limit [%d] \n",
> +					exch_used, ha->fwres.exch_limit);
> +		}
>   	}
>   
>   	return 0;
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index ddc9b54f5703..7faf2109228e 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -4214,6 +4214,14 @@ void qla_init_iocb_limit(scsi_qla_host_t *vha)
>   			ha->queue_pair_map[i]->fwres.exch_used = 0;
>   		}
>   	}
> +
> +	ha->fwres.iocb_total = ha->orig_fw_iocb_count;
> +	ha->fwres.iocb_limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100;
> +	ha->fwres.exch_total = ha->orig_fw_xcb_count;
> +	ha->fwres.exch_limit = (ha->orig_fw_xcb_count * QLA_IOCB_PCT_LIMIT) / 100;
> +
> +	atomic_set(&ha->fwres.iocb_used, 0);
> +	atomic_set(&ha->fwres.exch_used, 0);
>   }
>   
>   void qla_adjust_iocb_limit(scsi_qla_host_t *vha)
> diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
> index 0167e85ba058..0556969f6dc1 100644
> --- a/drivers/scsi/qla2xxx/qla_inline.h
> +++ b/drivers/scsi/qla2xxx/qla_inline.h
> @@ -386,6 +386,7 @@ enum {
>   	RESOURCE_IOCB = BIT_0,
>   	RESOURCE_EXCH = BIT_1,  /* exchange */
>   	RESOURCE_FORCE = BIT_2,
> +	RESOURCE_HA = BIT_3,
>   };
>   
>   static inline int
> @@ -393,7 +394,7 @@ qla_get_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores)
>   {
>   	u16 iocbs_used, i;
>   	u16 exch_used;
> -	struct qla_hw_data *ha = qp->vha->hw;
> +	struct qla_hw_data *ha = qp->hw;
>   
>   	if (!ql2xenforce_iocb_limit) {
>   		iores->res_type = RESOURCE_NONE;
> @@ -428,15 +429,69 @@ qla_get_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores)
>   			return -ENOSPC;
>   		}
>   	}
> +
> +	if (ql2xenforce_iocb_limit == 2) {
> +		if ((iores->iocb_cnt + atomic_read(&ha->fwres.iocb_used)) >=
> +		    ha->fwres.iocb_limit) {
> +			iores->res_type = RESOURCE_NONE;
> +			return -ENOSPC;
> +		}
> +
> +		if (iores->res_type & RESOURCE_EXCH) {
> +			if ((iores->exch_cnt + atomic_read(&ha->fwres.exch_used)) >=
> +			    ha->fwres.exch_limit) {
> +				iores->res_type = RESOURCE_NONE;
> +				return -ENOSPC;
> +			}
> +		}
> +	}
> +
>   force:
>   	qp->fwres.iocbs_used += iores->iocb_cnt;
>   	qp->fwres.exch_used += iores->exch_cnt;
> +	if (ql2xenforce_iocb_limit == 2) {
> +		atomic_add(iores->iocb_cnt, &ha->fwres.iocb_used);
> +		atomic_add(iores->exch_cnt, &ha->fwres.exch_used);
> +		iores->res_type |= RESOURCE_HA;
> +	}
>   	return 0;
>   }
>   
> +/*
> + * decrement to zero.  This routine will not decrement below zero
> + * @v:  pointer of type atomic_t
> + * @amount: amount to decrement from v
> + */
> +static void qla_atomic_dtz(atomic_t *v, int amount)
> +{
> +	int c, old, dec;
> +
> +	c = atomic_read(v);
> +	for (;;) {
> +		dec = c - amount;
> +		if (unlikely(dec < 0))
> +			dec = 0;
> +
> +		old = atomic_cmpxchg((v), c, dec);
> +		if (likely(old == c))
> +			break;
> +		c = old;
> +	}
> +}
> +
>   static inline void
>   qla_put_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores)
>   {
> +	struct qla_hw_data *ha = qp->hw;
> +
> +	if (iores->res_type & RESOURCE_HA) {
> +		if (iores->res_type & RESOURCE_IOCB)
> +			qla_atomic_dtz(&ha->fwres.iocb_used, iores->iocb_cnt);
> +
> +		if (iores->res_type & RESOURCE_EXCH)
> +			qla_atomic_dtz(&ha->fwres.exch_used, iores->exch_cnt);
> +	}
> +
>   	if (iores->res_type & RESOURCE_IOCB) {
>   		if (qp->fwres.iocbs_used >= iores->iocb_cnt) {
>   			qp->fwres.iocbs_used -= iores->iocb_cnt;
> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
> index a18bcc86a21a..7da13607e239 100644
> --- a/drivers/scsi/qla2xxx/qla_os.c
> +++ b/drivers/scsi/qla2xxx/qla_os.c
> @@ -44,10 +44,11 @@ module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR);
>   MODULE_PARM_DESC(ql2xfulldump_on_mpifail,
>   		 "Set this to take full dump on MPI hang.");
>   
> -int ql2xenforce_iocb_limit = 1;
> +int ql2xenforce_iocb_limit = 2;
>   module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR);
>   MODULE_PARM_DESC(ql2xenforce_iocb_limit,
> -		 "Enforce IOCB throttling, to avoid FW congestion. (default: 1)");
> +		 "Enforce IOCB throttling, to avoid FW congestion. (default: 2) "
> +		 "1: track usage per queue, 2: track usage per adapter");
>   
>   /*
>    * CT6 CTX allocation cache

Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Himanshu Madhani Aug. 2, 2023, 7:53 p.m. UTC | #2
On 8/1/23 04:40, Nilesh Javali wrote:
> From: Quinn Tran <qutran@marvell.com>
> 
> TMF was returned with an error code. The error code was not
> preserved to be returned to upper layer. Instead, the error code
> from the Marker was returned.
> 
> Preserve error code from TMF and return it to upper layer.
> 
> Cc: stable@vger.kernel.org
> Fixes: da7c21b72aa8 ("scsi: qla2xxx: Fix command flush during TMF")
> Signed-off-by: Quinn Tran <qutran@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> ---
>   drivers/scsi/qla2xxx/qla_init.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index 7faf2109228e..3ab90c159034 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -2223,6 +2223,8 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
>   			rval = QLA_FUNCTION_FAILED;
>   		}
>   	}
> +	if (tm_iocb->u.tmf.data)
> +		rval = tm_iocb->u.tmf.data;
>   
>   done_free_sp:
>   	/* ref: INIT */

Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Himanshu Madhani Aug. 2, 2023, 7:54 p.m. UTC | #3
On 8/1/23 04:40, Nilesh Javali wrote:
> From: Bikash Hazarika <bhazarika@marvell.com>
> 
> Following Call Trace was observed,
> 
> localhost kernel: nvme nvme0: NVME-FC{0}: controller connect complete
> localhost kernel: BUG: using smp_processor_id() in preemptible [00000000] code: kworker/u129:4/75092
> localhost kernel: nvme nvme0: NVME-FC{0}: new ctrl: NQN "nqn.1992-08.com.netapp:sn.b42d198afb4d11ecad6d00a098d6abfa:subsystem.PR_Channel2022_RH84_subsystem_291"
> localhost kernel: caller is qla_nvme_post_cmd+0x216/0x1380 [qla2xxx]
> localhost kernel: CPU: 6 PID: 75092 Comm: kworker/u129:4 Kdump: loaded Tainted: G    B   W  OE    --------- ---  5.14.0-70.22.1.el9_0.x86_64+debug #1
> localhost kernel: Hardware name: HPE ProLiant XL420 Gen10/ProLiant XL420 Gen10, BIOS U39 01/13/2022
> localhost kernel: Workqueue: nvme-wq nvme_async_event_work [nvme_core]
> localhost kernel: Call Trace:
> localhost kernel: dump_stack_lvl+0x57/0x7d
> localhost kernel: check_preemption_disabled+0xc8/0xd0
> localhost kernel: qla_nvme_post_cmd+0x216/0x1380 [qla2xxx]
> 
> Use raw_smp_processor_id api instead of smp_processor_id
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Bikash Hazarika <bhazarika@marvell.com>
> Signed-off-by: Nilesh Javali <njavali@marvell.com>
> ---
>   drivers/scsi/qla2xxx/qla_inline.h  | 2 +-
>   drivers/scsi/qla2xxx/qla_isr.c     | 6 +++---
>   drivers/scsi/qla2xxx/qla_target.c  | 2 +-
>   drivers/scsi/qla2xxx/tcm_qla2xxx.c | 4 ++--
>   4 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
> index 0556969f6dc1..a4a56ab0ba74 100644
> --- a/drivers/scsi/qla2xxx/qla_inline.h
> +++ b/drivers/scsi/qla2xxx/qla_inline.h
> @@ -577,7 +577,7 @@ fcport_is_bigger(fc_port_t *fcport)
>   static inline struct qla_qpair *
>   qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair)
>   {
> -	int cpuid = smp_processor_id();
> +	int cpuid = raw_smp_processor_id();
>   
>   	if (qpair->cpuid != cpuid &&
>   	    ha->qp_cpu_map[cpuid]) {
> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
> index e98788191897..01fc300d640f 100644
> --- a/drivers/scsi/qla2xxx/qla_isr.c
> +++ b/drivers/scsi/qla2xxx/qla_isr.c
> @@ -3965,7 +3965,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>   	if (!ha->flags.fw_started)
>   		return;
>   
> -	if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) {
> +	if (rsp->qpair->cpuid != raw_smp_processor_id() || !rsp->qpair->rcv_intr) {
>   		rsp->qpair->rcv_intr = 1;
>   
>   		if (!rsp->qpair->cpu_mapped)
> @@ -4468,7 +4468,7 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id)
>   	}
>   	ha = qpair->hw;
>   
> -	queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work);
> +	queue_work_on(raw_smp_processor_id(), ha->wq, &qpair->q_work);
>   
>   	return IRQ_HANDLED;
>   }
> @@ -4494,7 +4494,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id)
>   	wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT);
>   	spin_unlock_irqrestore(&ha->hardware_lock, flags);
>   
> -	queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work);
> +	queue_work_on(raw_smp_processor_id(), ha->wq, &qpair->q_work);
>   
>   	return IRQ_HANDLED;
>   }
> diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
> index 2b815a9928ea..9278713c3021 100644
> --- a/drivers/scsi/qla2xxx/qla_target.c
> +++ b/drivers/scsi/qla2xxx/qla_target.c
> @@ -4425,7 +4425,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
>   		queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work);
>   	} else if (ha->msix_count) {
>   		if (cmd->atio.u.isp24.fcp_cmnd.rddata)
> -			queue_work_on(smp_processor_id(), qla_tgt_wq,
> +			queue_work_on(raw_smp_processor_id(), qla_tgt_wq,
>   			    &cmd->work);
>   		else
>   			queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq,
> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> index 3b5ba4b47b3b..9566f0384353 100644
> --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> @@ -310,7 +310,7 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd)
>   	cmd->trc_flags |= TRC_CMD_DONE;
>   
>   	INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free);
> -	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
> +	queue_work_on(raw_smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
>   }
>   
>   /*
> @@ -547,7 +547,7 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
>   	cmd->trc_flags |= TRC_DATA_IN;
>   	cmd->cmd_in_wq = 1;
>   	INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work);
> -	queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
> +	queue_work_on(raw_smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
>   }
>   
>   static int tcm_qla2xxx_chk_dif_tags(uint32_t tag)

Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>