lightnvm: pblk: use vmalloc for GC data buffer
authorJavier González <jg@lightnvm.io>
Fri, 30 Jun 2017 15:56:39 +0000 (17:56 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 30 Jun 2017 17:08:18 +0000 (11:08 -0600)
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: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <matias@cnexlabs.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/lightnvm/pblk-core.c
drivers/lightnvm/pblk-gc.c
drivers/lightnvm/pblk-read.c
drivers/lightnvm/pblk-write.c
drivers/lightnvm/pblk.h

index a654b34f6f86466deb90334ef46ad34458a40f36..74b8d9db05e19767bf7c94c8ddb2794605c25ae4 100644 (file)
@@ -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,
                              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 pblk_line_mgmt *l_mg = &pblk->l_mg;
        void *kaddr = data;
        struct page *page;
        struct bio *bio;
        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);
 
        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,
 {
        struct nvm_tgt_dev *dev = pblk->dev;
        struct nvm_geo *geo = &dev->geo;
+       struct pblk_line_mgmt *l_mg = &pblk->l_mg;
        struct pblk_line_meta *lm = &pblk->lm;
        void *ppa_list, *meta_list;
        struct bio *bio;
@@ -589,7 +589,8 @@ next_rq:
        rq_ppas = pblk_calc_secs(pblk, left_ppas, 0);
        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)) {
                ret = PTR_ERR(bio);
                goto free_rqd_dma;
index 9b4059b93855d702f956a3ec4e0a46fd849141a5..6090d28f7995a51f4d5972bf965457f1388874f7 100644 (file)
@@ -20,7 +20,7 @@
 
 static void pblk_gc_free_gc_rq(struct pblk_gc_rq *gc_rq)
 {
-       kfree(gc_rq->data);
+       vfree(gc_rq->data);
        kfree(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;
        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) {
                ret = -ENOMEM;
                goto out;
@@ -110,7 +110,7 @@ retry:
 free_rq:
        kfree(gc_rq);
 free_data:
-       kfree(data);
+       vfree(data);
 out:
        kref_put(&line->ref, pblk_line_put);
        return ret;
index ed2ea01a0a3864fcf98b0f63dca5dde4906dac66..31d4869b05008a201c8df45a713fd82c5fc704b3 100644 (file)
@@ -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_geo *geo = &dev->geo;
-       struct request_queue *q = dev->q;
        struct bio *bio;
        struct nvm_rq rqd;
        int ret, data_len;
@@ -491,7 +490,8 @@ int pblk_submit_read_gc(struct pblk *pblk, u64 *lba_list, void *data,
                goto out;
 
        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)) {
                pr_err("pblk: could not allocate GC bio (%lu)\n", PTR_ERR(bio));
                goto err_free_dma;
index 3e0b84937b90039d8d6557e6870a60e8ae70dd0b..8151bf4bb945b7b86b52c13785fc1ebdf85a121e 100644 (file)
@@ -389,7 +389,8 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
        rq_len = rq_ppas * geo->sec_size;
        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)) {
                ret = PTR_ERR(bio);
                goto fail_free_rqd;
index 36c5f5999324f8c2e7081c96fed726ea6a217cd1..cdad2c9edbdf86dcf8099d09d529d2ecf247f293 100644 (file)
@@ -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);
 struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
                              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_first_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,
  * pblk gc
  */
 #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_RSV_LINE 1     /* Reserved lines for GC */