Re: [PATCH] dm: add asymmetric stripe target device dirver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



No, I don't think so, "target_stripe > stripe" is another condition, but I do nothing here. If I use "else" the condition "target_strie > stripe" can not be handled. 

2017-12-26 12:22 GMT+08:00 Randy Dunlap <rdunlap@xxxxxxxxxxxxx>:
On 12/25/2017 07:52 PM, tgvlcw@xxxxxxxxx wrote:
> From: liuchaowei <tgvlcw@xxxxxxxxx>
>
> 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 permance are 220M/s and 315M/s inspectively, so their sequential

       performance                    respectively,

> 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 seletect asymmetric stripe type, their layout could be illustrated

        select

> 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 defvice will be split

                                                device

> 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 splited two ios, this can be achieve

                                   split into two ios,

> perfect io performance.
>
> Change-Id: Iebaee3480e27022e2b3a7edbfb65425b1166274e
> Signed-off-by: liuchaowei <tgvlcw@xxxxxxxxx>
> ---
>  Documentation/device-mapper/asymmetric-striped.txt |  85 ++++
>  drivers/md/Kconfig                                 |  11 +
>  drivers/md/Makefile                                |   1 +
>  drivers/md/dm-asymmetric-stripe.c                  | 523 +++++++++++++++++++++
>  drivers/md/dm.c                                    |   5 +
>  include/linux/device-mapper.h                      |  15 +
>  6 files changed, 640 insertions(+)
>  create mode 100644 Documentation/device-mapper/asymmetric-striped.txt
>  create mode 100644 drivers/md/dm-asymmetric-stripe.c
>
> diff --git a/Documentation/device-mapper/asymmetric-striped.txt b/Documentation/device-mapper/asymmetric-striped.txt
> new file mode 100644
> index 000000000000..0412a224a49e
> --- /dev/null
> +++ b/Documentation/device-mapper/asymmetric-striped.txt
> @@ -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 bewteen

                                                                          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 can be setting, e.g.: 2:3 means the first one

                     there is a ratio that can be set,

> +striped device optimal width size is 2 time as much as 1 chunk size, the second

                                          times

> +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 permance are 220M/s and 315M/s inspectively, so their sequential

        performance                    respectively,

> +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 seletect asymmetric stripe type, their layout could be illustrated

         select

> +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 defvice will be split to 5 ios which io

                                       device

> +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 splited two ios, this can be achieve

                                             split into two ios,

> +perfect io performance.
> +
> diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
> index 7d5aa2c5c81d..4232b929c2f3 100644
> --- a/drivers/md/Kconfig
> +++ b/drivers/md/Kconfig
> @@ -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

Align "support" and "raid0" under "This".  And end the sentence with a period (".").

> +
> +          You must configure the accurate ratio between different physical storage
> +          device respectively

End sentence with a period.

> +
>  config DM_VERITY
>       tristate "Verity target support"
>       depends on BLK_DEV_DM

> diff --git a/drivers/md/dm-asymmetric-stripe.c b/drivers/md/dm-asymmetric-stripe.c
> new file mode 100644
> index 000000000000..4ef3915b435a
> --- /dev/null
> +++ b/drivers/md/dm-asymmetric-stripe.c
> @@ -0,0 +1,523 @@
> +/*
> + * Copyright (C) 2018 Smartisan, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * Author: <tgvlcw@xxxxxxxxx>
> + * Name: Henry Liu
> + *
> + */
> +
> +
> +#include "dm.h"
> +#include <linux/device-mapper.h>
> +

#include <linux/atomic.h>

> +#include <linux/module.h>
> +#include <linux/init.h>

#include <linux/kernel.h>

> +#include <linux/blkdev.h>
> +#include <linux/bio.h>

#include <linux/bitops.h>

> +#include <linux/slab.h>
> +#include <linux/log2.h>

#include <linux/workqueue.h>

> +
> +#define DM_MSG_PREFIX "asm-striped"
> +#define DM_IO_ERROR_THRESHOLD 15

> +/*
> + * An event is triggered whenever a drive
> + * drops out of a stripe volume.
> + */
> +static void trigger_event(struct work_struct *work)
> +{
> +     asm_stripe_c *sc = container_of(work, asm_stripe_c, trigger_event);
> +
> +     dm_table_event(sc->ti->table);
> +}
> +
> +     static inline

Above line should not be indented.
Above and below should be on one line if <= 80 characters.

> +asm_stripe_c *alloc_context(unsigned int stripes)
> +{
> +     size_t len;
> +
> +     if (dm_array_too_big(sizeof(asm_stripe_c),
> +                             sizeof(asm_stripe),
> +                             stripes))
> +             return NULL;
> +
> +     len = sizeof(asm_stripe_c) + (sizeof(asm_stripe) * stripes);
> +
> +     return kmalloc(len, GFP_KERNEL);
> +}

> +static int set_stripe_ratio(struct dm_target *ti,
> +             asm_stripe_c *sc,
> +             char *ratio_str)
> +{
> +     char *p;
> +     unsigned int i;
> +     uint32_t r = 0, ratio;
> +     char *tmp_ratio = ratio_str;
> +
> +     if (sizeof(sc->ratio_str) < strlen(ratio_str)) {
> +             ti->error = "Too big stripe ratio string";
> +             return -ENOMEM;
> +     }
> +
> +     strlcpy(sc->ratio_str, ratio_str, strlen(ratio_str) + 1);
> +     for (i = 0; i < sc->stripes; i++) {
> +             p  = strsep(&tmp_ratio, ":");
> +             if (p == NULL)
> +                     return -EINVAL;
> +
> +             if (kstrtouint(p, 10, &ratio) || !ratio)
> +                     return -EINVAL;
> +
> +             sc->stripe[i].ratio = ratio;
> +             r += ratio;
> +     }
> +
> +     sc->total_ratio = r;
> +     sc->avg_width = ti->len / r;
> +     sc->stripe_size = r * sc->chunk_size;
> +
> +     return 0;
> +}

Insert blank line here.

> +/*
> + * Construct a striped mapping.
> + * <number of stripes> <chunk size> <ratio> [<dev_path> <offset>]+
> + */
> +static int asymmetric_stripe_ctr(struct dm_target *ti,
> +             unsigned int argc,
> +             char **argv)
> +{

[snip]


> +static void asymmetric_stripe_map_range_sector(asm_stripe_c *sc,
> +             sector_t sector,
> +             uint32_t target_stripe,
> +             sector_t *result)
> +{
> +     sector_t width_offset;
> +     uint32_t stripe;
> +
> +     width_offset = stripe_index_fetch(sc, &sector, &stripe);
> +
> +     *result = sector * sc->stripe[target_stripe].opt_io_size;
> +
> +     if (target_stripe < stripe)
> +             *result += sc->stripe[target_stripe].opt_io_size;
> +     else if (target_stripe == stripe)
> +             *result += width_offset;

Here you don't expect target_stripe ever to be > stripe, right?
Then the last "else if" can just be "else"...


> +}
> +


--
~Randy

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux