summaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/pblk-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lightnvm/pblk-cache.c')
-rw-r--r--drivers/lightnvm/pblk-cache.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/lightnvm/pblk-cache.c b/drivers/lightnvm/pblk-cache.c
index 024a8fc93069..0d227ef7d1b9 100644
--- a/drivers/lightnvm/pblk-cache.c
+++ b/drivers/lightnvm/pblk-cache.c
@@ -43,8 +43,10 @@ retry:
43 if (unlikely(!bio_has_data(bio))) 43 if (unlikely(!bio_has_data(bio)))
44 goto out; 44 goto out;
45 45
46 w_ctx.flags = flags;
47 pblk_ppa_set_empty(&w_ctx.ppa); 46 pblk_ppa_set_empty(&w_ctx.ppa);
47 w_ctx.flags = flags;
48 if (bio->bi_opf & REQ_PREFLUSH)
49 w_ctx.flags |= PBLK_FLUSH_ENTRY;
48 50
49 for (i = 0; i < nr_entries; i++) { 51 for (i = 0; i < nr_entries; i++) {
50 void *data = bio_data(bio); 52 void *data = bio_data(bio);
@@ -73,12 +75,11 @@ out:
73 * On GC the incoming lbas are not necessarily sequential. Also, some of the 75 * On GC the incoming lbas are not necessarily sequential. Also, some of the
74 * lbas might not be valid entries, which are marked as empty by the GC thread 76 * lbas might not be valid entries, which are marked as empty by the GC thread
75 */ 77 */
76int pblk_write_gc_to_cache(struct pblk *pblk, void *data, u64 *lba_list, 78int pblk_write_gc_to_cache(struct pblk *pblk, struct pblk_gc_rq *gc_rq)
77 unsigned int nr_entries, unsigned int nr_rec_entries,
78 struct pblk_line *gc_line, unsigned long flags)
79{ 79{
80 struct pblk_w_ctx w_ctx; 80 struct pblk_w_ctx w_ctx;
81 unsigned int bpos, pos; 81 unsigned int bpos, pos;
82 void *data = gc_rq->data;
82 int i, valid_entries; 83 int i, valid_entries;
83 84
84 /* Update the write buffer head (mem) with the entries that we can 85 /* Update the write buffer head (mem) with the entries that we can
@@ -86,28 +87,29 @@ int pblk_write_gc_to_cache(struct pblk *pblk, void *data, u64 *lba_list,
86 * rollback from here on. 87 * rollback from here on.
87 */ 88 */
88retry: 89retry:
89 if (!pblk_rb_may_write_gc(&pblk->rwb, nr_rec_entries, &bpos)) { 90 if (!pblk_rb_may_write_gc(&pblk->rwb, gc_rq->secs_to_gc, &bpos)) {
90 io_schedule(); 91 io_schedule();
91 goto retry; 92 goto retry;
92 } 93 }
93 94
94 w_ctx.flags = flags; 95 w_ctx.flags = PBLK_IOTYPE_GC;
95 pblk_ppa_set_empty(&w_ctx.ppa); 96 pblk_ppa_set_empty(&w_ctx.ppa);
96 97
97 for (i = 0, valid_entries = 0; i < nr_entries; i++) { 98 for (i = 0, valid_entries = 0; i < gc_rq->nr_secs; i++) {
98 if (lba_list[i] == ADDR_EMPTY) 99 if (gc_rq->lba_list[i] == ADDR_EMPTY)
99 continue; 100 continue;
100 101
101 w_ctx.lba = lba_list[i]; 102 w_ctx.lba = gc_rq->lba_list[i];
102 103
103 pos = pblk_rb_wrap_pos(&pblk->rwb, bpos + valid_entries); 104 pos = pblk_rb_wrap_pos(&pblk->rwb, bpos + valid_entries);
104 pblk_rb_write_entry_gc(&pblk->rwb, data, w_ctx, gc_line, pos); 105 pblk_rb_write_entry_gc(&pblk->rwb, data, w_ctx, gc_rq->line,
106 gc_rq->paddr_list[i], pos);
105 107
106 data += PBLK_EXPOSED_PAGE_SIZE; 108 data += PBLK_EXPOSED_PAGE_SIZE;
107 valid_entries++; 109 valid_entries++;
108 } 110 }
109 111
110 WARN_ONCE(nr_rec_entries != valid_entries, 112 WARN_ONCE(gc_rq->secs_to_gc != valid_entries,
111 "pblk: inconsistent GC write\n"); 113 "pblk: inconsistent GC write\n");
112 114
113#ifdef CONFIG_NVM_DEBUG 115#ifdef CONFIG_NVM_DEBUG