summaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm
diff options
context:
space:
mode:
authorMatias Bjørling <m@bjorling.me>2016-07-07 03:54:19 -0400
committerJens Axboe <axboe@fb.com>2016-07-07 10:51:52 -0400
commit41285fad511a2c3746bee7ccb3b2f21b70305c14 (patch)
tree960420e74ab3069dff06c171f31041c3883f0b0b /drivers/lightnvm
parent8c39eddbf2842861f6c7412bd498c9d880b1c9e8 (diff)
lightnvm: remove _unlocked variant of [get/put]_blk
The [get/put]_blk API enables targets to get ownership of blocks at runtime. This information is currently not recorded on disk, and the information is therefore lost on power failure. To restore the metadata, the [get/put]_blk must persist its metadata. In that case, we need to control the outer lock, so that we can disable them while updating the on-disk metadata. Fortunately, the _unlocked versions can be removed, which allows us to move the lock into the [get/put]_blk functions. Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r--drivers/lightnvm/core.c14
-rw-r--r--drivers/lightnvm/gennvm.c32
-rw-r--r--drivers/lightnvm/rrpc.c14
3 files changed, 6 insertions, 54 deletions
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 04469e0c84ce..ddc809803084 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -176,20 +176,6 @@ static struct nvm_dev *nvm_find_nvm_dev(const char *name)
176 return NULL; 176 return NULL;
177} 177}
178 178
179struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *dev, struct nvm_lun *lun,
180 unsigned long flags)
181{
182 return dev->mt->get_blk_unlocked(dev, lun, flags);
183}
184EXPORT_SYMBOL(nvm_get_blk_unlocked);
185
186/* Assumes that all valid pages have already been moved on release to bm */
187void nvm_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk)
188{
189 return dev->mt->put_blk_unlocked(dev, blk);
190}
191EXPORT_SYMBOL(nvm_put_blk_unlocked);
192
193struct nvm_block *nvm_get_blk(struct nvm_dev *dev, struct nvm_lun *lun, 179struct nvm_block *nvm_get_blk(struct nvm_dev *dev, struct nvm_lun *lun,
194 unsigned long flags) 180 unsigned long flags)
195{ 181{
diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c
index 41760b24bea7..c65fb675e374 100644
--- a/drivers/lightnvm/gennvm.c
+++ b/drivers/lightnvm/gennvm.c
@@ -473,15 +473,14 @@ static void gen_unregister(struct nvm_dev *dev)
473 module_put(THIS_MODULE); 473 module_put(THIS_MODULE);
474} 474}
475 475
476static struct nvm_block *gen_get_blk_unlocked(struct nvm_dev *dev, 476static struct nvm_block *gen_get_blk(struct nvm_dev *dev,
477 struct nvm_lun *vlun, unsigned long flags) 477 struct nvm_lun *vlun, unsigned long flags)
478{ 478{
479 struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun); 479 struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun);
480 struct nvm_block *blk = NULL; 480 struct nvm_block *blk = NULL;
481 int is_gc = flags & NVM_IOTYPE_GC; 481 int is_gc = flags & NVM_IOTYPE_GC;
482 482
483 assert_spin_locked(&vlun->lock); 483 spin_lock(&vlun->lock);
484
485 if (list_empty(&lun->free_list)) { 484 if (list_empty(&lun->free_list)) {
486 pr_err_ratelimited("gen: lun %u have no free pages available", 485 pr_err_ratelimited("gen: lun %u have no free pages available",
487 lun->vlun.id); 486 lun->vlun.id);
@@ -496,29 +495,17 @@ static struct nvm_block *gen_get_blk_unlocked(struct nvm_dev *dev,
496 list_move_tail(&blk->list, &lun->used_list); 495 list_move_tail(&blk->list, &lun->used_list);
497 blk->state = NVM_BLK_ST_TGT; 496 blk->state = NVM_BLK_ST_TGT;
498 lun->vlun.nr_free_blocks--; 497 lun->vlun.nr_free_blocks--;
499
500out: 498out:
501 return blk;
502}
503
504static struct nvm_block *gen_get_blk(struct nvm_dev *dev,
505 struct nvm_lun *vlun, unsigned long flags)
506{
507 struct nvm_block *blk;
508
509 spin_lock(&vlun->lock);
510 blk = gen_get_blk_unlocked(dev, vlun, flags);
511 spin_unlock(&vlun->lock); 499 spin_unlock(&vlun->lock);
512 return blk; 500 return blk;
513} 501}
514 502
515static void gen_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk) 503static void gen_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
516{ 504{
517 struct nvm_lun *vlun = blk->lun; 505 struct nvm_lun *vlun = blk->lun;
518 struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun); 506 struct gen_lun *lun = container_of(vlun, struct gen_lun, vlun);
519 507
520 assert_spin_locked(&vlun->lock); 508 spin_lock(&vlun->lock);
521
522 if (blk->state & NVM_BLK_ST_TGT) { 509 if (blk->state & NVM_BLK_ST_TGT) {
523 list_move_tail(&blk->list, &lun->free_list); 510 list_move_tail(&blk->list, &lun->free_list);
524 lun->vlun.nr_free_blocks++; 511 lun->vlun.nr_free_blocks++;
@@ -532,14 +519,6 @@ static void gen_put_blk_unlocked(struct nvm_dev *dev, struct nvm_block *blk)
532 blk->id, blk->state); 519 blk->id, blk->state);
533 list_move_tail(&blk->list, &lun->bb_list); 520 list_move_tail(&blk->list, &lun->bb_list);
534 } 521 }
535}
536
537static void gen_put_blk(struct nvm_dev *dev, struct nvm_block *blk)
538{
539 struct nvm_lun *vlun = blk->lun;
540
541 spin_lock(&vlun->lock);
542 gen_put_blk_unlocked(dev, blk);
543 spin_unlock(&vlun->lock); 522 spin_unlock(&vlun->lock);
544} 523}
545 524
@@ -669,9 +648,6 @@ static struct nvmm_type gen = {
669 .create_tgt = gen_create_tgt, 648 .create_tgt = gen_create_tgt,
670 .remove_tgt = gen_remove_tgt, 649 .remove_tgt = gen_remove_tgt,
671 650
672 .get_blk_unlocked = gen_get_blk_unlocked,
673 .put_blk_unlocked = gen_put_blk_unlocked,
674
675 .get_blk = gen_get_blk, 651 .get_blk = gen_get_blk,
676 .put_blk = gen_put_blk, 652 .put_blk = gen_put_blk,
677 653
diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c
index 10ed22b9875d..fa8d5be2987c 100644
--- a/drivers/lightnvm/rrpc.c
+++ b/drivers/lightnvm/rrpc.c
@@ -192,21 +192,16 @@ static void rrpc_set_lun_cur(struct rrpc_lun *rlun, struct rrpc_block *rblk)
192static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun, 192static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
193 unsigned long flags) 193 unsigned long flags)
194{ 194{
195 struct nvm_lun *lun = rlun->parent;
196 struct nvm_block *blk; 195 struct nvm_block *blk;
197 struct rrpc_block *rblk; 196 struct rrpc_block *rblk;
198 197
199 spin_lock(&lun->lock); 198 blk = nvm_get_blk(rrpc->dev, rlun->parent, flags);
200 blk = nvm_get_blk_unlocked(rrpc->dev, rlun->parent, flags);
201 if (!blk) { 199 if (!blk) {
202 pr_err("nvm: rrpc: cannot get new block from media manager\n"); 200 pr_err("nvm: rrpc: cannot get new block from media manager\n");
203 spin_unlock(&lun->lock);
204 return NULL; 201 return NULL;
205 } 202 }
206 203
207 rblk = rrpc_get_rblk(rlun, blk->id); 204 rblk = rrpc_get_rblk(rlun, blk->id);
208 spin_unlock(&lun->lock);
209
210 blk->priv = rblk; 205 blk->priv = rblk;
211 bitmap_zero(rblk->invalid_pages, rrpc->dev->sec_per_blk); 206 bitmap_zero(rblk->invalid_pages, rrpc->dev->sec_per_blk);
212 rblk->next_page = 0; 207 rblk->next_page = 0;
@@ -218,12 +213,7 @@ static struct rrpc_block *rrpc_get_blk(struct rrpc *rrpc, struct rrpc_lun *rlun,
218 213
219static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk) 214static void rrpc_put_blk(struct rrpc *rrpc, struct rrpc_block *rblk)
220{ 215{
221 struct rrpc_lun *rlun = rblk->rlun; 216 nvm_put_blk(rrpc->dev, rblk->parent);
222 struct nvm_lun *lun = rlun->parent;
223
224 spin_lock(&lun->lock);
225 nvm_put_blk_unlocked(rrpc->dev, rblk->parent);
226 spin_unlock(&lun->lock);
227} 217}
228 218
229static void rrpc_put_blks(struct rrpc *rrpc) 219static void rrpc_put_blks(struct rrpc *rrpc)