diff options
author | Javier González <jg@lightnvm.io> | 2017-06-26 05:57:20 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-06-26 18:27:39 -0400 |
commit | f9c101523da75cd483b95f04c21242bb83960d93 (patch) | |
tree | a6d20ae407bb1768d844bab613f165617d7ddff3 | |
parent | 0880a9aa2d91ff5131ecd0902a758afe760b9c1c (diff) |
lightnvm: pblk: issue multiplane reads if possible
If a read request is sequential and its size aligns with a
multi-plane page size, use the multi-plane hint to process the I/O in
parallel in the controller.
Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <matias@cnexlabs.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/lightnvm/pblk-core.c | 12 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-read.c | 11 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-recovery.c | 18 | ||||
-rw-r--r-- | drivers/lightnvm/pblk.h | 22 |
4 files changed, 51 insertions, 12 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c index beae1618483f..29565f89a85e 100644 --- a/drivers/lightnvm/pblk-core.c +++ b/drivers/lightnvm/pblk-core.c | |||
@@ -564,7 +564,6 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line, | |||
564 | int id = line->id; | 564 | int id = line->id; |
565 | int rq_ppas, rq_len; | 565 | int rq_ppas, rq_len; |
566 | int cmd_op, bio_op; | 566 | int cmd_op, bio_op; |
567 | int flags; | ||
568 | int i, j; | 567 | int i, j; |
569 | int ret; | 568 | int ret; |
570 | DECLARE_COMPLETION_ONSTACK(wait); | 569 | DECLARE_COMPLETION_ONSTACK(wait); |
@@ -572,11 +571,9 @@ static int pblk_line_submit_emeta_io(struct pblk *pblk, struct pblk_line *line, | |||
572 | if (dir == WRITE) { | 571 | if (dir == WRITE) { |
573 | bio_op = REQ_OP_WRITE; | 572 | bio_op = REQ_OP_WRITE; |
574 | cmd_op = NVM_OP_PWRITE; | 573 | cmd_op = NVM_OP_PWRITE; |
575 | flags = pblk_set_progr_mode(pblk, WRITE); | ||
576 | } else if (dir == READ) { | 574 | } else if (dir == READ) { |
577 | bio_op = REQ_OP_READ; | 575 | bio_op = REQ_OP_READ; |
578 | cmd_op = NVM_OP_PREAD; | 576 | cmd_op = NVM_OP_PREAD; |
579 | flags = pblk_set_read_mode(pblk); | ||
580 | } else | 577 | } else |
581 | return -EINVAL; | 578 | return -EINVAL; |
582 | 579 | ||
@@ -601,7 +598,6 @@ next_rq: | |||
601 | 598 | ||
602 | rqd.bio = bio; | 599 | rqd.bio = bio; |
603 | rqd.opcode = cmd_op; | 600 | rqd.opcode = cmd_op; |
604 | rqd.flags = flags; | ||
605 | rqd.nr_ppas = rq_ppas; | 601 | rqd.nr_ppas = rq_ppas; |
606 | rqd.ppa_list = ppa_list; | 602 | rqd.ppa_list = ppa_list; |
607 | rqd.dma_ppa_list = dma_ppa_list; | 603 | rqd.dma_ppa_list = dma_ppa_list; |
@@ -609,6 +605,7 @@ next_rq: | |||
609 | rqd.private = &wait; | 605 | rqd.private = &wait; |
610 | 606 | ||
611 | if (dir == WRITE) { | 607 | if (dir == WRITE) { |
608 | rqd.flags = pblk_set_progr_mode(pblk, WRITE); | ||
612 | for (i = 0; i < rqd.nr_ppas; ) { | 609 | for (i = 0; i < rqd.nr_ppas; ) { |
613 | spin_lock(&line->lock); | 610 | spin_lock(&line->lock); |
614 | paddr = __pblk_alloc_page(pblk, line, min); | 611 | paddr = __pblk_alloc_page(pblk, line, min); |
@@ -621,6 +618,11 @@ next_rq: | |||
621 | for (i = 0; i < rqd.nr_ppas; ) { | 618 | for (i = 0; i < rqd.nr_ppas; ) { |
622 | struct ppa_addr ppa = addr_to_gen_ppa(pblk, paddr, id); | 619 | struct ppa_addr ppa = addr_to_gen_ppa(pblk, paddr, id); |
623 | int pos = pblk_dev_ppa_to_pos(geo, ppa); | 620 | int pos = pblk_dev_ppa_to_pos(geo, ppa); |
621 | int read_type = PBLK_READ_RANDOM; | ||
622 | |||
623 | if (pblk_io_aligned(pblk, rq_ppas)) | ||
624 | read_type = PBLK_READ_SEQUENTIAL; | ||
625 | rqd.flags = pblk_set_read_mode(pblk, read_type); | ||
624 | 626 | ||
625 | while (test_bit(pos, line->blk_bitmap)) { | 627 | while (test_bit(pos, line->blk_bitmap)) { |
626 | paddr += min; | 628 | paddr += min; |
@@ -717,7 +719,7 @@ static int pblk_line_submit_smeta_io(struct pblk *pblk, struct pblk_line *line, | |||
717 | } else if (dir == READ) { | 719 | } else if (dir == READ) { |
718 | bio_op = REQ_OP_READ; | 720 | bio_op = REQ_OP_READ; |
719 | cmd_op = NVM_OP_PREAD; | 721 | cmd_op = NVM_OP_PREAD; |
720 | flags = pblk_set_read_mode(pblk); | 722 | flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); |
721 | } else | 723 | } else |
722 | return -EINVAL; | 724 | return -EINVAL; |
723 | 725 | ||
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c index 9c4d89cdd32f..1e7e98961821 100644 --- a/drivers/lightnvm/pblk-read.c +++ b/drivers/lightnvm/pblk-read.c | |||
@@ -88,6 +88,11 @@ retry: | |||
88 | bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE); | 88 | bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE); |
89 | } | 89 | } |
90 | 90 | ||
91 | if (pblk_io_aligned(pblk, nr_secs)) | ||
92 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | ||
93 | else | ||
94 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
95 | |||
91 | #ifdef CONFIG_NVM_DEBUG | 96 | #ifdef CONFIG_NVM_DEBUG |
92 | atomic_long_add(nr_secs, &pblk->inflight_reads); | 97 | atomic_long_add(nr_secs, &pblk->inflight_reads); |
93 | #endif | 98 | #endif |
@@ -97,8 +102,6 @@ static int pblk_submit_read_io(struct pblk *pblk, struct nvm_rq *rqd) | |||
97 | { | 102 | { |
98 | int err; | 103 | int err; |
99 | 104 | ||
100 | rqd->flags = pblk_set_read_mode(pblk); | ||
101 | |||
102 | err = pblk_submit_io(pblk, rqd); | 105 | err = pblk_submit_io(pblk, rqd); |
103 | if (err) | 106 | if (err) |
104 | return NVM_IO_ERR; | 107 | return NVM_IO_ERR; |
@@ -177,6 +180,7 @@ static int pblk_fill_partial_read_bio(struct pblk *pblk, struct nvm_rq *rqd, | |||
177 | 180 | ||
178 | rqd->bio = new_bio; | 181 | rqd->bio = new_bio; |
179 | rqd->nr_ppas = nr_holes; | 182 | rqd->nr_ppas = nr_holes; |
183 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
180 | rqd->end_io = NULL; | 184 | rqd->end_io = NULL; |
181 | 185 | ||
182 | if (unlikely(nr_secs > 1 && nr_holes == 1)) { | 186 | if (unlikely(nr_secs > 1 && nr_holes == 1)) { |
@@ -290,6 +294,8 @@ retry: | |||
290 | } else { | 294 | } else { |
291 | rqd->ppa_addr = ppa; | 295 | rqd->ppa_addr = ppa; |
292 | } | 296 | } |
297 | |||
298 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
293 | } | 299 | } |
294 | 300 | ||
295 | int pblk_submit_read(struct pblk *pblk, struct bio *bio) | 301 | int pblk_submit_read(struct pblk *pblk, struct bio *bio) |
@@ -497,6 +503,7 @@ int pblk_submit_read_gc(struct pblk *pblk, u64 *lba_list, void *data, | |||
497 | rqd.end_io = pblk_end_io_sync; | 503 | rqd.end_io = pblk_end_io_sync; |
498 | rqd.private = &wait; | 504 | rqd.private = &wait; |
499 | rqd.nr_ppas = *secs_to_gc; | 505 | rqd.nr_ppas = *secs_to_gc; |
506 | rqd.flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
500 | rqd.bio = bio; | 507 | rqd.bio = bio; |
501 | 508 | ||
502 | ret = pblk_submit_read_io(pblk, &rqd); | 509 | ret = pblk_submit_read_io(pblk, &rqd); |
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index 7b0ace2f4957..b9f2b40bd5a7 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c | |||
@@ -257,7 +257,6 @@ next_read_rq: | |||
257 | 257 | ||
258 | rqd->bio = bio; | 258 | rqd->bio = bio; |
259 | rqd->opcode = NVM_OP_PREAD; | 259 | rqd->opcode = NVM_OP_PREAD; |
260 | rqd->flags = pblk_set_read_mode(pblk); | ||
261 | rqd->meta_list = meta_list; | 260 | rqd->meta_list = meta_list; |
262 | rqd->nr_ppas = rq_ppas; | 261 | rqd->nr_ppas = rq_ppas; |
263 | rqd->ppa_list = ppa_list; | 262 | rqd->ppa_list = ppa_list; |
@@ -266,6 +265,11 @@ next_read_rq: | |||
266 | rqd->end_io = pblk_end_io_sync; | 265 | rqd->end_io = pblk_end_io_sync; |
267 | rqd->private = &wait; | 266 | rqd->private = &wait; |
268 | 267 | ||
268 | if (pblk_io_aligned(pblk, rq_ppas)) | ||
269 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | ||
270 | else | ||
271 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
272 | |||
269 | for (i = 0; i < rqd->nr_ppas; ) { | 273 | for (i = 0; i < rqd->nr_ppas; ) { |
270 | struct ppa_addr ppa; | 274 | struct ppa_addr ppa; |
271 | int pos; | 275 | int pos; |
@@ -473,7 +477,6 @@ next_rq: | |||
473 | 477 | ||
474 | rqd->bio = bio; | 478 | rqd->bio = bio; |
475 | rqd->opcode = NVM_OP_PREAD; | 479 | rqd->opcode = NVM_OP_PREAD; |
476 | rqd->flags = pblk_set_read_mode(pblk); | ||
477 | rqd->meta_list = meta_list; | 480 | rqd->meta_list = meta_list; |
478 | rqd->nr_ppas = rq_ppas; | 481 | rqd->nr_ppas = rq_ppas; |
479 | rqd->ppa_list = ppa_list; | 482 | rqd->ppa_list = ppa_list; |
@@ -482,6 +485,11 @@ next_rq: | |||
482 | rqd->end_io = pblk_end_io_sync; | 485 | rqd->end_io = pblk_end_io_sync; |
483 | rqd->private = &wait; | 486 | rqd->private = &wait; |
484 | 487 | ||
488 | if (pblk_io_aligned(pblk, rq_ppas)) | ||
489 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | ||
490 | else | ||
491 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
492 | |||
485 | for (i = 0; i < rqd->nr_ppas; ) { | 493 | for (i = 0; i < rqd->nr_ppas; ) { |
486 | struct ppa_addr ppa; | 494 | struct ppa_addr ppa; |
487 | int pos; | 495 | int pos; |
@@ -607,7 +615,6 @@ next_rq: | |||
607 | 615 | ||
608 | rqd->bio = bio; | 616 | rqd->bio = bio; |
609 | rqd->opcode = NVM_OP_PREAD; | 617 | rqd->opcode = NVM_OP_PREAD; |
610 | rqd->flags = pblk_set_read_mode(pblk); | ||
611 | rqd->meta_list = meta_list; | 618 | rqd->meta_list = meta_list; |
612 | rqd->nr_ppas = rq_ppas; | 619 | rqd->nr_ppas = rq_ppas; |
613 | rqd->ppa_list = ppa_list; | 620 | rqd->ppa_list = ppa_list; |
@@ -616,6 +623,11 @@ next_rq: | |||
616 | rqd->end_io = pblk_end_io_sync; | 623 | rqd->end_io = pblk_end_io_sync; |
617 | rqd->private = &wait; | 624 | rqd->private = &wait; |
618 | 625 | ||
626 | if (pblk_io_aligned(pblk, rq_ppas)) | ||
627 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_SEQUENTIAL); | ||
628 | else | ||
629 | rqd->flags = pblk_set_read_mode(pblk, PBLK_READ_RANDOM); | ||
630 | |||
619 | for (i = 0; i < rqd->nr_ppas; ) { | 631 | for (i = 0; i < rqd->nr_ppas; ) { |
620 | struct ppa_addr ppa; | 632 | struct ppa_addr ppa; |
621 | int pos; | 633 | int pos; |
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h index 50f30434718f..6dc58d360077 100644 --- a/drivers/lightnvm/pblk.h +++ b/drivers/lightnvm/pblk.h | |||
@@ -1075,9 +1075,27 @@ static inline int pblk_set_progr_mode(struct pblk *pblk, int type) | |||
1075 | return flags; | 1075 | return flags; |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | static inline int pblk_set_read_mode(struct pblk *pblk) | 1078 | enum { |
1079 | PBLK_READ_RANDOM = 0, | ||
1080 | PBLK_READ_SEQUENTIAL = 1, | ||
1081 | }; | ||
1082 | |||
1083 | static inline int pblk_set_read_mode(struct pblk *pblk, int type) | ||
1084 | { | ||
1085 | struct nvm_tgt_dev *dev = pblk->dev; | ||
1086 | struct nvm_geo *geo = &dev->geo; | ||
1087 | int flags; | ||
1088 | |||
1089 | flags = NVM_IO_SUSPEND | NVM_IO_SCRAMBLE_ENABLE; | ||
1090 | if (type == PBLK_READ_SEQUENTIAL) | ||
1091 | flags |= geo->plane_mode >> 1; | ||
1092 | |||
1093 | return flags; | ||
1094 | } | ||
1095 | |||
1096 | static inline int pblk_io_aligned(struct pblk *pblk, int nr_secs) | ||
1079 | { | 1097 | { |
1080 | return NVM_IO_SNGL_ACCESS | NVM_IO_SUSPEND | NVM_IO_SCRAMBLE_ENABLE; | 1098 | return !(nr_secs % pblk->min_write_pgs); |
1081 | } | 1099 | } |
1082 | 1100 | ||
1083 | #ifdef CONFIG_NVM_DEBUG | 1101 | #ifdef CONFIG_NVM_DEBUG |