Commit c2e9f5d4 authored by Javier González's avatar Javier González Committed by Jens Axboe

lightnvm: pblk: expose max sec per write on sysfs

Allow to configure the number of maximum sectors per write command
through sysfs. This makes it easier to tune write command sizes for
different controller configurations.
Signed-off-by: default avatarJavier González <javier@cnexlabs.com>
Signed-off-by: default avatarMatias Bjørling <matias@cnexlabs.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent db7ada33
...@@ -397,6 +397,11 @@ void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd) ...@@ -397,6 +397,11 @@ void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd)
#endif #endif
} }
void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write)
{
pblk->sec_per_write = sec_per_write;
}
int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd) int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
{ {
struct nvm_tgt_dev *dev = pblk->dev; struct nvm_tgt_dev *dev = pblk->dev;
...@@ -478,7 +483,7 @@ struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data, ...@@ -478,7 +483,7 @@ struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail, int pblk_calc_secs(struct pblk *pblk, unsigned long secs_avail,
unsigned long secs_to_flush) unsigned long secs_to_flush)
{ {
int max = pblk->max_write_pgs; int max = pblk->sec_per_write;
int min = pblk->min_write_pgs; int min = pblk->min_write_pgs;
int secs_to_sync = 0; int secs_to_sync = 0;
......
...@@ -250,6 +250,8 @@ static int pblk_core_init(struct pblk *pblk) ...@@ -250,6 +250,8 @@ static int pblk_core_init(struct pblk *pblk)
pblk->pgs_in_buffer = NVM_MEM_PAGE_WRITE * geo->sec_per_pg * pblk->pgs_in_buffer = NVM_MEM_PAGE_WRITE * geo->sec_per_pg *
geo->nr_planes * geo->nr_luns; geo->nr_planes * geo->nr_luns;
pblk_set_sec_per_write(pblk, pblk->min_write_pgs);
if (pblk->max_write_pgs > PBLK_MAX_REQ_ADDRS) { if (pblk->max_write_pgs > PBLK_MAX_REQ_ADDRS) {
pr_err("pblk: cannot support device max_phys_sect\n"); pr_err("pblk: cannot support device max_phys_sect\n");
return -EINVAL; return -EINVAL;
......
...@@ -290,6 +290,11 @@ static ssize_t pblk_sysfs_lines_info(struct pblk *pblk, char *page) ...@@ -290,6 +290,11 @@ static ssize_t pblk_sysfs_lines_info(struct pblk *pblk, char *page)
return sz; return sz;
} }
static ssize_t pblk_sysfs_get_sec_per_write(struct pblk *pblk, char *page)
{
return snprintf(page, PAGE_SIZE, "%d\n", pblk->sec_per_write);
}
#ifdef CONFIG_NVM_DEBUG #ifdef CONFIG_NVM_DEBUG
static ssize_t pblk_sysfs_stats_debug(struct pblk *pblk, char *page) static ssize_t pblk_sysfs_stats_debug(struct pblk *pblk, char *page)
{ {
...@@ -354,6 +359,29 @@ static ssize_t pblk_sysfs_gc_force(struct pblk *pblk, const char *page, ...@@ -354,6 +359,29 @@ static ssize_t pblk_sysfs_gc_force(struct pblk *pblk, const char *page,
return len; return len;
} }
static ssize_t pblk_sysfs_set_sec_per_write(struct pblk *pblk,
const char *page, size_t len)
{
size_t c_len;
int sec_per_write;
c_len = strcspn(page, "\n");
if (c_len >= len)
return -EINVAL;
if (kstrtouint(page, 0, &sec_per_write))
return -EINVAL;
if (sec_per_write < pblk->min_write_pgs
|| sec_per_write > pblk->max_write_pgs
|| sec_per_write % pblk->min_write_pgs != 0)
return -EINVAL;
pblk_set_sec_per_write(pblk, sec_per_write);
return len;
}
static struct attribute sys_write_luns = { static struct attribute sys_write_luns = {
.name = "write_luns", .name = "write_luns",
.mode = 0444, .mode = 0444,
...@@ -399,6 +427,11 @@ static struct attribute sys_gc_force = { ...@@ -399,6 +427,11 @@ static struct attribute sys_gc_force = {
.mode = 0200, .mode = 0200,
}; };
static struct attribute sys_max_sec_per_write = {
.name = "max_sec_per_write",
.mode = 0644,
};
static struct attribute sys_gc_rl_max = { static struct attribute sys_gc_rl_max = {
.name = "gc_rl_max", .name = "gc_rl_max",
.mode = 0200, .mode = 0200,
...@@ -417,6 +450,7 @@ static struct attribute *pblk_attrs[] = { ...@@ -417,6 +450,7 @@ static struct attribute *pblk_attrs[] = {
&sys_errors_attr, &sys_errors_attr,
&sys_gc_state, &sys_gc_state,
&sys_gc_force, &sys_gc_force,
&sys_max_sec_per_write,
&sys_gc_rl_max, &sys_gc_rl_max,
&sys_rb_attr, &sys_rb_attr,
&sys_stats_ppaf_attr, &sys_stats_ppaf_attr,
...@@ -449,6 +483,8 @@ static ssize_t pblk_sysfs_show(struct kobject *kobj, struct attribute *attr, ...@@ -449,6 +483,8 @@ static ssize_t pblk_sysfs_show(struct kobject *kobj, struct attribute *attr,
return pblk_sysfs_lines(pblk, buf); return pblk_sysfs_lines(pblk, buf);
else if (strcmp(attr->name, "lines_info") == 0) else if (strcmp(attr->name, "lines_info") == 0)
return pblk_sysfs_lines_info(pblk, buf); return pblk_sysfs_lines_info(pblk, buf);
else if (strcmp(attr->name, "max_sec_per_write") == 0)
return pblk_sysfs_get_sec_per_write(pblk, buf);
#ifdef CONFIG_NVM_DEBUG #ifdef CONFIG_NVM_DEBUG
else if (strcmp(attr->name, "stats") == 0) else if (strcmp(attr->name, "stats") == 0)
return pblk_sysfs_stats_debug(pblk, buf); return pblk_sysfs_stats_debug(pblk, buf);
...@@ -465,6 +501,8 @@ static ssize_t pblk_sysfs_store(struct kobject *kobj, struct attribute *attr, ...@@ -465,6 +501,8 @@ static ssize_t pblk_sysfs_store(struct kobject *kobj, struct attribute *attr,
return pblk_sysfs_rate_store(pblk, buf, len); return pblk_sysfs_rate_store(pblk, buf, len);
else if (strcmp(attr->name, "gc_force") == 0) else if (strcmp(attr->name, "gc_force") == 0)
return pblk_sysfs_gc_force(pblk, buf, len); return pblk_sysfs_gc_force(pblk, buf, len);
else if (strcmp(attr->name, "max_sec_per_write") == 0)
return pblk_sysfs_set_sec_per_write(pblk, buf, len);
return 0; return 0;
} }
......
...@@ -499,6 +499,7 @@ struct pblk { ...@@ -499,6 +499,7 @@ struct pblk {
/* pblk provisioning values. Used by rate limiter */ /* pblk provisioning values. Used by rate limiter */
struct pblk_rl rl; struct pblk_rl rl;
int sec_per_write;
struct semaphore erase_sem; struct semaphore erase_sem;
unsigned char instance_uuid[16]; unsigned char instance_uuid[16];
...@@ -613,6 +614,7 @@ ssize_t pblk_rb_sysfs(struct pblk_rb *rb, char *buf); ...@@ -613,6 +614,7 @@ ssize_t pblk_rb_sysfs(struct pblk_rb *rb, char *buf);
* pblk core * pblk core
*/ */
struct nvm_rq *pblk_alloc_rqd(struct pblk *pblk, int rw); struct nvm_rq *pblk_alloc_rqd(struct pblk *pblk, int rw);
void pblk_set_sec_per_write(struct pblk *pblk, int sec_per_write);
int pblk_setup_w_rec_rq(struct pblk *pblk, struct nvm_rq *rqd, int pblk_setup_w_rec_rq(struct pblk *pblk, struct nvm_rq *rqd,
struct pblk_c_ctx *c_ctx); struct pblk_c_ctx *c_ctx);
void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, int rw); void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, int rw);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment