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.

Acked-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
This commit is contained in:
Mariusz Dabrowski 2019-02-18 15:04:09 +01:00 коммит произвёл Song Liu
Родитель 9205e44916
Коммит a596d08677
4 изменённых файлов: 68 добавлений и 0 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 = {