.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2016 CNEX Labs |
---|
3 | 4 | * Initial release: Javier Gonzalez <javier@cnexlabs.com> |
---|
.. | .. |
---|
25 | 26 | * issued. |
---|
26 | 27 | */ |
---|
27 | 28 | static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio, |
---|
28 | | - sector_t lba, struct ppa_addr ppa, |
---|
29 | | - int bio_iter, bool advanced_bio) |
---|
| 29 | + sector_t lba, struct ppa_addr ppa) |
---|
30 | 30 | { |
---|
31 | 31 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
32 | 32 | /* Callers must ensure that the ppa points to a cache address */ |
---|
.. | .. |
---|
34 | 34 | BUG_ON(!pblk_addr_in_cache(ppa)); |
---|
35 | 35 | #endif |
---|
36 | 36 | |
---|
37 | | - return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa, |
---|
38 | | - bio_iter, advanced_bio); |
---|
| 37 | + return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa); |
---|
39 | 38 | } |
---|
40 | 39 | |
---|
41 | | -static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd, |
---|
| 40 | +static int pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd, |
---|
42 | 41 | struct bio *bio, sector_t blba, |
---|
43 | | - unsigned long *read_bitmap) |
---|
| 42 | + bool *from_cache) |
---|
44 | 43 | { |
---|
45 | | - struct pblk_sec_meta *meta_list = rqd->meta_list; |
---|
46 | | - struct ppa_addr ppas[PBLK_MAX_REQ_ADDRS]; |
---|
47 | | - int nr_secs = rqd->nr_ppas; |
---|
48 | | - bool advanced_bio = false; |
---|
49 | | - int i, j = 0; |
---|
50 | | - |
---|
51 | | - pblk_lookup_l2p_seq(pblk, ppas, blba, nr_secs); |
---|
52 | | - |
---|
53 | | - for (i = 0; i < nr_secs; i++) { |
---|
54 | | - struct ppa_addr p = ppas[i]; |
---|
55 | | - sector_t lba = blba + i; |
---|
| 44 | + void *meta_list = rqd->meta_list; |
---|
| 45 | + int nr_secs, i; |
---|
56 | 46 | |
---|
57 | 47 | retry: |
---|
58 | | - if (pblk_ppa_empty(p)) { |
---|
59 | | - WARN_ON(test_and_set_bit(i, read_bitmap)); |
---|
60 | | - meta_list[i].lba = cpu_to_le64(ADDR_EMPTY); |
---|
| 48 | + nr_secs = pblk_lookup_l2p_seq(pblk, rqd->ppa_list, blba, rqd->nr_ppas, |
---|
| 49 | + from_cache); |
---|
61 | 50 | |
---|
62 | | - if (unlikely(!advanced_bio)) { |
---|
63 | | - bio_advance(bio, (i) * PBLK_EXPOSED_PAGE_SIZE); |
---|
64 | | - advanced_bio = true; |
---|
| 51 | + if (!*from_cache) |
---|
| 52 | + goto end; |
---|
| 53 | + |
---|
| 54 | + for (i = 0; i < nr_secs; i++) { |
---|
| 55 | + struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i); |
---|
| 56 | + sector_t lba = blba + i; |
---|
| 57 | + |
---|
| 58 | + if (pblk_ppa_empty(rqd->ppa_list[i])) { |
---|
| 59 | + __le64 addr_empty = cpu_to_le64(ADDR_EMPTY); |
---|
| 60 | + |
---|
| 61 | + meta->lba = addr_empty; |
---|
| 62 | + } else if (pblk_addr_in_cache(rqd->ppa_list[i])) { |
---|
| 63 | + /* |
---|
| 64 | + * Try to read from write buffer. The address is later |
---|
| 65 | + * checked on the write buffer to prevent retrieving |
---|
| 66 | + * overwritten data. |
---|
| 67 | + */ |
---|
| 68 | + if (!pblk_read_from_cache(pblk, bio, lba, |
---|
| 69 | + rqd->ppa_list[i])) { |
---|
| 70 | + if (i == 0) { |
---|
| 71 | + /* |
---|
| 72 | + * We didn't call with bio_advance() |
---|
| 73 | + * yet, so we can just retry. |
---|
| 74 | + */ |
---|
| 75 | + goto retry; |
---|
| 76 | + } else { |
---|
| 77 | + /* |
---|
| 78 | + * We already call bio_advance() |
---|
| 79 | + * so we cannot retry and we need |
---|
| 80 | + * to quit that function in order |
---|
| 81 | + * to allow caller to handle the bio |
---|
| 82 | + * splitting in the current sector |
---|
| 83 | + * position. |
---|
| 84 | + */ |
---|
| 85 | + nr_secs = i; |
---|
| 86 | + goto end; |
---|
| 87 | + } |
---|
65 | 88 | } |
---|
66 | | - |
---|
67 | | - goto next; |
---|
68 | | - } |
---|
69 | | - |
---|
70 | | - /* Try to read from write buffer. The address is later checked |
---|
71 | | - * on the write buffer to prevent retrieving overwritten data. |
---|
72 | | - */ |
---|
73 | | - if (pblk_addr_in_cache(p)) { |
---|
74 | | - if (!pblk_read_from_cache(pblk, bio, lba, p, i, |
---|
75 | | - advanced_bio)) { |
---|
76 | | - pblk_lookup_l2p_seq(pblk, &p, lba, 1); |
---|
77 | | - goto retry; |
---|
78 | | - } |
---|
79 | | - WARN_ON(test_and_set_bit(i, read_bitmap)); |
---|
80 | | - meta_list[i].lba = cpu_to_le64(lba); |
---|
81 | | - advanced_bio = true; |
---|
| 89 | + meta->lba = cpu_to_le64(lba); |
---|
82 | 90 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
83 | 91 | atomic_long_inc(&pblk->cache_reads); |
---|
84 | 92 | #endif |
---|
85 | | - } else { |
---|
86 | | - /* Read from media non-cached sectors */ |
---|
87 | | - rqd->ppa_list[j++] = p; |
---|
88 | 93 | } |
---|
89 | | - |
---|
90 | | -next: |
---|
91 | | - if (advanced_bio) |
---|
92 | | - bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE); |
---|
| 94 | + bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE); |
---|
93 | 95 | } |
---|
94 | 96 | |
---|
| 97 | +end: |
---|
95 | 98 | if (pblk_io_aligned(pblk, nr_secs)) |
---|
96 | | - rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); |
---|
97 | | - else |
---|
98 | | - rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); |
---|
| 99 | + rqd->is_seq = 1; |
---|
99 | 100 | |
---|
100 | 101 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
101 | 102 | atomic_long_add(nr_secs, &pblk->inflight_reads); |
---|
102 | 103 | #endif |
---|
| 104 | + |
---|
| 105 | + return nr_secs; |
---|
103 | 106 | } |
---|
104 | 107 | |
---|
105 | 108 | |
---|
106 | 109 | static void pblk_read_check_seq(struct pblk *pblk, struct nvm_rq *rqd, |
---|
107 | 110 | sector_t blba) |
---|
108 | 111 | { |
---|
109 | | - struct pblk_sec_meta *meta_lba_list = rqd->meta_list; |
---|
| 112 | + void *meta_list = rqd->meta_list; |
---|
110 | 113 | int nr_lbas = rqd->nr_ppas; |
---|
111 | 114 | int i; |
---|
112 | 115 | |
---|
| 116 | + if (!pblk_is_oob_meta_supported(pblk)) |
---|
| 117 | + return; |
---|
| 118 | + |
---|
113 | 119 | for (i = 0; i < nr_lbas; i++) { |
---|
114 | | - u64 lba = le64_to_cpu(meta_lba_list[i].lba); |
---|
| 120 | + struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i); |
---|
| 121 | + u64 lba = le64_to_cpu(meta->lba); |
---|
115 | 122 | |
---|
116 | 123 | if (lba == ADDR_EMPTY) |
---|
117 | 124 | continue; |
---|
118 | 125 | |
---|
119 | 126 | if (lba != blba + i) { |
---|
120 | 127 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
121 | | - struct ppa_addr *p; |
---|
| 128 | + struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd); |
---|
122 | 129 | |
---|
123 | | - p = (nr_lbas == 1) ? &rqd->ppa_list[i] : &rqd->ppa_addr; |
---|
124 | | - print_ppa(pblk, p, "seq", i); |
---|
| 130 | + print_ppa(pblk, &ppa_list[i], "seq", i); |
---|
125 | 131 | #endif |
---|
126 | 132 | pblk_err(pblk, "corrupted read LBA (%llu/%llu)\n", |
---|
127 | 133 | lba, (u64)blba + i); |
---|
.. | .. |
---|
136 | 142 | static void pblk_read_check_rand(struct pblk *pblk, struct nvm_rq *rqd, |
---|
137 | 143 | u64 *lba_list, int nr_lbas) |
---|
138 | 144 | { |
---|
139 | | - struct pblk_sec_meta *meta_lba_list = rqd->meta_list; |
---|
| 145 | + void *meta_lba_list = rqd->meta_list; |
---|
140 | 146 | int i, j; |
---|
141 | 147 | |
---|
| 148 | + if (!pblk_is_oob_meta_supported(pblk)) |
---|
| 149 | + return; |
---|
| 150 | + |
---|
142 | 151 | for (i = 0, j = 0; i < nr_lbas; i++) { |
---|
| 152 | + struct pblk_sec_meta *meta = pblk_get_meta(pblk, |
---|
| 153 | + meta_lba_list, j); |
---|
143 | 154 | u64 lba = lba_list[i]; |
---|
144 | 155 | u64 meta_lba; |
---|
145 | 156 | |
---|
146 | 157 | if (lba == ADDR_EMPTY) |
---|
147 | 158 | continue; |
---|
148 | 159 | |
---|
149 | | - meta_lba = le64_to_cpu(meta_lba_list[j].lba); |
---|
| 160 | + meta_lba = le64_to_cpu(meta->lba); |
---|
150 | 161 | |
---|
151 | 162 | if (lba != meta_lba) { |
---|
152 | 163 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
153 | | - struct ppa_addr *p; |
---|
154 | | - int nr_ppas = rqd->nr_ppas; |
---|
| 164 | + struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd); |
---|
155 | 165 | |
---|
156 | | - p = (nr_ppas == 1) ? &rqd->ppa_list[j] : &rqd->ppa_addr; |
---|
157 | | - print_ppa(pblk, p, "seq", j); |
---|
| 166 | + print_ppa(pblk, &ppa_list[j], "rnd", j); |
---|
158 | 167 | #endif |
---|
159 | 168 | pblk_err(pblk, "corrupted read LBA (%llu/%llu)\n", |
---|
160 | | - lba, meta_lba); |
---|
| 169 | + meta_lba, lba); |
---|
161 | 170 | WARN_ON(1); |
---|
162 | 171 | } |
---|
163 | 172 | |
---|
.. | .. |
---|
167 | 176 | WARN_ONCE(j != rqd->nr_ppas, "pblk: corrupted random request\n"); |
---|
168 | 177 | } |
---|
169 | 178 | |
---|
170 | | -static void pblk_read_put_rqd_kref(struct pblk *pblk, struct nvm_rq *rqd) |
---|
| 179 | +static void pblk_end_user_read(struct bio *bio, int error) |
---|
171 | 180 | { |
---|
172 | | - struct ppa_addr *ppa_list; |
---|
173 | | - int i; |
---|
174 | | - |
---|
175 | | - ppa_list = (rqd->nr_ppas > 1) ? rqd->ppa_list : &rqd->ppa_addr; |
---|
176 | | - |
---|
177 | | - for (i = 0; i < rqd->nr_ppas; i++) { |
---|
178 | | - struct ppa_addr ppa = ppa_list[i]; |
---|
179 | | - struct pblk_line *line; |
---|
180 | | - |
---|
181 | | - line = &pblk->lines[pblk_ppa_to_line(ppa)]; |
---|
182 | | - kref_put(&line->ref, pblk_line_put_wq); |
---|
183 | | - } |
---|
184 | | -} |
---|
185 | | - |
---|
186 | | -static void pblk_end_user_read(struct bio *bio) |
---|
187 | | -{ |
---|
188 | | -#ifdef CONFIG_NVM_PBLK_DEBUG |
---|
189 | | - WARN_ONCE(bio->bi_status, "pblk: corrupted read bio\n"); |
---|
190 | | -#endif |
---|
191 | | - bio_endio(bio); |
---|
| 181 | + if (error && error != NVM_RSP_WARN_HIGHECC) |
---|
| 182 | + bio_io_error(bio); |
---|
| 183 | + else |
---|
| 184 | + bio_endio(bio); |
---|
192 | 185 | } |
---|
193 | 186 | |
---|
194 | 187 | static void __pblk_end_io_read(struct pblk *pblk, struct nvm_rq *rqd, |
---|
195 | 188 | bool put_line) |
---|
196 | 189 | { |
---|
197 | | - struct nvm_tgt_dev *dev = pblk->dev; |
---|
198 | 190 | struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); |
---|
199 | 191 | struct bio *int_bio = rqd->bio; |
---|
200 | 192 | unsigned long start_time = r_ctx->start_time; |
---|
201 | 193 | |
---|
202 | | - generic_end_io_acct(dev->q, REQ_OP_READ, &pblk->disk->part0, start_time); |
---|
| 194 | + bio_end_io_acct(int_bio, start_time); |
---|
203 | 195 | |
---|
204 | 196 | if (rqd->error) |
---|
205 | 197 | pblk_log_read_err(pblk, rqd); |
---|
206 | 198 | |
---|
207 | 199 | pblk_read_check_seq(pblk, rqd, r_ctx->lba); |
---|
208 | | - |
---|
209 | | - if (int_bio) |
---|
210 | | - bio_put(int_bio); |
---|
| 200 | + bio_put(int_bio); |
---|
211 | 201 | |
---|
212 | 202 | if (put_line) |
---|
213 | | - pblk_read_put_rqd_kref(pblk, rqd); |
---|
| 203 | + pblk_rq_to_line_put(pblk, rqd); |
---|
214 | 204 | |
---|
215 | 205 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
216 | 206 | atomic_long_add(rqd->nr_ppas, &pblk->sync_reads); |
---|
.. | .. |
---|
227 | 217 | struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); |
---|
228 | 218 | struct bio *bio = (struct bio *)r_ctx->private; |
---|
229 | 219 | |
---|
230 | | - pblk_end_user_read(bio); |
---|
| 220 | + pblk_end_user_read(bio, rqd->error); |
---|
231 | 221 | __pblk_end_io_read(pblk, rqd, true); |
---|
232 | 222 | } |
---|
233 | 223 | |
---|
234 | | -static void pblk_end_partial_read(struct nvm_rq *rqd) |
---|
235 | | -{ |
---|
236 | | - struct pblk *pblk = rqd->private; |
---|
237 | | - struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); |
---|
238 | | - struct pblk_pr_ctx *pr_ctx = r_ctx->private; |
---|
239 | | - struct bio *new_bio = rqd->bio; |
---|
240 | | - struct bio *bio = pr_ctx->orig_bio; |
---|
241 | | - struct bio_vec src_bv, dst_bv; |
---|
242 | | - struct pblk_sec_meta *meta_list = rqd->meta_list; |
---|
243 | | - int bio_init_idx = pr_ctx->bio_init_idx; |
---|
244 | | - unsigned long *read_bitmap = pr_ctx->bitmap; |
---|
245 | | - int nr_secs = pr_ctx->orig_nr_secs; |
---|
246 | | - int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); |
---|
247 | | - __le64 *lba_list_mem, *lba_list_media; |
---|
248 | | - void *src_p, *dst_p; |
---|
249 | | - int hole, i; |
---|
250 | | - |
---|
251 | | - if (unlikely(nr_holes == 1)) { |
---|
252 | | - struct ppa_addr ppa; |
---|
253 | | - |
---|
254 | | - ppa = rqd->ppa_addr; |
---|
255 | | - rqd->ppa_list = pr_ctx->ppa_ptr; |
---|
256 | | - rqd->dma_ppa_list = pr_ctx->dma_ppa_list; |
---|
257 | | - rqd->ppa_list[0] = ppa; |
---|
258 | | - } |
---|
259 | | - |
---|
260 | | - /* Re-use allocated memory for intermediate lbas */ |
---|
261 | | - lba_list_mem = (((void *)rqd->ppa_list) + pblk_dma_ppa_size); |
---|
262 | | - lba_list_media = (((void *)rqd->ppa_list) + 2 * pblk_dma_ppa_size); |
---|
263 | | - |
---|
264 | | - for (i = 0; i < nr_secs; i++) { |
---|
265 | | - lba_list_media[i] = meta_list[i].lba; |
---|
266 | | - meta_list[i].lba = lba_list_mem[i]; |
---|
267 | | - } |
---|
268 | | - |
---|
269 | | - /* Fill the holes in the original bio */ |
---|
270 | | - i = 0; |
---|
271 | | - hole = find_first_zero_bit(read_bitmap, nr_secs); |
---|
272 | | - do { |
---|
273 | | - int line_id = pblk_ppa_to_line(rqd->ppa_list[i]); |
---|
274 | | - struct pblk_line *line = &pblk->lines[line_id]; |
---|
275 | | - |
---|
276 | | - kref_put(&line->ref, pblk_line_put); |
---|
277 | | - |
---|
278 | | - meta_list[hole].lba = lba_list_media[i]; |
---|
279 | | - |
---|
280 | | - src_bv = new_bio->bi_io_vec[i++]; |
---|
281 | | - dst_bv = bio->bi_io_vec[bio_init_idx + hole]; |
---|
282 | | - |
---|
283 | | - src_p = kmap_atomic(src_bv.bv_page); |
---|
284 | | - dst_p = kmap_atomic(dst_bv.bv_page); |
---|
285 | | - |
---|
286 | | - memcpy(dst_p + dst_bv.bv_offset, |
---|
287 | | - src_p + src_bv.bv_offset, |
---|
288 | | - PBLK_EXPOSED_PAGE_SIZE); |
---|
289 | | - |
---|
290 | | - kunmap_atomic(src_p); |
---|
291 | | - kunmap_atomic(dst_p); |
---|
292 | | - |
---|
293 | | - mempool_free(src_bv.bv_page, &pblk->page_bio_pool); |
---|
294 | | - |
---|
295 | | - hole = find_next_zero_bit(read_bitmap, nr_secs, hole + 1); |
---|
296 | | - } while (hole < nr_secs); |
---|
297 | | - |
---|
298 | | - bio_put(new_bio); |
---|
299 | | - kfree(pr_ctx); |
---|
300 | | - |
---|
301 | | - /* restore original request */ |
---|
302 | | - rqd->bio = NULL; |
---|
303 | | - rqd->nr_ppas = nr_secs; |
---|
304 | | - |
---|
305 | | - bio_endio(bio); |
---|
306 | | - __pblk_end_io_read(pblk, rqd, false); |
---|
307 | | -} |
---|
308 | | - |
---|
309 | | -static int pblk_setup_partial_read(struct pblk *pblk, struct nvm_rq *rqd, |
---|
310 | | - unsigned int bio_init_idx, |
---|
311 | | - unsigned long *read_bitmap, |
---|
312 | | - int nr_holes) |
---|
313 | | -{ |
---|
314 | | - struct pblk_sec_meta *meta_list = rqd->meta_list; |
---|
315 | | - struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); |
---|
316 | | - struct pblk_pr_ctx *pr_ctx; |
---|
317 | | - struct bio *new_bio, *bio = r_ctx->private; |
---|
318 | | - __le64 *lba_list_mem; |
---|
319 | | - int nr_secs = rqd->nr_ppas; |
---|
320 | | - int i; |
---|
321 | | - |
---|
322 | | - /* Re-use allocated memory for intermediate lbas */ |
---|
323 | | - lba_list_mem = (((void *)rqd->ppa_list) + pblk_dma_ppa_size); |
---|
324 | | - |
---|
325 | | - new_bio = bio_alloc(GFP_KERNEL, nr_holes); |
---|
326 | | - |
---|
327 | | - if (pblk_bio_add_pages(pblk, new_bio, GFP_KERNEL, nr_holes)) |
---|
328 | | - goto fail_bio_put; |
---|
329 | | - |
---|
330 | | - if (nr_holes != new_bio->bi_vcnt) { |
---|
331 | | - WARN_ONCE(1, "pblk: malformed bio\n"); |
---|
332 | | - goto fail_free_pages; |
---|
333 | | - } |
---|
334 | | - |
---|
335 | | - pr_ctx = kmalloc(sizeof(struct pblk_pr_ctx), GFP_KERNEL); |
---|
336 | | - if (!pr_ctx) |
---|
337 | | - goto fail_free_pages; |
---|
338 | | - |
---|
339 | | - for (i = 0; i < nr_secs; i++) |
---|
340 | | - lba_list_mem[i] = meta_list[i].lba; |
---|
341 | | - |
---|
342 | | - new_bio->bi_iter.bi_sector = 0; /* internal bio */ |
---|
343 | | - bio_set_op_attrs(new_bio, REQ_OP_READ, 0); |
---|
344 | | - |
---|
345 | | - rqd->bio = new_bio; |
---|
346 | | - rqd->nr_ppas = nr_holes; |
---|
347 | | - rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); |
---|
348 | | - |
---|
349 | | - pr_ctx->ppa_ptr = NULL; |
---|
350 | | - pr_ctx->orig_bio = bio; |
---|
351 | | - bitmap_copy(pr_ctx->bitmap, read_bitmap, NVM_MAX_VLBA); |
---|
352 | | - pr_ctx->bio_init_idx = bio_init_idx; |
---|
353 | | - pr_ctx->orig_nr_secs = nr_secs; |
---|
354 | | - r_ctx->private = pr_ctx; |
---|
355 | | - |
---|
356 | | - if (unlikely(nr_holes == 1)) { |
---|
357 | | - pr_ctx->ppa_ptr = rqd->ppa_list; |
---|
358 | | - pr_ctx->dma_ppa_list = rqd->dma_ppa_list; |
---|
359 | | - rqd->ppa_addr = rqd->ppa_list[0]; |
---|
360 | | - } |
---|
361 | | - return 0; |
---|
362 | | - |
---|
363 | | -fail_free_pages: |
---|
364 | | - pblk_bio_free_pages(pblk, new_bio, 0, new_bio->bi_vcnt); |
---|
365 | | -fail_bio_put: |
---|
366 | | - bio_put(new_bio); |
---|
367 | | - |
---|
368 | | - return -ENOMEM; |
---|
369 | | -} |
---|
370 | | - |
---|
371 | | -static int pblk_partial_read_bio(struct pblk *pblk, struct nvm_rq *rqd, |
---|
372 | | - unsigned int bio_init_idx, |
---|
373 | | - unsigned long *read_bitmap, int nr_secs) |
---|
374 | | -{ |
---|
375 | | - int nr_holes; |
---|
376 | | - int ret; |
---|
377 | | - |
---|
378 | | - nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); |
---|
379 | | - |
---|
380 | | - if (pblk_setup_partial_read(pblk, rqd, bio_init_idx, read_bitmap, |
---|
381 | | - nr_holes)) |
---|
382 | | - return NVM_IO_ERR; |
---|
383 | | - |
---|
384 | | - rqd->end_io = pblk_end_partial_read; |
---|
385 | | - |
---|
386 | | - ret = pblk_submit_io(pblk, rqd); |
---|
387 | | - if (ret) { |
---|
388 | | - bio_put(rqd->bio); |
---|
389 | | - pblk_err(pblk, "partial read IO submission failed\n"); |
---|
390 | | - goto err; |
---|
391 | | - } |
---|
392 | | - |
---|
393 | | - return NVM_IO_OK; |
---|
394 | | - |
---|
395 | | -err: |
---|
396 | | - pblk_err(pblk, "failed to perform partial read\n"); |
---|
397 | | - |
---|
398 | | - /* Free allocated pages in new bio */ |
---|
399 | | - pblk_bio_free_pages(pblk, rqd->bio, 0, rqd->bio->bi_vcnt); |
---|
400 | | - __pblk_end_io_read(pblk, rqd, false); |
---|
401 | | - return NVM_IO_ERR; |
---|
402 | | -} |
---|
403 | | - |
---|
404 | 224 | static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd, struct bio *bio, |
---|
405 | | - sector_t lba, unsigned long *read_bitmap) |
---|
| 225 | + sector_t lba, bool *from_cache) |
---|
406 | 226 | { |
---|
407 | | - struct pblk_sec_meta *meta_list = rqd->meta_list; |
---|
| 227 | + struct pblk_sec_meta *meta = pblk_get_meta(pblk, rqd->meta_list, 0); |
---|
408 | 228 | struct ppa_addr ppa; |
---|
409 | 229 | |
---|
410 | | - pblk_lookup_l2p_seq(pblk, &ppa, lba, 1); |
---|
| 230 | + pblk_lookup_l2p_seq(pblk, &ppa, lba, 1, from_cache); |
---|
411 | 231 | |
---|
412 | 232 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
413 | 233 | atomic_long_inc(&pblk->inflight_reads); |
---|
.. | .. |
---|
415 | 235 | |
---|
416 | 236 | retry: |
---|
417 | 237 | if (pblk_ppa_empty(ppa)) { |
---|
418 | | - WARN_ON(test_and_set_bit(0, read_bitmap)); |
---|
419 | | - meta_list[0].lba = cpu_to_le64(ADDR_EMPTY); |
---|
| 238 | + __le64 addr_empty = cpu_to_le64(ADDR_EMPTY); |
---|
| 239 | + |
---|
| 240 | + meta->lba = addr_empty; |
---|
420 | 241 | return; |
---|
421 | 242 | } |
---|
422 | 243 | |
---|
.. | .. |
---|
424 | 245 | * write buffer to prevent retrieving overwritten data. |
---|
425 | 246 | */ |
---|
426 | 247 | if (pblk_addr_in_cache(ppa)) { |
---|
427 | | - if (!pblk_read_from_cache(pblk, bio, lba, ppa, 0, 1)) { |
---|
428 | | - pblk_lookup_l2p_seq(pblk, &ppa, lba, 1); |
---|
| 248 | + if (!pblk_read_from_cache(pblk, bio, lba, ppa)) { |
---|
| 249 | + pblk_lookup_l2p_seq(pblk, &ppa, lba, 1, from_cache); |
---|
429 | 250 | goto retry; |
---|
430 | 251 | } |
---|
431 | 252 | |
---|
432 | | - WARN_ON(test_and_set_bit(0, read_bitmap)); |
---|
433 | | - meta_list[0].lba = cpu_to_le64(lba); |
---|
| 253 | + meta->lba = cpu_to_le64(lba); |
---|
434 | 254 | |
---|
435 | 255 | #ifdef CONFIG_NVM_PBLK_DEBUG |
---|
436 | 256 | atomic_long_inc(&pblk->cache_reads); |
---|
.. | .. |
---|
438 | 258 | } else { |
---|
439 | 259 | rqd->ppa_addr = ppa; |
---|
440 | 260 | } |
---|
441 | | - |
---|
442 | | - rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); |
---|
443 | 261 | } |
---|
444 | 262 | |
---|
445 | | -int pblk_submit_read(struct pblk *pblk, struct bio *bio) |
---|
| 263 | +void pblk_submit_read(struct pblk *pblk, struct bio *bio) |
---|
446 | 264 | { |
---|
447 | | - struct nvm_tgt_dev *dev = pblk->dev; |
---|
448 | | - struct request_queue *q = dev->q; |
---|
449 | 265 | sector_t blba = pblk_get_lba(bio); |
---|
450 | 266 | unsigned int nr_secs = pblk_get_secs(bio); |
---|
| 267 | + bool from_cache; |
---|
451 | 268 | struct pblk_g_ctx *r_ctx; |
---|
452 | 269 | struct nvm_rq *rqd; |
---|
453 | | - unsigned int bio_init_idx; |
---|
454 | | - DECLARE_BITMAP(read_bitmap, NVM_MAX_VLBA); |
---|
455 | | - int ret = NVM_IO_ERR; |
---|
| 270 | + struct bio *int_bio, *split_bio; |
---|
| 271 | + unsigned long start_time; |
---|
456 | 272 | |
---|
457 | | - /* logic error: lba out-of-bounds. Ignore read request */ |
---|
458 | | - if (blba >= pblk->rl.nr_secs || nr_secs > PBLK_MAX_REQ_ADDRS) { |
---|
459 | | - WARN(1, "pblk: read lba out of bounds (lba:%llu, nr:%d)\n", |
---|
460 | | - (unsigned long long)blba, nr_secs); |
---|
461 | | - return NVM_IO_ERR; |
---|
462 | | - } |
---|
463 | | - |
---|
464 | | - generic_start_io_acct(q, REQ_OP_READ, bio_sectors(bio), |
---|
465 | | - &pblk->disk->part0); |
---|
466 | | - |
---|
467 | | - bitmap_zero(read_bitmap, nr_secs); |
---|
| 273 | + start_time = bio_start_io_acct(bio); |
---|
468 | 274 | |
---|
469 | 275 | rqd = pblk_alloc_rqd(pblk, PBLK_READ); |
---|
470 | 276 | |
---|
471 | 277 | rqd->opcode = NVM_OP_PREAD; |
---|
472 | 278 | rqd->nr_ppas = nr_secs; |
---|
473 | | - rqd->bio = NULL; /* cloned bio if needed */ |
---|
474 | 279 | rqd->private = pblk; |
---|
475 | 280 | rqd->end_io = pblk_end_io_read; |
---|
476 | 281 | |
---|
477 | 282 | r_ctx = nvm_rq_to_pdu(rqd); |
---|
478 | | - r_ctx->start_time = jiffies; |
---|
| 283 | + r_ctx->start_time = start_time; |
---|
479 | 284 | r_ctx->lba = blba; |
---|
480 | | - r_ctx->private = bio; /* original bio */ |
---|
481 | 285 | |
---|
482 | | - /* Save the index for this bio's start. This is needed in case |
---|
483 | | - * we need to fill a partial read. |
---|
| 286 | + if (pblk_alloc_rqd_meta(pblk, rqd)) { |
---|
| 287 | + bio_io_error(bio); |
---|
| 288 | + pblk_free_rqd(pblk, rqd, PBLK_READ); |
---|
| 289 | + return; |
---|
| 290 | + } |
---|
| 291 | + |
---|
| 292 | + /* Clone read bio to deal internally with: |
---|
| 293 | + * -read errors when reading from drive |
---|
| 294 | + * -bio_advance() calls during cache reads |
---|
484 | 295 | */ |
---|
485 | | - bio_init_idx = pblk_get_bi_idx(bio); |
---|
| 296 | + int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set); |
---|
486 | 297 | |
---|
487 | | - rqd->meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, |
---|
488 | | - &rqd->dma_meta_list); |
---|
489 | | - if (!rqd->meta_list) { |
---|
490 | | - pblk_err(pblk, "not able to allocate ppa list\n"); |
---|
491 | | - goto fail_rqd_free; |
---|
492 | | - } |
---|
| 298 | + if (nr_secs > 1) |
---|
| 299 | + nr_secs = pblk_read_ppalist_rq(pblk, rqd, int_bio, blba, |
---|
| 300 | + &from_cache); |
---|
| 301 | + else |
---|
| 302 | + pblk_read_rq(pblk, rqd, int_bio, blba, &from_cache); |
---|
493 | 303 | |
---|
494 | | - if (nr_secs > 1) { |
---|
495 | | - rqd->ppa_list = rqd->meta_list + pblk_dma_meta_size; |
---|
496 | | - rqd->dma_ppa_list = rqd->dma_meta_list + pblk_dma_meta_size; |
---|
| 304 | +split_retry: |
---|
| 305 | + r_ctx->private = bio; /* original bio */ |
---|
| 306 | + rqd->bio = int_bio; /* internal bio */ |
---|
497 | 307 | |
---|
498 | | - pblk_read_ppalist_rq(pblk, rqd, bio, blba, read_bitmap); |
---|
499 | | - } else { |
---|
500 | | - pblk_read_rq(pblk, rqd, bio, blba, read_bitmap); |
---|
501 | | - } |
---|
502 | | - |
---|
503 | | - if (bitmap_full(read_bitmap, nr_secs)) { |
---|
| 308 | + if (from_cache && nr_secs == rqd->nr_ppas) { |
---|
| 309 | + /* All data was read from cache, we can complete the IO. */ |
---|
| 310 | + pblk_end_user_read(bio, 0); |
---|
504 | 311 | atomic_inc(&pblk->inflight_io); |
---|
505 | 312 | __pblk_end_io_read(pblk, rqd, false); |
---|
506 | | - return NVM_IO_DONE; |
---|
507 | | - } |
---|
| 313 | + } else if (nr_secs != rqd->nr_ppas) { |
---|
| 314 | + /* The read bio request could be partially filled by the write |
---|
| 315 | + * buffer, but there are some holes that need to be read from |
---|
| 316 | + * the drive. In order to handle this, we will use block layer |
---|
| 317 | + * mechanism to split this request in to smaller ones and make |
---|
| 318 | + * a chain of it. |
---|
| 319 | + */ |
---|
| 320 | + split_bio = bio_split(bio, nr_secs * NR_PHY_IN_LOG, GFP_KERNEL, |
---|
| 321 | + &pblk_bio_set); |
---|
| 322 | + bio_chain(split_bio, bio); |
---|
| 323 | + submit_bio_noacct(bio); |
---|
508 | 324 | |
---|
509 | | - /* All sectors are to be read from the device */ |
---|
510 | | - if (bitmap_empty(read_bitmap, rqd->nr_ppas)) { |
---|
511 | | - struct bio *int_bio = NULL; |
---|
| 325 | + /* New bio contains first N sectors of the previous one, so |
---|
| 326 | + * we can continue to use existing rqd, but we need to shrink |
---|
| 327 | + * the number of PPAs in it. New bio is also guaranteed that |
---|
| 328 | + * it contains only either data from cache or from drive, newer |
---|
| 329 | + * mix of them. |
---|
| 330 | + */ |
---|
| 331 | + bio = split_bio; |
---|
| 332 | + rqd->nr_ppas = nr_secs; |
---|
| 333 | + if (rqd->nr_ppas == 1) |
---|
| 334 | + rqd->ppa_addr = rqd->ppa_list[0]; |
---|
512 | 335 | |
---|
513 | | - /* Clone read bio to deal with read errors internally */ |
---|
| 336 | + /* Recreate int_bio - existing might have some needed internal |
---|
| 337 | + * fields modified already. |
---|
| 338 | + */ |
---|
| 339 | + bio_put(int_bio); |
---|
514 | 340 | int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set); |
---|
515 | | - if (!int_bio) { |
---|
516 | | - pblk_err(pblk, "could not clone read bio\n"); |
---|
517 | | - goto fail_end_io; |
---|
518 | | - } |
---|
519 | | - |
---|
520 | | - rqd->bio = int_bio; |
---|
521 | | - |
---|
522 | | - if (pblk_submit_io(pblk, rqd)) { |
---|
523 | | - pblk_err(pblk, "read IO submission failed\n"); |
---|
524 | | - ret = NVM_IO_ERR; |
---|
525 | | - goto fail_end_io; |
---|
526 | | - } |
---|
527 | | - |
---|
528 | | - return NVM_IO_OK; |
---|
| 341 | + goto split_retry; |
---|
| 342 | + } else if (pblk_submit_io(pblk, rqd, NULL)) { |
---|
| 343 | + /* Submitting IO to drive failed, let's report an error */ |
---|
| 344 | + rqd->error = -ENODEV; |
---|
| 345 | + pblk_end_io_read(rqd); |
---|
529 | 346 | } |
---|
530 | | - |
---|
531 | | - /* The read bio request could be partially filled by the write buffer, |
---|
532 | | - * but there are some holes that need to be read from the drive. |
---|
533 | | - */ |
---|
534 | | - ret = pblk_partial_read_bio(pblk, rqd, bio_init_idx, read_bitmap, |
---|
535 | | - nr_secs); |
---|
536 | | - if (ret) |
---|
537 | | - goto fail_meta_free; |
---|
538 | | - |
---|
539 | | - return NVM_IO_OK; |
---|
540 | | - |
---|
541 | | -fail_meta_free: |
---|
542 | | - nvm_dev_dma_free(dev->parent, rqd->meta_list, rqd->dma_meta_list); |
---|
543 | | -fail_rqd_free: |
---|
544 | | - pblk_free_rqd(pblk, rqd, PBLK_READ); |
---|
545 | | - return ret; |
---|
546 | | -fail_end_io: |
---|
547 | | - __pblk_end_io_read(pblk, rqd, false); |
---|
548 | | - return ret; |
---|
549 | 347 | } |
---|
550 | 348 | |
---|
551 | 349 | static int read_ppalist_rq_gc(struct pblk *pblk, struct nvm_rq *rqd, |
---|
552 | 350 | struct pblk_line *line, u64 *lba_list, |
---|
553 | 351 | u64 *paddr_list_gc, unsigned int nr_secs) |
---|
554 | 352 | { |
---|
555 | | - struct ppa_addr ppa_list_l2p[PBLK_MAX_REQ_ADDRS]; |
---|
| 353 | + struct ppa_addr ppa_list_l2p[NVM_MAX_VLBA]; |
---|
556 | 354 | struct ppa_addr ppa_gc; |
---|
557 | 355 | int valid_secs = 0; |
---|
558 | 356 | int i; |
---|
.. | .. |
---|
590 | 388 | goto out; |
---|
591 | 389 | |
---|
592 | 390 | /* logic error: lba out-of-bounds */ |
---|
593 | | - if (lba >= pblk->rl.nr_secs) { |
---|
| 391 | + if (lba >= pblk->capacity) { |
---|
594 | 392 | WARN(1, "pblk: read lba out of bounds\n"); |
---|
595 | 393 | goto out; |
---|
596 | 394 | } |
---|
.. | .. |
---|
616 | 414 | |
---|
617 | 415 | int pblk_submit_read_gc(struct pblk *pblk, struct pblk_gc_rq *gc_rq) |
---|
618 | 416 | { |
---|
619 | | - struct nvm_tgt_dev *dev = pblk->dev; |
---|
620 | | - struct nvm_geo *geo = &dev->geo; |
---|
621 | | - struct bio *bio; |
---|
622 | 417 | struct nvm_rq rqd; |
---|
623 | | - int data_len; |
---|
624 | 418 | int ret = NVM_IO_OK; |
---|
625 | 419 | |
---|
626 | 420 | memset(&rqd, 0, sizeof(struct nvm_rq)); |
---|
627 | 421 | |
---|
628 | | - rqd.meta_list = nvm_dev_dma_alloc(dev->parent, GFP_KERNEL, |
---|
629 | | - &rqd.dma_meta_list); |
---|
630 | | - if (!rqd.meta_list) |
---|
631 | | - return -ENOMEM; |
---|
| 422 | + ret = pblk_alloc_rqd_meta(pblk, &rqd); |
---|
| 423 | + if (ret) |
---|
| 424 | + return ret; |
---|
632 | 425 | |
---|
633 | 426 | if (gc_rq->nr_secs > 1) { |
---|
634 | | - rqd.ppa_list = rqd.meta_list + pblk_dma_meta_size; |
---|
635 | | - rqd.dma_ppa_list = rqd.dma_meta_list + pblk_dma_meta_size; |
---|
636 | | - |
---|
637 | 427 | gc_rq->secs_to_gc = read_ppalist_rq_gc(pblk, &rqd, gc_rq->line, |
---|
638 | 428 | gc_rq->lba_list, |
---|
639 | 429 | gc_rq->paddr_list, |
---|
.. | .. |
---|
649 | 439 | if (!(gc_rq->secs_to_gc)) |
---|
650 | 440 | goto out; |
---|
651 | 441 | |
---|
652 | | - data_len = (gc_rq->secs_to_gc) * geo->csecs; |
---|
653 | | - bio = pblk_bio_map_addr(pblk, gc_rq->data, gc_rq->secs_to_gc, data_len, |
---|
654 | | - PBLK_VMALLOC_META, GFP_KERNEL); |
---|
655 | | - if (IS_ERR(bio)) { |
---|
656 | | - pblk_err(pblk, "could not allocate GC bio (%lu)\n", |
---|
657 | | - PTR_ERR(bio)); |
---|
658 | | - goto err_free_dma; |
---|
659 | | - } |
---|
660 | | - |
---|
661 | | - bio->bi_iter.bi_sector = 0; /* internal bio */ |
---|
662 | | - bio_set_op_attrs(bio, REQ_OP_READ, 0); |
---|
663 | | - |
---|
664 | 442 | rqd.opcode = NVM_OP_PREAD; |
---|
665 | 443 | rqd.nr_ppas = gc_rq->secs_to_gc; |
---|
666 | | - rqd.flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); |
---|
667 | | - rqd.bio = bio; |
---|
668 | 444 | |
---|
669 | | - if (pblk_submit_io_sync(pblk, &rqd)) { |
---|
| 445 | + if (pblk_submit_io_sync(pblk, &rqd, gc_rq->data)) { |
---|
670 | 446 | ret = -EIO; |
---|
671 | | - pblk_err(pblk, "GC read request failed\n"); |
---|
672 | | - goto err_free_bio; |
---|
| 447 | + goto err_free_dma; |
---|
673 | 448 | } |
---|
674 | 449 | |
---|
675 | 450 | pblk_read_check_rand(pblk, &rqd, gc_rq->lba_list, gc_rq->nr_secs); |
---|
.. | .. |
---|
690 | 465 | #endif |
---|
691 | 466 | |
---|
692 | 467 | out: |
---|
693 | | - nvm_dev_dma_free(dev->parent, rqd.meta_list, rqd.dma_meta_list); |
---|
| 468 | + pblk_free_rqd_meta(pblk, &rqd); |
---|
694 | 469 | return ret; |
---|
695 | 470 | |
---|
696 | | -err_free_bio: |
---|
697 | | - bio_put(bio); |
---|
698 | 471 | err_free_dma: |
---|
699 | | - nvm_dev_dma_free(dev->parent, rqd.meta_list, rqd.dma_meta_list); |
---|
| 472 | + pblk_free_rqd_meta(pblk, &rqd); |
---|
700 | 473 | return ret; |
---|
701 | 474 | } |
---|