Pull passthrough updates from Jens Axboe: "With these changes, passthrough NVMe support over io_uring now performs at the same level as block device O_DIRECT, and in many cases 6-8% better. This contains: - Add support for fixed buffers for passthrough (Anuj, Kanchan) - Enable batched allocations and freeing on passthrough, similarly to what we support on the normal storage path (me) - Fix from Geert fixing an issue with !CONFIG_IO_URING" * tag 'for-6.1/passthrough-2022-10-04' of git://git.kernel.dk/linux: io_uring: Add missing inline to io_uring_cmd_import_fixed() dummy nvme: wire up fixed buffer support for nvme passthrough nvme: pass ubuffer as an integer block: extend functionality to map bvec iterator block: factor out blk_rq_map_bio_alloc helper block: rename bio_map_put to blk_mq_map_bio_put nvme: refactor nvme_alloc_request nvme: refactor nvme_add_user_metadata nvme: Use blk_rq_map_user_io helper scsi: Use blk_rq_map_user_io helper block: add blk_rq_map_user_io io_uring: introduce fixed buffer support for io_uring_cmd io_uring: add io_uring_cmd_import_fixed nvme: enable batched completions of passthrough IO nvme: split out metadata vs non metadata end_io uring_cmd completions block: allow end_io based requests in the completion batch handling block: change request end_io handler to pass back a return value block: enable batched allocation for blk_mq_alloc_request() block: kill deprecated BUG_ON() in the flush handling
Unified · Split
| @@ -205,7 +205,6 @@ static void blk_flush_complete_seq(struct request *rq, · 204 unmodified lines | |||
| 205 | * flush data request completion path. Restore @rq for | 205 | * flush data request completion path. Restore @rq for |
| 206 | * normal completion and end it. | 206 | * normal completion and end it. |
| 207 | */ | 207 | */ |
| 208 | BUG_ON(!list_empty(&rq->queuelist)); | ||
| 209 | list_del_init(&rq->flush.list); | 208 | list_del_init(&rq->flush.list); |
| 210 | blk_flush_restore_request(rq); | 209 | blk_flush_restore_request(rq); |
| 211 | blk_mq_end_request(rq, error); | 210 | blk_mq_end_request(rq, error); |
| @@ -218,7 +217,8 @@ static void blk_flush_complete_seq(struct request *rq, · 6 unmodified lines | |||
| 218 | blk_kick_flush(q, fq, cmd_flags); | 217 | blk_kick_flush(q, fq, cmd_flags); |
| 219 | } | 218 | } |
| 220 | 219 | ||
| 221 | static void flush_end_io(struct request *flush_rq, blk_status_t error) | 220 | static enum rq_end_io_ret flush_end_io(struct request *flush_rq, |
| 221 | blk_status_t error) | ||
| 222 | { | 222 | { |
| 223 | struct request_queue *q = flush_rq->q; | 223 | struct request_queue *q = flush_rq->q; |
| 224 | struct list_head *running; | 224 | struct list_head *running; |
| @@ -232,7 +232,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) · 7 unmodified lines | |||
| 232 | if (!req_ref_put_and_test(flush_rq)) { | 232 | if (!req_ref_put_and_test(flush_rq)) { |
| 233 | fq->rq_status = error; | 233 | fq->rq_status = error; |
| 234 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); | 234 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); |
| 235 | return; | 235 | return RQ_END_IO_NONE; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | blk_account_io_flush(flush_rq); | 238 | blk_account_io_flush(flush_rq); |
| @@ -269,6 +269,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) · 30 unmodified lines | |||
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); | 271 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); |
| 272 | return RQ_END_IO_NONE; | ||
| 272 | } | 273 | } |
| 273 | 274 | ||
| 274 | bool is_flush_rq(struct request *rq) | 275 | bool is_flush_rq(struct request *rq) |
| @@ -354,7 +355,8 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq, · 79 unmodified lines | |||
| 354 | blk_flush_queue_rq(flush_rq, false); | 355 | blk_flush_queue_rq(flush_rq, false); |
| 355 | } | 356 | } |
| 356 | 357 | ||
| 357 | static void mq_flush_data_end_io(struct request *rq, blk_status_t error) | 358 | static enum rq_end_io_ret mq_flush_data_end_io(struct request *rq, |
| 359 | blk_status_t error) | ||
| 358 | { | 360 | { |
| 359 | struct request_queue *q = rq->q; | 361 | struct request_queue *q = rq->q; |
| 360 | struct blk_mq_hw_ctx *hctx = rq->mq_hctx; | 362 | struct blk_mq_hw_ctx *hctx = rq->mq_hctx; |
| @@ -376,6 +378,7 @@ static void mq_flush_data_end_io(struct request *rq, blk_status_t error) · 15 unmodified lines | |||
| 376 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); | 378 | spin_unlock_irqrestore(&fq->mq_flush_lock, flags); |
| 377 | 379 | ||
| 378 | blk_mq_sched_restart(hctx); | 380 | blk_mq_sched_restart(hctx); |
| 381 | return RQ_END_IO_NONE; | ||
| 379 | } | 382 | } |
| 380 | 383 | ||
| 381 | /** | 384 | /** |
| @@ -231,7 +231,7 @@ out_bmd: · 230 unmodified lines | |||
| 231 | return ret; | 231 | return ret; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | static void bio_map_put(struct bio *bio) | 234 | static void blk_mq_map_bio_put(struct bio *bio) |
| 235 | { | 235 | { |
| 236 | if (bio->bi_opf & REQ_ALLOC_CACHE) { | 236 | if (bio->bi_opf & REQ_ALLOC_CACHE) { |
| 237 | bio_put(bio); | 237 | bio_put(bio); |
| @@ -241,17 +241,10 @@ static void bio_map_put(struct bio *bio) · 3 unmodified lines | |||
| 241 | } | 241 | } |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, | 244 | static struct bio *blk_rq_map_bio_alloc(struct request *rq, |
| 245 | gfp_t gfp_mask) | 245 | unsigned int nr_vecs, gfp_t gfp_mask) |
| 246 | { | 246 | { |
| 247 | unsigned int max_sectors = queue_max_hw_sectors(rq->q); | ||
| 248 | unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS); | ||
| 249 | struct bio *bio; | 247 | struct bio *bio; |
| 250 | int ret; | ||
| 251 | int j; | ||
| 252 | |||
| 253 | if (!iov_iter_count(iter)) | ||
| 254 | return -EINVAL; | ||
| 255 | 248 | ||
| 256 | if (rq->cmd_flags & REQ_POLLED) { | 249 | if (rq->cmd_flags & REQ_POLLED) { |
| 257 | blk_opf_t opf = rq->cmd_flags | REQ_ALLOC_CACHE; | 250 | blk_opf_t opf = rq->cmd_flags | REQ_ALLOC_CACHE; |
| @@ -259,13 +252,31 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, · 1 unmodified line | |||
| 259 | bio = bio_alloc_bioset(NULL, nr_vecs, opf, gfp_mask, | 252 | bio = bio_alloc_bioset(NULL, nr_vecs, opf, gfp_mask, |
| 260 | &fs_bio_set); | 253 | &fs_bio_set); |
| 261 | if (!bio) | 254 | if (!bio) |
| 262 | return -ENOMEM; | 255 | return NULL; |
| 263 | } else { | 256 | } else { |
| 264 | bio = bio_kmalloc(nr_vecs, gfp_mask); | 257 | bio = bio_kmalloc(nr_vecs, gfp_mask); |
| 265 | if (!bio) | 258 | if (!bio) |
| 266 | return -ENOMEM; | 259 | return NULL; |
| 267 | bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, req_op(rq)); | 260 | bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, req_op(rq)); |
| 268 | } | 261 | } |
| 262 | return bio; | ||
| 263 | } | ||
| 264 | |||
| 265 | static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, | ||
| 266 | gfp_t gfp_mask) | ||
| 267 | { | ||
| 268 | unsigned int max_sectors = queue_max_hw_sectors(rq->q); | ||
| 269 | unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS); | ||
| 270 | struct bio *bio; | ||
| 271 | int ret; | ||
| 272 | int j; | ||
| 273 | |||
| 274 | if (!iov_iter_count(iter)) | ||
| 275 | return -EINVAL; | ||
| 276 | |||
| 277 | bio = blk_rq_map_bio_alloc(rq, nr_vecs, gfp_mask); | ||
| 278 | if (bio == NULL) | ||
| 279 | return -ENOMEM; | ||
| 269 | 280 | ||
| 270 | while (iov_iter_count(iter)) { | 281 | while (iov_iter_count(iter)) { |
| 271 | struct page **pages, *stack_pages[UIO_FASTIOV]; | 282 | struct page **pages, *stack_pages[UIO_FASTIOV]; |
| @@ -331,7 +342,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, · 59 unmodified lines | |||
| 331 | 342 | ||
| 332 | out_unmap: | 343 | out_unmap: |
| 333 | bio_release_pages(bio, false); | 344 | bio_release_pages(bio, false); |
| 334 | bio_map_put(bio); | 345 | blk_mq_map_bio_put(bio); |
| 335 | return ret; | 346 | return ret; |
| 336 | } | 347 | } |
| 337 | 348 | ||
| @@ -537,6 +548,62 @@ int blk_rq_append_bio(struct request *rq, struct bio *bio) · 199 unmodified lines | |||
| 537 | } | 548 | } |
| 538 | EXPORT_SYMBOL(blk_rq_append_bio); | 549 | EXPORT_SYMBOL(blk_rq_append_bio); |
| 539 | 550 | ||
| 551 | /* Prepare bio for passthrough IO given ITER_BVEC iter */ | ||
| 552 | static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter) | ||
| 553 | { | ||
| 554 | struct request_queue *q = rq->q; | ||
| 555 | size_t nr_iter = iov_iter_count(iter); | ||
| 556 | size_t nr_segs = iter->nr_segs; | ||
| 557 | struct bio_vec *bvecs, *bvprvp = NULL; | ||
| 558 | struct queue_limits *lim = &q->limits; | ||
| 559 | unsigned int nsegs = 0, bytes = 0; | ||
| 560 | struct bio *bio; | ||
| 561 | size_t i; | ||
| 562 | |||
| 563 | if (!nr_iter || (nr_iter >> SECTOR_SHIFT) > queue_max_hw_sectors(q)) | ||
| 564 | return -EINVAL; | ||
| 565 | if (nr_segs > queue_max_segments(q)) | ||
| 566 | return -EINVAL; | ||
| 567 | |||
| 568 | /* no iovecs to alloc, as we already have a BVEC iterator */ | ||
| 569 | bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL); | ||
| 570 | if (bio == NULL) | ||
| 571 | return -ENOMEM; | ||
| 572 | |||
| 573 | bio_iov_bvec_set(bio, (struct iov_iter *)iter); | ||
| 574 | blk_rq_bio_prep(rq, bio, nr_segs); | ||
| 575 | |||
| 576 | /* loop to perform a bunch of sanity checks */ | ||
| 577 | bvecs = (struct bio_vec *)iter->bvec; | ||
| 578 | for (i = 0; i < nr_segs; i++) { | ||
| 579 | struct bio_vec *bv = &bvecs[i]; | ||
| 580 | |||
| 581 | /* | ||
| 582 | * If the queue doesn't support SG gaps and adding this | ||
| 583 | * offset would create a gap, fallback to copy. | ||
| 584 | */ | ||
| 585 | if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv->bv_offset)) { | ||
| 586 | blk_mq_map_bio_put(bio); | ||
| 587 | return -EREMOTEIO; | ||
| 588 | } | ||
| 589 | /* check full condition */ | ||
| 590 | if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len) | ||
| 591 | goto put_bio; | ||
| 592 | if (bytes + bv->bv_len > nr_iter) | ||
| 593 | goto put_bio; | ||
| 594 | if (bv->bv_offset + bv->bv_len > PAGE_SIZE) | ||
| 595 | goto put_bio; | ||
| 596 | |||
| 597 | nsegs++; | ||
| 598 | bytes += bv->bv_len; | ||
| 599 | bvprvp = bv; | ||
| 600 | } | ||
| 601 | return 0; | ||
| 602 | put_bio: | ||
| 603 | blk_mq_map_bio_put(bio); | ||
| 604 | return -EINVAL; | ||
| 605 | } | ||
| 606 | |||
| 540 | /** | 607 | /** |
| 541 | * blk_rq_map_user_iov - map user data to a request, for passthrough requests | 608 | * blk_rq_map_user_iov - map user data to a request, for passthrough requests |
| 542 | * @q: request queue where request should be inserted | 609 | * @q: request queue where request should be inserted |
| @@ -556,24 +623,35 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, · 13 unmodified lines | |||
| 556 | struct rq_map_data *map_data, | 623 | struct rq_map_data *map_data, |
| 557 | const struct iov_iter *iter, gfp_t gfp_mask) | 624 | const struct iov_iter *iter, gfp_t gfp_mask) |
| 558 | { | 625 | { |
| 559 | bool copy = false; | 626 | bool copy = false, map_bvec = false; |
| 560 | unsigned long align = q->dma_pad_mask | queue_dma_alignment(q); | 627 | unsigned long align = q->dma_pad_mask | queue_dma_alignment(q); |
| 561 | struct bio *bio = NULL; | 628 | struct bio *bio = NULL; |
| 562 | struct iov_iter i; | 629 | struct iov_iter i; |
| 563 | int ret = -EINVAL; | 630 | int ret = -EINVAL; |
| 564 | 631 | ||
| 565 | if (!iter_is_iovec(iter)) | ||
| 566 | goto fail; | ||
| 567 | |||
| 568 | if (map_data) | 632 | if (map_data) |
| 569 | copy = true; | 633 | copy = true; |
| 570 | else if (blk_queue_may_bounce(q)) | 634 | else if (blk_queue_may_bounce(q)) |
| 571 | copy = true; | 635 | copy = true; |
| 572 | else if (iov_iter_alignment(iter) & align) | 636 | else if (iov_iter_alignment(iter) & align) |
| 573 | copy = true; | 637 | copy = true; |
| 638 | else if (iov_iter_is_bvec(iter)) | ||
| 639 | map_bvec = true; | ||
| 640 | else if (!iter_is_iovec(iter)) | ||
| 641 | copy = true; | ||
| 574 | else if (queue_virt_boundary(q)) | 642 | else if (queue_virt_boundary(q)) |
| 575 | copy = queue_virt_boundary(q) & iov_iter_gap_alignment(iter); | 643 | copy = queue_virt_boundary(q) & iov_iter_gap_alignment(iter); |
| 576 | 644 | ||
| 645 | if (map_bvec) { | ||
| 646 | ret = blk_rq_map_user_bvec(rq, iter); | ||
| 647 | if (!ret) | ||
| 648 | return 0; | ||
| 649 | if (ret != -EREMOTEIO) | ||
| 650 | goto fail; | ||
| 651 | /* fall back to copying the data on limits mismatches */ | ||
| 652 | copy = true; | ||
| 653 | } | ||
| 654 | |||
| 577 | i = *iter; | 655 | i = *iter; |
| 578 | do { | 656 | do { |
| 579 | if (copy) | 657 | if (copy) |
| @@ -611,6 +689,42 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, · 31 unmodified lines | |||
| 611 | } | 689 | } |
| 612 | EXPORT_SYMBOL(blk_rq_map_user); | 690 | EXPORT_SYMBOL(blk_rq_map_user); |
| 613 | 691 | ||
| 692 | int blk_rq_map_user_io(struct request *req, struct rq_map_data *map_data, | ||
| 693 | void __user *ubuf, unsigned long buf_len, gfp_t gfp_mask, | ||
| 694 | bool vec, int iov_count, bool check_iter_count, int rw) | ||
| 695 | { | ||
| 696 | int ret = 0; | ||
| 697 | |||
| 698 | if (vec) { | ||
| 699 | struct iovec fast_iov[UIO_FASTIOV]; | ||
| 700 | struct iovec *iov = fast_iov; | ||
| 701 | struct iov_iter iter; | ||
| 702 | |||
| 703 | ret = import_iovec(rw, ubuf, iov_count ? iov_count : buf_len, | ||
| 704 | UIO_FASTIOV, &iov, &iter); | ||
| 705 | if (ret < 0) | ||
| 706 | return ret; | ||
| 707 | |||
| 708 | if (iov_count) { | ||
| 709 | /* SG_IO howto says that the shorter of the two wins */ | ||
| 710 | iov_iter_truncate(&iter, buf_len); | ||
| 711 | if (check_iter_count && !iov_iter_count(&iter)) { | ||
| 712 | kfree(iov); | ||
| 713 | return -EINVAL; | ||
| 714 | } | ||
| 715 | } | ||
| 716 | |||
| 717 | ret = blk_rq_map_user_iov(req->q, req, map_data, &iter, | ||
| 718 | gfp_mask); | ||
| 719 | kfree(iov); | ||
| 720 | } else if (buf_len) { | ||
| 721 | ret = blk_rq_map_user(req->q, req, map_data, ubuf, buf_len, | ||
| 722 | gfp_mask); | ||
| 723 | } | ||
| 724 | return ret; | ||
| 725 | } | ||
| 726 | EXPORT_SYMBOL(blk_rq_map_user_io); | ||
| 727 | |||
| 614 | /** | 728 | /** |
| 615 | * blk_rq_unmap_user - unmap a request with user data | 729 | * blk_rq_unmap_user - unmap a request with user data |
| 616 | * @bio: start of bio list | 730 | * @bio: start of bio list |
| @@ -636,7 +750,7 @@ int blk_rq_unmap_user(struct bio *bio) · 19 unmodified lines | |||
| 636 | 750 | ||
| 637 | next_bio = bio; | 751 | next_bio = bio; |
| 638 | bio = bio->bi_next; | 752 | bio = bio->bi_next; |
| 639 | bio_map_put(next_bio); | 753 | blk_mq_map_bio_put(next_bio); |
| 640 | } | 754 | } |
| 641 | 755 | ||
| 642 | return ret; | 756 | return ret; |
| @@ -510,25 +510,87 @@ retry: · 509 unmodified lines | |||
| 510 | alloc_time_ns); | 510 | alloc_time_ns); |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | struct request *blk_mq_alloc_request(struct request_queue *q, blk_opf_t opf, | 513 | static struct request *blk_mq_rq_cache_fill(struct request_queue *q, |
| 514 | blk_mq_req_flags_t flags) | 514 | struct blk_plug *plug, |
| 515 | blk_opf_t opf, | ||
| 516 | blk_mq_req_flags_t flags) | ||
| 515 | { | 517 | { |
| 516 | struct blk_mq_alloc_data data = { | 518 | struct blk_mq_alloc_data data = { |
| 517 | .q = q, | 519 | .q = q, |
| 518 | .flags = flags, | 520 | .flags = flags, |
| 519 | .cmd_flags = opf, | 521 | .cmd_flags = opf, |
| 520 | .nr_tags = 1, | 522 | .nr_tags = plug->nr_ios, |
| 523 | .cached_rq = &plug->cached_rq, | ||
| 521 | }; | 524 | }; |
| 522 | struct request *rq; | 525 | struct request *rq; |
| 523 | int ret; | ||
| 524 | 526 | ||
| 525 | ret = blk_queue_enter(q, flags); | 527 | if (blk_queue_enter(q, flags)) |
| 526 | if (ret) | 528 | return NULL; |
| 527 | return ERR_PTR(ret); | 529 | |
| 530 | plug->nr_ios = 1; | ||
| 528 | 531 | ||
| 529 | rq = __blk_mq_alloc_requests(&data); | 532 | rq = __blk_mq_alloc_requests(&data); |
| 530 | if (!rq) | 533 | if (unlikely(!rq)) |
| 531 | goto out_queue_exit; | 534 | blk_queue_exit(q); |
| 535 | return rq; | ||
| 536 | } | ||
| 537 | |||
| 538 | static struct request *blk_mq_alloc_cached_request(struct request_queue *q, | ||
| 539 | blk_opf_t opf, | ||
| 540 | blk_mq_req_flags_t flags) | ||
| 541 | { | ||
| 542 | struct blk_plug *plug = current->plug; | ||
| 543 | struct request *rq; | ||
| 544 | |||
| 545 | if (!plug) | ||
| 546 | return NULL; | ||
| 547 | if (rq_list_empty(plug->cached_rq)) { | ||
| 548 | if (plug->nr_ios == 1) | ||
| 549 | return NULL; | ||
| 550 | rq = blk_mq_rq_cache_fill(q, plug, opf, flags); | ||
| 551 | if (rq) | ||
| 552 | goto got_it; | ||
| 553 | return NULL; | ||
| 554 | } | ||
| 555 | rq = rq_list_peek(&plug->cached_rq); | ||
| 556 | if (!rq || rq->q != q) | ||
| 557 | return NULL; | ||
| 558 | |||
| 559 | if (blk_mq_get_hctx_type(opf) != rq->mq_hctx->type) | ||
| 560 | return NULL; | ||
| 561 | if (op_is_flush(rq->cmd_flags) != op_is_flush(opf)) | ||
| 562 | return NULL; | ||
| 563 | |||
| 564 | plug->cached_rq = rq_list_next(rq); | ||
| 565 | got_it: | ||
| 566 | rq->cmd_flags = opf; | ||
| 567 | INIT_LIST_HEAD(&rq->queuelist); | ||
| 568 | return rq; | ||
| 569 | } | ||
| 570 | |||
| 571 | struct request *blk_mq_alloc_request(struct request_queue *q, blk_opf_t opf, | ||
| 572 | blk_mq_req_flags_t flags) | ||
| 573 | { | ||
| 574 | struct request *rq; | ||
| 575 | |||
| 576 | rq = blk_mq_alloc_cached_request(q, opf, flags); | ||
| 577 | if (!rq) { | ||
| 578 | struct blk_mq_alloc_data data = { | ||
| 579 | .q = q, | ||
| 580 | .flags = flags, | ||
| 581 | .cmd_flags = opf, | ||
| 582 | .nr_tags = 1, | ||
| 583 | }; | ||
| 584 | int ret; | ||
| 585 | |||
| 586 | ret = blk_queue_enter(q, flags); | ||
| 587 | if (ret) | ||
| 588 | return ERR_PTR(ret); | ||
| 589 | |||
| 590 | rq = __blk_mq_alloc_requests(&data); | ||
| 591 | if (!rq) | ||
| 592 | goto out_queue_exit; | ||
| 593 | } | ||
| 532 | rq->__data_len = 0; | 594 | rq->__data_len = 0; |
| 533 | rq->__sector = (sector_t) -1; | 595 | rq->__sector = (sector_t) -1; |
| 534 | rq->bio = rq->biotail = NULL; | 596 | rq->bio = rq->biotail = NULL; |
| @@ -761,8 +823,10 @@ static void blk_complete_request(struct request *req) · 226 unmodified lines | |||
| 761 | * can find how many bytes remain in the request | 823 | * can find how many bytes remain in the request |
| 762 | * later. | 824 | * later. |
| 763 | */ | 825 | */ |
| 764 | req->bio = NULL; | 826 | if (!req->end_io) { |
| 765 | req->__data_len = 0; | 827 | req->bio = NULL; |
| 828 | req->__data_len = 0; | ||
| 829 | } | ||
| 766 | } | 830 | } |
| 767 | 831 | ||
| 768 | /** | 832 | /** |
| @@ -939,7 +1003,8 @@ inline void __blk_mq_end_request(struct request *rq, blk_status_t error) · 170 unmodified lines | |||
| 939 | 1003 | ||
| 940 | if (rq->end_io) { | 1004 | if (rq->end_io) { |
| 941 | rq_qos_done(rq->q, rq); | 1005 | rq_qos_done(rq->q, rq); |
| 942 | rq->end_io(rq, error); | 1006 | if (rq->end_io(rq, error) == RQ_END_IO_FREE) |
| 1007 | blk_mq_free_request(rq); | ||
| 943 | } else { | 1008 | } else { |
| 944 | blk_mq_free_request(rq); | 1009 | blk_mq_free_request(rq); |
| 945 | } | 1010 | } |
| @@ -992,6 +1057,13 @@ void blk_mq_end_request_batch(struct io_comp_batch *iob) · 46 unmodified lines | |||
| 992 | 1057 | ||
| 993 | rq_qos_done(rq->q, rq); | 1058 | rq_qos_done(rq->q, rq); |
| 994 | 1059 | ||
| 1060 | /* | ||
| 1061 | * If end_io handler returns NONE, then it still has | ||
| 1062 | * ownership of the request. | ||
| 1063 | */ | ||
| 1064 | if (rq->end_io && rq->end_io(rq, 0) == RQ_END_IO_NONE) | ||
| 1065 | continue; | ||
| 1066 | |||
| 995 | WRITE_ONCE(rq->state, MQ_RQ_IDLE); | 1067 | WRITE_ONCE(rq->state, MQ_RQ_IDLE); |
| 996 | if (!req_ref_put_and_test(rq)) | 1068 | if (!req_ref_put_and_test(rq)) |
| 997 | continue; | 1069 | continue; |
| @@ -1233,12 +1305,13 @@ struct blk_rq_wait { · 235 unmodified lines | |||
| 1233 | blk_status_t ret; | 1305 | blk_status_t ret; |
| 1234 | }; | 1306 | }; |
| 1235 | 1307 | ||
| 1236 | static void blk_end_sync_rq(struct request *rq, blk_status_t ret) | 1308 | static enum rq_end_io_ret blk_end_sync_rq(struct request *rq, blk_status_t ret) |
| 1237 | { | 1309 | { |
| 1238 | struct blk_rq_wait *wait = rq->end_io_data; | 1310 | struct blk_rq_wait *wait = rq->end_io_data; |
| 1239 | 1311 | ||
| 1240 | wait->ret = ret; | 1312 | wait->ret = ret; |
| 1241 | complete(&wait->done); | 1313 | complete(&wait->done); |
| 1314 | return RQ_END_IO_NONE; | ||
| 1242 | } | 1315 | } |
| 1243 | 1316 | ||
| 1244 | bool blk_rq_is_poll(struct request *rq) | 1317 | bool blk_rq_is_poll(struct request *rq) |
| @@ -1472,10 +1545,12 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next) · 227 unmodified lines | |||
| 1472 | 1545 | ||
| 1473 | void blk_mq_put_rq_ref(struct request *rq) | 1546 | void blk_mq_put_rq_ref(struct request *rq) |
| 1474 | { | 1547 | { |
| 1475 | if (is_flush_rq(rq)) | 1548 | if (is_flush_rq(rq)) { |
| 1476 | rq->end_io(rq, 0); | 1549 | if (rq->end_io(rq, 0) == RQ_END_IO_FREE) |
| 1477 | else if (req_ref_put_and_test(rq)) | 1550 | blk_mq_free_request(rq); |
| 1551 | } else if (req_ref_put_and_test(rq)) { | ||
| 1478 | __blk_mq_free_request(rq); | 1552 | __blk_mq_free_request(rq); |
| 1553 | } | ||
| 1479 | } | 1554 | } |
| 1480 | 1555 | ||
| 1481 | static bool blk_mq_check_expired(struct request *rq, void *priv) | 1556 | static bool blk_mq_check_expired(struct request *rq, void *priv) |
| @@ -292,11 +292,13 @@ static void dm_kill_unmapped_request(struct request *rq, blk_status_t error) · 291 unmodified lines | |||
| 292 | dm_complete_request(rq, error); | 292 | dm_complete_request(rq, error); |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | static void end_clone_request(struct request *clone, blk_status_t error) | 295 | static enum rq_end_io_ret end_clone_request(struct request *clone, |
| 296 | blk_status_t error) | ||
| 296 | { | 297 | { |
| 297 | struct dm_rq_target_io *tio = clone->end_io_data; | 298 | struct dm_rq_target_io *tio = clone->end_io_data; |
| 298 | 299 | ||
| 299 | dm_complete_request(tio->orig, error); | 300 | dm_complete_request(tio->orig, error); |
| 301 | return RQ_END_IO_NONE; | ||
| 300 | } | 302 | } |
| 301 | 303 | ||
| 302 | static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig, | 304 | static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig, |
| @@ -1172,7 +1172,8 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) · 1171 unmodified lines | |||
| 1172 | queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ / 2); | 1172 | queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ / 2); |
| 1173 | } | 1173 | } |
| 1174 | 1174 | ||
| 1175 | static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) | 1175 | static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, |
| 1176 | blk_status_t status) | ||
| 1176 | { | 1177 | { |
| 1177 | struct nvme_ctrl *ctrl = rq->end_io_data; | 1178 | struct nvme_ctrl *ctrl = rq->end_io_data; |
| 1178 | unsigned long flags; | 1179 | unsigned long flags; |
| @@ -1184,7 +1185,7 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) · 5 unmodified lines | |||
| 1184 | dev_err(ctrl->device, | 1185 | dev_err(ctrl->device, |
| 1185 | "failed nvme_keep_alive_end_io error=%d\n", | 1186 | "failed nvme_keep_alive_end_io error=%d\n", |
| 1186 | status); | 1187 | status); |
| 1187 | return; | 1188 | return RQ_END_IO_NONE; |
| 1188 | } | 1189 | } |
| 1189 | 1190 | ||
| 1190 | ctrl->comp_seen = false; | 1191 | ctrl->comp_seen = false; |
| @@ -1195,6 +1196,7 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) · 4 unmodified lines | |||
| 1195 | spin_unlock_irqrestore(&ctrl->lock, flags); | 1196 | spin_unlock_irqrestore(&ctrl->lock, flags); |
| 1196 | if (startka) | 1197 | if (startka) |
| 1197 | nvme_queue_keep_alive_work(ctrl); | 1198 | nvme_queue_keep_alive_work(ctrl); |
| 1199 | return RQ_END_IO_NONE; | ||
| 1198 | } | 1200 | } |
| 1199 | 1201 | ||
| 1200 | static void nvme_keep_alive_work(struct work_struct *work) | 1202 | static void nvme_keep_alive_work(struct work_struct *work) |
| @@ -20,19 +20,20 @@ static void __user *nvme_to_user_ptr(uintptr_t ptrval) · 19 unmodified lines | |||
| 20 | return (void __user *)ptrval; | 20 | return (void __user *)ptrval; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | static void *nvme_add_user_metadata(struct bio *bio, void __user *ubuf, | 23 | static void *nvme_add_user_metadata(struct request *req, void __user *ubuf, |
| 24 | unsigned len, u32 seed, bool write) | 24 | unsigned len, u32 seed) |
| 25 | { | 25 | { |
| 26 | struct bio_integrity_payload *bip; | 26 | struct bio_integrity_payload *bip; |
| 27 | int ret = -ENOMEM; | 27 | int ret = -ENOMEM; |
| 28 | void *buf; | 28 | void *buf; |
| 29 | struct bio *bio = req->bio; | ||
| 29 | 30 | ||
| 30 | buf = kmalloc(len, GFP_KERNEL); | 31 | buf = kmalloc(len, GFP_KERNEL); |
| 31 | if (!buf) | 32 | if (!buf) |
| 32 | goto out; | 33 | goto out; |
| 33 | 34 | ||
| 34 | ret = -EFAULT; | 35 | ret = -EFAULT; |
| 35 | if (write && copy_from_user(buf, ubuf, len)) | 36 | if ((req_op(req) == REQ_OP_DRV_OUT) && copy_from_user(buf, ubuf, len)) |
| 36 | goto out_free_meta; | 37 | goto out_free_meta; |
| 37 | 38 | ||
| 38 | bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); | 39 | bip = bio_integrity_alloc(bio, GFP_KERNEL, 1); |
| @@ -45,9 +46,13 @@ static void *nvme_add_user_metadata(struct bio *bio, void __user *ubuf, · 6 unmodified lines | |||
| 45 | bip->bip_iter.bi_sector = seed; | 46 | bip->bip_iter.bi_sector = seed; |
| 46 | ret = bio_integrity_add_page(bio, virt_to_page(buf), len, | 47 | ret = bio_integrity_add_page(bio, virt_to_page(buf), len, |
| 47 | offset_in_page(buf)); | 48 | offset_in_page(buf)); |
| 48 | if (ret == len) | 49 | if (ret != len) { |
| 49 | return buf; | 50 | ret = -ENOMEM; |
| 50 | ret = -ENOMEM; | 51 | goto out_free_meta; |
| 52 | } | ||
| 53 | |||
| 54 | req->cmd_flags |= REQ_INTEGRITY; | ||
| 55 | return buf; | ||
| 51 | out_free_meta: | 56 | out_free_meta: |
| 52 | kfree(buf); | 57 | kfree(buf); |
| 53 | out: | 58 | out: |
| @@ -65,74 +70,76 @@ static int nvme_finish_user_metadata(struct request *req, void __user *ubuf, · 11 unmodified lines | |||
| 65 | } | 70 | } |
| 66 | 71 | ||
| 67 | static struct request *nvme_alloc_user_request(struct request_queue *q, | 72 | static struct request *nvme_alloc_user_request(struct request_queue *q, |
| 68 | struct nvme_command *cmd, void __user *ubuffer, | 73 | struct nvme_command *cmd, blk_opf_t rq_flags, |
| 69 | unsigned bufflen, void __user *meta_buffer, unsigned meta_len, | 74 | blk_mq_req_flags_t blk_flags) |
| 70 | u32 meta_seed, void **metap, unsigned timeout, bool vec, | ||
| 71 | blk_opf_t rq_flags, blk_mq_req_flags_t blk_flags) | ||
| 72 | { | 75 | { |
| 73 | bool write = nvme_is_write(cmd); | ||
| 74 | struct nvme_ns *ns = q->queuedata; | ||
| 75 | struct block_device *bdev = ns ? ns->disk->part0 : NULL; | ||
| 76 | struct request *req; | 76 | struct request *req; |
| 77 | struct bio *bio = NULL; | ||
| 78 | void *meta = NULL; | ||
| 79 | int ret; | ||
| 80 | 77 | ||
| 81 | req = blk_mq_alloc_request(q, nvme_req_op(cmd) | rq_flags, blk_flags); | 78 | req = blk_mq_alloc_request(q, nvme_req_op(cmd) | rq_flags, blk_flags); |
| 82 | if (IS_ERR(req)) | 79 | if (IS_ERR(req)) |
| 83 | return req; | 80 | return req; |
| 84 | nvme_init_request(req, cmd); | 81 | nvme_init_request(req, cmd); |
| 85 | |||
| 86 | if (timeout) | ||
| 87 | req->timeout = timeout; | ||
| 88 | nvme_req(req)->flags |= NVME_REQ_USERCMD; | 82 | nvme_req(req)->flags |= NVME_REQ_USERCMD; |
| 83 | return req; | ||
| 84 | } | ||
| 89 | 85 | ||
| 90 | if (ubuffer && bufflen) { | 86 | static int nvme_map_user_request(struct request *req, u64 ubuffer, |
| 91 | if (!vec) | 87 | unsigned bufflen, void __user *meta_buffer, unsigned meta_len, |
| 92 | ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen, | 88 | u32 meta_seed, void **metap, struct io_uring_cmd *ioucmd, |
| 93 | GFP_KERNEL); | 89 | bool vec) |
| 94 | else { | 90 | { |
| 95 | struct iovec fast_iov[UIO_FASTIOV]; | 91 | struct request_queue *q = req->q; |
| 96 | struct iovec *iov = fast_iov; | 92 | struct nvme_ns *ns = q->queuedata; |
| 97 | struct iov_iter iter; | 93 | struct block_device *bdev = ns ? ns->disk->part0 : NULL; |
| 98 | 94 | struct bio *bio = NULL; | |
| 99 | ret = import_iovec(rq_data_dir(req), ubuffer, bufflen, | 95 | void *meta = NULL; |
| 100 | UIO_FASTIOV, &iov, &iter); | 96 | int ret; |
| 101 | if (ret < 0) | 97 | |
| 102 | goto out; | 98 | if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) { |
| 103 | ret = blk_rq_map_user_iov(q, req, NULL, &iter, | 99 | struct iov_iter iter; |
| 104 | GFP_KERNEL); | 100 | |
| 105 | kfree(iov); | 101 | /* fixedbufs is only for non-vectored io */ |
| 106 | } | 102 | if (WARN_ON_ONCE(vec)) |
| 107 | if (ret) | 103 | return -EINVAL; |
| 104 | ret = io_uring_cmd_import_fixed(ubuffer, bufflen, | ||
| 105 | rq_data_dir(req), &iter, ioucmd); | ||
| 106 | if (ret < 0) | ||
| 108 | goto out; | 107 | goto out; |
| 109 | bio = req->bio; | 108 | ret = blk_rq_map_user_iov(q, req, NULL, &iter, GFP_KERNEL); |
| 110 | if (bdev) | 109 | } else { |
| 111 | bio_set_dev(bio, bdev); | 110 | ret = blk_rq_map_user_io(req, NULL, nvme_to_user_ptr(ubuffer), |
| 112 | if (bdev && meta_buffer && meta_len) { | 111 | bufflen, GFP_KERNEL, vec, 0, 0, |
| 113 | meta = nvme_add_user_metadata(bio, meta_buffer, meta_len, | 112 | rq_data_dir(req)); |
| 114 | meta_seed, write); | 113 | } |
| 115 | if (IS_ERR(meta)) { | 114 | |
| 116 | ret = PTR_ERR(meta); | 115 | if (ret) |
| 117 | goto out_unmap; | 116 | goto out; |
| 118 | } | 117 | bio = req->bio; |
| 119 | req->cmd_flags |= REQ_INTEGRITY; | 118 | if (bdev) |
| 120 | *metap = meta; | 119 | bio_set_dev(bio, bdev); |
| 120 | |||
| 121 | if (bdev && meta_buffer && meta_len) { | ||
| 122 | meta = nvme_add_user_metadata(req, meta_buffer, meta_len, | ||
| 123 | meta_seed); | ||
| 124 | if (IS_ERR(meta)) { | ||
| 125 | ret = PTR_ERR(meta); | ||
| 126 | goto out_unmap; | ||
| 121 | } | 127 | } |
| 128 | *metap = meta; | ||
| 122 | } | 129 | } |
| 123 | 130 | ||
| 124 | return req; | 131 | return ret; |
| 125 | 132 | ||
| 126 | out_unmap: | 133 | out_unmap: |
| 127 | if (bio) | 134 | if (bio) |
| 128 | blk_rq_unmap_user(bio); | 135 | blk_rq_unmap_user(bio); |
| 129 | out: | 136 | out: |
| 130 | blk_mq_free_request(req); | 137 | blk_mq_free_request(req); |
| 131 | return ERR_PTR(ret); | 138 | return ret; |
| 132 | } | 139 | } |
| 133 | 140 | ||
| 134 | static int nvme_submit_user_cmd(struct request_queue *q, | 141 | static int nvme_submit_user_cmd(struct request_queue *q, |
| 135 | struct nvme_command *cmd, void __user *ubuffer, | 142 | struct nvme_command *cmd, u64 ubuffer, |
| 136 | unsigned bufflen, void __user *meta_buffer, unsigned meta_len, | 143 | unsigned bufflen, void __user *meta_buffer, unsigned meta_len, |
| 137 | u32 meta_seed, u64 *result, unsigned timeout, bool vec) | 144 | u32 meta_seed, u64 *result, unsigned timeout, bool vec) |
| 138 | { | 145 | { |
| @@ -143,11 +150,18 @@ static int nvme_submit_user_cmd(struct request_queue *q, · 4 unmodified lines | |||
| 143 | u32 effects; | 150 | u32 effects; |
| 144 | int ret; | 151 | int ret; |
| 145 | 152 | ||
| 146 | req = nvme_alloc_user_request(q, cmd, ubuffer, bufflen, meta_buffer, | 153 | req = nvme_alloc_user_request(q, cmd, 0, 0); |
| 147 | meta_len, meta_seed, &meta, timeout, vec, 0, 0); | ||
| 148 | if (IS_ERR(req)) | 154 | if (IS_ERR(req)) |
| 149 | return PTR_ERR(req); | 155 | return PTR_ERR(req); |
| 150 | 156 | ||
| 157 | req->timeout = timeout; | ||
| 158 | if (ubuffer && bufflen) { | ||
| 159 | ret = nvme_map_user_request(req, ubuffer, bufflen, meta_buffer, | ||
| 160 | meta_len, meta_seed, &meta, NULL, vec); | ||
| 161 | if (ret) | ||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 151 | bio = req->bio; | 165 | bio = req->bio; |
| 152 | ctrl = nvme_req(req)->ctrl; | 166 | ctrl = nvme_req(req)->ctrl; |
| 153 | 167 | ||
| @@ -227,7 +241,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) · 73 unmodified lines | |||
| 227 | c.rw.appmask = cpu_to_le16(io.appmask); | 241 | c.rw.appmask = cpu_to_le16(io.appmask); |
| 228 | 242 | ||
| 229 | return nvme_submit_user_cmd(ns->queue, &c, | 243 | return nvme_submit_user_cmd(ns->queue, &c, |
| 230 | nvme_to_user_ptr(io.addr), length, | 244 | io.addr, length, |
| 231 | metadata, meta_len, lower_32_bits(io.slba), NULL, 0, | 245 | metadata, meta_len, lower_32_bits(io.slba), NULL, 0, |
| 232 | false); | 246 | false); |
| 233 | } | 247 | } |
| @@ -281,7 +295,7 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns, · 47 unmodified lines | |||
| 281 | timeout = msecs_to_jiffies(cmd.timeout_ms); | 295 | timeout = msecs_to_jiffies(cmd.timeout_ms); |
| 282 | 296 | ||
| 283 | status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, | 297 | status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, |
| 284 | nvme_to_user_ptr(cmd.addr), cmd.data_len, | 298 | cmd.addr, cmd.data_len, |
| 285 | nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, | 299 | nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, |
| 286 | 0, &result, timeout, false); | 300 | 0, &result, timeout, false); |
| 287 | 301 | ||
| @@ -327,7 +341,7 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns, · 39 unmodified lines | |||
| 327 | timeout = msecs_to_jiffies(cmd.timeout_ms); | 341 | timeout = msecs_to_jiffies(cmd.timeout_ms); |
| 328 | 342 | ||
| 329 | status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, | 343 | status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, |
| 330 | nvme_to_user_ptr(cmd.addr), cmd.data_len, | 344 | cmd.addr, cmd.data_len, |
| 331 | nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, | 345 | nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, |
| 332 | 0, &cmd.result, timeout, vec); | 346 | 0, &cmd.result, timeout, vec); |
| 333 | 347 | ||
| @@ -356,9 +370,15 @@ struct nvme_uring_cmd_pdu { · 22 unmodified lines | |||
| 356 | struct bio *bio; | 370 | struct bio *bio; |
| 357 | struct request *req; | 371 | struct request *req; |
| 358 | }; | 372 | }; |
| 359 | void *meta; /* kernel-resident buffer */ | ||
| 360 | void __user *meta_buffer; | ||
| 361 | u32 meta_len; | 373 | u32 meta_len; |
| 374 | u32 nvme_status; | ||
| 375 | union { | ||
| 376 | struct { | ||
| 377 | void *meta; /* kernel-resident buffer */ | ||
| 378 | void __user *meta_buffer; | ||
| 379 | }; | ||
| 380 | u64 result; | ||
| 381 | } u; | ||
| 362 | }; | 382 | }; |
| 363 | 383 | ||
| 364 | static inline struct nvme_uring_cmd_pdu *nvme_uring_cmd_pdu( | 384 | static inline struct nvme_uring_cmd_pdu *nvme_uring_cmd_pdu( |
| @@ -367,11 +387,10 @@ static inline struct nvme_uring_cmd_pdu *nvme_uring_cmd_pdu( · 2 unmodified lines | |||
| 367 | return (struct nvme_uring_cmd_pdu *)&ioucmd->pdu; | 387 | return (struct nvme_uring_cmd_pdu *)&ioucmd->pdu; |
| 368 | } | 388 | } |
| 369 | 389 | ||
| 370 | static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd) | 390 | static void nvme_uring_task_meta_cb(struct io_uring_cmd *ioucmd) |
| 371 | { | 391 | { |
| 372 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); | 392 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); |
| 373 | struct request *req = pdu->req; | 393 | struct request *req = pdu->req; |
| 374 | struct bio *bio = req->bio; | ||
| 375 | int status; | 394 | int status; |
| 376 | u64 result; | 395 | u64 result; |
| 377 | 396 | ||
| @@ -382,26 +401,39 @@ static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd) · 4 unmodified lines | |||
| 382 | 401 | ||
| 383 | result = le64_to_cpu(nvme_req(req)->result.u64); | 402 | result = le64_to_cpu(nvme_req(req)->result.u64); |
| 384 | 403 | ||
| 385 | if (pdu->meta) | 404 | if (pdu->meta_len) |
| 386 | status = nvme_finish_user_metadata(req, pdu->meta_buffer, | 405 | status = nvme_finish_user_metadata(req, pdu->u.meta_buffer, |
| 387 | pdu->meta, pdu->meta_len, status); | 406 | pdu->u.meta, pdu->meta_len, status); |
| 388 | if (bio) | 407 | if (req->bio) |
| 389 | blk_rq_unmap_user(bio); | 408 | blk_rq_unmap_user(req->bio); |
| 390 | blk_mq_free_request(req); | 409 | blk_mq_free_request(req); |
| 391 | 410 | ||
| 392 | io_uring_cmd_done(ioucmd, status, result); | 411 | io_uring_cmd_done(ioucmd, status, result); |
| 393 | } | 412 | } |
| 394 | 413 | ||
| 395 | static void nvme_uring_cmd_end_io(struct request *req, blk_status_t err) | 414 | static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd) |
| 415 | { | ||
| 416 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); | ||
| 417 | |||
| 418 | if (pdu->bio) | ||
| 419 | blk_rq_unmap_user(pdu->bio); | ||
| 420 | |||
| 421 | io_uring_cmd_done(ioucmd, pdu->nvme_status, pdu->u.result); | ||
| 422 | } | ||
| 423 | |||
| 424 | static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req, | ||
| 425 | blk_status_t err) | ||
| 396 | { | 426 | { |
| 397 | struct io_uring_cmd *ioucmd = req->end_io_data; | 427 | struct io_uring_cmd *ioucmd = req->end_io_data; |
| 398 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); | 428 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); |
| 399 | /* extract bio before reusing the same field for request */ | ||
| 400 | struct bio *bio = pdu->bio; | ||
| 401 | void *cookie = READ_ONCE(ioucmd->cookie); | 429 | void *cookie = READ_ONCE(ioucmd->cookie); |
| 402 | 430 | ||
| 403 | pdu->req = req; | 431 | req->bio = pdu->bio; |
| 404 | req->bio = bio; | 432 | if (nvme_req(req)->flags & NVME_REQ_CANCELLED) |
| 433 | pdu->nvme_status = -EINTR; | ||
| 434 | else | ||
| 435 | pdu->nvme_status = nvme_req(req)->status; | ||
| 436 | pdu->u.result = le64_to_cpu(nvme_req(req)->result.u64); | ||
| 405 | 437 | ||
| 406 | /* | 438 | /* |
| 407 | * For iopoll, complete it directly. | 439 | * For iopoll, complete it directly. |
| @@ -411,6 +443,30 @@ static void nvme_uring_cmd_end_io(struct request *req, blk_status_t err) · 3 unmodified lines | |||
| 411 | nvme_uring_task_cb(ioucmd); | 443 | nvme_uring_task_cb(ioucmd); |
| 412 | else | 444 | else |
| 413 | io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_cb); | 445 | io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_cb); |
| 446 | |||
| 447 | return RQ_END_IO_FREE; | ||
| 448 | } | ||
| 449 | |||
| 450 | static enum rq_end_io_ret nvme_uring_cmd_end_io_meta(struct request *req, | ||
| 451 | blk_status_t err) | ||
| 452 | { | ||
| 453 | struct io_uring_cmd *ioucmd = req->end_io_data; | ||
| 454 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); | ||
| 455 | void *cookie = READ_ONCE(ioucmd->cookie); | ||
| 456 | |||
| 457 | req->bio = pdu->bio; | ||
| 458 | pdu->req = req; | ||
| 459 | |||
| 460 | /* | ||
| 461 | * For iopoll, complete it directly. | ||
| 462 | * Otherwise, move the completion to task work. | ||
| 463 | */ | ||
| 464 | if (cookie != NULL && blk_rq_is_poll(req)) | ||
| 465 | nvme_uring_task_meta_cb(ioucmd); | ||
| 466 | else | ||
| 467 | io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_meta_cb); | ||
| 468 | |||
| 469 | return RQ_END_IO_NONE; | ||
| 414 | } | 470 | } |
| 415 | 471 | ||
| 416 | static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, | 472 | static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, |
| @@ -425,6 +481,7 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, · 8 unmodified lines | |||
| 425 | blk_opf_t rq_flags = 0; | 481 | blk_opf_t rq_flags = 0; |
| 426 | blk_mq_req_flags_t blk_flags = 0; | 482 | blk_mq_req_flags_t blk_flags = 0; |
| 427 | void *meta = NULL; | 483 | void *meta = NULL; |
| 484 | int ret; | ||
| 428 | 485 | ||
| 429 | if (!capable(CAP_SYS_ADMIN)) | 486 | if (!capable(CAP_SYS_ADMIN)) |
| 430 | return -EACCES; | 487 | return -EACCES; |
| @@ -464,15 +521,18 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, · 33 unmodified lines | |||
| 464 | rq_flags |= REQ_POLLED; | 521 | rq_flags |= REQ_POLLED; |
| 465 | 522 | ||
| 466 | retry: | 523 | retry: |
| 467 | req = nvme_alloc_user_request(q, &c, nvme_to_user_ptr(d.addr), | 524 | req = nvme_alloc_user_request(q, &c, rq_flags, blk_flags); |
| 468 | d.data_len, nvme_to_user_ptr(d.metadata), | ||
| 469 | d.metadata_len, 0, &meta, d.timeout_ms ? | ||
| 470 | msecs_to_jiffies(d.timeout_ms) : 0, vec, rq_flags, | ||
| 471 | blk_flags); | ||
| 472 | if (IS_ERR(req)) | 525 | if (IS_ERR(req)) |
| 473 | return PTR_ERR(req); | 526 | return PTR_ERR(req); |
| 474 | req->end_io = nvme_uring_cmd_end_io; | 527 | req->timeout = d.timeout_ms ? msecs_to_jiffies(d.timeout_ms) : 0; |
| 475 | req->end_io_data = ioucmd; | 528 | |
| 529 | if (d.addr && d.data_len) { | ||
| 530 | ret = nvme_map_user_request(req, d.addr, | ||
| 531 | d.data_len, nvme_to_user_ptr(d.metadata), | ||
| 532 | d.metadata_len, 0, &meta, ioucmd, vec); | ||
| 533 | if (ret) | ||
| 534 | return ret; | ||
| 535 | } | ||
| 476 | 536 | ||
| 477 | if (issue_flags & IO_URING_F_IOPOLL && rq_flags & REQ_POLLED) { | 537 | if (issue_flags & IO_URING_F_IOPOLL && rq_flags & REQ_POLLED) { |
| 478 | if (unlikely(!req->bio)) { | 538 | if (unlikely(!req->bio)) { |
| @@ -487,10 +547,15 @@ retry: · 8 unmodified lines | |||
| 487 | } | 547 | } |
| 488 | /* to free bio on completion, as req->bio will be null at that time */ | 548 | /* to free bio on completion, as req->bio will be null at that time */ |
| 489 | pdu->bio = req->bio; | 549 | pdu->bio = req->bio; |
| 490 | pdu->meta = meta; | ||
| 491 | pdu->meta_buffer = nvme_to_user_ptr(d.metadata); | ||
| 492 | pdu->meta_len = d.metadata_len; | 550 | pdu->meta_len = d.metadata_len; |
| 493 | 551 | req->end_io_data = ioucmd; | |
| 552 | if (pdu->meta_len) { | ||
| 553 | pdu->u.meta = meta; | ||
| 554 | pdu->u.meta_buffer = nvme_to_user_ptr(d.metadata); | ||
| 555 | req->end_io = nvme_uring_cmd_end_io_meta; | ||
| 556 | } else { | ||
| 557 | req->end_io = nvme_uring_cmd_end_io; | ||
| 558 | } | ||
| 494 | blk_execute_rq_nowait(req, false); | 559 | blk_execute_rq_nowait(req, false); |
| 495 | return -EIOCBQUEUED; | 560 | return -EIOCBQUEUED; |
| 496 | } | 561 | } |
| @@ -1268,7 +1268,7 @@ static int adapter_delete_sq(struct nvme_dev *dev, u16 sqid) · 1267 unmodified lines | |||
| 1268 | return adapter_delete_queue(dev, nvme_admin_delete_sq, sqid); | 1268 | return adapter_delete_queue(dev, nvme_admin_delete_sq, sqid); |
| 1269 | } | 1269 | } |
| 1270 | 1270 | ||
| 1271 | static void abort_endio(struct request *req, blk_status_t error) | 1271 | static enum rq_end_io_ret abort_endio(struct request *req, blk_status_t error) |
| 1272 | { | 1272 | { |
| 1273 | struct nvme_queue *nvmeq = req->mq_hctx->driver_data; | 1273 | struct nvme_queue *nvmeq = req->mq_hctx->driver_data; |
| 1274 | 1274 | ||
| @@ -1276,6 +1276,7 @@ static void abort_endio(struct request *req, blk_status_t error) · 1 unmodified line | |||
| 1276 | "Abort status: 0x%x", nvme_req(req)->status); | 1276 | "Abort status: 0x%x", nvme_req(req)->status); |
| 1277 | atomic_inc(&nvmeq->dev->ctrl.abort_limit); | 1277 | atomic_inc(&nvmeq->dev->ctrl.abort_limit); |
| 1278 | blk_mq_free_request(req); | 1278 | blk_mq_free_request(req); |
| 1279 | return RQ_END_IO_NONE; | ||
| 1279 | } | 1280 | } |
| 1280 | 1281 | ||
| 1281 | static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) | 1282 | static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) |
| @@ -2447,22 +2448,25 @@ out_unlock: · 1165 unmodified lines | |||
| 2447 | return result; | 2448 | return result; |
| 2448 | } | 2449 | } |
| 2449 | 2450 | ||
| 2450 | static void nvme_del_queue_end(struct request *req, blk_status_t error) | 2451 | static enum rq_end_io_ret nvme_del_queue_end(struct request *req, |
| 2452 | blk_status_t error) | ||
| 2451 | { | 2453 | { |
| 2452 | struct nvme_queue *nvmeq = req->end_io_data; | 2454 | struct nvme_queue *nvmeq = req->end_io_data; |
| 2453 | 2455 | ||
| 2454 | blk_mq_free_request(req); | 2456 | blk_mq_free_request(req); |
| 2455 | complete(&nvmeq->delete_done); | 2457 | complete(&nvmeq->delete_done); |
| 2458 | return RQ_END_IO_NONE; | ||
| 2456 | } | 2459 | } |
| 2457 | 2460 | ||
| 2458 | static void nvme_del_cq_end(struct request *req, blk_status_t error) | 2461 | static enum rq_end_io_ret nvme_del_cq_end(struct request *req, |
| 2462 | blk_status_t error) | ||
| 2459 | { | 2463 | { |
| 2460 | struct nvme_queue *nvmeq = req->end_io_data; | 2464 | struct nvme_queue *nvmeq = req->end_io_data; |
| 2461 | 2465 | ||
| 2462 | if (error) | 2466 | if (error) |
| 2463 | set_bit(NVMEQ_DELETE_ERROR, &nvmeq->flags); | 2467 | set_bit(NVMEQ_DELETE_ERROR, &nvmeq->flags); |
| 2464 | 2468 | ||
| 2465 | nvme_del_queue_end(req, error); | 2469 | return nvme_del_queue_end(req, error); |
| 2466 | } | 2470 | } |
| 2467 | 2471 | ||
| 2468 | static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode) | 2472 | static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode) |
| @@ -245,14 +245,15 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w) · 244 unmodified lines | |||
| 245 | nvme_passthru_end(ctrl, effects, req->cmd, status); | 245 | nvme_passthru_end(ctrl, effects, req->cmd, status); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static void nvmet_passthru_req_done(struct request *rq, | 248 | static enum rq_end_io_ret nvmet_passthru_req_done(struct request *rq, |
| 249 | blk_status_t blk_status) | 249 | blk_status_t blk_status) |
| 250 | { | 250 | { |
| 251 | struct nvmet_req *req = rq->end_io_data; | 251 | struct nvmet_req *req = rq->end_io_data; |
| 252 | 252 | ||
| 253 | req->cqe->result = nvme_req(rq)->result; | 253 | req->cqe->result = nvme_req(rq)->result; |
| 254 | nvmet_req_complete(req, nvme_req(rq)->status); | 254 | nvmet_req_complete(req, nvme_req(rq)->status); |
| 255 | blk_mq_free_request(rq); | 255 | blk_mq_free_request(rq); |
| 256 | return RQ_END_IO_NONE; | ||
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | static int nvmet_passthru_map_sg(struct nvmet_req *req, struct request *rq) | 259 | static int nvmet_passthru_map_sg(struct nvmet_req *req, struct request *rq) |
| @@ -2004,9 +2004,11 @@ maybe_retry: · 2003 unmodified lines | |||
| 2004 | } | 2004 | } |
| 2005 | } | 2005 | } |
| 2006 | 2006 | ||
| 2007 | static void eh_lock_door_done(struct request *req, blk_status_t status) | 2007 | static enum rq_end_io_ret eh_lock_door_done(struct request *req, |
| 2008 | blk_status_t status) | ||
| 2008 | { | 2009 | { |
| 2009 | blk_mq_free_request(req); | 2010 | blk_mq_free_request(req); |
| 2011 | return RQ_END_IO_NONE; | ||
| 2010 | } | 2012 | } |
| 2011 | 2013 | ||
| 2012 | /** | 2014 | /** |
| @@ -449,25 +449,9 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode) · 448 unmodified lines | |||
| 449 | if (ret < 0) | 449 | if (ret < 0) |
| 450 | goto out_put_request; | 450 | goto out_put_request; |
| 451 | 451 | ||
| 452 | ret = 0; | 452 | ret = blk_rq_map_user_io(rq, NULL, hdr->dxferp, hdr->dxfer_len, |
| 453 | if (hdr->iovec_count && hdr->dxfer_len) { | 453 | GFP_KERNEL, hdr->iovec_count && hdr->dxfer_len, |
| 454 | struct iov_iter i; | 454 | hdr->iovec_count, 0, rq_data_dir(rq)); |
| 455 | struct iovec *iov = NULL; | ||
| 456 | |||
| 457 | ret = import_iovec(rq_data_dir(rq), hdr->dxferp, | ||
| 458 | hdr->iovec_count, 0, &iov, &i); | ||
| 459 | if (ret < 0) | ||
| 460 | goto out_put_request; | ||
| 461 | |||
| 462 | /* SG_IO howto says that the shorter of the two wins */ | ||
| 463 | iov_iter_truncate(&i, hdr->dxfer_len); | ||
| 464 | |||
| 465 | ret = blk_rq_map_user_iov(rq->q, rq, NULL, &i, GFP_KERNEL); | ||
| 466 | kfree(iov); | ||
| 467 | } else if (hdr->dxfer_len) | ||
| 468 | ret = blk_rq_map_user(rq->q, rq, NULL, hdr->dxferp, | ||
| 469 | hdr->dxfer_len, GFP_KERNEL); | ||
| 470 | |||
| 471 | if (ret) | 455 | if (ret) |
| 472 | goto out_put_request; | 456 | goto out_put_request; |
| 473 | 457 | ||
| @@ -177,7 +177,7 @@ typedef struct sg_device { /* holds the state of each scsi generic device */ · 176 unmodified lines | |||
| 177 | } Sg_device; | 177 | } Sg_device; |
| 178 | 178 | ||
| 179 | /* tasklet or soft irq callback */ | 179 | /* tasklet or soft irq callback */ |
| 180 | static void sg_rq_end_io(struct request *rq, blk_status_t status); | 180 | static enum rq_end_io_ret sg_rq_end_io(struct request *rq, blk_status_t status); |
| 181 | static int sg_start_req(Sg_request *srp, unsigned char *cmd); | 181 | static int sg_start_req(Sg_request *srp, unsigned char *cmd); |
| 182 | static int sg_finish_rem_req(Sg_request * srp); | 182 | static int sg_finish_rem_req(Sg_request * srp); |
| 183 | static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size); | 183 | static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size); |
| @@ -1311,7 +1311,7 @@ sg_rq_end_io_usercontext(struct work_struct *work) · 1127 unmodified lines | |||
| 1311 | * This function is a "bottom half" handler that is called by the mid | 1311 | * This function is a "bottom half" handler that is called by the mid |
| 1312 | * level when a command is completed (or has failed). | 1312 | * level when a command is completed (or has failed). |
| 1313 | */ | 1313 | */ |
| 1314 | static void | 1314 | static enum rq_end_io_ret |
| 1315 | sg_rq_end_io(struct request *rq, blk_status_t status) | 1315 | sg_rq_end_io(struct request *rq, blk_status_t status) |
| 1316 | { | 1316 | { |
| 1317 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq); | 1317 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq); |
| @@ -1324,11 +1324,11 @@ sg_rq_end_io(struct request *rq, blk_status_t status) · 6 unmodified lines | |||
| 1324 | int result, resid, done = 1; | 1324 | int result, resid, done = 1; |
| 1325 | 1325 | ||
| 1326 | if (WARN_ON(srp->done != 0)) | 1326 | if (WARN_ON(srp->done != 0)) |
| 1327 | return; | 1327 | return RQ_END_IO_NONE; |
| 1328 | 1328 | ||
| 1329 | sfp = srp->parentfp; | 1329 | sfp = srp->parentfp; |
| 1330 | if (WARN_ON(sfp == NULL)) | 1330 | if (WARN_ON(sfp == NULL)) |
| 1331 | return; | 1331 | return RQ_END_IO_NONE; |
| 1332 | 1332 | ||
| 1333 | sdp = sfp->parentdp; | 1333 | sdp = sfp->parentdp; |
| 1334 | if (unlikely(atomic_read(&sdp->detaching))) | 1334 | if (unlikely(atomic_read(&sdp->detaching))) |
| @@ -1406,6 +1406,7 @@ sg_rq_end_io(struct request *rq, blk_status_t status) · 71 unmodified lines | |||
| 1406 | INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext); | 1406 | INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext); |
| 1407 | schedule_work(&srp->ew.work); | 1407 | schedule_work(&srp->ew.work); |
| 1408 | } | 1408 | } |
| 1409 | return RQ_END_IO_NONE; | ||
| 1409 | } | 1410 | } |
| 1410 | 1411 | ||
| 1411 | static const struct file_operations sg_fops = { | 1412 | static const struct file_operations sg_fops = { |
| @@ -1803,26 +1804,8 @@ sg_start_req(Sg_request *srp, unsigned char *cmd) · 391 unmodified lines | |||
| 1803 | md->from_user = 0; | 1804 | md->from_user = 0; |
| 1804 | } | 1805 | } |
| 1805 | 1806 | ||
| 1806 | if (iov_count) { | 1807 | res = blk_rq_map_user_io(rq, md, hp->dxferp, hp->dxfer_len, |
| 1807 | struct iovec *iov = NULL; | 1808 | GFP_ATOMIC, iov_count, iov_count, 1, rw); |
| 1808 | struct iov_iter i; | ||
| 1809 | |||
| 1810 | res = import_iovec(rw, hp->dxferp, iov_count, 0, &iov, &i); | ||
| 1811 | if (res < 0) | ||
| 1812 | return res; | ||
| 1813 | |||
| 1814 | iov_iter_truncate(&i, hp->dxfer_len); | ||
| 1815 | if (!iov_iter_count(&i)) { | ||
| 1816 | kfree(iov); | ||
| 1817 | return -EINVAL; | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | res = blk_rq_map_user_iov(q, rq, md, &i, GFP_ATOMIC); | ||
| 1821 | kfree(iov); | ||
| 1822 | } else | ||
| 1823 | res = blk_rq_map_user(q, rq, md, hp->dxferp, | ||
| 1824 | hp->dxfer_len, GFP_ATOMIC); | ||
| 1825 | |||
| 1826 | if (!res) { | 1809 | if (!res) { |
| 1827 | srp->bio = rq->bio; | 1810 | srp->bio = rq->bio; |
| 1828 | 1811 | ||
| @@ -512,7 +512,8 @@ static void st_do_stats(struct scsi_tape *STp, struct request *req) · 511 unmodified lines | |||
| 512 | atomic64_dec(&STp->stats->in_flight); | 512 | atomic64_dec(&STp->stats->in_flight); |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | static void st_scsi_execute_end(struct request *req, blk_status_t status) | 515 | static enum rq_end_io_ret st_scsi_execute_end(struct request *req, |
| 516 | blk_status_t status) | ||
| 516 | { | 517 | { |
| 517 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); | 518 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); |
| 518 | struct st_request *SRpnt = req->end_io_data; | 519 | struct st_request *SRpnt = req->end_io_data; |
| @@ -532,6 +533,7 @@ static void st_scsi_execute_end(struct request *req, blk_status_t status) · 13 unmodified lines | |||
| 532 | 533 | ||
| 533 | blk_rq_unmap_user(tmp); | 534 | blk_rq_unmap_user(tmp); |
| 534 | blk_mq_free_request(req); | 535 | blk_mq_free_request(req); |
| 536 | return RQ_END_IO_NONE; | ||
| 535 | } | 537 | } |
| 536 | 538 | ||
| 537 | static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd, | 539 | static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd, |
| @@ -39,7 +39,7 @@ static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev) · 38 unmodified lines | |||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd); | 41 | static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd); |
| 42 | static void pscsi_req_done(struct request *, blk_status_t); | 42 | static enum rq_end_io_ret pscsi_req_done(struct request *, blk_status_t); |
| 43 | 43 | ||
| 44 | /* pscsi_attach_hba(): | 44 | /* pscsi_attach_hba(): |
| 45 | * | 45 | * |
| @@ -1002,7 +1002,8 @@ static sector_t pscsi_get_blocks(struct se_device *dev) · 956 unmodified lines | |||
| 1002 | return 0; | 1002 | return 0; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | static void pscsi_req_done(struct request *req, blk_status_t status) | 1005 | static enum rq_end_io_ret pscsi_req_done(struct request *req, |
| 1006 | blk_status_t status) | ||
| 1006 | { | 1007 | { |
| 1007 | struct se_cmd *cmd = req->end_io_data; | 1008 | struct se_cmd *cmd = req->end_io_data; |
| 1008 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); | 1009 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); |
| @@ -1029,6 +1030,7 @@ static void pscsi_req_done(struct request *req, blk_status_t status) · 20 unmodified lines | |||
| 1029 | } | 1030 | } |
| 1030 | 1031 | ||
| 1031 | blk_mq_free_request(req); | 1032 | blk_mq_free_request(req); |
| 1033 | return RQ_END_IO_NONE; | ||
| 1032 | } | 1034 | } |
| 1033 | 1035 | ||
| 1034 | static const struct target_backend_ops pscsi_ops = { | 1036 | static const struct target_backend_ops pscsi_ops = { |
| @@ -613,14 +613,17 @@ static void ufshpb_activate_subregion(struct ufshpb_lu *hpb, · 612 unmodified lines | |||
| 613 | srgn->srgn_state = HPB_SRGN_VALID; | 613 | srgn->srgn_state = HPB_SRGN_VALID; |
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | static void ufshpb_umap_req_compl_fn(struct request *req, blk_status_t error) | 616 | static enum rq_end_io_ret ufshpb_umap_req_compl_fn(struct request *req, |
| 617 | blk_status_t error) | ||
| 617 | { | 618 | { |
| 618 | struct ufshpb_req *umap_req = (struct ufshpb_req *)req->end_io_data; | 619 | struct ufshpb_req *umap_req = (struct ufshpb_req *)req->end_io_data; |
| 619 | 620 | ||
| 620 | ufshpb_put_req(umap_req->hpb, umap_req); | 621 | ufshpb_put_req(umap_req->hpb, umap_req); |
| 622 | return RQ_END_IO_NONE; | ||
| 621 | } | 623 | } |
| 622 | 624 | ||
| 623 | static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) | 625 | static enum rq_end_io_ret ufshpb_map_req_compl_fn(struct request *req, |
| 626 | blk_status_t error) | ||
| 624 | { | 627 | { |
| 625 | struct ufshpb_req *map_req = (struct ufshpb_req *) req->end_io_data; | 628 | struct ufshpb_req *map_req = (struct ufshpb_req *) req->end_io_data; |
| 626 | struct ufshpb_lu *hpb = map_req->hpb; | 629 | struct ufshpb_lu *hpb = map_req->hpb; |
| @@ -636,6 +639,7 @@ static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) · 9 unmodified lines | |||
| 636 | spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); | 639 | spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); |
| 637 | 640 | ||
| 638 | ufshpb_put_map_req(map_req->hpb, map_req); | 641 | ufshpb_put_map_req(map_req->hpb, map_req); |
| 642 | return RQ_END_IO_NONE; | ||
| 639 | } | 643 | } |
| 640 | 644 | ||
| 641 | static void ufshpb_set_unmap_cmd(unsigned char *cdb, struct ufshpb_region *rgn) | 645 | static void ufshpb_set_unmap_cmd(unsigned char *cdb, struct ufshpb_region *rgn) |
| @@ -14,7 +14,12 @@ struct blk_flush_queue; · 13 unmodified lines | |||
| 14 | #define BLKDEV_MIN_RQ 4 | 14 | #define BLKDEV_MIN_RQ 4 |
| 15 | #define BLKDEV_DEFAULT_RQ 128 | 15 | #define BLKDEV_DEFAULT_RQ 128 |
| 16 | 16 | ||
| 17 | typedef void (rq_end_io_fn)(struct request *, blk_status_t); | 17 | enum rq_end_io_ret { |
| 18 | RQ_END_IO_NONE, | ||
| 19 | RQ_END_IO_FREE, | ||
| 20 | }; | ||
| 21 | |||
| 22 | typedef enum rq_end_io_ret (rq_end_io_fn)(struct request *, blk_status_t); | ||
| 18 | 23 | ||
| 19 | /* | 24 | /* |
| 20 | * request flags */ | 25 | * request flags */ |
| @@ -848,8 +853,9 @@ static inline bool blk_mq_add_to_batch(struct request *req, · 827 unmodified lines | |||
| 848 | struct io_comp_batch *iob, int ioerror, | 853 | struct io_comp_batch *iob, int ioerror, |
| 849 | void (*complete)(struct io_comp_batch *)) | 854 | void (*complete)(struct io_comp_batch *)) |
| 850 | { | 855 | { |
| 851 | if (!iob || (req->rq_flags & RQF_ELV) || req->end_io || ioerror) | 856 | if (!iob || (req->rq_flags & RQF_ELV) || ioerror) |
| 852 | return false; | 857 | return false; |
| 858 | |||
| 853 | if (!iob->complete) | 859 | if (!iob->complete) |
| 854 | iob->complete = complete; | 860 | iob->complete = complete; |
| 855 | else if (iob->complete != complete) | 861 | else if (iob->complete != complete) |
| @@ -979,6 +985,8 @@ struct rq_map_data { · 123 unmodified lines | |||
| 979 | 985 | ||
| 980 | int blk_rq_map_user(struct request_queue *, struct request *, | 986 | int blk_rq_map_user(struct request_queue *, struct request *, |
| 981 | struct rq_map_data *, void __user *, unsigned long, gfp_t); | 987 | struct rq_map_data *, void __user *, unsigned long, gfp_t); |
| 988 | int blk_rq_map_user_io(struct request *, struct rq_map_data *, | ||
| 989 | void __user *, unsigned long, gfp_t, bool, int, bool, int); | ||
| 982 | int blk_rq_map_user_iov(struct request_queue *, struct request *, | 990 | int blk_rq_map_user_iov(struct request_queue *, struct request *, |
| 983 | struct rq_map_data *, const struct iov_iter *, gfp_t); | 991 | struct rq_map_data *, const struct iov_iter *, gfp_t); |
| 984 | int blk_rq_unmap_user(struct bio *); | 992 | int blk_rq_unmap_user(struct bio *); |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
| 6 | #include <linux/xarray.h> | 6 | #include <linux/xarray.h> |
| 7 | #include <uapi/linux/io_uring.h> | ||
| 7 | 8 | ||
| 8 | enum io_uring_cmd_flags { | 9 | enum io_uring_cmd_flags { |
| 9 | IO_URING_F_COMPLETE_DEFER = 1, | 10 | IO_URING_F_COMPLETE_DEFER = 1, |
| @@ -27,11 +28,13 @@ struct io_uring_cmd { · 17 unmodified lines | |||
| 27 | void *cookie; | 28 | void *cookie; |
| 28 | }; | 29 | }; |
| 29 | u32 cmd_op; | 30 | u32 cmd_op; |
| 30 | u32 pad; | 31 | u32 flags; |
| 31 | u8 pdu[32]; /* available inline for free use */ | 32 | u8 pdu[32]; /* available inline for free use */ |
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | #if defined(CONFIG_IO_URING) | 35 | #if defined(CONFIG_IO_URING) |
| 36 | int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, | ||
| 37 | struct iov_iter *iter, void *ioucmd); | ||
| 35 | void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2); | 38 | void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2); |
| 36 | void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, | 39 | void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd, |
| 37 | void (*task_work_cb)(struct io_uring_cmd *)); | 40 | void (*task_work_cb)(struct io_uring_cmd *)); |
| @@ -59,6 +62,11 @@ static inline void io_uring_free(struct task_struct *tsk) · 21 unmodified lines | |||
| 59 | __io_uring_free(tsk); | 62 | __io_uring_free(tsk); |
| 60 | } | 63 | } |
| 61 | #else | 64 | #else |
| 65 | static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, | ||
| 66 | struct iov_iter *iter, void *ioucmd) | ||
| 67 | { | ||
| 68 | return -EOPNOTSUPP; | ||
| 69 | } | ||
| 62 | static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, | 70 | static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, |
| 63 | ssize_t ret2) | 71 | ssize_t ret2) |
| 64 | { | 72 | { |
| @@ -56,6 +56,7 @@ struct io_uring_sqe { · 55 unmodified lines | |||
| 56 | __u32 hardlink_flags; | 56 | __u32 hardlink_flags; |
| 57 | __u32 xattr_flags; | 57 | __u32 xattr_flags; |
| 58 | __u32 msg_ring_flags; | 58 | __u32 msg_ring_flags; |
| 59 | __u32 uring_cmd_flags; | ||
| 59 | }; | 60 | }; |
| 60 | __u64 user_data; /* data to be passed back at completion time */ | 61 | __u64 user_data; /* data to be passed back at completion time */ |
| 61 | /* pack this to avoid bogus arm OABI complaints */ | 62 | /* pack this to avoid bogus arm OABI complaints */ |
| @@ -219,6 +220,14 @@ enum io_uring_op { · 157 unmodified lines | |||
| 219 | IORING_OP_LAST, | 220 | IORING_OP_LAST, |
| 220 | }; | 221 | }; |
| 221 | 222 | ||
| 223 | /* | ||
| 224 | * sqe->uring_cmd_flags | ||
| 225 | * IORING_URING_CMD_FIXED use registered buffer; pass thig flag | ||
| 226 | * along with setting sqe->buf_index. | ||
| 227 | */ | ||
| 228 | #define IORING_URING_CMD_FIXED (1U << 0) | ||
| 229 | |||
| 230 | |||
| 222 | /* | 231 | /* |
| 223 | * sqe->fsync_flags | 232 | * sqe->fsync_flags |
| 224 | */ | 233 | */ |
| @@ -4,10 +4,12 @@ · 3 unmodified lines | |||
| 4 | #include <linux/file.h> | 4 | #include <linux/file.h> |
| 5 | #include <linux/io_uring.h> | 5 | #include <linux/io_uring.h> |
| 6 | #include <linux/security.h> | 6 | #include <linux/security.h> |
| 7 | #include <linux/nospec.h> | ||
| 7 | 8 | ||
| 8 | #include <uapi/linux/io_uring.h> | 9 | #include <uapi/linux/io_uring.h> |
| 9 | 10 | ||
| 10 | #include "io_uring.h" | 11 | #include "io_uring.h" |
| 12 | #include "rsrc.h" | ||
| 11 | #include "uring_cmd.h" | 13 | #include "uring_cmd.h" |
| 12 | 14 | ||
| 13 | static void io_uring_cmd_work(struct io_kiocb *req, bool *locked) | 15 | static void io_uring_cmd_work(struct io_kiocb *req, bool *locked) |
| @@ -76,8 +78,24 @@ int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 62 unmodified lines | |||
| 76 | { | 78 | { |
| 77 | struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); | 79 | struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); |
| 78 | 80 | ||
| 79 | if (sqe->rw_flags || sqe->__pad1) | 81 | if (sqe->__pad1) |
| 80 | return -EINVAL; | 82 | return -EINVAL; |
| 83 | |||
| 84 | ioucmd->flags = READ_ONCE(sqe->uring_cmd_flags); | ||
| 85 | if (ioucmd->flags & ~IORING_URING_CMD_FIXED) | ||
| 86 | return -EINVAL; | ||
| 87 | |||
| 88 | if (ioucmd->flags & IORING_URING_CMD_FIXED) { | ||
| 89 | struct io_ring_ctx *ctx = req->ctx; | ||
| 90 | u16 index; | ||
| 91 | |||
| 92 | req->buf_index = READ_ONCE(sqe->buf_index); | ||
| 93 | if (unlikely(req->buf_index >= ctx->nr_user_bufs)) | ||
| 94 | return -EFAULT; | ||
| 95 | index = array_index_nospec(req->buf_index, ctx->nr_user_bufs); | ||
| 96 | req->imu = ctx->user_bufs[index]; | ||
| 97 | io_req_set_rsrc_node(req, ctx, 0); | ||
| 98 | } | ||
| 81 | ioucmd->cmd = sqe->cmd; | 99 | ioucmd->cmd = sqe->cmd; |
| 82 | ioucmd->cmd_op = READ_ONCE(sqe->cmd_op); | 100 | ioucmd->cmd_op = READ_ONCE(sqe->cmd_op); |
| 83 | return 0; | 101 | return 0; |
| @@ -129,3 +147,12 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags) · 45 unmodified lines | |||
| 129 | 147 | ||
| 130 | return IOU_ISSUE_SKIP_COMPLETE; | 148 | return IOU_ISSUE_SKIP_COMPLETE; |
| 131 | } | 149 | } |
| 150 | |||
| 151 | int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, | ||
| 152 | struct iov_iter *iter, void *ioucmd) | ||
| 153 | { | ||
| 154 | struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); | ||
| 155 | |||
| 156 | return io_import_fixed(rw, iter, req->imu, ubuf, len); | ||
| 157 | } | ||
| 158 | EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed); | ||