public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
To: linux-scsi@vger.kernel.org
Cc: kashyap.desai@broadcom.com, sumit.saxena@broadcom.com,
	kiran-kumar.kasturi@broadcom.com, sankar.patra@broadcom.com,
	sasikumar.pc@broadcom.com,
	shivasharan.srikanteshwara@broadcom.com,
	anand.lodnoor@broadcom.com,
	Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Subject: [PATCH 3/5] megaraid_sas: Early detection of VD deletion through RaidMap update
Date: Thu, 18 Mar 2021 00:38:22 +0530	[thread overview]
Message-ID: <20210317190824.3050-4-chandrakanth.patil@broadcom.com> (raw)
In-Reply-To: <20210317190824.3050-1-chandrakanth.patil@broadcom.com>

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

Consider in a case, when a VD is deleted and the targetID of
that VD is assigned to a newly created VD. If the sequence of
deletion/addition of VD happens very quickly, there is a possibility
that second event(VD add) occurs even before the driver processes the
first event(VD delete).
As event processing is done in deferred context the device list
remains same(but targetID is re-used) so driver will not learn the
VD deletion/additon and IOs meant for older VD will be directed to
new VD which may lead to data corruption.

In new design, driver will detect the deleted VD as soon as possible
based on the RaidMap update and blocks further IOs to that device.

Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas.h      |  3 ++
 drivers/scsi/megaraid/megaraid_sas_base.c | 61 ++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas_fp.c   |  6 ++-
 3 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 0f808d63580e..d7185aa21eb5 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2023,6 +2023,7 @@ union megasas_frame {
 struct MR_PRIV_DEVICE {
 	bool is_tm_capable;
 	bool tm_busy;
+	bool device_removed_by_fw;
 	atomic_t r1_ldio_hint;
 	u8 interface_type;
 	u8 task_abort_tmo;
@@ -2323,6 +2324,8 @@ struct megasas_instance {
 	struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
 	struct megasas_pd_list          local_pd_list[MEGASAS_MAX_PD];
 	u8 ld_ids[MEGASAS_MAX_LD_IDS];
+	u8 ld_ids_prev[MEGASAS_MAX_LD_IDS];
+	u8 ld_ids_from_raidmap[MEGASAS_MAX_LD_IDS];
 	s8 init_id;
 
 	u16 max_num_sge;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 7ab741f03b84..f3716f7e1d10 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -426,6 +426,12 @@ megasas_decode_evt(struct megasas_instance *instance)
 			(class_locale.members.locale),
 			format_class(class_locale.members.class),
 			evt_detail->description);
+
+	if (megasas_dbg_lvl & LD_PD_DEBUG)
+		dev_info(&instance->pdev->dev,
+			 "evt_detail.args.ld.target_id/index %d/%d\n",
+			 evt_detail->args.ld.target_id, evt_detail->args.ld.ld_index);
+
 }
 
 /*
@@ -1802,7 +1808,8 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	}
 
 	mr_device_priv_data = scmd->device->hostdata;
-	if (!mr_device_priv_data) {
+	if (!mr_device_priv_data ||
+	    mr_device_priv_data->device_removed_by_fw) {
 		scmd->result = DID_NO_CONNECT << 16;
 		scmd->scsi_done(scmd);
 		return 0;
@@ -3491,6 +3498,39 @@ megasas_complete_abort(struct megasas_instance *instance,
 	}
 }
 
+void
+megasas_set_sdev_removed_by_fw(struct megasas_instance *instance)
+{
+	struct scsi_device *sdev;
+	struct MR_PRIV_DEVICE *mr_device_priv_data;
+	uint channel, id, i;
+
+	for (i = 0; (i < MEGASAS_MAX_LD_IDS); i++) {
+		if (instance->ld_ids_prev[i] != 0xff &&
+		    instance->ld_ids_from_raidmap[i] == 0xff) {
+			channel = MEGASAS_MAX_PD_CHANNELS +
+					(instance->ld_ids_prev[i] /
+					MEGASAS_MAX_DEV_PER_CHANNEL);
+			id = (instance->ld_ids_prev[i] %
+				MEGASAS_MAX_DEV_PER_CHANNEL);
+
+			if (megasas_dbg_lvl & LD_PD_DEBUG)
+				dev_info(&instance->pdev->dev,
+					 "index %d old 0x%x new 0x%x from %s\n",
+					 i, instance->ld_ids_prev[i],
+					 instance->ld_ids_from_raidmap[i],
+					 __func__);
+
+			sdev = scsi_device_lookup(instance->host, channel, id, 0);
+			if (sdev) {
+				mr_device_priv_data = sdev->hostdata;
+				mr_device_priv_data->device_removed_by_fw = true;
+				scsi_device_put(sdev);
+			}
+		}
+	}
+}
+
 /**
  * megasas_complete_cmd -	Completes a command
  * @instance:			Adapter soft state
@@ -3656,6 +3696,10 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
 			megasas_sync_map_info(instance);
 			spin_unlock_irqrestore(instance->host->host_lock,
 					       flags);
+
+			if (instance->adapter_type >= INVADER_SERIES)
+				megasas_set_sdev_removed_by_fw(instance);
+
 			break;
 		}
 		if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
@@ -8764,8 +8808,10 @@ megasas_aen_polling(struct work_struct *work)
 	union megasas_evt_class_locale class_locale;
 	int event_type = 0;
 	u32 seq_num;
+	u16 ld_target_id;
 	int error;
 	u8  dcmd_ret = DCMD_SUCCESS;
+	struct scsi_device *sdev1;
 
 	if (!instance) {
 		printk(KERN_ERR "invalid instance!\n");
@@ -8788,12 +8834,23 @@ megasas_aen_polling(struct work_struct *work)
 			break;
 
 		case MR_EVT_LD_OFFLINE:
-		case MR_EVT_CFG_CLEARED:
 		case MR_EVT_LD_DELETED:
+			ld_target_id = instance->evt_detail->args.ld.target_id;
+			sdev1 = scsi_device_lookup(instance->host,
+						   MEGASAS_MAX_PD_CHANNELS +
+						   (ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL),
+						   (ld_target_id - MEGASAS_MAX_DEV_PER_CHANNEL),
+						   0);
+			if (sdev1)
+				megasas_remove_scsi_device(sdev1);
+
+			event_type = SCAN_VD_CHANNEL;
+			break;
 		case MR_EVT_LD_CREATED:
 			event_type = SCAN_VD_CHANNEL;
 			break;
 
+		case MR_EVT_CFG_CLEARED:
 		case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
 		case MR_EVT_FOREIGN_CFG_IMPORTED:
 		case MR_EVT_LD_STATE_CHANGE:
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index b6c08d620033..470b9797dd65 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -349,6 +349,10 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id)
 
 	num_lds = le16_to_cpu(drv_map->raidMap.ldCount);
 
+	memcpy(instance->ld_ids_prev,
+	       instance->ld_ids_from_raidmap,
+	       sizeof(instance->ld_ids_from_raidmap));
+	memset(instance->ld_ids_from_raidmap, 0xff, MEGASAS_MAX_LD_IDS);
 	/*Convert Raid capability values to CPU arch */
 	for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) {
 		ld = MR_TargetIdToLdGet(i, drv_map);
@@ -359,7 +363,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id)
 
 		raid = MR_LdRaidGet(ld, drv_map);
 		le32_to_cpus((u32 *)&raid->capability);
