Re: [PATCH v2] raid5: set write hint for PPL

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

 



On 2/18/19 3:04 PM, Mariusz Dabrowski wrote:
> When the Partial Parity Log is enabled, circular buffer is used to store
> PPL data. Each write to RAID device causes overwrite of data in this buffer
> so some write_hint can be set to those request to help drives handle
> garbage collection. This patch adds new sysfs attribute which can be used
> to specify which write_hint should be assigned to PPL.
> 
> Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@xxxxxxxxx>
> ---
> v2: moved ppl_write_hint releated stuff from raid5.c to raid5-ppl.c
> 
>   Documentation/admin-guide/md.rst |  3 ++
>   drivers/md/raid5-log.h           |  1 +
>   drivers/md/raid5-ppl.c           | 63 ++++++++++++++++++++++++++++++++++++++++
>   drivers/md/raid5.c               |  1 +
>   4 files changed, 68 insertions(+)
> 
> diff --git a/Documentation/admin-guide/md.rst b/Documentation/admin-guide/md.rst
> index 84de718f24a4..3c51084ffd37 100644
> --- a/Documentation/admin-guide/md.rst
> +++ b/Documentation/admin-guide/md.rst
> @@ -756,3 +756,6 @@ These currently include:
>         The cache mode for raid5. raid5 could include an extra disk for
>         caching. The mode can be "write-throuth" and "write-back". The
>         default is "write-through".
> +
> +  ppl_write_hint
> +      NVMe stream ID to be set for each PPL write request.
> diff --git a/drivers/md/raid5-log.h b/drivers/md/raid5-log.h
> index bfb811407061..43c714a8798c 100644
> --- a/drivers/md/raid5-log.h
> +++ b/drivers/md/raid5-log.h
> @@ -45,6 +45,7 @@ extern void ppl_stripe_write_finished(struct stripe_head *sh);
>   extern int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add);
>   extern void ppl_quiesce(struct r5conf *conf, int quiesce);
>   extern int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio);
> +extern struct md_sysfs_entry ppl_write_hint;
>   
>   static inline bool raid5_has_log(struct r5conf *conf)
>   {
> diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c
> index 3a7c36326589..f2b3020c2ac8 100644
> --- a/drivers/md/raid5-ppl.c
> +++ b/drivers/md/raid5-ppl.c
> @@ -21,6 +21,7 @@
>   #include <linux/raid/md_p.h>
>   #include "md.h"
>   #include "raid5.h"
> +#include "raid5-log.h"
>   
>   /*
>    * PPL consists of a 4KB header (struct ppl_header) and at least 128KB for
> @@ -116,6 +117,8 @@ struct ppl_conf {
>   	/* stripes to retry if failed to allocate io_unit */
>   	struct list_head no_mem_stripes;
>   	spinlock_t no_mem_stripes_lock;
> +
> +	unsigned short write_hint;
>   };
>   
>   struct ppl_log {
> @@ -476,6 +479,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
>   	bio_set_dev(bio, log->rdev->bdev);
>   	bio->bi_iter.bi_sector = log->next_io_sector;
>   	bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
> +	bio->bi_write_hint = ppl_conf->write_hint;
>   
>   	pr_debug("%s: log->current_io_sector: %llu\n", __func__,
>   	    (unsigned long long)log->next_io_sector);
> @@ -505,6 +509,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
>   			bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES,
>   					       &ppl_conf->bs);
>   			bio->bi_opf = prev->bi_opf;
> +			bio->bi_write_hint = prev->bi_write_hint;
>   			bio_copy_dev(bio, prev);
>   			bio->bi_iter.bi_sector = bio_end_sector(prev);
>   			bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);
> @@ -1409,6 +1414,7 @@ int ppl_init_log(struct r5conf *conf)
>   	atomic64_set(&ppl_conf->seq, 0);
>   	INIT_LIST_HEAD(&ppl_conf->no_mem_stripes);
>   	spin_lock_init(&ppl_conf->no_mem_stripes_lock);
> +	ppl_conf->write_hint = RWF_WRITE_LIFE_NOT_SET;
>   
>   	if (!mddev->external) {
>   		ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid));
> @@ -1503,3 +1509,60 @@ int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add)
>   
>   	return ret;
>   }
> +
> +static ssize_t
> +ppl_write_hint_show(struct mddev *mddev, char *buf)
> +{
> +	size_t ret = 0;
> +	struct r5conf *conf;
> +	struct ppl_conf *ppl_conf = NULL;
> +
> +	spin_lock(&mddev->lock);
> +	conf = mddev->private;
> +	if (conf && raid5_has_ppl(conf))
> +		ppl_conf = conf->log_private;
> +	ret = sprintf(buf, "%d\n", ppl_conf ? ppl_conf->write_hint : 0);
> +	spin_unlock(&mddev->lock);
> +
> +	return ret;
> +}
> +
> +static ssize_t
> +ppl_write_hint_store(struct mddev *mddev, const char *page, size_t len)
> +{
> +	struct r5conf *conf;
> +	struct ppl_conf *ppl_conf;
> +	int err = 0;
> +	unsigned short new;
> +
> +	if (len >= PAGE_SIZE)
> +		return -EINVAL;
> +	if (kstrtou16(page, 10, &new))
> +		return -EINVAL;
> +
> +	err = mddev_lock(mddev);
> +	if (err)
> +		return err;
> +
> +	conf = mddev->private;
> +	if (!conf) {
> +		err = -ENODEV;
> +	} else if (raid5_has_ppl(conf)) {
> +		ppl_conf = conf->log_private;
> +		if (!ppl_conf)
> +			err = -EINVAL;
> +		else
> +			ppl_conf->write_hint = new;
> +	} else {
> +		err = -EINVAL;
> +	}
> +
> +	mddev_unlock(mddev);
> +
> +	return err ?: len;
> +}
> +
> +struct md_sysfs_entry
> +ppl_write_hint = __ATTR(ppl_write_hint, S_IRUGO | S_IWUSR,
> +			ppl_write_hint_show,
> +			ppl_write_hint_store);
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index cecea901ab8c..09562d7cc080 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -6660,6 +6660,7 @@ static struct attribute *raid5_attrs[] =  {
>   	&raid5_skip_copy.attr,
>   	&raid5_rmw_level.attr,
>   	&r5c_journal_mode.attr,
> +	&ppl_write_hint.attr,
>   	NULL,
>   };
>   static struct attribute_group raid5_attrs_group = {
> 

Ping




[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux