Skip to contentSkip to conversation

dm: add asymmetric stripe target device dirver

PATCH New [email protected] 1 participant 1 message Dec 26, 2017

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

PATCH 1/1 dm: add asymmetric stripe target device dirver

From: liuchaowei <[email protected]>

This asymmetric stripe target device driver can achieve better io performance between those devices which possess different io performance

There are 2 storage device or flash devices: A and B, their sequential read performance are 220M/s and 315M/s respectively, so their sequential read speed ratio could be approximately equal to 2:3, if we use stripe type to combine these two devices, their layout could be showed below:
--------------------------------------------------------
| A1 | A2 | B1 | B2 | B3 |
--------------------------------------------------------

If we select asymmetric stripe type, their layout could be illustrated follow:
--------------------------------------------------------
| A1 | B1 |
--------------------------------------------------------

The former has 5 stripe devices and each stripe device has also equal chunk size, e.g.: 256secs. If there is a data block which size is 1280secs, so transfer the data to this stripe device will be split to 5 ios which io size is 256secs. But if we use the asymmetric stripe device, it only has two stripe devices and each one has be setting in optimal chunk size, e.g.: ratio is 2:3, the first one optimal chunk size is 512secs, the second is 768secs. And same 1280secs data block just only be split into two ios, this can be achieved perfect io performance.

---
 Documentation/device-mapper/asymmetric-striped.txt |  85 ++++
 drivers/md/Kconfig                                 |  11 +
 drivers/md/Makefile                                |   1 +
 drivers/md/dm-asymmetric-stripe.c                  | 526 +++++++++++++++++++++
 drivers/md/dm.c                                    |   5 +
 include/linux/device-mapper.h                      |  15 +
 6 files changed, 643 insertions(+)
 create mode 100644 Documentation/device-mapper/asymmetric-striped.txt
 create mode 100644 drivers/md/dm-asymmetric-stripe.c
Documentation/device-mapper/asymmetric-striped.txt new file +85 -0
new file mode 100644
index 000000000000..fb588535c49b
@@ -0,0 +1,85 @@
+dm-asymmetric-stripe
+=========
+
+Device-Mapper's "asm-striped" target is used to create a striped (i.e. RAID-0)
+device across one or more underlying devices. Data is written in "chunks",
+with consecutive chunks rotating among the underlying devices. This can
+potentially provide improved I/O throughput by utilizing several physical
+devices in parallel. However, in order to gain maximum I/O performance
+between slow and fast device, there is a ratio to set up the chunk size
+among these device.
+
+Parameters: <num devs> <chunk size> <ratio> [<dev path> <offset>]+
+<num devs>: Number of underlying devices.
+<chunk size>: Size of each chunk of data. Must be at least as
+large as the system's PAGE_SIZE.
+<ratio>: The proportion of per io size, it is the times as much
+as 1 chunk size
+<dev path>: Full pathname to the underlying block-device, or a
+"major:minor" device-number.
+<offset>: Starting sector within the device.
+
+One or more underlying devices can be specified. The striped device
+size must be a multiple of the chunk size multiplied by the number of
+underlying devices. However, there is a ratio that can be set, e.g.: 2:3
+means the first one striped device optimal width size is 2 times as
+much as 1 chunk size, the second striped device is 3.
+
+
+Example scripts
+===============
+
+[[
+#!/usr/bin/perl -w
+# Create a striped device across any number of underlying devices. The device
+# will be called "stripe_dev" and have a chunk-size of 128k.
+
+my $chunk_size = 128 * 2;
+my $ratio = "2:3";
+my $dev_name = "stripe_dev";
+my $num_devs = @ARGV;
+my @devs = @ARGV;
+
+if ($num_devs < 2) {
+die("Specify at least two devices\n");
+}
+
+
+$stripe_average_size = 1073741824
+$stripe_dev_size = $stripe_average_size * 5;
+
+$table = "0 $stripe_dev_size asm-striped $num_devs $chunk_size $ratio";
+for ($i = 0; $i < $num_devs; $i++) {
+$table .= " $devs[$i] 0";
+}
+
+`echo $table | dmsetup create $dev_name`;
+]]
+
+
+Why asymmetric striped
+=======================
+Considering one case:
+There are 2 storage device or flash devices: A and B, their sequential
+read performance are 220M/s and 315M/s respectively, so their sequential
+read speed could be approximately equal to 2:3, if we use stripe type
+to combine these two devices, their layout could be showed below:
+--------------------------------------------------------
+|    A1    |    A2    |    B1    |    B2    |    B3    |
+--------------------------------------------------------
+
+If we select asymmetric stripe type, their layout could be illustrated
+follow:
+--------------------------------------------------------
+|         A1          |               B1               |
+--------------------------------------------------------
+
+The former has 5 stripe devices and each stripe device has also equal
+chunk size, e.g.: 256secs. If there is a data block which size is 1280secs,
+so transfer the data to this stripe device will be split into 5 ios which io
+size is 256secs. But if we use the asymmetric stripe device, it only has two
+stripe devices and each one has be setting in optimal chunk size, e.g.: ratio
+is 2:3, the first one optimal chunk size is 512secs, the second is 768secs.
+And same 1280secs data block just only be split into two ios, this can be
+achieved perfect io performance.
+
drivers/md/Kconfig +11 -0
index 7d5aa2c5c81d..0f243a58144d 100644
@@ -455,6 +455,17 @@ config DM_FLAKEY
        ---help---
          A target that intermittently fails I/O for debugging purposes.
 
