lightnvm: pblk: free padded entries in write buffer
authorJavier González <javier@cnexlabs.com>
Fri, 13 Oct 2017 12:46:03 +0000 (14:46 +0200)
committerJens Axboe <axboe@kernel.dk>
Fri, 13 Oct 2017 14:34:57 +0000 (08:34 -0600)
When a REQ_FLUSH reaches pblk, the bio cannot be directly completed.
Instead, data on the write buffer is flushed and the bio is completed on
the completion pah. This might require some sectors to be padded in
order to guarantee a successful write.

This patch fixes a memory leak on the padded pages. A consequence of
this bad free was that internal bios not containing data (only a flush)
were not being completed.

Fixes: a4bd217b4326 ("lightnvm: physical block device (pblk) target")
Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/lightnvm/pblk-core.c
drivers/lightnvm/pblk-write.c

index a68c6ae536e5992c17b8f18afb4b6ac3d49b70c5..9299a5a75a187cf995ef01cc10c4caedfc71f12c 100644 (file)
@@ -190,7 +190,6 @@ void pblk_bio_free_pages(struct pblk *pblk, struct bio *bio, int off,
 
        WARN_ON(off + nr_pages != bio->bi_vcnt);
 
-       bio_advance(bio, off * PBLK_EXPOSED_PAGE_SIZE);
        for (i = off; i < nr_pages + off; i++) {
                bv = bio->bi_io_vec[i];
                mempool_free(bv.bv_page, pblk->page_pool);
index 3ad9e56d2473412ae3ead5b2946066643ebd541c..d89ac573f8d838eca3401f671f558c25df19260b 100644 (file)
@@ -33,6 +33,10 @@ static unsigned long pblk_end_w_bio(struct pblk *pblk, struct nvm_rq *rqd,
                        bio_endio(original_bio);
        }
 
+       if (c_ctx->nr_padded)
+               pblk_bio_free_pages(pblk, rqd->bio, c_ctx->nr_valid,
+                                                       c_ctx->nr_padded);
+
 #ifdef CONFIG_NVM_DEBUG
        atomic_long_add(c_ctx->nr_valid, &pblk->sync_writes);
 #endif
@@ -521,7 +525,8 @@ static void pblk_free_write_rqd(struct pblk *pblk, struct nvm_rq *rqd)
        struct bio *bio = rqd->bio;
 
        if (c_ctx->nr_padded)
-               pblk_bio_free_pages(pblk, bio, rqd->nr_ppas, c_ctx->nr_padded);
+               pblk_bio_free_pages(pblk, bio, c_ctx->nr_valid,
+                                                       c_ctx->nr_padded);
 }
 
 static int pblk_submit_write(struct pblk *pblk)