lightnvm: enable to send hint to erase command
authorJavier González <jg@lightnvm.io>
Mon, 28 Nov 2016 21:38:54 +0000 (22:38 +0100)
committerJens Axboe <axboe@fb.com>
Tue, 29 Nov 2016 19:12:51 +0000 (12:12 -0700)
Erases might be subject to host hints. An example is multi-plane
programming to erase blocks in parallel. Enable targets to specify this
hint.

Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/lightnvm/core.c
drivers/lightnvm/gennvm.c
drivers/lightnvm/rrpc.c
drivers/lightnvm/sysblk.c
drivers/nvme/host/lightnvm.c
include/linux/lightnvm.h

index 1111740..8664fe0 100644 (file)
@@ -202,9 +202,9 @@ int nvm_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
 }
 EXPORT_SYMBOL(nvm_submit_io);
 
-int nvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk)
+int nvm_erase_blk(struct nvm_dev *dev, struct nvm_block *blk, int flags)
 {
-       return dev->mt->erase_blk(dev, blk, 0);
+       return dev->mt->erase_blk(dev, blk, flags);
 }
 EXPORT_SYMBOL(nvm_erase_blk);
 
@@ -285,7 +285,8 @@ void nvm_free_rqd_ppalist(struct nvm_dev *dev, struct nvm_rq *rqd)
 }
 EXPORT_SYMBOL(nvm_free_rqd_ppalist);
 
-int nvm_erase_ppa(struct nvm_dev *dev, struct ppa_addr *ppas, int nr_ppas)
+int nvm_erase_ppa(struct nvm_dev *dev, struct ppa_addr *ppas, int nr_ppas,
+                                                               int flags)
 {
        struct nvm_rq rqd;
        int ret;
@@ -301,6 +302,8 @@ int nvm_erase_ppa(struct nvm_dev *dev, struct ppa_addr *ppas, int nr_ppas)
 
        nvm_generic_to_addr_mode(dev, &rqd);
 
+       rqd.flags = flags;
+
        ret = dev->ops->erase_block(dev, &rqd);
 
        nvm_free_rqd_ppalist(dev, &rqd);
index b74174c..730d736 100644 (file)
@@ -593,12 +593,11 @@ static int gen_submit_io(struct nvm_dev *dev, struct nvm_rq *rqd)
        return dev->ops->submit_io(dev, rqd);
 }
 
-static int gen_erase_blk(struct nvm_dev *dev, struct nvm_block *blk,
-                                                       unsigned long flags)
+static int gen_erase_blk(struct nvm_dev *dev, struct nvm_block *blk, int flags)
 {
        struct ppa_addr addr = block_to_ppa(dev, blk);
 
-       return nvm_erase_ppa(dev, &addr, 1);
+       return nvm_erase_ppa(dev, &addr, 1, flags);
 }
 
 static int gen_reserve_lun(struct nvm_dev *dev, int lunid)
index 37fcaad..067e890 100644 (file)
@@ -404,7 +404,7 @@ static void rrpc_block_gc(struct work_struct *work)
        if (rrpc_move_valid_pages(rrpc, rblk))
                goto put_back;
 
-       if (nvm_erase_blk(dev, rblk->parent))
+       if (nvm_erase_blk(dev, rblk->parent, 0))
                goto put_back;
 
        rrpc_put_blk(rrpc, rblk);
index a75bd28..d229067 100644 (file)
@@ -379,7 +379,7 @@ static int nvm_prepare_new_sysblks(struct nvm_dev *dev, struct sysblk_scan *s)
                ppa = &s->ppas[scan_ppa_idx(i, nxt_blk)];
                ppa->g.pg = ppa_to_slc(dev, 0);
 
-               ret = nvm_erase_ppa(dev, ppa, 1);
+               ret = nvm_erase_ppa(dev, ppa, 1, 0);
                if (ret)
                        return ret;
 
@@ -725,7 +725,7 @@ int nvm_dev_factory(struct nvm_dev *dev, int flags)
        /* continue to erase until list of blks until empty */
        while ((ppa_cnt =
                        nvm_fact_get_blks(dev, ppas, max_ppas, blk_bitmap)) > 0)
-               nvm_erase_ppa(dev, ppas, ppa_cnt);
+               nvm_erase_ppa(dev, ppas, ppa_cnt, 0);
 
        /* mark host reserved blocks free */
        if (flags & NVM_FACTORY_RESET_HOST_BLKS) {
index f23e6fe..037dff5 100644 (file)
@@ -526,6 +526,7 @@ static int nvme_nvm_erase_block(struct nvm_dev *dev, struct nvm_rq *rqd)
        c.erase.nsid = cpu_to_le32(ns->ns_id);
        c.erase.spba = cpu_to_le64(rqd->ppa_addr.ppa);
        c.erase.length = cpu_to_le16(rqd->nr_ppas - 1);
+       c.erase.control = cpu_to_le16(rqd->flags);
 
        return nvme_submit_sync_cmd(q, (struct nvme_command *)&c, NULL, 0);
 }
index fb2e601..d87be02 100644 (file)
@@ -470,8 +470,7 @@ typedef int (nvmm_open_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef int (nvmm_close_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef void (nvmm_flush_blk_fn)(struct nvm_dev *, struct nvm_block *);
 typedef int (nvmm_submit_io_fn)(struct nvm_dev *, struct nvm_rq *);
-typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *,
-                                                               unsigned long);
+typedef int (nvmm_erase_blk_fn)(struct nvm_dev *, struct nvm_block *, int);
 typedef void (nvmm_mark_blk_fn)(struct nvm_dev *, struct ppa_addr, int);
 typedef struct nvm_lun *(nvmm_get_lun_fn)(struct nvm_dev *, int);
 typedef int (nvmm_reserve_lun)(struct nvm_dev *, int);
@@ -537,8 +536,8 @@ extern void nvm_addr_to_generic_mode(struct nvm_dev *, struct nvm_rq *);
 extern int nvm_set_rqd_ppalist(struct nvm_dev *, struct nvm_rq *,
                                        const struct ppa_addr *, int, int);
 extern void nvm_free_rqd_ppalist(struct nvm_dev *, struct nvm_rq *);
-extern int nvm_erase_ppa(struct nvm_dev *, struct ppa_addr *, int);
-extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *);
+extern int nvm_erase_ppa(struct nvm_dev *, struct ppa_addr *, int, int);
+extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *, int);
 extern void nvm_end_io(struct nvm_rq *, int);
 extern int nvm_submit_ppa(struct nvm_dev *, struct ppa_addr *, int, int, int,
                                                                void *, int);