Skip to contentSkip to conversation

scsi_dh: Move hardware handlers from dm to SCSI

PATCH In review Chandra Seetharaman 2 participants 15 messages Apr 16, 2008 – Apr 22, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover scsi_dh: Move hardware handlers from dm to SCSI

Hello,

This is the same set of patches that was posted on Apr 01:
http://marc.info/?l=dm-devel&m=120716401627550&w=2

Only change is that these patches are created on top of 2.6.25-rc8-mm2.

Testing has been done with the following storage devices:
- IBM DS4800 storage device for the lsi_rdac hardware handler
- HP storage device for the hp_sw hardware handler.
Thanks to Dave([email protected])
- EMC storage device for the EMC hardware handler.
Thanks to Arthur([email protected]) and Ronald([email protected])
In effect all hardware handlers are tested.

These patches need an ACK from Alasdair([email protected]).

Thanks,

chandra

#1 lore raw

PATCH 1/7 scsi_dh: add skeleton for SCSI Device Handlers

Subject: scsi_dh: add skeleton for SCSI Device Handlers

From: Chandra Seetharaman <[email protected]>

Add base support to the SCSI subsystem for SCSI device handlers.

---

 drivers/scsi/Kconfig                  |    2 	2 +	0 -	0 !
 drivers/scsi/Makefile                 |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/Kconfig   |   12 	12 +	0 -	0 !
 drivers/scsi/device_handler/Makefile  |    4 	4 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh.c |  151 	151 +	0 -	0 !
 drivers/scsi/scsi_error.c             |   11 	11 +	0 -	0 !
 drivers/scsi/scsi_lib.c               |    8 	8 +	0 -	0 !
 drivers/scsi/scsi_sysfs.c             |    1 	1 +	0 -	0 !
 include/scsi/scsi.h                   |    1 	1 +	0 -	0 !
 include/scsi/scsi_device.h            |   22 	22 +	0 -	0 !
 include/scsi/scsi_dh.h                |   58 	58 +	0 -	0 !
 11 files changed, 271 insertions(+)
drivers/scsi/Kconfig +2 -0
@@ -1761,4 +1761,6 @@ endif # SCSI_LOWLEVEL
 
 source "drivers/scsi/pcmcia/Kconfig"
 
+source "drivers/scsi/device_handler/Kconfig"
+
 endmenu
drivers/scsi/Makefile +1 -0
@@ -34,6 +34,7 @@ obj-$(CONFIG_SCSI_ISCSI_ATTRS)	+= scsi_t
 obj-$(CONFIG_SCSI_SAS_ATTRS)	+= scsi_transport_sas.o
 obj-$(CONFIG_SCSI_SAS_LIBSAS)	+= libsas/
 obj-$(CONFIG_SCSI_SRP_ATTRS)	+= scsi_transport_srp.o
+obj-$(CONFIG_SCSI_DH)		+= device_handler/
 
 obj-$(CONFIG_ISCSI_TCP) 	+= libiscsi.o	iscsi_tcp.o
 obj-$(CONFIG_INFINIBAND_ISER) 	+= libiscsi.o
drivers/scsi/device_handler/Kconfig new file +12 -0
@@ -0,0 +1,12 @@
+#
+# SCSI Device Handler configuration
+#
+
+menuconfig SCSI_DH
+	tristate "SCSI Device Handlers"
+	depends on SCSI
+	default n
+	help
+	  SCSI Device Handlers provide device specific support for
+	  devices utilized in multipath configurations. Say Y here to
+	  select support for specific hardware.
drivers/scsi/device_handler/Makefile new file +4 -0
@@ -0,0 +1,4 @@
+#
+# SCSI Device Handler
+#
+obj-$(CONFIG_SCSI_DH)		+= scsi_dh.o
drivers/scsi/scsi_error.c +11 -0
@@ -298,6 +298,7 @@ static inline void scsi_eh_prt_fail_stat
  */
 static int scsi_check_sense(struct scsi_cmnd *scmd)
 {
+	struct scsi_device *sdev = scmd->device;
 	struct scsi_sense_hdr sshdr;
 
 	if (! scsi_command_normalize_sense(scmd, &sshdr))
@@ -306,6 +307,16 @@ static int scsi_check_sense(struct scsi_
 	if (scsi_sense_is_deferred(&sshdr))
 		return NEEDS_RETRY;
 
+	if (sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh &&
+			sdev->scsi_dh_data->scsi_dh->check_sense) {
+		int rc;
+
+		rc = sdev->scsi_dh_data->scsi_dh->check_sense(sdev, &sshdr);
+		if (rc != SCSI_RETURN_NOT_HANDLED)
+			return rc;
+		/* handler does not care. Drop down to default handling */
+	}
+
 	/*
 	 * Previous logic looked for FILEMARK, EOM or ILI which are
 	 * mainly associated with tapes and returned SUCCESS.
include/scsi/scsi_device.h +22 -0
@@ -161,9 +161,29 @@ struct scsi_device {
 
 	struct execute_work	ew; /* used to get process context on put */
 
+	struct scsi_dh_data	*scsi_dh_data;
 	enum scsi_device_state sdev_state;
 	unsigned long		sdev_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
+
+struct scsi_device_handler {
+	/* Used by the infrastructure */
+	struct list_head list; /* list of scsi_device_handlers */
+	struct notifier_block nb;
+
+	/* Filled by the hardware handler */
+	struct module *module;
+	const char *name;
+	int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
+	int (*activate)(struct scsi_device *);
+	int (*prep_fn)(struct scsi_device *, struct request *);
+};
+
+struct scsi_dh_data {
+	struct scsi_device_handler *scsi_dh;
+	char buf[0];
+};
+
 #define	to_scsi_device(d)	\
 	container_of(d, struct scsi_device, sdev_gendev)
 #define	class_to_sdev(d)	\
@@ -229,7 +249,9 @@ extern struct scsi_device *__scsi_add_de
 		uint, uint, uint, void *hostdata);
 extern int scsi_add_device(struct Scsi_Host *host, uint channel,
 			   uint target, uint lun);
+extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh);
 extern void scsi_remove_device(struct scsi_device *);
+extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
 
 extern int scsi_device_get(struct scsi_device *);
 extern void scsi_device_put(struct scsi_device *);
drivers/scsi/device_handler/scsi_dh.c new file +151 -0

151 lines not on this page · raw message

include/scsi/scsi_dh.h new file +58 -0

58 lines not on this page · raw message

drivers/scsi/scsi_lib.c +8 -0
@@ -1156,6 +1156,14 @@ int scsi_setup_fs_cmnd(struct scsi_devic
 
 	if (ret != BLKPREP_OK)
 		return ret;
+
+	if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh
+			 && sdev->scsi_dh_data->scsi_dh->prep_fn)) {
+		ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req);
+		if (ret != BLKPREP_OK)
+			return ret;
+	}
+
 	/*
 	 * Filesystem requests must transfer data.
 	 */
