hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/lightnvm/pblk-map.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2016 CNEX Labs
34 * Initial release: Javier Gonzalez <javier@cnexlabs.com>
....@@ -21,7 +22,7 @@
2122 static int pblk_map_page_data(struct pblk *pblk, unsigned int sentry,
2223 struct ppa_addr *ppa_list,
2324 unsigned long *lun_bitmap,
24
- struct pblk_sec_meta *meta_list,
25
+ void *meta_list,
2526 unsigned int valid_secs)
2627 {
2728 struct pblk_line *line = pblk_line_get_data(pblk);
....@@ -32,6 +33,9 @@
3233 int nr_secs = pblk->min_write_pgs;
3334 int i;
3435
36
+ if (!line)
37
+ return -ENOSPC;
38
+
3539 if (pblk_line_is_full(line)) {
3640 struct pblk_line *prev_line = line;
3741
....@@ -41,8 +45,11 @@
4145 line = pblk_line_replace_data(pblk);
4246 pblk_line_close_meta(pblk, prev_line);
4347
44
- if (!line)
45
- return -EINTR;
48
+ if (!line) {
49
+ pblk_pipeline_stop(pblk);
50
+ return -ENOSPC;
51
+ }
52
+
4653 }
4754
4855 emeta = line->emeta;
....@@ -51,6 +58,7 @@
5158 paddr = pblk_alloc_page(pblk, line, nr_secs);
5259
5360 for (i = 0; i < nr_secs; i++, paddr++) {
61
+ struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i);
5462 __le64 addr_empty = cpu_to_le64(ADDR_EMPTY);
5563
5664 /* ppa to be sent to the device */
....@@ -65,68 +73,79 @@
6573 */
6674 if (i < valid_secs) {
6775 kref_get(&line->ref);
76
+ atomic_inc(&line->sec_to_update);
6877 w_ctx = pblk_rb_w_ctx(&pblk->rwb, sentry + i);
6978 w_ctx->ppa = ppa_list[i];
70
- meta_list[i].lba = cpu_to_le64(w_ctx->lba);
79
+ meta->lba = cpu_to_le64(w_ctx->lba);
7180 lba_list[paddr] = cpu_to_le64(w_ctx->lba);
7281 if (lba_list[paddr] != addr_empty)
7382 line->nr_valid_lbas++;
7483 else
7584 atomic64_inc(&pblk->pad_wa);
7685 } else {
77
- lba_list[paddr] = meta_list[i].lba = addr_empty;
86
+ lba_list[paddr] = addr_empty;
87
+ meta->lba = addr_empty;
7888 __pblk_map_invalidate(pblk, line, paddr);
7989 }
8090 }
8191
82
- pblk_down_rq(pblk, ppa_list, nr_secs, lun_bitmap);
92
+ pblk_down_rq(pblk, ppa_list[0], lun_bitmap);
8393 return 0;
8494 }
8595
86
-void pblk_map_rq(struct pblk *pblk, struct nvm_rq *rqd, unsigned int sentry,
96
+int pblk_map_rq(struct pblk *pblk, struct nvm_rq *rqd, unsigned int sentry,
8797 unsigned long *lun_bitmap, unsigned int valid_secs,
8898 unsigned int off)
8999 {
90
- struct pblk_sec_meta *meta_list = rqd->meta_list;
100
+ void *meta_list = pblk_get_meta_for_writes(pblk, rqd);
101
+ void *meta_buffer;
102
+ struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
91103 unsigned int map_secs;
92104 int min = pblk->min_write_pgs;
93105 int i;
106
+ int ret;
94107
95108 for (i = off; i < rqd->nr_ppas; i += min) {
96109 map_secs = (i + min > valid_secs) ? (valid_secs % min) : min;
97
- if (pblk_map_page_data(pblk, sentry + i, &rqd->ppa_list[i],
98
- lun_bitmap, &meta_list[i], map_secs)) {
99
- bio_put(rqd->bio);
100
- pblk_free_rqd(pblk, rqd, PBLK_WRITE);
101
- pblk_pipeline_stop(pblk);
102
- }
110
+ meta_buffer = pblk_get_meta(pblk, meta_list, i);
111
+
112
+ ret = pblk_map_page_data(pblk, sentry + i, &ppa_list[i],
113
+ lun_bitmap, meta_buffer, map_secs);
114
+ if (ret)
115
+ return ret;
103116 }
117
+
118
+ return 0;
104119 }
105120
106121 /* only if erase_ppa is set, acquire erase semaphore */
107
-void pblk_map_erase_rq(struct pblk *pblk, struct nvm_rq *rqd,
122
+int pblk_map_erase_rq(struct pblk *pblk, struct nvm_rq *rqd,
108123 unsigned int sentry, unsigned long *lun_bitmap,
109124 unsigned int valid_secs, struct ppa_addr *erase_ppa)
110125 {
111126 struct nvm_tgt_dev *dev = pblk->dev;
112127 struct nvm_geo *geo = &dev->geo;
113128 struct pblk_line_meta *lm = &pblk->lm;
114
- struct pblk_sec_meta *meta_list = rqd->meta_list;
129
+ void *meta_list = pblk_get_meta_for_writes(pblk, rqd);
130
+ void *meta_buffer;
131
+ struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
115132 struct pblk_line *e_line, *d_line;
116133 unsigned int map_secs;
117134 int min = pblk->min_write_pgs;
118135 int i, erase_lun;
136
+ int ret;
137
+
119138
120139 for (i = 0; i < rqd->nr_ppas; i += min) {
121140 map_secs = (i + min > valid_secs) ? (valid_secs % min) : min;
122
- if (pblk_map_page_data(pblk, sentry + i, &rqd->ppa_list[i],
123
- lun_bitmap, &meta_list[i], map_secs)) {
124
- bio_put(rqd->bio);
125
- pblk_free_rqd(pblk, rqd, PBLK_WRITE);
126
- pblk_pipeline_stop(pblk);
127
- }
141
+ meta_buffer = pblk_get_meta(pblk, meta_list, i);
128142
129
- erase_lun = pblk_ppa_to_pos(geo, rqd->ppa_list[i]);
143
+ ret = pblk_map_page_data(pblk, sentry + i, &ppa_list[i],
144
+ lun_bitmap, meta_buffer, map_secs);
145
+ if (ret)
146
+ return ret;
147
+
148
+ erase_lun = pblk_ppa_to_pos(geo, ppa_list[i]);
130149
131150 /* line can change after page map. We might also be writing the
132151 * last line.
....@@ -141,8 +160,9 @@
141160 set_bit(erase_lun, e_line->erase_bitmap);
142161 atomic_dec(&e_line->left_eblks);
143162
144
- *erase_ppa = rqd->ppa_list[i];
163
+ *erase_ppa = ppa_list[i];
145164 erase_ppa->a.blk = e_line->id;
165
+ erase_ppa->a.reserved = 0;
146166
147167 spin_unlock(&e_line->lock);
148168
....@@ -160,7 +180,7 @@
160180 */
161181 e_line = pblk_line_get_erase(pblk);
162182 if (!e_line)
163
- return;
183
+ return -ENOSPC;
164184
165185 /* Erase blocks that are bad in this line but might not be in next */
166186 if (unlikely(pblk_ppa_empty(*erase_ppa)) &&
....@@ -171,7 +191,7 @@
171191 bit = find_next_bit(d_line->blk_bitmap,
172192 lm->blk_per_line, bit + 1);
173193 if (bit >= lm->blk_per_line)
174
- return;
194
+ return 0;
175195
176196 spin_lock(&e_line->lock);
177197 if (test_bit(bit, e_line->erase_bitmap)) {
....@@ -185,4 +205,6 @@
185205 *erase_ppa = pblk->luns[bit].bppa; /* set ch and lun */
186206 erase_ppa->a.blk = e_line->id;
187207 }
208
+
209
+ return 0;
188210 }