-
+		instance->ld_ids_from_raidmap[ld] = i;
 		num_lds--;
 	}
 
-- 
2.18.1


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

  parent reply	other threads:[~2021-03-17 19:10 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-17 19:08 [PATCH 0/5] megaraid_sas: Update driver version to 07.717.01.00-rc1 Chandrakanth Patil
2021-03-17 19:08 ` [PATCH 1/5] megaraid_sas: Send all non-RW IOs for TYPE_ENCLOSURE device through firmware Chandrakanth Patil
2021-03-17 19:08 ` [PATCH 2/5] megaraid_sas: Fix the resource leak in case of probe failure Chandrakanth Patil
2021-03-17 19:08 ` Chandrakanth Patil [this message]
2021-03-17 20:55   ` [PATCH 3/5] megaraid_sas: Early detection of VD deletion through RaidMap update kernel test robot
2021-03-17 22:53   ` kernel test robot
2021-03-17 22:53   ` [RFC PATCH] megaraid_sas: megasas_set_sdev_removed_by_fw can be static kernel test robot
2021-03-17 19:08 ` [PATCH 4/5] megaraid_sas: Handle missing interrupts while re-enabling IRQs Chandrakanth Patil
2021-03-17 19:08 ` [PATCH 5/5] megaraid_sas: Update driver version to 07.717.01.00-rc1 Chandrakanth Patil

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=20210317190824.3050-4-chandrakanth.patil@broadcom.com \
    --to=chandrakanth.patil@broadcom.com \
    --cc=anand.lodnoor@broadcom.com \
    --cc=kashyap.desai@broadcom.com \
    --cc=kiran-kumar.kasturi@broadcom.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sankar.patra@broadcom.com \
    --cc=sasikumar.pc@broadcom.com \
    --cc=shivasharan.srikanteshwara@broadcom.com \
    --cc=sumit.saxena@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox