All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
To: linux-scsi@vger.kernel.org
Cc: martin.petersen@oracle.com, mpi3mr-linuxdrv.pdl@broadcom.com,
	Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Subject: [PATCH 17/25] mpi3mr: Gracefully handle online FW update operation
Date: Mon, 20 Dec 2021 19:41:51 +0530	[thread overview]
Message-ID: <20211220141159.16117-18-sreekanth.reddy@broadcom.com> (raw)
In-Reply-To: <20211220141159.16117-1-sreekanth.reddy@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 9151 bytes --]

The driver is enhanced to gracefully handle discrepancies in
certain key data sizes between firmware update operations as
mentioned below,
- The driver displays an error message and marks the controller
as unrecoverable if the firmware reports ReplyFrameSize that
is greater than the current ReplyFrameSize.
- If the firmware reports ReplyFrameSize greater than the
current ReplyFrameSize then the driver uses the current
ReplyFrameSize while copying the reply messages.
- The driver displays an error message and marks the controller
as unrecoverable if the firmware reports
MaxOperationalReplyQueues less than the currently allocated
operational reply queues count.
- If the firmware reports MaxOperationalReplyQueues that is
greater than the currently allocated operational reply queue
count then the driver ignores the new increased value and
uses the previously allocated number of operational queues
only.
- If the firmware reports MaxDevHandle greater than the
previously used MaxDevHandle value after a reset then the
driver re-allocates the 'device remove pending bitmap'
buffer with the newer size using krealloc().

Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h    |   1 +
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 109 ++++++++++++++++++++++++++------
 2 files changed, 92 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index b24efe2..24b65bb 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -752,6 +752,7 @@ struct mpi3mr_ioc {
 	dma_addr_t reply_buf_dma_max_address;
 
 	u16 reply_free_qsz;
+	u16 reply_sz;
 	struct dma_pool *reply_free_q_pool;
 	__le64 *reply_free_q;
 	dma_addr_t reply_free_q_dma;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 4d048e5..4050195 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -13,6 +13,8 @@
 static int
 mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type, u32 reset_reason);
 static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc);
+static void mpi3mr_process_factsdata(struct mpi3mr_ioc *mrioc,
+	struct mpi3_ioc_facts_data *facts_data);
 
 #if defined(writeq) && defined(CONFIG_64BIT)
 static inline void mpi3mr_writeq(__u64 b, volatile void __iomem *addr)
@@ -376,7 +378,7 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,
 			if (def_reply) {
 				cmdptr->state |= MPI3MR_CMD_REPLY_VALID;
 				memcpy((u8 *)cmdptr->reply, (u8 *)def_reply,
-				    mrioc->facts.reply_sz);
+				    mrioc->reply_sz);
 			}
 			if (cmdptr->is_waiting) {
 				complete(&cmdptr->done);
@@ -996,6 +998,66 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
 	return retval;
 }
 
+/**
+ * mpi3mr_revalidate_factsdata - validate IOCFacts parameters
+ * during reset/resume
+ * @mrioc: Adapter instance reference
+ *
+ * Return zero if the new IOCFacts parameters value is compatible with
+ * older values else return -EPERM
+ */
+static int
+mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
+{
+	u16 dev_handle_bitmap_sz;
+	void *removepend_bitmap;
+
+	if (mrioc->facts.reply_sz > mrioc->reply_sz) {
+		ioc_err(mrioc,
+		    "cannot increase reply size from %d to %d\n",
+		    mrioc->reply_sz, mrioc->facts.reply_sz);
+		return -EPERM;
+	}
+
+	if (mrioc->facts.max_op_reply_q < mrioc->num_op_reply_q) {
+		ioc_err(mrioc,
+		    "cannot reduce number of operational reply queues from %d to %d\n",
+		    mrioc->num_op_reply_q,
+		    mrioc->facts.max_op_reply_q);
+		return -EPERM;
+	}
+
+	if (mrioc->facts.max_op_req_q < mrioc->num_op_req_q) {
+		ioc_err(mrioc,
+		    "cannot reduce number of operational request queues from %d to %d\n",
+		    mrioc->num_op_req_q, mrioc->facts.max_op_req_q);
+		return -EPERM;
+	}
+
+	dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
+	if (mrioc->facts.max_devhandle % 8)
+		dev_handle_bitmap_sz++;
+	if (dev_handle_bitmap_sz > mrioc->dev_handle_bitmap_sz) {
+		removepend_bitmap = krealloc(mrioc->removepend_bitmap,
+		    dev_handle_bitmap_sz, GFP_KERNEL);
+		if (!removepend_bitmap) {
+			ioc_err(mrioc,
+			    "failed to increase removepend_bitmap sz from: %d to %d\n",
+			    mrioc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
+			return -EPERM;
+		}
+		memset(removepend_bitmap + mrioc->dev_handle_bitmap_sz, 0,
+		    dev_handle_bitmap_sz - mrioc->dev_handle_bitmap_sz);
+		mrioc->removepend_bitmap = removepend_bitmap;
+		ioc_info(mrioc,
+		    "increased dev_handle_bitmap_sz from %d to %d\n",
+		    mrioc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
+		mrioc->dev_handle_bitmap_sz = dev_handle_bitmap_sz;
+	}
+
+	return 0;
+}
+
 /**
  * mpi3mr_bring_ioc_ready - Bring controller to ready state
  * @mrioc: Adapter instance reference
@@ -1854,8 +1916,13 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc)
 	    mrioc->intr_info_count - mrioc->op_reply_q_offset;
 	if (!mrioc->num_queues)
 		mrioc->num_queues = min_t(int, num_queues, msix_count_op_q);
-	num_queues = mrioc->num_queues;
-	ioc_info(mrioc, "Trying to create %d Operational Q pairs\n",
+	/*
+	 * During reset set the num_queues to the number of queues
+	 * that was set before the reset.
+	 */
+	num_queues = mrioc->num_op_reply_q ?
+	    mrioc->num_op_reply_q : mrioc->num_queues;
+	ioc_info(mrioc, "trying to create %d operational queue pairs\n",
 	    num_queues);
 
 	if (!mrioc->req_qinfo) {
@@ -2447,6 +2514,7 @@ static int mpi3mr_issue_iocfacts(struct mpi3mr_ioc *mrioc,
 		goto out_unlock;
 	}
 	memcpy(facts_data, (u8 *)data, data_len);
+	mpi3mr_process_factsdata(mrioc, facts_data);
 out_unlock:
 	mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;
 	mutex_unlock(&mrioc->init_cmds.mutex);
@@ -2593,12 +2661,6 @@ static void mpi3mr_process_factsdata(struct mpi3mr_ioc *mrioc,
 	ioc_info(mrioc, "DMA mask %d InitialPE status 0x%x\n",
 	    mrioc->facts.dma_mask, (facts_flags &
 	    MPI3_IOCFACTS_FLAGS_INITIAL_PORT_ENABLE_MASK));
-
-	mrioc->max_host_ios = mrioc->facts.max_reqs - MPI3MR_INTERNAL_CMDS_RESVD;
-
-	if (reset_devices)
-		mrioc->max_host_ios = min_t(int, mrioc->max_host_ios,
-		    MPI3MR_HOST_IOS_KDUMP);
 }
 
 /**
@@ -2618,18 +2680,18 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
 	if (mrioc->init_cmds.reply)
 		return retval;
 
-	mrioc->init_cmds.reply = kzalloc(mrioc->facts.reply_sz, GFP_KERNEL);
+	mrioc->init_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL);
 	if (!mrioc->init_cmds.reply)
 		goto out_failed;
 
 	for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) {
-		mrioc->dev_rmhs_cmds[i].reply = kzalloc(mrioc->facts.reply_sz,
+		mrioc->dev_rmhs_cmds[i].reply = kzalloc(mrioc->reply_sz,
 		    GFP_KERNEL);
 		if (!mrioc->dev_rmhs_cmds[i].reply)
 			goto out_failed;
 	}
 
-	mrioc->host_tm_cmds.reply = kzalloc(mrioc->facts.reply_sz, GFP_KERNEL);
+	mrioc->host_tm_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL);
 	if (!mrioc->host_tm_cmds.reply)
 		goto out_failed;
 
@@ -2655,7 +2717,7 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
 	mrioc->sense_buf_q_sz = mrioc->num_sense_bufs + 1;
 
 	/* reply buffer pool, 16 byte align */
-	sz = mrioc->num_reply_bufs * mrioc->facts.reply_sz;
+	sz = mrioc->num_reply_bufs * mrioc->reply_sz;
 	mrioc->reply_buf_pool = dma_pool_create("reply_buf pool",
 	    &mrioc->pdev->dev, sz, 16, 0);
 	if (!mrioc->reply_buf_pool) {
@@ -2731,10 +2793,10 @@ static void mpimr_initialize_reply_sbuf_queues(struct mpi3mr_ioc *mrioc)
 	u32 sz, i;
 	dma_addr_t phy_addr;
 
-	sz = mrioc->num_reply_bufs * mrioc->facts.reply_sz;
+	sz = mrioc->num_reply_bufs * mrioc->reply_sz;
 	ioc_info(mrioc,
 	    "reply buf pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB), reply_dma(0x%llx)\n",
-	    mrioc->reply_buf, mrioc->num_reply_bufs, mrioc->facts.reply_sz,
+	    mrioc->reply_buf, mrioc->num_reply_bufs, mrioc->reply_sz,
 	    (sz / 1024), (unsigned long long)mrioc->reply_buf_dma);
 	sz = mrioc->reply_free_qsz * 8;
 	ioc_info(mrioc,
@@ -2754,7 +2816,7 @@ static void mpimr_initialize_reply_sbuf_queues(struct mpi3mr_ioc *mrioc)
 
 	/* initialize Reply buffer Queue */
 	for (i = 0, phy_addr = mrioc->reply_buf_dma;
-	    i < mrioc->num_reply_bufs; i++, phy_addr += mrioc->facts.reply_sz)
+	    i < mrioc->num_reply_bufs; i++, phy_addr += mrioc->reply_sz)
 		mrioc->reply_free_q[i] = cpu_to_le64(phy_addr);
 	mrioc->reply_free_q[i] = cpu_to_le64(0);
 
@@ -3459,7 +3521,13 @@ retry_init:
 		goto out_failed;
 	}
 
-	mpi3mr_process_factsdata(mrioc, &facts_data);
+	mrioc->max_host_ios = mrioc->facts.max_reqs - MPI3MR_INTERNAL_CMDS_RESVD;
+
+	if (reset_devices)
+		mrioc->max_host_ios = min_t(int, mrioc->max_host_ios,
+		    MPI3MR_HOST_IOS_KDUMP);
+
+	mrioc->reply_sz = mrioc->facts.reply_sz;
 
 	retval = mpi3mr_check_reset_dma_mask(mrioc);
 	if (retval) {
@@ -3582,7 +3650,12 @@ retry_init:
 		goto out_failed;
 	}
 
-	mpi3mr_process_factsdata(mrioc, &facts_data);
+	dprint_reset(mrioc, "validating ioc_facts\n");
+	retval = mpi3mr_revalidate_factsdata(mrioc);
+	if (retval) {
+		ioc_err(mrioc, "failed to revalidate ioc_facts data\n");
+		goto out_failed_noretry;
+	}
 
 	mpi3mr_print_ioc_info(mrioc);
 
-- 
2.27.0


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

  parent reply	other threads:[~2021-12-20 14:04 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-20 14:11 [PATCH 00/25] mpi3mr: driver fixes and enhancements Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 01/25] mpi3mr: Add debug APIs based on logging_level bits Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 02/25] mpi3mr: replace spin_lock with spin_lock_irqsave Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 03/25] mpi3mr: Don't reset IOC if cmnds flush with reset status Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 04/25] mpi3mr: Update MPI3 headers - part1 Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 05/25] mpi3mr: Update MPI3 headers - part2 Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 06/25] mpi3mr: Add support for PCIe Managed Switch SES device Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 07/25] mpi3mr: Do access status validation before adding devices Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 08/25] mpi3mr: Increase internal cmnds timeout to 60s Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 09/25] mpi3mr: Handling unaligned PLL in unmap cmnds Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 10/25] mpi3mr: Display IOC firmware package version Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 11/25] mpi3mr: Fault IOC when internal commands gets timeout Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 12/25] mpi3mr: code refactor of IOC init patch - part1 Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 13/25] mpi3mr: code refactor of IOC init patch - part2 Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 14/25] mpi3mr: Handle offline FW activation in graceful manner Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 15/25] mpi3mr: Add IOC reinit function Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 16/25] mpi3mr: Detect async reset occurred in firmware Sreekanth Reddy
2021-12-20 14:11 ` Sreekanth Reddy [this message]
2021-12-20 14:11 ` [PATCH 18/25] mpi3mr: Add Event acknowledgment logic Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 19/25] mpi3mr: Add support Prepare for Reset event Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 20/25] mpi3mr: Print cable mngnt and temp threshold events Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 21/25] mpi3mr: Add iouring interface support in io-polled mode Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 22/25] mpi3mr: use TM response codes from MPI3 headers Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 23/25] mpi3mr: Enhanced Task Management Support Reply handling Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 24/25] mpi3mr: Fixes around reply request queues Sreekanth Reddy
2021-12-20 14:11 ` [PATCH 25/25] mpi3mr: Bump driver version to 8.0.0.61.0 Sreekanth Reddy
2021-12-23  5:06 ` [PATCH 00/25] mpi3mr: driver fixes and enhancements Martin K. Petersen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211220141159.16117-18-sreekanth.reddy@broadcom.com \
    --to=sreekanth.reddy@broadcom.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=mpi3mr-linuxdrv.pdl@broadcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.