include/scsi/scsi.h +1 -0
@@ -374,6 +374,7 @@ struct scsi_lun {
 #define SOFT_ERROR      0x2005
 #define ADD_TO_MLQUEUE  0x2006
 #define TIMEOUT_ERROR   0x2007
+#define SCSI_RETURN_NOT_HANDLED   0x2008
 
 /*
  * Midlevel queue return values.
drivers/scsi/scsi_sysfs.c +1 -0
@@ -406,6 +406,7 @@ struct bus_type scsi_bus_type = {
 	.resume		= scsi_bus_resume,
 	.remove		= scsi_bus_remove,
 };
+EXPORT_SYMBOL_GPL(scsi_bus_type);
 
 int scsi_sysfs_register(void)
 {
#2 lore raw

PATCH 2/7 scsi_dh: add lsi rdac device handler

In reply to Chandra Seetharaman

Subject: scsi_dh: add lsi rdac device handler

From: Chandra Seetharaman <[email protected]>

add LSI RDAC SCSI device handler

---

 drivers/scsi/device_handler/Kconfig        |    6 	6 +	0 -	0 !
 drivers/scsi/device_handler/Makefile       |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh_rdac.c |  678 	678 +	0 -	0 !
 3 files changed, 685 insertions(+)
drivers/scsi/device_handler/Kconfig +6 -0
Index: linux-2.6.25-rc8-mm2/drivers/scsi/device_handler/Kconfig
===================================================================
@@ -10,3 +10,9 @@ menuconfig SCSI_DH
 	  SCSI Device Handlers provide device specific support for
 	  devices utilized in multipath configurations. Say Y here to
 	  select support for specific hardware.
+
+config SCSI_DH_RDAC
+	tristate "LSI RDAC Device Handler"
+	depends on SCSI_DH
+	help
+	If you have a LSI RDAC select y. Otherwise, say N.
drivers/scsi/device_handler/scsi_dh_rdac.c new file +678 -0

678 lines not on this page · raw message

drivers/scsi/device_handler/Makefile +1 -0
Index: linux-2.6.25-rc8-mm2/drivers/scsi/device_handler/Makefile
===================================================================
@@ -2,3 +2,4 @@
 # SCSI Device Handler
 #
 obj-$(CONFIG_SCSI_DH)		+= scsi_dh.o
+obj-$(CONFIG_SCSI_DH_RDAC)	+= scsi_dh_rdac.o
#3 lore raw

PATCH 3/7 scsi_dh: add hp sw device handler

In reply to Chandra Seetharaman

Subject: scsi_dh: add hp sw device handler

From: Mike Christie <[email protected]>

This patch adds a very basic scsi device handler for older hp boxes which cannot be upgraded.

---

 drivers/scsi/device_handler/Kconfig         |    8 	8 +	0 -	0 !
 drivers/scsi/device_handler/Makefile        |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh_hp_sw.c |  201 	201 +	0 -	0 !
 3 files changed, 210 insertions(+)
drivers/scsi/device_handler/Kconfig +8 -0
Index: linux-2.6.25-rc8-mm2/drivers/scsi/device_handler/Kconfig
===================================================================
@@ -16,3 +16,11 @@ config SCSI_DH_RDAC
 	depends on SCSI_DH
 	help
 	If you have a LSI RDAC select y. Otherwise, say N.
+
+config SCSI_DH_HP_SW
+	tristate "HP/COMPAQ MSA Device Handler"
+	depends on SCSI_DH
+	help
+	If you have a HP/COMPAQ MSA device that requires START_STOP to
+	be sent to start it and cannot upgrade the firmware then select y.
+	Otherwise, say N.
drivers/scsi/device_handler/Makefile +1 -0
Index: linux-2.6.25-rc8-mm2/drivers/scsi/device_handler/Makefile
===================================================================
@@ -3,3 +3,4 @@
 #
 obj-$(CONFIG_SCSI_DH)		+= scsi_dh.o
 obj-$(CONFIG_SCSI_DH_RDAC)	+= scsi_dh_rdac.o
+obj-$(CONFIG_SCSI_DH_HP_SW)	+= scsi_dh_hp_sw.o
drivers/scsi/device_handler/scsi_dh_hp_sw.c new file +201 -0

201 lines not on this page · raw message

#4 lore raw

PATCH 4/7 scsi_dh: add EMC Clariion device handler

In reply to Chandra Seetharaman

Subject: scsi_dh: add EMC Clariion device handler

From: Chandra Seetharaman <[email protected]>

This adds support for EMC Clariions. This patch has the features that currently exists in mainline and advanced features from Ed's patches.

---

 drivers/scsi/device_handler/Kconfig       |    6 	6 +	0 -	0 !
 drivers/scsi/device_handler/Makefile      |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh_emc.c |  499 	499 +	0 -	0 !
 3 files changed, 506 insertions(+)
drivers/scsi/device_handler/Kconfig +6 -0
Index: linux-2.6.25-rc8-mm2/drivers/scsi/device_handler/Kconfig
===================================================================
@@ -24,3 +24,9 @@ config SCSI_DH_HP_SW
 	If you have a HP/COMPAQ MSA device that requires START_STOP to
 	be sent to start it and cannot upgrade the firmware then select y.
 	Otherwise, say N.
+
+config SCSI_DH_EMC
+	tristate "EMC CLARiiON Device Handler"
+	depends on SCSI_DH
+	help
+	If you have a EMC CLARiiON select y. Otherwise, say N.
drivers/scsi/device_handler/scsi_dh_emc.c new file +499 -0

499 lines not on this page · raw message

drivers/scsi/device_handler/Makefile +1 -0
Index: linux-2.6.25-rc8-mm2/drivers/scsi/device_handler/Makefile
===================================================================
@@ -4,3 +4,4 @@
 obj-$(CONFIG_SCSI_DH)		+= scsi_dh.o
 obj-$(CONFIG_SCSI_DH_RDAC)	+= scsi_dh_rdac.o
 obj-$(CONFIG_SCSI_DH_HP_SW)	+= scsi_dh_hp_sw.o
+obj-$(CONFIG_SCSI_DH_EMC)	+= scsi_dh_emc.o
#5 lore raw

Re: [PATCH 4/7] scsi_dh: add EMC Clariion device handler

drivers/scsi/device_handler/scsi_dh_emc.c line 323

Quoted 11 lines · Chandra Seetharaman
drivers/scsi/device_handler/scsi_dh_emc.c new file +11 -0
+
+static int send_cmd(struct scsi_device *sdev, int cmd)
+{
+	struct request *rq = get_req(sdev, cmd);
+
+	if (!rq)
+		return SCSI_DH_RES_TEMP_UNAVAIL;
+
+	return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
+}
+

My only concerns are:

1. EMC and HP need to send a command to every device to transition them. Because we do blk_execute_rq from the dm multipath workqueue we can now only failover/failback for a couple devices at a time.

I am not sure if this is a big deal, because this the error handler path so it is going to be slower than the normal path. But it seems like customers are really picky about failover times and want them as fast as possible. If they have a couple hundred devices doing a couple at a time might be something that users see as a regression from the old code. I am not sure though. I just do not want the bugzillas when they come to work :)

2. EMC guys did you test the short vs long tress pass stuff? Do we need to add some code to handle the case where we send a short one, but we needed to send a long one. Is there some sense error or some inquiry data we can base this off of?

#6 lore raw

Re: [dm-devel] [PATCH 4/7] scsi_dh: add EMC Clariion device handler

Quoted 15 lines · Mike Christie

drivers/scsi/device_handler/scsi_dh_emc.c line 323

Quoted 11 lines · Chandra Seetharaman
drivers/scsi/device_handler/scsi_dh_emc.c new file +11 -0
+
+static int send_cmd(struct scsi_device *sdev, int cmd)
+{
+	struct request *rq = get_req(sdev, cmd);
+
+	if (!rq)
+		return SCSI_DH_RES_TEMP_UNAVAIL;
+
+	return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
+}
+

My only concerns are:

Quoted 7 lines

1. EMC and HP need to send a command to every device to transition them. Because we do blk_execute_rq from the dm multipath workqueue we can now only failover/failback for a couple devices at a time.

I am not sure if this is a big deal, because this the error handler path so it is going to be slower than the normal path. But it seems like

Yes. But...

pg_init() due to failover/failback will be sent only when I/O is sent/resent to a multipath device, isn't it ? and we don't expect I/Os to be sent to all the devices at the same time (all the time), do we ?

So, as you pointed, is it a big deal ? :)

BTW, As you know, it was originally coded that way(patchset posted on Jan 23, 2008) and later changed as per James comments (through you) that the code was overusing blk_execute_rq_nowait().

Quoted 15 lines

customers are really picky about failover times and want them as fast as possible. If they have a couple hundred devices doing a couple at a time might be something that users see as a regression from the old code. I am not sure though. I just do not want the bugzillas when they come to work :)

2. EMC guys did you test the short vs long tress pass stuff? Do we need to add some code to handle the case where we send a short one, but we needed to send a long one. Is there some sense error or some inquiry data we can base this off of?

--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel

#7 lore raw

Re: [PATCH 4/7] scsi_dh: add EMC Clariion device handler

Quoted 18 lines · Chandra Seetharaman
Quoted 16 lines · Mike Christie

drivers/scsi/device_handler/scsi_dh_emc.c line 323

Quoted 11 lines · Chandra Seetharaman
drivers/scsi/device_handler/scsi_dh_emc.c new file +11 -0
+
+static int send_cmd(struct scsi_device *sdev, int cmd)
+{
+	struct request *rq = get_req(sdev, cmd);
+
+	if (!rq)
+		return SCSI_DH_RES_TEMP_UNAVAIL;
+
+	return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
+}
+

My only concerns are:

1. EMC and HP need to send a command to every device to transition them. Because we do blk_execute_rq from the dm multipath workqueue we can now only failover/failback for a couple devices at a time.

Quoted 8 lines
Quoted 1 line

I am not sure if this is a big deal, because this the error handler path so it is going to be slower than the normal path. But it seems like

Yes. But...

pg_init() due to failover/failback will be sent only when I/O is sent/resent to a multipath device, isn't it ? and we don't expect I/Os to be sent to all the devices at the same time (all the time), do we ?

I am not sure what you mean by all the time, because I am talking about failover times above. And for failover I think I said yes in the previous mail. For EMC we are currently sending failover commands to all the devices at the same time, because EMC does not do the controller failover RDAC does.

Quoted 2 lines

So, as you pointed, is it a big deal ? :)

In the previous mail I specifically said users might care, because they are picky about failover times, so the answer is to your question is what I said before, maybe :) I said I am not sure, because I do not have any numbers for the failover times.

Quoted 4 lines

BTW, As you know, it was originally coded that way(patchset posted on Jan 23, 2008) and later changed as per James comments (through you) that the code was overusing blk_execute_rq_nowait().

Yes, I know, and as you know I did not agree with James. The reason I bring it up again is that Ed is not doing dm-multipath stuff, so EMC does not have a good reviewer right now, and I want to make sure these issues are raised on the list during the review so we can all discuss them together.

If James thinks it is a big enough problem he can offer some of this alternatives. If not then he will merge it and we can see if people even notice and handle it later. I just want to make sure we all know what is going on, because Alasdair is not a scsi guy. James does not know all the fun details of every box. And the EMC guys are not up to speed on linux. I am just worried we are going to get a bad review.

#8 lore raw

Re: [dm-devel] [PATCH 4/7] scsi_dh: add EMC Clariion device handler

Quoted 24 lines · Mike Christie
Quoted 23 lines · Chandra Seetharaman
Quoted 21 lines · Mike Christie

drivers/scsi/device_handler/scsi_dh_emc.c line 323

Quoted 11 lines · Chandra Seetharaman
drivers/scsi/device_handler/scsi_dh_emc.c new file +11 -0
+
+static int send_cmd(struct scsi_device *sdev, int cmd)
+{
+	struct request *rq = get_req(sdev, cmd);
+
+	if (!rq)
+		return SCSI_DH_RES_TEMP_UNAVAIL;
+
+	return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
+}
+

My only concerns are:

1. EMC and HP need to send a command to every device to transition them. Because we do blk_execute_rq from the dm multipath workqueue we can now only failover/failback for a couple devices at a time.

I am not sure if this is a big deal, because this the error handler path so it is going to be slower than the normal path. But it seems like

Quoted 8 lines
Quoted 6 lines

Yes. But...

pg_init() due to failover/failback will be sent only when I/O is sent/resent to a multipath device, isn't it ? and we don't expect I/Os to be sent to all the devices at the same time (all the time), do we ?

I am not sure what you mean by all the time, because I am talking about

What I meant was that we do not expect I/Os to be sent to all the devices at all the times (pg_init will be sent only when I/Os fails on a path, right ?).

Sorry for not being clear.

Quoted 4 lines

failover times above. And for failover I think I said yes in the previous mail. For EMC we are currently sending failover commands to all the devices at the same time, because EMC does not do the controller failover RDAC does.

RDAC doesn't do controller failover. It also does per lun failover.

Quoted 6 lines
Quoted 3 lines

So, as you pointed, is it a big deal ? :)

In the previous mail I specifically said users might care, because they
are picky about failover times, real 3m39.728s

user 0m4.135s
sys 0m14.536s

Quoted 3 lines

so the answer is to your question is
what I said before, maybe :) I said I am not sure, because I do not have any numbers for the failover times.

Since RDAC also does the failover per device (as is the case with EMC), I ran tests on about 49 luns. I ran disktest on all the disks at the same time and disabled/enabled the port to the preferred path to generate failover and failback.

Let me know what do you think.

Here are the results:
Tests run in an idle system. With 49 luns and the following script:
******************************************************
for i in ls -1 /dev/mapper/mpath*
do

	disktest $i -L 4000 -t 100 -P X &
	sleep 1

done

wait
******************************************************
Simple Run:

with patchset: 2.6.25-mm1:

real    3m30.122s	real    3m29.746s
user    0m4.069s	user    0m4.099s
sys     0m14.876s	sys     0m14.535s

-----------------------------------------------

Failover Run:

with patchset: 2.6.25-mm1:

real    5m18.875s	real    5m31.741s
user    0m4.069s	user    0m3.883s
sys     0m14.838s	sys     0m13.822s

-----------------------------------------------

Failback Run:

with patchset: 2.6.25-mm1*:

real    4m50.313s	real    3m39.728s
user    0m4.051s	user    0m4.135s
sys     0m14.809s	sys     0m14.536s

* In 2.6.25-mm1 not all paths failed back for I/Os to be completed due to the delay/failures during probing (which is being handled in the new patchset)
-----------------------------------------------

Quoted 22 lines
Quoted 5 lines

BTW, As you know, it was originally coded that way(patchset posted on Jan 23, 2008) and later changed as per James comments (through you) that the code was overusing blk_execute_rq_nowait().

Yes, I know, and as you know I did not agree with James. The reason I bring it up again is that Ed is not doing dm-multipath stuff, so EMC does not have a good reviewer right now, and I want to make sure these issues are raised on the list during the review so we can all discuss them together.

If James thinks it is a big enough problem he can offer some of this alternatives. If not then he will merge it and we can see if people even notice and handle it later. I just want to make sure we all know what is going on, because Alasdair is not a scsi guy. James does not know all the fun details of every box. And the EMC guys are not up to speed on linux. I am just worried we are going to get a bad review. --
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

Re: [PATCH 4/7] scsi_dh: add EMC Clariion device handler

Quoted 26 lines · Chandra Seetharaman
Quoted 25 lines · Mike Christie
Quoted 24 lines · Chandra Seetharaman
Quoted 14 lines · Mike Christie

drivers/scsi/device_handler/scsi_dh_emc.c line 323

Quoted 11 lines · Chandra Seetharaman
drivers/scsi/device_handler/scsi_dh_emc.c new file +11 -0
+
+static int send_cmd(struct scsi_device *sdev, int cmd)
+{
+	struct request *rq = get_req(sdev, cmd);
+
+	if (!rq)
+		return SCSI_DH_RES_TEMP_UNAVAIL;
+
+	return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
+}
+

My only concerns are:

Quoted 3 lines

1. EMC and HP need to send a command to every device to transition them. Because we do blk_execute_rq from the dm multipath workqueue we can now only failover/failback for a couple devices at a time.

I am not sure if this is a big deal, because this the error handler path so it is going to be slower than the normal path. But it seems like

Yes. But...

pg_init() due to failover/failback will be sent only when I/O is sent/resent to a multipath device, isn't it ? and we don't expect I/Os to be sent to all the devices at the same time (all the time), do we ?

Quoted 8 lines
Quoted 1 line

I am not sure what you mean by all the time, because I am talking about

What I meant was that we do not expect I/Os to be sent to all the devices at all the times (pg_init will be sent only when I/Os fails on a path, right ?).

Sorry for not being clear.

No problem.

Quoted 4 lines
Quoted 1 line

failover times above. And for failover I think I said yes in the previous mail. For EMC we are currently sending failover commands to all the devices at the same time, because EMC does not do the controller failover RDAC does.

RDAC doesn't do controller failover. It also does per lun failover.

Oh yeah, I forgot.

Quoted 10 lines
Quoted 3 lines
Quoted 2 lines

So, as you pointed, is it a big deal ? :)

In the previous mail I specifically said users might care, because they are picky about failover times, real 3m39.728s

user 0m4.135s
sys 0m14.536s

Quoted 1 line

so the answer is to your question is what I said before, maybe :) I said I am not sure, because I do not have any numbers for the failover times.

Since RDAC also does the failover per device (as is the case with EMC), I ran tests on about 49 luns. I ran disktest on all the disks at the

Thanks.

Quoted 18 lines

same time and disabled/enabled the port to the preferred path to generate failover and failback.

Let me know what do you think.

Here are the results:
Tests run in an idle system. With 49 luns and the following script:
******************************************************
for i in ls -1 /dev/mapper/mpath*
do

	disktest $i -L 4000 -t 100 -P X &
	sleep 1

done

wait
******************************************************
Simple Run:

Quoted 5 lines

with patchset: 2.6.25-mm1:

real    3m30.122s	real    3m29.746s
user    0m4.069s	user    0m4.099s
sys     0m14.876s	sys     0m14.535s

-----------------------------------------------

Is this just a boot up test or a test just running IO but no failback/failover?

Quoted 7 lines

Failover Run:

with patchset: 2.6.25-mm1:

real    5m18.875s	real    5m31.741s
user    0m4.069s	user    0m3.883s
sys     0m14.838s	sys     0m13.822s

Ehh, I have no idea if this is good or bad. Does it mean it is talking 13 more seconds to complete?

Have you seen the type of thread on dm-devel or the iscsi list where people are concerned with getting the time the failure is detected to the time IO is running on a new path down from something like 10 to 5 seconds. One time the iscsi driver did not implement time2wait correctly and by fixing it we shaved only 2 seconds off and users were very happy with the extra 2 seconds. We added the nop timer stuff so we could get faster failovers. We have the fast io fail tmo so we can speed up the process even more. Shaving off a second here or there is really nitpicky and if I were you I would give me the middle finger :) It just seems like people expect better performance from this type of error.

If my comment is too nitpicky then I am fine with ignoring this for now. We just have to fix the emc short/long tress pass code then. I added another EMC guy to the thread so he can ping the other EMC devs to get going (I had sent them questions on how to handle it and have not got a response).

#10 lore raw

Re: [PATCH 4/7] scsi_dh: add EMC Clariion device handler

Quoted 87 lines · Mike Christie
Quoted 26 lines · Chandra Seetharaman
Quoted 25 lines · Mike Christie
Quoted 24 lines · Chandra Seetharaman
Quoted 14 lines · Mike Christie

drivers/scsi/device_handler/scsi_dh_emc.c line 323

Quoted 11 lines · Chandra Seetharaman
drivers/scsi/device_handler/scsi_dh_emc.c new file +11 -0
+
+static int send_cmd(struct scsi_device *sdev, int cmd)
+{
+    struct request *rq = get_req(sdev, cmd);
+
+    if (!rq)
+        return SCSI_DH_RES_TEMP_UNAVAIL;
+
+    return blk_execute_rq(sdev->request_queue, NULL, rq, 1);
+}
+

My only concerns are:

Quoted 3 lines

1. EMC and HP need to send a command to every device to transition them. Because we do blk_execute_rq from the dm multipath workqueue we can now only failover/failback for a couple devices at a time.

I am not sure if this is a big deal, because this the error handler path so it is going to be slower than the normal path. But it seems like

Yes. But...

pg_init() due to failover/failback will be sent only when I/O is sent/resent to a multipath device, isn't it ? and we don't expect I/Os to be sent to all the devices at the same time (all the time), do we ?

Quoted 8 lines
Quoted 1 line

I am not sure what you mean by all the time, because I am talking about

What I meant was that we do not expect I/Os to be sent to all the devices at all the times (pg_init will be sent only when I/Os fails on a path, right ?).

Sorry for not being clear.

No problem.

Quoted 4 lines
Quoted 1 line

failover times above. And for failover I think I said yes in the previous mail. For EMC we are currently sending failover commands to all the devices at the same time, because EMC does not do the controller failover RDAC does.

RDAC doesn't do controller failover. It also does per lun failover.

Oh yeah, I forgot.

Quoted 10 lines
Quoted 3 lines
Quoted 2 lines

So, as you pointed, is it a big deal ? :)

In the previous mail I specifically said users might care, because they are picky about failover times, real 3m39.728s

user 0m4.135s
sys 0m14.536s

Quoted 1 line

so the answer is to your question is what I said before, maybe :) I said I am not sure, because I do not have any numbers for the failover times.

Since RDAC also does the failover per device (as is the case with EMC), I ran tests on about 49 luns. I ran disktest on all the disks at the

Thanks.

Quoted 18 lines

same time and disabled/enabled the port to the preferred path to generate failover and failback.

Let me know what do you think.

Here are the results:
Tests run in an idle system. With 49 luns and the following script:
******************************************************
for i in ls -1 /dev/mapper/mpath*
do

    disktest $i -L 4000 -t 100 -P X &
    sleep 1

done

wait
******************************************************
Simple Run:

Quoted 5 lines

with patchset: 2.6.25-mm1:

real    3m30.122s    real    3m29.746s
user    0m4.069s    user    0m4.099s
sys     0m14.876s    sys     0m14.535s

-----------------------------------------------

Is this just a boot up test or a test just running IO but no failback/failover?

Quoted 1 line
Quoted 9 lines
Quoted 6 lines

Failover Run:

with patchset: 2.6.25-mm1:

real    5m18.875s    real    5m31.741s
user    0m4.069s    user    0m3.883s
sys     0m14.838s    sys     0m13.822s

Ehh, I have no idea if this is good or bad. Does it mean it is talking 13 more seconds to complete?

Oops, I read that wrong. With the new code it is 13 seconds faster. I have no concerns about that.

#11 lore raw

Re: [dm-devel] [PATCH 4/7] scsi_dh: add EMC Clariion device handler

In reply to Mike Christie

On Tue, 2008-04-22 at 16:47 -0500, Mike Christie wrote:
<snip>

Quoted 4 lines
Quoted 4 lines

wait
******************************************************
Simple Run:

Quoted 8 lines
Quoted 5 lines

with patchset: 2.6.25-mm1:

real    3m30.122s	real    3m29.746s
user    0m4.069s	user    0m4.099s
sys     0m14.876s	sys     0m14.535s

-----------------------------------------------

Is this just a boot up test or a test just running IO but no failback/failover?

Test running IO but no failover/failback.

Quoted 11 lines
Quoted 8 lines

Failover Run:

with patchset: 2.6.25-mm1:

real    5m18.875s	real    5m31.741s
user    0m4.069s	user    0m3.883s
sys     0m14.838s	sys     0m13.822s

Ehh, I have no idea if this is good or bad. Does it mean it is talking 13 more seconds to complete?

It is taking 13 more seconds without the serialization :) (i.e the old code).

Quoted 4 lines

Have you seen the type of thread on dm-devel or the iscsi list where people are concerned with getting the time the failure is detected to the time IO is running on a new path down from something like 10 to 5

I totally agree with you that shaving a second here and a second there has lot of value to the customers.

Quoted 7 lines

seconds. One time the iscsi driver did not implement time2wait correctly and by fixing it we shaved only 2 seconds off and users were very happy with the extra 2 seconds. We added the nop timer stuff so we could get faster failovers. We have the fast io fail tmo so we can speed up the process even more. Shaving off a second here or there is really nitpicky and if I were you I would give me the middle finger :) It just seems

But, I wouldn't :)

Quoted 8 lines

like people expect better performance from this type of error.

If my comment is too nitpicky then I am fine with ignoring this for now. We just have to fix the emc short/long tress pass code then. I added another EMC guy to the thread so he can ping the other EMC devs to get going (I had sent them questions on how to handle it and have not got a response).

#12 lore raw

PATCH 5/7 scsi_dh: Use SCSI device handler in dm-multipath

In reply to Chandra Seetharaman

Subject: scsi_dh: Use SCSI device handler in dm-multipath

From: Chandra Seetharaman <[email protected]>

This patch converts dm-mpath to scsi hw handlers. It does not add any new functionality and old behaviors and userspace tools work as is except we use the safe clariion default instead of using the userspace setting.

---
drivers/md/Kconfig | 1 1 + 0 - 0 !
drivers/md/dm-mpath.c | 226 111 + 115 - 0 !

 2 files changed, 112 insertions(+), 115 deletions(-)
drivers/md/dm-mpath.c +111 -115
Index: linux-2.6.25-rc8-mm2/drivers/md/dm-mpath.c
===================================================================
@@ -7,7 +7,6 @@
 
 #include "dm.h"
 #include "dm-path-selector.h"
-#include "dm-hw-handler.h"
 #include "dm-bio-list.h"
 #include "dm-bio-record.h"
 #include "dm-uevent.h"
@@ -20,6 +19,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/workqueue.h>
+#include <scsi/scsi_dh.h>
 #include <asm/atomic.h>
 
 #define DM_MSG_PREFIX "multipath"
@@ -61,9 +61,14 @@ struct multipath {
 
 	spinlock_t lock;
 
-	struct hw_handler hw_handler;
 	unsigned nr_priority_groups;
 	struct list_head priority_groups;
+
+	/* Fields used by hardware handler usage */
+	char *hw_handler_name;
+	struct work_struct activate_passive_path;
+	struct dm_path *path_to_activate;
+
 	unsigned pg_init_required;	/* pg_init needs calling? */
 	unsigned pg_init_in_progress;	/* Only one pg_init allowed at once */
 
@@ -106,9 +111,13 @@ typedef int (*action_fn) (struct pgpath 
 
 static struct kmem_cache *_mpio_cache;
 
-static struct workqueue_struct *kmultipathd;
+static struct workqueue_struct *kmultipathd, *hw_handlerd;
 static void process_queued_ios(struct work_struct *work);
 static void trigger_event(struct work_struct *work);
+static void activate_passive_path(struct work_struct *work);
+static void bypass_pg(struct multipath *m, struct priority_group *pg,
+		      int bypassed);
+static int fail_path(struct pgpath *pgpath);
 
 
 /*-----------------------------------------------
@@ -178,6 +187,7 @@ static struct multipath *alloc_multipath
 		m->queue_io = 1;
 		INIT_WORK(&m->process_queued_ios, process_queued_ios);
 		INIT_WORK(&m->trigger_event, trigger_event);
+		INIT_WORK(&m->activate_passive_path, activate_passive_path);
 		m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
 		if (!m->mpio_pool) {
 			kfree(m);
@@ -193,18 +203,13 @@ static struct multipath *alloc_multipath
 static void free_multipath(struct multipath *m)
 {
 	struct priority_group *pg, *tmp;
-	struct hw_handler *hwh = &m->hw_handler;
 
 	list_for_each_entry_safe(pg, tmp, &m->priority_groups, list) {
 		list_del(&pg->list);
 		free_priority_group(pg, m->ti);
 	}
 
-	if (hwh->type) {
-		hwh->type->destroy(hwh);
-		dm_put_hw_handler(hwh->type);
-	}
-
+	kfree(m->hw_handler_name);
 	mempool_destroy(m->mpio_pool);
 	kfree(m);
 }
@@ -216,12 +221,10 @@ static void free_multipath(struct multip
 
 static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
 {
-	struct hw_handler *hwh = &m->hw_handler;
-
 	m->current_pg = pgpath->pg;
 
 	/* Must we initialise the PG first, and queue I/O till it's ready? */
-	if (hwh->type && hwh->type->pg_init) {
+	if (m->hw_handler_name) {
 		m->pg_init_required = 1;
 		m->queue_io = 1;
 	} else {
@@ -405,11 +408,86 @@ static void dispatch_queued_ios(struct m
 	}
 }
 
+static void pg_init_done(struct dm_path *path, int errors)
+{
+	struct pgpath *pgpath = path_to_pgpath(path);
+	struct priority_group *pg = pgpath->pg;
+	struct multipath *m = pg->m;
+	unsigned long flags;
+
+	/* device or driver problems */
+	switch (errors) {
+	case SCSI_DH_OK:
+		break;
+	case SCSI_DH_NOSYS:
+		if (!m->hw_handler_name) {
+			errors = 0;
+			break;
+		}
+		DMERR("Cannot failover device because hw-%s may not be "
+		      "loaded.", m->hw_handler_name);
+		/*
+		 * Fail path for now, so we do not ping poing
+		 */
+		fail_path(pgpath);
+		break;
+	case SCSI_DH_DEV_TEMP_BUSY:
+		/*
+		 * Probably doing something like FW upgrade on the
+		 * controller so try the other pg.
+		 */
+		bypass_pg(m, pg, 1);
+		break;
+	/* TODO: For SCSI_DH_RETRY we should wait a couple seconds */
+	case SCSI_DH_RETRY:
+	case SCSI_DH_IMM_RETRY:
+	case SCSI_DH_RES_TEMP_UNAVAIL:
+		break;
+	default:
+		/*
+		 * We probably do not want to fail the path for a device
+		 * error, but this is what the old dm did. In future
+		 * patches we can do more advanced handling.
+		 */
+		fail_path(pgpath);
+	}
+
+	spin_lock_irqsave(&m->lock, flags);
+	if (errors) {
+		DMERR("Could not failover device. Error %d.", errors);
+		m->current_pgpath = NULL;
+		m->current_pg = NULL;
+	} else if (!m->pg_init_required) {
+		m->queue_io = 0;
+		pg->bypassed = 0;
+	}
+
+	m->pg_init_in_progress = 0;
+	queue_work(kmultipathd, &m->process_queued_ios);
+	spin_unlock_irqrestore(&m->lock, flags);
+}
+
+static void activate_passive_path(struct work_struct *work)
+{
+	int ret;
+	struct multipath *m =
+		container_of(work, struct multipath, activate_passive_path);
+	struct dm_path *path = m->path_to_activate;
+
+	ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev));
+	pg_init_done(path, ret);
+}
+
+static void pg_init(struct multipath *m, struct dm_path *path)
+{
+	m->path_to_activate = path;
+	queue_work(hw_handlerd, &m->activate_passive_path);
+}
+
 static void process_queued_ios(struct work_struct *work)
 {
 	struct multipath *m =
 		container_of(work, struct multipath, process_queued_ios);
-	struct hw_handler *hwh = &m->hw_handler;
 	struct pgpath *pgpath = NULL;
 	unsigned init_required = 0, must_queue = 1;
 	unsigned long flags;
@@ -439,7 +517,7 @@ out:
 	spin_unlock_irqrestore(&m->lock, flags);
 
 	if (init_required)
-		hwh->type->pg_init(hwh, pgpath->pg->bypassed, &pgpath->path);
+		pg_init(m, &pgpath->path);
 
 	if (!must_queue)
 		dispatch_queued_ios(m);
@@ -652,10 +730,9 @@ static struct priority_group *parse_prio
 
 static int parse_hw_handler(struct arg_set *as, struct multipath *m)
 {
+	struct dm_target *ti = m->ti;
 	int r;
-	struct hw_handler_type *hwht;
 	unsigned hw_argc;
-	struct dm_target *ti = m->ti;
 
 	static struct param _params[] = {
 		{0, 1024, "invalid number of hardware handler args"},
@@ -668,25 +745,9 @@ static int parse_hw_handler(struct arg_s
 	if (!hw_argc)
 		return 0;
 
-	hwht = dm_get_hw_handler(shift(as));
-	if (!hwht) {
-		ti->error = "unknown hardware handler type";
-		return -EINVAL;
-	}
-
-	m->hw_handler.md = dm_table_get_md(ti->table);
-	dm_put(m->hw_handler.md);
-
-	r = hwht->create(&m->hw_handler, hw_argc - 1, as->argv);
-	if (r) {
-		dm_put_hw_handler(hwht);
-		ti->error = "hardware handler constructor failed";
-		return r;
-	}
-
-	m->hw_handler.type = hwht;
+	m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL);
+	request_module("scsi_dh_%s", m->hw_handler_name);
 	consume(as, hw_argc - 1);
-
 	return 0;
 }
 
@@ -808,6 +869,7 @@ static void multipath_dtr(struct dm_targ
 {
 	struct multipath *m = (struct multipath *) ti->private;
 
+	flush_workqueue(hw_handlerd);
 	flush_workqueue(kmultipathd);
 	free_multipath(m);
 }
@@ -1006,71 +1068,11 @@ static int bypass_pg_num(struct multipat
 }
 
 /*
- * Should we retry pg_init immediately?
- */
-static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
-{
-	unsigned long flags;
-	int limit_reached = 0;
-
-	spin_lock_irqsave(&m->lock, flags);
-
-	if (m->pg_init_count <= m->pg_init_retries)
-		m->pg_init_required = 1;
-	else
-		limit_reached = 1;
-
-	spin_unlock_irqrestore(&m->lock, flags);
-
-	return limit_reached;
-}
-
-/*
- * pg_init must call this when it has completed its initialisation
- */
-void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
-{
-	struct pgpath *pgpath = path_to_pgpath(path);
-	struct priority_group *pg = pgpath->pg;
-	struct multipath *m = pg->m;
-	unsigned long flags;
-
-	/*
-	 * If requested, retry pg_init until maximum number of retries exceeded.
-	 * If retry not requested and PG already bypassed, always fail the path.
-	 */
-	if (err_flags & MP_RETRY) {
-		if (pg_init_limit_reached(m, pgpath))
-			err_flags |= MP_FAIL_PATH;
-	} else if (err_flags && pg->bypassed)
-		err_flags |= MP_FAIL_PATH;
-
-	if (err_flags & MP_FAIL_PATH)
-		fail_path(pgpath);
-
-	if (err_flags & MP_BYPASS_PG)
-		bypass_pg(m, pg, 1);
-
-	spin_lock_irqsave(&m->lock, flags);
-	if (err_flags & ~MP_RETRY) {
-		m->current_pgpath = NULL;
-		m->current_pg = NULL;
-	} else if (!m->pg_init_required)
-		m->queue_io = 0;
-
-	m->pg_init_in_progress = 0;
-	queue_work(kmultipathd, &m->process_queued_ios);
-	spin_unlock_irqrestore(&m->lock, flags);
-}
-
-/*
  * end_io handling
  */
 static int do_end_io(struct multipath *m, struct bio *bio,
 		     int error, struct dm_mpath_io *mpio)
 {
-	struct hw_handler *hwh = &m->hw_handler;
-	unsigned err_flags = MP_FAIL_PATH;	/* Default behavior */
 	unsigned long flags;
 
 	if (!error)
@@ -1097,19 +1099,8 @@ static int do_end_io(struct multipath *m
 	}
 	spin_unlock_irqrestore(&m->lock, flags);
 
-	if (hwh->type && hwh->type->error)
-		err_flags = hwh->type->error(hwh, bio);
-
-	if (mpio->pgpath) {
-		if (err_flags & MP_FAIL_PATH)
-			fail_path(mpio->pgpath);
-
-		if (err_flags & MP_BYPASS_PG)
-			bypass_pg(m, mpio->pgpath->pg, 1);
-	}
-
-	if (err_flags & MP_ERROR_IO)
-		return -EIO;
+	if (mpio->pgpath)
+		fail_path(mpio->pgpath);
 
       requeue:
 	dm_bio_restore(&mpio->details, bio);
@@ -1194,7 +1185,6 @@ static int multipath_status(struct dm_ta
 	int sz = 0;
 	unsigned long flags;
 	struct multipath *m = (struct multipath *) ti->private;
-	struct hw_handler *hwh = &m->hw_handler;
 	struct priority_group *pg;
 	struct pgpath *p;
 	unsigned pg_num;
@@ -1214,12 +1204,10 @@ static int multipath_status(struct dm_ta
 			DMEMIT("pg_init_retries %u ", m->pg_init_retries);
 	}
 
-	if (hwh->type && hwh->type->status)
-		sz += hwh->type->status(hwh, type, result + sz, maxlen - sz);
-	else if (!hwh->type || type == STATUSTYPE_INFO)
-		DMEMIT("0 ");
+	if (m->hw_handler_name)
+		DMEMIT("1 %s ", m->hw_handler_name);
 	else
-		DMEMIT("1 %s ", hwh->type->name);
+		DMEMIT("0 ");
 
 	DMEMIT("%u ", m->nr_priority_groups);
 
@@ -1422,6 +1410,15 @@ static int __init dm_multipath_init(void
 		return -ENOMEM;
 	}
 
+	hw_handlerd = create_workqueue("khwhandlerd");
+	if (!hw_handlerd) {
+		DMERR("failed to create workqueue khwhandlerd");
+		destroy_workqueue(kmultipathd);
+		dm_unregister_target(&multipath_target);
+		kmem_cache_destroy(_mpio_cache);
+		return -ENOMEM;
+	}
+
 	DMINFO("version %u.%u.%u loaded",
 	       multipath_target.version[0], multipath_target.version[1],
 	       multipath_target.version[2]);
@@ -1433,6 +1430,7 @@ static void __exit dm_multipath_exit(voi
 {
 	int r;
 
+	destroy_workqueue(hw_handlerd);
 	destroy_workqueue(kmultipathd);
 
 	r = dm_unregister_target(&multipath_target);
@@ -1441,8 +1439,6 @@ static void __exit dm_multipath_exit(voi
 	kmem_cache_destroy(_mpio_cache);
 }
 
-EXPORT_SYMBOL_GPL(dm_pg_init_complete);
-
 module_init(dm_multipath_init);
 module_exit(dm_multipath_exit);
 
drivers/md/Kconfig +1 -0
Index: linux-2.6.25-rc8-mm2/drivers/md/Kconfig
===================================================================
@@ -252,6 +252,7 @@ config DM_ZERO
 config DM_MULTIPATH
 	tristate "Multipath target"
 	depends on BLK_DEV_DM
+	select SCSI_DH
 	---help---
 	  Allow volume managers to support multipath hardware.
 
#13 lore raw

PATCH 6/7 scsi_dh: Remove hardware handlers from dm

In reply to Chandra Seetharaman

Subject: scsi_dh: Remove hardware handlers from dm

From: Chandra Seetharaman <[email protected]>

This patch removes the 3 hardware handlers that currently exist under dm as they are moved to SCSI layer in the previous patches.

---

 drivers/md/Kconfig          |   18 	0 +	18 -	0 !
 drivers/md/Makefile         |    3 	0 +	3 -	0 !
 drivers/md/dm-emc.c         |  347 	0 +	347 -	0 !
 drivers/md/dm-mpath-hp-sw.c |  248 	0 +	248 -	0 !
 drivers/md/dm-mpath-rdac.c  |  701 	0 +	701 -	0 !
 5 files changed, 1317 deletions(-)
drivers/md/Kconfig +0 -18
Index: linux-2.6.25-rc8-mm2/drivers/md/Kconfig
===================================================================
@@ -256,24 +256,6 @@ config DM_MULTIPATH
 	---help---
 	  Allow volume managers to support multipath hardware.
 
-config DM_MULTIPATH_EMC
-	tristate "EMC CX/AX multipath support"
-	depends on DM_MULTIPATH && BLK_DEV_DM
-	---help---
-	  Multipath support for EMC CX/AX series hardware.
-
-config DM_MULTIPATH_RDAC
-	tristate "LSI/Engenio RDAC multipath support (EXPERIMENTAL)"
-	depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL
-	---help---
-	  Multipath support for LSI/Engenio RDAC.
-
-config DM_MULTIPATH_HP
-        tristate "HP MSA multipath support (EXPERIMENTAL)"
-        depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL
-        ---help---
-          Multipath support for HP MSA (Active/Passive) series hardware.
-
 config DM_DELAY
 	tristate "I/O delaying target (EXPERIMENTAL)"
 	depends on BLK_DEV_DM && EXPERIMENTAL
drivers/md/Makefile +0 -3
Index: linux-2.6.25-rc8-mm2/drivers/md/Makefile
===================================================================
@@ -35,9 +35,6 @@ obj-$(CONFIG_BLK_DEV_DM)	+= dm-mod.o
 obj-$(CONFIG_DM_CRYPT)		+= dm-crypt.o
 obj-$(CONFIG_DM_DELAY)		+= dm-delay.o
 obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipath.o dm-round-robin.o
-obj-$(CONFIG_DM_MULTIPATH_EMC)	+= dm-emc.o
-obj-$(CONFIG_DM_MULTIPATH_HP)	+= dm-hp-sw.o
-obj-$(CONFIG_DM_MULTIPATH_RDAC)	+= dm-rdac.o
 obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o dm-log.o
 obj-$(CONFIG_DM_ZERO)		+= dm-zero.o
drivers/md/dm-emc.c deleted +0 -347

347 lines not on this page · raw message

drivers/md/dm-mpath-hp-sw.c deleted +0 -248

248 lines not on this page · raw message

drivers/md/dm-mpath-rdac.c deleted +0 -701

701 lines not on this page · raw message

#14 lore raw

PATCH 7/7 scsi_dh: Remove hardware handler infrastructure from dm

In reply to Chandra Seetharaman

Subject: scsi_dh: Remove hardware handler infrastructure from dm

From: Chandra Seetharaman <[email protected]>

This patch just removes infrastructure that provide support to add a hardware handler to dm.

---

 drivers/md/Makefile        |    2 	1 +	1 -	0 !
 drivers/md/dm-hw-handler.c |  213 	0 +	213 -	0 !
 drivers/md/dm-hw-handler.h |   63 	0 +	63 -	0 !
 drivers/md/dm-mpath.h      |    1 	0 +	1 -	0 !
 4 files changed, 1 insertion(+), 278 deletions(-)
drivers/md/dm-hw-handler.c deleted +0 -213
Index: linux-2.6.25-rc8-mm2/drivers/md/dm-hw-handler.c
===================================================================
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
- *
- * This file is released under the GPL.
- *
- * Multipath hardware handler registration.
- */
-
-#include "dm.h"
-#include "dm-hw-handler.h"
-
-#include <linux/slab.h>
-
-struct hwh_internal {
-	struct hw_handler_type hwht;
-
-	struct list_head list;
-	long use;
-};
-
-#define hwht_to_hwhi(__hwht) container_of((__hwht), struct hwh_internal, hwht)
-
-static LIST_HEAD(_hw_handlers);
-static DECLARE_RWSEM(_hwh_lock);
-
-static struct hwh_internal *__find_hw_handler_type(const char *name)
-{
-	struct hwh_internal *hwhi;
-
-	list_for_each_entry(hwhi, &_hw_handlers, list) {
-		if (!strcmp(name, hwhi->hwht.name))
-			return hwhi;
-	}
-
-	return NULL;
-}
-
-static struct hwh_internal *get_hw_handler(const char *name)
-{
-	struct hwh_internal *hwhi;
-
-	down_read(&_hwh_lock);
-	hwhi = __find_hw_handler_type(name);
-	if (hwhi) {
-		if ((hwhi->use == 0) && !try_module_get(hwhi->hwht.module))
-			hwhi = NULL;
-		else
-			hwhi->use++;
-	}
-	up_read(&_hwh_lock);
-
-	return hwhi;
-}
-
-struct hw_handler_type *dm_get_hw_handler(const char *name)
-{
-	struct hwh_internal *hwhi;
-
-	if (!name)
-		return NULL;
-
-	hwhi = get_hw_handler(name);
-	if (!hwhi) {
-		request_module("dm-%s", name);
-		hwhi = get_hw_handler(name);
-	}
-
-	return hwhi ? &hwhi->hwht : NULL;
-}
-
-void dm_put_hw_handler(struct hw_handler_type *hwht)
-{
-	struct hwh_internal *hwhi;
-
-	if (!hwht)
-		return;
-
-	down_read(&_hwh_lock);
-	hwhi = __find_hw_handler_type(hwht->name);
-	if (!hwhi)
-		goto out;
-
-	if (--hwhi->use == 0)
-		module_put(hwhi->hwht.module);
-
-	BUG_ON(hwhi->use < 0);
-
-      out:
-	up_read(&_hwh_lock);
-}
-
-static struct hwh_internal *_alloc_hw_handler(struct hw_handler_type *hwht)
-{
-	struct hwh_internal *hwhi = kzalloc(sizeof(*hwhi), GFP_KERNEL);
-
-	if (hwhi)
-		hwhi->hwht = *hwht;
-
-	return hwhi;
-}
-
-int dm_register_hw_handler(struct hw_handler_type *hwht)
-{
-	int r = 0;
-	struct hwh_internal *hwhi = _alloc_hw_handler(hwht);
-
-	if (!hwhi)
-		return -ENOMEM;
-
-	down_write(&_hwh_lock);
-
-	if (__find_hw_handler_type(hwht->name)) {
-		kfree(hwhi);
-		r = -EEXIST;
-	} else
-		list_add(&hwhi->list, &_hw_handlers);
-
-	up_write(&_hwh_lock);
-
-	return r;
-}
-
-int dm_unregister_hw_handler(struct hw_handler_type *hwht)
-{
-	struct hwh_internal *hwhi;
-
-	down_write(&_hwh_lock);
-
-	hwhi = __find_hw_handler_type(hwht->name);
-	if (!hwhi) {
-		up_write(&_hwh_lock);
-		return -EINVAL;
-	}
-
-	if (hwhi->use) {
-		up_write(&_hwh_lock);
-		return -ETXTBSY;
-	}
-
-	list_del(&hwhi->list);
-
-	up_write(&_hwh_lock);
-
-	kfree(hwhi);
-
-	return 0;
-}
-
-unsigned dm_scsi_err_handler(struct hw_handler *hwh, struct bio *bio)
-{
-#if 0
-	int sense_key, asc, ascq;
-
-	if (bio->bi_error & BIO_SENSE) {
-		/* FIXME: This is just an initial guess. */
-		/* key / asc / ascq */
-		sense_key = (bio->bi_error >> 16) & 0xff;
-		asc = (bio->bi_error >> 8) & 0xff;
-		ascq = bio->bi_error & 0xff;
-
-		switch (sense_key) {
-			/* This block as a whole comes from the device.
-			 * So no point retrying on another path. */
-		case 0x03:	/* Medium error */
-		case 0x05:	/* Illegal request */
-		case 0x07:	/* Data protect */
-		case 0x08:	/* Blank check */
-		case 0x0a:	/* copy aborted */
-		case 0x0c:	/* obsolete - no clue ;-) */
-		case 0x0d:	/* volume overflow */
-		case 0x0e:	/* data miscompare */
-		case 0x0f:	/* reserved - no idea either. */
-			return MP_ERROR_IO;
-
-			/* For these errors it's unclear whether they
-			 * come from the device or the controller.
-			 * So just lets try a different path, and if
-			 * it eventually succeeds, user-space will clear
-			 * the paths again... */
-		case 0x02:	/* Not ready */
-		case 0x04:	/* Hardware error */
-		case 0x09:	/* vendor specific */
-		case 0x0b:	/* Aborted command */
-			return MP_FAIL_PATH;
-
-		case 0x06:	/* Unit attention - might want to decode */
-			if (asc == 0x04 && ascq == 0x01)
-				/* "Unit in the process of
-				 * becoming ready" */
-				return 0;
-			return MP_FAIL_PATH;
-
-			/* FIXME: For Unit Not Ready we may want
-			 * to have a generic pg activation
-			 * feature (START_UNIT). */
-
-			/* Should these two ever end up in the
-			 * error path? I don't think so. */
-		case 0x00:	/* No sense */
-		case 0x01:	/* Recovered error */
-			return 0;
-		}
-	}
-#endif
-
-	/* We got no idea how to decode the other kinds of errors ->
-	 * assume generic error condition. */
-	return MP_FAIL_PATH;
-}
-
-EXPORT_SYMBOL_GPL(dm_register_hw_handler);
-EXPORT_SYMBOL_GPL(dm_unregister_hw_handler);
-EXPORT_SYMBOL_GPL(dm_scsi_err_handler);
drivers/md/dm-hw-handler.h deleted +0 -63

63 lines not on this page · raw message

drivers/md/Makefile +1 -1
Index: linux-2.6.25-rc8-mm2/drivers/md/Makefile
===================================================================
@@ -4,7 +4,7 @@
 
 dm-mod-objs	:= dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
 		   dm-ioctl.o dm-io.o dm-kcopyd.o
-dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o
+dm-multipath-objs := dm-path-selector.o dm-mpath.o
 dm-snapshot-objs := dm-snap.o dm-exception-store.o
 dm-mirror-objs	:= dm-raid1.o
 dm-rdac-objs	:= dm-mpath-rdac.o
drivers/md/dm-mpath.h +0 -1
Index: linux-2.6.25-rc8-mm2/drivers/md/dm-mpath.h
===================================================================
@@ -16,7 +16,6 @@ struct dm_path {
 	unsigned is_active;	/* Read-only */
 
 	void *pscontext;	/* For path-selector use */
-	void *hwhcontext;	/* For hw-handler use */
 };
 
 /* Callback for hwh_pg_init_fn to use when complete */