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

lightnvm: pblk: use vmalloc for GC data buffer

For now, we allocate a per I/O buffer for GC data. Since the potential
size of the buffer is 256KB and GC is not in the fast path, do this
allocation with vmalloc. This puts lets pressure on the memory
allocator at no performance cost.
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 8224cbd8
...@@ -425,16 +425,15 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd) ...@@ -425,16 +425,15 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data, struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
unsigned int nr_secs, unsigned int len, unsigned int nr_secs, unsigned int len,
gfp_t gfp_mask) int alloc_type, gfp_t gfp_mask)
{ {
struct nvm_tgt_dev *dev = pblk->dev; struct nvm_tgt_dev *dev = pblk->dev;
struct pblk_line_mgmt *l_mg = &pblk->l_mg;
void *kaddr = data; void *kaddr = data;
struct page *page; struct page *page;
struct bio *bio; struct bio *bio;
int i, ret; int i, ret;
if (l_mg->emeta_alloc_type == PBLK_KMALLOC_META) if (alloc_type == PBLK_KMALLOC_META)
return bio_map_kern(dev->q, kaddr, len, gfp_mask); return bio_map_kern(dev->q, kaddr, len, gfp_mask);
bio = bio_kmalloc(gfp_mask, nr_secs); bio = bio_kmalloc(gfp_mask, nr_secs);
...@@ -552,6 +551,7 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line, ...@@ -552,6 +551,7 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line,
{ {
struct nvm_tgt_dev *dev = pblk->dev; struct nvm_tgt_dev *dev = pblk->dev;
struct nvm_geo *geo = &dev->geo; struct nvm_geo *geo = &dev->geo;
struct pblk_line_mgmt *l_mg = &pblk->l_mg;
struct pblk_line_meta *lm = &pblk->lm; struct pblk_line_meta *lm = &pblk->lm;
void *ppa_list, *meta_list; void *ppa_list, *meta_list;
struct bio *bio; struct bio *bio;
...@@ -589,7 +589,8 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line, ...@@ -589,7 +589,8 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line,
rq_ppas = pblk_calc_secs(pblk, left_ppas, 0); rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
rq_len = rq_ppas * geo->sec_size; rq_len = rq_ppas * geo->sec_size;
bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len, GFP_KERNEL); bio = pblk_bio_map_addr(pblk, emeta_buf, rq_ppas, rq_len,
l_mg->emeta_alloc_type, GFP_KERNEL);
if (IS_ERR(bio)) { if (IS_ERR(bio)) {
ret = PTR_ERR(bio); ret = PTR_ERR(bio);
goto free_rqd_dma; goto free_rqd_dma;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
static void pblk_gc_free_gc_rq(struct pblk_gc_rq *gc_rq) static void pblk_gc_free_gc_rq(struct pblk_gc_rq *gc_rq)
{ {
kfree(gc_rq->data); vfree(gc_rq->data);
kfree(gc_rq); kfree(gc_rq);
} }
...@@ -72,7 +72,7 @@ static int pblk_gc_move_valid_secs(struct pblk *pblk, struct pblk_gc_rq *gc_rq) ...@@ -72,7 +72,7 @@ static int pblk_gc_move_valid_secs(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
unsigned int secs_to_gc; unsigned int secs_to_gc;
int ret = 0; int ret = 0;
data = kmalloc(gc_rq->nr_secs * geo->sec_size, GFP_KERNEL); data = vmalloc(gc_rq->nr_secs * geo->sec_size);
if (!data) { if (!data) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -110,7 +110,7 @@ static int pblk_gc_move_valid_secs(struct pblk *pblk, struct pblk_gc_rq *gc_rq) ...@@ -110,7 +110,7 @@ static int pblk_gc_move_valid_secs(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
free_rq: free_rq:
kfree(gc_rq); kfree(gc_rq);
free_data: free_data:
kfree(data); vfree(data);
out: out:
kref_put(&line->ref, pblk_line_put); kref_put(&line->ref, pblk_line_put);
return ret; return ret;
......
...@@ -462,7 +462,6 @@ int pblk_submit_read_gc(struct pblk *pblk, u64 *lba_list, void *data, ...@@ -462,7 +462,6 @@ int pblk_submit_read_gc(struct pblk *pblk, u64 *lba_list, void *data,
{ {
struct nvm_tgt_dev *dev = pblk->dev; struct nvm_tgt_dev *dev = pblk->dev;
struct nvm_geo *geo = &dev->geo; struct nvm_geo *geo = &dev->geo;
struct request_queue *q = dev->q;
struct bio *bio; struct bio *bio;
struct nvm_rq rqd; struct nvm_rq rqd;
int ret, data_len; int ret, data_len;
...@@ -491,7 +490,8 @@ int pblk_submit_read_gc(struct pblk *pblk, u64 *lba_list, void *data, ...@@ -491,7 +490,8 @@ int pblk_submit_read_gc(struct pblk *pblk, u64 *lba_list, void *data,
goto out; goto out;
data_len = (*secs_to_gc) * geo->sec_size; data_len = (*secs_to_gc) * geo->sec_size;
bio = bio_map_kern(q, data, data_len, GFP_KERNEL); bio = pblk_bio_map_addr(pblk, data, *secs_to_gc, data_len,
PBLK_KMALLOC_META, GFP_KERNEL);
if (IS_ERR(bio)) { if (IS_ERR(bio)) {
pr_err("pblk: could not allocate GC bio (%lu)\n", PTR_ERR(bio)); pr_err("pblk: could not allocate GC bio (%lu)\n", PTR_ERR(bio));
goto err_free_dma; goto err_free_dma;
......
...@@ -389,7 +389,8 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line) ...@@ -389,7 +389,8 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
rq_len = rq_ppas * geo->sec_size; rq_len = rq_ppas * geo->sec_size;
data = ((void *)emeta->buf) + emeta->mem; data = ((void *)emeta->buf) + emeta->mem;
bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len, GFP_KERNEL); bio = pblk_bio_map_addr(pblk, data, rq_ppas, rq_len,
l_mg->emeta_alloc_type, GFP_KERNEL);
if (IS_ERR(bio)) { if (IS_ERR(bio)) {
ret = PTR_ERR(bio); ret = PTR_ERR(bio);
goto fail_free_rqd; goto fail_free_rqd;
......
...@@ -698,7 +698,7 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd); ...@@ -698,7 +698,7 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line); int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data, struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
unsigned int nr_secs, unsigned int len, unsigned int nr_secs, unsigned int len,
gfp_t gfp_mask); int alloc_type, gfp_t gfp_mask);
struct pblk_line *pblk_line_get(struct pblk *pblk); struct pblk_line *pblk_line_get(struct pblk *pblk);
struct pblk_line *pblk_line_get_first_data(struct pblk *pblk); struct pblk_line *pblk_line_get_first_data(struct pblk *pblk);
void pblk_line_replace_data(struct pblk *pblk); void pblk_line_replace_data(struct pblk *pblk);
...@@ -805,7 +805,7 @@ int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx, ...@@ -805,7 +805,7 @@ int pblk_recov_setup_rq(struct pblk *pblk, struct pblk_c_ctx *c_ctx,
* pblk gc * pblk gc
*/ */
#define PBLK_GC_MAX_READERS 8 /* Max number of outstanding GC reader jobs */ #define PBLK_GC_MAX_READERS 8 /* Max number of outstanding GC reader jobs */
#define PBLK_GC_W_QD 1024 /* Queue depth for inflight GC write I/Os */ #define PBLK_GC_W_QD 128 /* Queue depth for inflight GC write I/Os */
#define PBLK_GC_L_QD 4 /* Queue depth for inflight GC lines */ #define PBLK_GC_L_QD 4 /* Queue depth for inflight GC lines */
#define PBLK_GC_RSV_LINE 1 /* Reserved lines for GC */ #define PBLK_GC_RSV_LINE 1 /* Reserved lines for GC */
......
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