diff options
| -rw-r--r-- | drivers/lightnvm/pblk-core.c | 13 | ||||
| -rw-r--r-- | drivers/lightnvm/pblk-rb.c | 11 | ||||
| -rw-r--r-- | drivers/lightnvm/pblk-read.c | 339 | ||||
| -rw-r--r-- | drivers/lightnvm/pblk.h | 18 |
4 files changed, 100 insertions, 281 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c index 73be3a0311ff..07270ba1e95f 100644 --- a/drivers/lightnvm/pblk-core.c +++ b/drivers/lightnvm/pblk-core.c | |||
| @@ -2147,8 +2147,8 @@ out: | |||
| 2147 | spin_unlock(&pblk->trans_lock); | 2147 | spin_unlock(&pblk->trans_lock); |
| 2148 | } | 2148 | } |
| 2149 | 2149 | ||
| 2150 | void pblk_lookup_l2p_seq(struct pblk *pblk, struct ppa_addr *ppas, | 2150 | int pblk_lookup_l2p_seq(struct pblk *pblk, struct ppa_addr *ppas, |
| 2151 | sector_t blba, int nr_secs) | 2151 | sector_t blba, int nr_secs, bool *from_cache) |
| 2152 | { | 2152 | { |
| 2153 | int i; | 2153 | int i; |
| 2154 | 2154 | ||
| @@ -2162,10 +2162,19 @@ void pblk_lookup_l2p_seq(struct pblk *pblk, struct ppa_addr *ppas, | |||
| 2162 | if (!pblk_ppa_empty(ppa) && !pblk_addr_in_cache(ppa)) { | 2162 | if (!pblk_ppa_empty(ppa) && !pblk_addr_in_cache(ppa)) { |
| 2163 | struct pblk_line *line = pblk_ppa_to_line(pblk, ppa); | 2163 | struct pblk_line *line = pblk_ppa_to_line(pblk, ppa); |
| 2164 | 2164 | ||
| 2165 | if (i > 0 && *from_cache) | ||
| 2166 | break; | ||
| 2167 | *from_cache = false; | ||
| 2168 | |||
| 2165 | kref_get(&line->ref); | 2169 | kref_get(&line->ref); |
| 2170 | } else { | ||
| 2171 | if (i > 0 && !*from_cache) | ||
| 2172 | break; | ||
| 2173 | *from_cache = true; | ||
| 2166 | } | 2174 | } |
| 2167 | } | 2175 | } |
| 2168 | spin_unlock(&pblk->trans_lock); | 2176 | spin_unlock(&pblk->trans_lock); |
| 2177 | return i; | ||
| 2169 | } | 2178 | } |
| 2170 | 2179 | ||
| 2171 | void pblk_lookup_l2p_rand(struct pblk *pblk, struct ppa_addr *ppas, | 2180 | void pblk_lookup_l2p_rand(struct pblk *pblk, struct ppa_addr *ppas, |
diff --git a/drivers/lightnvm/pblk-rb.c b/drivers/lightnvm/pblk-rb.c index 35550148b5e8..5abb1705b039 100644 --- a/drivers/lightnvm/pblk-rb.c +++ b/drivers/lightnvm/pblk-rb.c | |||
| @@ -642,7 +642,7 @@ try: | |||
| 642 | * be directed to disk. | 642 | * be directed to disk. |
| 643 | */ | 643 | */ |
| 644 | int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba, | 644 | int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba, |
| 645 | struct ppa_addr ppa, int bio_iter, bool advanced_bio) | 645 | struct ppa_addr ppa) |
| 646 | { | 646 | { |
| 647 | struct pblk *pblk = container_of(rb, struct pblk, rwb); | 647 | struct pblk *pblk = container_of(rb, struct pblk, rwb); |
| 648 | struct pblk_rb_entry *entry; | 648 | struct pblk_rb_entry *entry; |
| @@ -673,15 +673,6 @@ int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba, | |||
| 673 | ret = 0; | 673 | ret = 0; |
| 674 | goto out; | 674 | goto out; |
| 675 | } | 675 | } |
| 676 | |||
| 677 | /* Only advance the bio if it hasn't been advanced already. If advanced, | ||
| 678 | * this bio is at least a partial bio (i.e., it has partially been | ||
| 679 | * filled with data from the cache). If part of the data resides on the | ||
| 680 | * media, we will read later on | ||
| 681 | */ | ||
| 682 | if (unlikely(!advanced_bio)) | ||
| 683 | bio_advance(bio, bio_iter * PBLK_EXPOSED_PAGE_SIZE); | ||
| 684 | |||
| 685 | data = bio_data(bio); | 676 | data = bio_data(bio); |
| 686 | memcpy(data, entry->data, rb->seg_size); | 677 | memcpy(data, entry->data, rb->seg_size); |
| 687 | 678 | ||
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c index f5f155d540e2..d98ea392fe33 100644 --- a/drivers/lightnvm/pblk-read.c +++ b/drivers/lightnvm/pblk-read.c | |||
| @@ -26,8 +26,7 @@ | |||
| 26 | * issued. | 26 | * issued. |
| 27 | */ | 27 | */ |
| 28 | static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio, | 28 | static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio, |
| 29 | sector_t lba, struct ppa_addr ppa, | 29 | sector_t lba, struct ppa_addr ppa) |
| 30 | int bio_iter, bool advanced_bio) | ||
| 31 | { | 30 | { |
| 32 | #ifdef CONFIG_NVM_PBLK_DEBUG | 31 | #ifdef CONFIG_NVM_PBLK_DEBUG |
| 33 | /* Callers must ensure that the ppa points to a cache address */ | 32 | /* Callers must ensure that the ppa points to a cache address */ |
| @@ -35,73 +34,75 @@ static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio, | |||
| 35 | BUG_ON(!pblk_addr_in_cache(ppa)); | 34 | BUG_ON(!pblk_addr_in_cache(ppa)); |
| 36 | #endif | 35 | #endif |
| 37 | 36 | ||
| 38 | return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa, | 37 | return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa); |
| 39 | bio_iter, advanced_bio); | ||
| 40 | } | 38 | } |
| 41 | 39 | ||
| 42 | 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, |
| 43 | struct bio *bio, sector_t blba, | 41 | struct bio *bio, sector_t blba, |
| 44 | unsigned long *read_bitmap) | 42 | bool *from_cache) |
| 45 | { | 43 | { |
| 46 | void *meta_list = rqd->meta_list; | 44 | void *meta_list = rqd->meta_list; |
| 47 | struct ppa_addr ppas[NVM_MAX_VLBA]; | 45 | int nr_secs, i; |
| 48 | int nr_secs = rqd->nr_ppas; | ||
| 49 | bool advanced_bio = false; | ||
| 50 | int i, j = 0; | ||
| 51 | 46 | ||
| 52 | pblk_lookup_l2p_seq(pblk, ppas, blba, nr_secs); | 47 | retry: |
| 48 | nr_secs = pblk_lookup_l2p_seq(pblk, rqd->ppa_list, blba, rqd->nr_ppas, | ||
| 49 | from_cache); | ||
| 50 | |||
| 51 | if (!*from_cache) | ||
| 52 | goto end; | ||
| 53 | 53 | ||
| 54 | for (i = 0; i < nr_secs; i++) { | 54 | for (i = 0; i < nr_secs; i++) { |
| 55 | struct ppa_addr p = ppas[i]; | ||
| 56 | struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i); | 55 | struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i); |
| 57 | sector_t lba = blba + i; | 56 | sector_t lba = blba + i; |
| 58 | 57 | ||
| 59 | retry: | 58 | if (pblk_ppa_empty(rqd->ppa_list[i])) { |
| 60 | if (pblk_ppa_empty(p)) { | ||
| 61 | __le64 addr_empty = cpu_to_le64(ADDR_EMPTY); | 59 | __le64 addr_empty = cpu_to_le64(ADDR_EMPTY); |
| 62 | 60 | ||
| 63 | WARN_ON(test_and_set_bit(i, read_bitmap)); | ||
| 64 | meta->lba = addr_empty; | 61 | meta->lba = addr_empty; |
| 65 | 62 | } else if (pblk_addr_in_cache(rqd->ppa_list[i])) { | |
| 66 | if (unlikely(!advanced_bio)) { | 63 | /* |
| 67 | bio_advance(bio, (i) * PBLK_EXPOSED_PAGE_SIZE); | 64 | * Try to read from write buffer. The address is later |
| 68 | advanced_bio = true; | 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 | } | ||
| 69 | } | 88 | } |
| 70 | |||
| 71 | goto next; | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Try to read from write buffer. The address is later checked | ||
| 75 | * on the write buffer to prevent retrieving overwritten data. | ||
| 76 | */ | ||
| 77 | if (pblk_addr_in_cache(p)) { | ||
| 78 | if (!pblk_read_from_cache(pblk, bio, lba, p, i, | ||
| 79 | advanced_bio)) { | ||
| 80 | pblk_lookup_l2p_seq(pblk, &p, lba, 1); | ||
| 81 | goto retry; | ||
| 82 | } | ||
| 83 | WARN_ON(test_and_set_bit(i, read_bitmap)); | ||
| 84 | meta->lba = cpu_to_le64(lba); | 89 | meta->lba = cpu_to_le64(lba); |
| 85 | advanced_bio = true; | ||
| 86 | #ifdef CONFIG_NVM_PBLK_DEBUG | 90 | #ifdef CONFIG_NVM_PBLK_DEBUG |
| 87 | atomic_long_inc(&pblk->cache_reads); | 91 | atomic_long_inc(&pblk->cache_reads); |
| 88 | #endif | 92 | #endif |
| 89 | } else { | ||
| 90 | /* Read from media non-cached sectors */ | ||
| 91 | rqd->ppa_list[j++] = p; | ||
| 92 | } | 93 | } |
| 93 | 94 | bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE); | |
| 94 | next: | ||
| 95 | if (advanced_bio) | ||
| 96 | bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE); | ||
| 97 | } | 95 | } |
| 98 | 96 | ||
| 97 | end: | ||
| 99 | if (pblk_io_aligned(pblk, nr_secs)) | 98 | if (pblk_io_aligned(pblk, nr_secs)) |
| 100 | rqd->is_seq = 1; | 99 | rqd->is_seq = 1; |
| 101 | 100 | ||
| 102 | #ifdef CONFIG_NVM_PBLK_DEBUG | 101 | #ifdef CONFIG_NVM_PBLK_DEBUG |
| 103 | atomic_long_add(nr_secs, &pblk->inflight_reads); | 102 | atomic_long_add(nr_secs, &pblk->inflight_reads); |
| 104 | #endif | 103 | #endif |
| 104 | |||
| 105 | return nr_secs; | ||
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | 108 | ||
| @@ -197,9 +198,7 @@ static void __pblk_end_io_read(struct pblk *pblk, struct nvm_rq *rqd, | |||
| 197 | pblk_log_read_err(pblk, rqd); | 198 | pblk_log_read_err(pblk, rqd); |
| 198 | 199 | ||
| 199 | pblk_read_check_seq(pblk, rqd, r_ctx->lba); | 200 | pblk_read_check_seq(pblk, rqd, r_ctx->lba); |
| 200 | 201 | bio_put(int_bio); | |
| 201 | if (int_bio) | ||
| 202 | bio_put(int_bio); | ||
| 203 | 202 | ||
| 204 | if (put_line) | 203 | if (put_line) |
| 205 | pblk_rq_to_line_put(pblk, rqd); | 204 | pblk_rq_to_line_put(pblk, rqd); |
| @@ -223,183 +222,13 @@ static void pblk_end_io_read(struct nvm_rq *rqd) | |||
| 223 | __pblk_end_io_read(pblk, rqd, true); | 222 | __pblk_end_io_read(pblk, rqd, true); |
| 224 | } | 223 | } |
| 225 | 224 | ||
| 226 | static void pblk_end_partial_read(struct nvm_rq *rqd) | ||
| 227 | { | ||
| 228 | struct pblk *pblk = rqd->private; | ||
| 229 | struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); | ||
| 230 | struct pblk_pr_ctx *pr_ctx = r_ctx->private; | ||
| 231 | struct pblk_sec_meta *meta; | ||
| 232 | struct bio *new_bio = rqd->bio; | ||
| 233 | struct bio *bio = pr_ctx->orig_bio; | ||
| 234 | void *meta_list = rqd->meta_list; | ||
| 235 | unsigned long *read_bitmap = pr_ctx->bitmap; | ||
| 236 | struct bvec_iter orig_iter = BVEC_ITER_ALL_INIT; | ||
| 237 | struct bvec_iter new_iter = BVEC_ITER_ALL_INIT; | ||
| 238 | int nr_secs = pr_ctx->orig_nr_secs; | ||
| 239 | int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); | ||
| 240 | void *src_p, *dst_p; | ||
| 241 | int bit, i; | ||
| 242 | |||
| 243 | if (unlikely(nr_holes == 1)) { | ||
| 244 | struct ppa_addr ppa; | ||
| 245 | |||
| 246 | ppa = rqd->ppa_addr; | ||
| 247 | rqd->ppa_list = pr_ctx->ppa_ptr; | ||
| 248 | rqd->dma_ppa_list = pr_ctx->dma_ppa_list; | ||
| 249 | rqd->ppa_list[0] = ppa; | ||
| 250 | } | ||
| 251 | |||
| 252 | for (i = 0; i < nr_secs; i++) { | ||
| 253 | meta = pblk_get_meta(pblk, meta_list, i); | ||
| 254 | pr_ctx->lba_list_media[i] = le64_to_cpu(meta->lba); | ||
| 255 | meta->lba = cpu_to_le64(pr_ctx->lba_list_mem[i]); | ||
| 256 | } | ||
| 257 | |||
| 258 | /* Fill the holes in the original bio */ | ||
| 259 | i = 0; | ||
| 260 | for (bit = 0; bit < nr_secs; bit++) { | ||
| 261 | if (!test_bit(bit, read_bitmap)) { | ||
| 262 | struct bio_vec dst_bv, src_bv; | ||
| 263 | struct pblk_line *line; | ||
| 264 | |||
| 265 | line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]); | ||
| 266 | kref_put(&line->ref, pblk_line_put); | ||
| 267 | |||
| 268 | meta = pblk_get_meta(pblk, meta_list, bit); | ||
| 269 | meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]); | ||
| 270 | |||
| 271 | dst_bv = bio_iter_iovec(bio, orig_iter); | ||
| 272 | src_bv = bio_iter_iovec(new_bio, new_iter); | ||
| 273 | |||
| 274 | src_p = kmap_atomic(src_bv.bv_page); | ||
| 275 | dst_p = kmap_atomic(dst_bv.bv_page); | ||
| 276 | |||
| 277 | memcpy(dst_p + dst_bv.bv_offset, | ||
| 278 | src_p + src_bv.bv_offset, | ||
| 279 | PBLK_EXPOSED_PAGE_SIZE); | ||
| 280 | |||
| 281 | kunmap_atomic(src_p); | ||
| 282 | kunmap_atomic(dst_p); | ||
| 283 | |||
| 284 | flush_dcache_page(dst_bv.bv_page); | ||
| 285 | mempool_free(src_bv.bv_page, &pblk->page_bio_pool); | ||
| 286 | |||
| 287 | bio_advance_iter(new_bio, &new_iter, | ||
| 288 | PBLK_EXPOSED_PAGE_SIZE); | ||
| 289 | i++; | ||
| 290 | } | ||
| 291 | bio_advance_iter(bio, &orig_iter, PBLK_EXPOSED_PAGE_SIZE); | ||
| 292 | } | ||
| 293 | |||
| 294 | bio_put(new_bio); | ||
| 295 | kfree(pr_ctx); | ||
| 296 | |||
| 297 | /* restore original request */ | ||
| 298 | rqd->bio = NULL; | ||
| 299 | rqd->nr_ppas = nr_secs; | ||
| 300 | |||
| 301 | pblk_end_user_read(bio, rqd->error); | ||
| 302 | __pblk_end_io_read(pblk, rqd, false); | ||
| 303 | } | ||
| 304 | |||
| 305 | static int pblk_setup_partial_read(struct pblk *pblk, struct nvm_rq *rqd, | ||
| 306 | unsigned int bio_init_idx, | ||
| 307 | unsigned long *read_bitmap, | ||
| 308 | int nr_holes) | ||
| 309 | { | ||
| 310 | void *meta_list = rqd->meta_list; | ||
| 311 | struct pblk_g_ctx *r_ctx = nvm_rq_to_pdu(rqd); | ||
| 312 | struct pblk_pr_ctx *pr_ctx; | ||
| 313 | struct bio *new_bio, *bio = r_ctx->private; | ||
| 314 | int nr_secs = rqd->nr_ppas; | ||
| 315 | int i; | ||
| 316 | |||
| 317 | new_bio = bio_alloc(GFP_KERNEL, nr_holes); | ||
| 318 | |||
| 319 | if (pblk_bio_add_pages(pblk, new_bio, GFP_KERNEL, nr_holes)) | ||
| 320 | goto fail_bio_put; | ||
| 321 | |||
| 322 | if (nr_holes != new_bio->bi_vcnt) { | ||
| 323 | WARN_ONCE(1, "pblk: malformed bio\n"); | ||
| 324 | goto fail_free_pages; | ||
| 325 | } | ||
| 326 | |||
| 327 | pr_ctx = kzalloc(sizeof(struct pblk_pr_ctx), GFP_KERNEL); | ||
| 328 | if (!pr_ctx) | ||
| 329 | goto fail_free_pages; | ||
| 330 | |||
| 331 | for (i = 0; i < nr_secs; i++) { | ||
| 332 | struct pblk_sec_meta *meta = pblk_get_meta(pblk, meta_list, i); | ||
| 333 | |||
| 334 | pr_ctx->lba_list_mem[i] = le64_to_cpu(meta->lba); | ||
| 335 | } | ||
| 336 | |||
| 337 | new_bio->bi_iter.bi_sector = 0; /* internal bio */ | ||
| 338 | bio_set_op_attrs(new_bio, REQ_OP_READ, 0); | ||
| 339 | |||
| 340 | rqd->bio = new_bio; | ||
| 341 | rqd->nr_ppas = nr_holes; | ||
| 342 | |||
| 343 | pr_ctx->orig_bio = bio; | ||
| 344 | bitmap_copy(pr_ctx->bitmap, read_bitmap, NVM_MAX_VLBA); | ||
| 345 | pr_ctx->bio_init_idx = bio_init_idx; | ||
| 346 | pr_ctx->orig_nr_secs = nr_secs; | ||
| 347 | r_ctx->private = pr_ctx; | ||
| 348 | |||
| 349 | if (unlikely(nr_holes == 1)) { | ||
| 350 | pr_ctx->ppa_ptr = rqd->ppa_list; | ||
| 351 | pr_ctx->dma_ppa_list = rqd->dma_ppa_list; | ||
| 352 | rqd->ppa_addr = rqd->ppa_list[0]; | ||
| 353 | } | ||
| 354 | return 0; | ||
| 355 | |||
| 356 | fail_free_pages: | ||
| 357 | pblk_bio_free_pages(pblk, new_bio, 0, new_bio->bi_vcnt); | ||
| 358 | fail_bio_put: | ||
| 359 | bio_put(new_bio); | ||
| 360 | |||
| 361 | return -ENOMEM; | ||
| 362 | } | ||
| 363 | |||
| 364 | static int pblk_partial_read_bio(struct pblk *pblk, struct nvm_rq *rqd, | ||
| 365 | unsigned int bio_init_idx, | ||
| 366 | unsigned long *read_bitmap, int nr_secs) | ||
| 367 | { | ||
| 368 | int nr_holes; | ||
| 369 | int ret; | ||
| 370 | |||
| 371 | nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); | ||
| 372 | |||
| 373 | if (pblk_setup_partial_read(pblk, rqd, bio_init_idx, read_bitmap, | ||
| 374 | nr_holes)) | ||
| 375 | return NVM_IO_ERR; | ||
| 376 | |||
| 377 | rqd->end_io = pblk_end_partial_read; | ||
| 378 | |||
| 379 | ret = pblk_submit_io(pblk, rqd); | ||
| 380 | if (ret) { | ||
| 381 | bio_put(rqd->bio); | ||
| 382 | pblk_err(pblk, "partial read IO submission failed\n"); | ||
| 383 | goto err; | ||
| 384 | } | ||
| 385 | |||
| 386 | return NVM_IO_OK; | ||
| 387 | |||
| 388 | err: | ||
| 389 | pblk_err(pblk, "failed to perform partial read\n"); | ||
| 390 | |||
| 391 | /* Free allocated pages in new bio */ | ||
| 392 | pblk_bio_free_pages(pblk, rqd->bio, 0, rqd->bio->bi_vcnt); | ||
| 393 | return NVM_IO_ERR; | ||
| 394 | } | ||
| 395 | |||
| 396 | static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd, struct bio *bio, | 225 | static void pblk_read_rq(struct pblk *pblk, struct nvm_rq *rqd, struct bio *bio, |
| 397 | sector_t lba, unsigned long *read_bitmap) | 226 | sector_t lba, bool *from_cache) |
| 398 | { | 227 | { |
| 399 | struct pblk_sec_meta *meta = pblk_get_meta(pblk, rqd->meta_list, 0); | 228 | struct pblk_sec_meta *meta = pblk_get_meta(pblk, rqd->meta_list, 0); |
| 400 | struct ppa_addr ppa; | 229 | struct ppa_addr ppa; |
| 401 | 230 | ||
| 402 | pblk_lookup_l2p_seq(pblk, &ppa, lba, 1); | 231 | pblk_lookup_l2p_seq(pblk, &ppa, lba, 1, from_cache); |
| 403 | 232 | ||
| 404 | #ifdef CONFIG_NVM_PBLK_DEBUG | 233 | #ifdef CONFIG_NVM_PBLK_DEBUG |
| 405 | atomic_long_inc(&pblk->inflight_reads); | 234 | atomic_long_inc(&pblk->inflight_reads); |
| @@ -409,7 +238,6 @@ retry: | |||
| 409 | if (pblk_ppa_empty(ppa)) { | 238 | if (pblk_ppa_empty(ppa)) { |
| 410 | __le64 addr_empty = cpu_to_le64(ADDR_EMPTY); | 239 | __le64 addr_empty = cpu_to_le64(ADDR_EMPTY); |
| 411 | 240 | ||
| 412 | WARN_ON(test_and_set_bit(0, read_bitmap)); | ||
| 413 | meta->lba = addr_empty; | 241 | meta->lba = addr_empty; |
| 414 | return; | 242 | return; |
| 415 | } | 243 | } |
| @@ -418,12 +246,11 @@ retry: | |||
| 418 | * write buffer to prevent retrieving overwritten data. | 246 | * write buffer to prevent retrieving overwritten data. |
| 419 | */ | 247 | */ |
| 420 | if (pblk_addr_in_cache(ppa)) { | 248 | if (pblk_addr_in_cache(ppa)) { |
| 421 | if (!pblk_read_from_cache(pblk, bio, lba, ppa, 0, 1)) { | 249 | if (!pblk_read_from_cache(pblk, bio, lba, ppa)) { |
| 422 | pblk_lookup_l2p_seq(pblk, &ppa, lba, 1); | 250 | pblk_lookup_l2p_seq(pblk, &ppa, lba, 1, from_cache); |
| 423 | goto retry; | 251 | goto retry; |
| 424 | } | 252 | } |
| 425 | 253 | ||
| 426 | WARN_ON(test_and_set_bit(0, read_bitmap)); | ||
| 427 | meta->lba = cpu_to_le64(lba); | 254 | meta->lba = cpu_to_le64(lba); |
| 428 | 255 | ||
| 429 | #ifdef CONFIG_NVM_PBLK_DEBUG | 256 | #ifdef CONFIG_NVM_PBLK_DEBUG |
| @@ -440,17 +267,14 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio) | |||
| 440 | struct request_queue *q = dev->q; | 267 | struct request_queue *q = dev->q; |
| 441 | sector_t blba = pblk_get_lba(bio); | 268 | sector_t blba = pblk_get_lba(bio); |
| 442 | unsigned int nr_secs = pblk_get_secs(bio); | 269 | unsigned int nr_secs = pblk_get_secs(bio); |
| 270 | bool from_cache; | ||
| 443 | struct pblk_g_ctx *r_ctx; | 271 | struct pblk_g_ctx *r_ctx; |
| 444 | struct nvm_rq *rqd; | 272 | struct nvm_rq *rqd; |
| 445 | struct bio *int_bio; | 273 | struct bio *int_bio, *split_bio; |
| 446 | unsigned int bio_init_idx; | ||
| 447 | DECLARE_BITMAP(read_bitmap, NVM_MAX_VLBA); | ||
| 448 | 274 | ||
| 449 | generic_start_io_acct(q, REQ_OP_READ, bio_sectors(bio), | 275 | generic_start_io_acct(q, REQ_OP_READ, bio_sectors(bio), |
| 450 | &pblk->disk->part0); | 276 | &pblk->disk->part0); |
| 451 | 277 | ||
| 452 | bitmap_zero(read_bitmap, nr_secs); | ||
| 453 | |||
| 454 | rqd = pblk_alloc_rqd(pblk, PBLK_READ); | 278 | rqd = pblk_alloc_rqd(pblk, PBLK_READ); |
| 455 | 279 | ||
| 456 | rqd->opcode = NVM_OP_PREAD; | 280 | rqd->opcode = NVM_OP_PREAD; |
| @@ -462,11 +286,6 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio) | |||
| 462 | r_ctx->start_time = jiffies; | 286 | r_ctx->start_time = jiffies; |
| 463 | r_ctx->lba = blba; | 287 | r_ctx->lba = blba; |
| 464 | 288 | ||
| 465 | /* Save the index for this bio's start. This is needed in case | ||
| 466 | * we need to fill a partial read. | ||
| 467 | */ | ||
| 468 | bio_init_idx = pblk_get_bi_idx(bio); | ||
| 469 | |||
| 470 | if (pblk_alloc_rqd_meta(pblk, rqd)) { | 289 | if (pblk_alloc_rqd_meta(pblk, rqd)) { |
| 471 | bio_io_error(bio); | 290 | bio_io_error(bio); |
| 472 | pblk_free_rqd(pblk, rqd, PBLK_READ); | 291 | pblk_free_rqd(pblk, rqd, PBLK_READ); |
| @@ -475,46 +294,58 @@ void pblk_submit_read(struct pblk *pblk, struct bio *bio) | |||
| 475 | 294 | ||
| 476 | /* Clone read bio to deal internally with: | 295 | /* Clone read bio to deal internally with: |
| 477 | * -read errors when reading from drive | 296 | * -read errors when reading from drive |
| 478 | * -bio_advance() calls during l2p lookup and cache reads | 297 | * -bio_advance() calls during cache reads |
| 479 | */ | 298 | */ |
| 480 | int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set); | 299 | int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set); |
| 481 | 300 | ||
| 482 | if (nr_secs > 1) | 301 | if (nr_secs > 1) |
| 483 | pblk_read_ppalist_rq(pblk, rqd, bio, blba, read_bitmap); | 302 | nr_secs = pblk_read_ppalist_rq(pblk, rqd, int_bio, blba, |
| 303 | &from_cache); | ||
| 484 | else | 304 | else |
| 485 | pblk_read_rq(pblk, rqd, bio, blba, read_bitmap); | 305 | pblk_read_rq(pblk, rqd, int_bio, blba, &from_cache); |
| 486 | 306 | ||
| 307 | split_retry: | ||
| 487 | r_ctx->private = bio; /* original bio */ | 308 | r_ctx->private = bio; /* original bio */ |
| 488 | rqd->bio = int_bio; /* internal bio */ | 309 | rqd->bio = int_bio; /* internal bio */ |
| 489 | 310 | ||
| 490 | if (bitmap_full(read_bitmap, nr_secs)) { | 311 | if (from_cache && nr_secs == rqd->nr_ppas) { |
| 312 | /* All data was read from cache, we can complete the IO. */ | ||
| 491 | pblk_end_user_read(bio, 0); | 313 | pblk_end_user_read(bio, 0); |
| 492 | atomic_inc(&pblk->inflight_io); | 314 | atomic_inc(&pblk->inflight_io); |
| 493 | __pblk_end_io_read(pblk, rqd, false); | 315 | __pblk_end_io_read(pblk, rqd, false); |
| 494 | return; | 316 | } else if (nr_secs != rqd->nr_ppas) { |
| 495 | } | ||
| 496 | |||
| 497 | if (!bitmap_empty(read_bitmap, rqd->nr_ppas)) { | ||
| 498 | /* The read bio request could be partially filled by the write | 317 | /* The read bio request could be partially filled by the write |
| 499 | * buffer, but there are some holes that need to be read from | 318 | * buffer, but there are some holes that need to be read from |
| 500 | * the drive. | 319 | * the drive. In order to handle this, we will use block layer |
| 320 | * mechanism to split this request in to smaller ones and make | ||
| 321 | * a chain of it. | ||
| 501 | */ | 322 | */ |
| 502 | bio_put(int_bio); | 323 | split_bio = bio_split(bio, nr_secs * NR_PHY_IN_LOG, GFP_KERNEL, |
| 503 | rqd->bio = NULL; | 324 | &pblk_bio_set); |
| 504 | if (pblk_partial_read_bio(pblk, rqd, bio_init_idx, read_bitmap, | 325 | bio_chain(split_bio, bio); |
| 505 | nr_secs)) { | 326 | generic_make_request(bio); |
| 506 | pblk_err(pblk, "read IO submission failed\n"); | 327 | |
| 507 | bio_io_error(bio); | 328 | /* New bio contains first N sectors of the previous one, so |
| 508 | __pblk_end_io_read(pblk, rqd, false); | 329 | * we can continue to use existing rqd, but we need to shrink |
| 509 | } | 330 | * the number of PPAs in it. New bio is also guaranteed that |
| 510 | return; | 331 | * it contains only either data from cache or from drive, newer |
| 511 | } | 332 | * mix of them. |
| 333 | */ | ||
| 334 | bio = split_bio; | ||
| 335 | rqd->nr_ppas = nr_secs; | ||
| 336 | if (rqd->nr_ppas == 1) | ||
| 337 | rqd->ppa_addr = rqd->ppa_list[0]; | ||
| 512 | 338 | ||
| 513 | /* All sectors are to be read from the device */ | 339 | /* Recreate int_bio - existing might have some needed internal |
| 514 | if (pblk_submit_io(pblk, rqd)) { | 340 | * fields modified already. |
| 515 | pblk_err(pblk, "read IO submission failed\n"); | 341 | */ |
| 516 | bio_io_error(bio); | 342 | bio_put(int_bio); |
| 517 | __pblk_end_io_read(pblk, rqd, false); | 343 | int_bio = bio_clone_fast(bio, GFP_KERNEL, &pblk_bio_set); |
| 344 | goto split_retry; | ||
| 345 | } else if (pblk_submit_io(pblk, rqd)) { | ||
| 346 | /* Submitting IO to drive failed, let's report an error */ | ||
| 347 | rqd->error = -ENODEV; | ||
| 348 | pblk_end_io_read(rqd); | ||
| 518 | } | 349 | } |
| 519 | } | 350 | } |
| 520 | 351 | ||
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h index 17ced12db7dd..a67855387f53 100644 --- a/drivers/lightnvm/pblk.h +++ b/drivers/lightnvm/pblk.h | |||
| @@ -121,18 +121,6 @@ struct pblk_g_ctx { | |||
| 121 | u64 lba; | 121 | u64 lba; |
| 122 | }; | 122 | }; |
| 123 | 123 | ||
| 124 | /* partial read context */ | ||
| 125 | struct pblk_pr_ctx { | ||
| 126 | struct bio *orig_bio; | ||
| 127 | DECLARE_BITMAP(bitmap, NVM_MAX_VLBA); | ||
| 128 | unsigned int orig_nr_secs; | ||
| 129 | unsigned int bio_init_idx; | ||
| 130 | void *ppa_ptr; | ||
| 131 | dma_addr_t dma_ppa_list; | ||
| 132 | u64 lba_list_mem[NVM_MAX_VLBA]; | ||
| 133 | u64 lba_list_media[NVM_MAX_VLBA]; | ||
| 134 | }; | ||
| 135 | |||
| 136 | /* Pad context */ | 124 | /* Pad context */ |
| 137 | struct pblk_pad_rq { | 125 | struct pblk_pad_rq { |
| 138 | struct pblk *pblk; | 126 | struct pblk *pblk; |
| @@ -759,7 +747,7 @@ unsigned int pblk_rb_read_to_bio(struct pblk_rb *rb, struct nvm_rq *rqd, | |||
| 759 | unsigned int pos, unsigned int nr_entries, | 747 | unsigned int pos, unsigned int nr_entries, |
| 760 | unsigned int count); | 748 | unsigned int count); |
| 761 | int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba, | 749 | int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba, |
| 762 | struct ppa_addr ppa, int bio_iter, bool advanced_bio); | 750 | struct ppa_addr ppa); |
| 763 | unsigned int pblk_rb_read_commit(struct pblk_rb *rb, unsigned int entries); | 751 | unsigned int pblk_rb_read_commit(struct pblk_rb *rb, unsigned int entries); |
| 764 | 752 | ||
| 765 | unsigned int pblk_rb_sync_init(struct pblk_rb *rb, unsigned long *flags); | 753 | unsigned int pblk_rb_sync_init(struct pblk_rb *rb, unsigned long *flags); |
| @@ -859,8 +847,8 @@ int pblk_update_map_gc(struct pblk *pblk, sector_t lba, struct ppa_addr ppa, | |||
| 859 | struct pblk_line *gc_line, u64 paddr); | 847 | struct pblk_line *gc_line, u64 paddr); |
| 860 | void pblk_lookup_l2p_rand(struct pblk *pblk, struct ppa_addr *ppas, | 848 | void pblk_lookup_l2p_rand(struct pblk *pblk, struct ppa_addr *ppas, |
| 861 | u64 *lba_list, int nr_secs); | 849 | u64 *lba_list, int nr_secs); |
| 862 | void pblk_lookup_l2p_seq(struct pblk *pblk, struct ppa_addr *ppas, | 850 | int pblk_lookup_l2p_seq(struct pblk *pblk, struct ppa_addr *ppas, |
| 863 | sector_t blba, int nr_secs); | 851 | sector_t blba, int nr_secs, bool *from_cache); |
| 864 | void *pblk_get_meta_for_writes(struct pblk *pblk, struct nvm_rq *rqd); | 852 | void *pblk_get_meta_for_writes(struct pblk *pblk, struct nvm_rq *rqd); |
| 865 | void pblk_get_packed_meta(struct pblk *pblk, struct nvm_rq *rqd); | 853 | void pblk_get_packed_meta(struct pblk *pblk, struct nvm_rq *rqd); |
| 866 | 854 | ||