+config DM_ASYMMETRIC_STRIPE
+	tristate "DM asymmetric stripe(asymmetric raid0)"
+	depends on BLK_DEV_DM
+	---help---
+	  This device-mapper target creates a asymmetric raid0/stripe device that
+	  support asymmetric stripe chunk size and can gain same performance as
+	  raid0 device.
+
+	  You must configure the accurate ratio between different physical storage
+	  device respectively.
+
 config DM_VERITY
 	tristate "Verity target support"
 	depends on BLK_DEV_DM
drivers/md/Makefile +1 -0
index 2b2ba36638cd..0f0ea7bd7737 100644
@@ -62,6 +62,7 @@ obj-$(CONFIG_DM_ERA)		+= dm-era.o
 obj-$(CONFIG_DM_LOG_WRITES)	+= dm-log-writes.o
 obj-$(CONFIG_DM_REQ_CRYPT)	+= dm-req-crypt.o
 obj-$(CONFIG_DM_ANDROID_VERITY) += dm-android-verity.o
+obj-$(CONFIG_DM_ASYMMETRIC_STRIPE) += dm-asymmetric-stripe.o
 
 ifeq ($(CONFIG_DM_UEVENT),y)
 dm-mod-objs			+= dm-uevent.o
drivers/md/dm-asymmetric-stripe.c new file +526 -0

526 lines not on this page · raw message

drivers/md/dm.c +5 -0
index 36a20ff5d195..9c5b05db3180 100644
@@ -1393,6 +1393,7 @@ static sector_t max_io_len(sector_t sector, struct dm_target *ti)
 {
 	sector_t len = max_io_len_target_boundary(sector, ti);
 	sector_t offset, max_len;
+	sector_t optimal_len;
 
 	/*
 	 * Does the target need to split even further?
@@ -1407,6 +1408,10 @@ static sector_t max_io_len(sector_t sector, struct dm_target *ti)
 
 		if (len > max_len)
 			len = max_len;
+	} else if (ti->asymmetric_chunk_supported) {
+		offset = dm_target_offset(ti, sector);
+		ti->type->io_calculate(ti, offset, &optimal_len);
+		len = optimal_len;
 	}
 
 	return len;
include/linux/device-mapper.h +15 -0
index 5c720864db89..ec6fc5e6b884 100644
@@ -109,6 +109,14 @@ typedef int (*dm_iterate_devices_fn) (struct dm_target *ti,
 typedef void (*dm_io_hints_fn) (struct dm_target *ti,
 				struct queue_limits *limits);
 
+/*
+ * This function will recalculate io size per bio if this target support
+ * asymmetric chunk size
+ */
+typedef void (*dm_io_len_calculate_fn) (struct dm_target *ti,
+				sector_t offset,
+				sector_t *optimal_len);
+
 /*
  * Returns:
  *    0: The target can handle the next I/O immediately.
@@ -162,6 +170,7 @@ struct target_type {
 	dm_busy_fn busy;
 	dm_iterate_devices_fn iterate_devices;
 	dm_io_hints_fn io_hints;
+	dm_io_len_calculate_fn io_calculate;
 
 	/* For internal device-mapper use. */
 	struct list_head list;
@@ -273,6 +282,12 @@ struct dm_target {
 	 * Set if this target does not return zeroes on discarded blocks.
 	 */
 	bool discard_zeroes_data_unsupported:1;
+
+	/*
+	 * Set if this target supported asymmetric chunk size.
+	 */
+	bool asymmetric_chunk_supported:1;
+
 };
 
 /* Each target can link one of these into the table */
Signature · 1 line
2.15.1