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

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

 




> On Mar 6, 2019, at 11:46 PM, Dabrowski, Mariusz <mariusz.dabrowski@xxxxxxxxx> wrote:
> 
> 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

Sorry for the delay. I somehow missed this one during vacation. 

Guoqing, could you please give "Acked-by" or "Reviewed-by" on this?

Thanks,
Song








[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