diff options
| -rw-r--r-- | block/bfq-iosched.c | 15 | ||||
| -rw-r--r-- | block/bfq-iosched.h | 2 | ||||
| -rw-r--r-- | block/bfq-wf2q.c | 17 | ||||
| -rw-r--r-- | block/bio.c | 5 | ||||
| -rw-r--r-- | block/blk-mq.c | 7 | ||||
| -rw-r--r-- | drivers/block/virtio_blk.c | 2 | ||||
| -rw-r--r-- | drivers/lightnvm/pblk-read.c | 50 | ||||
| -rw-r--r-- | drivers/nvme/host/core.c | 2 | ||||
| -rw-r--r-- | drivers/nvme/host/fc.c | 20 | ||||
| -rw-r--r-- | drivers/nvme/target/admin-cmd.c | 5 | ||||
| -rw-r--r-- | drivers/nvme/target/discovery.c | 68 | ||||
| -rw-r--r-- | drivers/nvme/target/nvmet.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/virtio_scsi.c | 1 | ||||
| -rw-r--r-- | fs/block_dev.c | 8 | ||||
| -rw-r--r-- | fs/io_uring.c | 4 | ||||
| -rw-r--r-- | include/linux/bio.h | 20 | ||||
| -rw-r--r-- | include/linux/blk-mq.h | 1 | ||||
| -rw-r--r-- | include/linux/bvec.h | 14 | ||||
| -rw-r--r-- | include/linux/nvme.h | 9 | ||||
| -rw-r--r-- | tools/io_uring/io_uring-bench.c | 32 |
20 files changed, 174 insertions, 109 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index fac188dd78fa..dfb8cb0af13a 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c | |||
| @@ -2822,7 +2822,7 @@ static void bfq_dispatch_remove(struct request_queue *q, struct request *rq) | |||
| 2822 | bfq_remove_request(q, rq); | 2822 | bfq_remove_request(q, rq); |
| 2823 | } | 2823 | } |
| 2824 | 2824 | ||
| 2825 | static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) | 2825 | static bool __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) |
| 2826 | { | 2826 | { |
| 2827 | /* | 2827 | /* |
| 2828 | * If this bfqq is shared between multiple processes, check | 2828 | * If this bfqq is shared between multiple processes, check |
| @@ -2855,9 +2855,11 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) | |||
| 2855 | /* | 2855 | /* |
| 2856 | * All in-service entities must have been properly deactivated | 2856 | * All in-service entities must have been properly deactivated |
| 2857 | * or requeued before executing the next function, which | 2857 | * or requeued before executing the next function, which |
| 2858 | * resets all in-service entites as no more in service. | 2858 | * resets all in-service entities as no more in service. This |
| 2859 | * may cause bfqq to be freed. If this happens, the next | ||
| 2860 | * function returns true. | ||
| 2859 | */ | 2861 | */ |
| 2860 | __bfq_bfqd_reset_in_service(bfqd); | 2862 | return __bfq_bfqd_reset_in_service(bfqd); |
| 2861 | } | 2863 | } |
| 2862 | 2864 | ||
| 2863 | /** | 2865 | /** |
| @@ -3262,7 +3264,6 @@ void bfq_bfqq_expire(struct bfq_data *bfqd, | |||
| 3262 | bool slow; | 3264 | bool slow; |
| 3263 | unsigned long delta = 0; | 3265 | unsigned long delta = 0; |
| 3264 | struct bfq_entity *entity = &bfqq->entity; | 3266 | struct bfq_entity *entity = &bfqq->entity; |
| 3265 | int ref; | ||
| 3266 | 3267 | ||
| 3267 | /* | 3268 | /* |
| 3268 | * Check whether the process is slow (see bfq_bfqq_is_slow). | 3269 | * Check whether the process is slow (see bfq_bfqq_is_slow). |
| @@ -3347,10 +3348,8 @@ void bfq_bfqq_expire(struct bfq_data *bfqd, | |||
| 3347 | * reason. | 3348 | * reason. |
| 3348 | */ | 3349 | */ |
| 3349 | __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); | 3350 | __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); |
| 3350 | ref = bfqq->ref; | 3351 | if (__bfq_bfqq_expire(bfqd, bfqq)) |
| 3351 | __bfq_bfqq_expire(bfqd, bfqq); | 3352 | /* bfqq is gone, no more actions on it */ |
| 3352 | |||
| 3353 | if (ref == 1) /* bfqq is gone, no more actions on it */ | ||
| 3354 | return; | 3353 | return; |
| 3355 | 3354 | ||
| 3356 | bfqq->injected_service = 0; | 3355 | bfqq->injected_service = 0; |
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h index 062e1c4787f4..86394e503ca9 100644 --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h | |||
| @@ -995,7 +995,7 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, | |||
| 995 | bool ins_into_idle_tree); | 995 | bool ins_into_idle_tree); |
| 996 | bool next_queue_may_preempt(struct bfq_data *bfqd); | 996 | bool next_queue_may_preempt(struct bfq_data *bfqd); |
| 997 | struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd); | 997 | struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd); |
| 998 | void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd); | 998 | bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd); |
| 999 | void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, | 999 | void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, |
| 1000 | bool ins_into_idle_tree, bool expiration); | 1000 | bool ins_into_idle_tree, bool expiration); |
| 1001 | void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); | 1001 | void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); |
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c index a11bef75483d..ae4d000ac0af 100644 --- a/block/bfq-wf2q.c +++ b/block/bfq-wf2q.c | |||
| @@ -1605,7 +1605,8 @@ struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) | |||
| 1605 | return bfqq; | 1605 | return bfqq; |
| 1606 | } | 1606 | } |
| 1607 | 1607 | ||
| 1608 | void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) | 1608 | /* returns true if the in-service queue gets freed */ |
| 1609 | bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) | ||
| 1609 | { | 1610 | { |
| 1610 | struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue; | 1611 | struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue; |
| 1611 | struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity; | 1612 | struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity; |
| @@ -1629,8 +1630,20 @@ void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) | |||
| 1629 | * service tree either, then release the service reference to | 1630 | * service tree either, then release the service reference to |
| 1630 | * the queue it represents (taken with bfq_get_entity). | 1631 | * the queue it represents (taken with bfq_get_entity). |
| 1631 | */ | 1632 | */ |
| 1632 | if (!in_serv_entity->on_st) | 1633 | if (!in_serv_entity->on_st) { |
| 1634 | /* | ||
| 1635 | * If no process is referencing in_serv_bfqq any | ||
| 1636 | * longer, then the service reference may be the only | ||
| 1637 | * reference to the queue. If this is the case, then | ||
| 1638 | * bfqq gets freed here. | ||
| 1639 | */ | ||
| 1640 | int ref = in_serv_bfqq->ref; | ||
| 1633 | bfq_put_queue(in_serv_bfqq); | 1641 | bfq_put_queue(in_serv_bfqq); |
| 1642 | if (ref == 1) | ||
| 1643 | return true; | ||
| 1644 | } | ||
| 1645 | |||
| 1646 | return false; | ||
| 1634 | } | 1647 | } |
| 1635 | 1648 | ||
| 1636 | void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, | 1649 | void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, |
diff --git a/block/bio.c b/block/bio.c index b64cedc7f87c..716510ecd7ff 100644 --- a/block/bio.c +++ b/block/bio.c | |||
| @@ -1298,8 +1298,11 @@ struct bio *bio_copy_user_iov(struct request_queue *q, | |||
| 1298 | } | 1298 | } |
| 1299 | } | 1299 | } |
| 1300 | 1300 | ||
| 1301 | if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) | 1301 | if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) { |
| 1302 | if (!map_data) | ||
| 1303 | __free_page(page); | ||
| 1302 | break; | 1304 | break; |
| 1305 | } | ||
| 1303 | 1306 | ||
| 1304 | len -= bytes; | 1307 | len -= bytes; |
| 1305 | offset = 0; | 1308 | offset = 0; |
diff --git a/block/blk-mq.c b/block/blk-mq.c index a9354835cf51..9516304a38ee 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -654,6 +654,13 @@ bool blk_mq_complete_request(struct request *rq) | |||
| 654 | } | 654 | } |
| 655 | EXPORT_SYMBOL(blk_mq_complete_request); | 655 | EXPORT_SYMBOL(blk_mq_complete_request); |
| 656 | 656 | ||
| 657 | void blk_mq_complete_request_sync(struct request *rq) | ||
| 658 | { | ||
| 659 | WRITE_ONCE(rq->state, MQ_RQ_COMPLETE); | ||
| 660 | rq->q->mq_ops->complete(rq); | ||
| 661 | } | ||
| 662 | EXPORT_SYMBOL_GPL(blk_mq_complete_request_sync); | ||
| 663 | |||
| 657 | int blk_mq_request_started(struct request *rq) | 664 | int blk_mq_request_started(struct request *rq) |
| 658 | { | 665 | { |
| 659 | return blk_mq_rq_state(rq) != MQ_RQ_IDLE; | 666 | return blk_mq_rq_state(rq) != MQ_RQ_IDLE; |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 4bc083b7c9b5..2a7ca4a1e6f7 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -513,6 +513,8 @@ static int init_vq(struct virtio_blk *vblk) | |||
| 513 | if (err) | 513 | if (err) |
| 514 | num_vqs = 1; | 514 | num_vqs = 1; |
| 515 | 515 | ||
| 516 | num_vqs = min_t(unsigned int, nr_cpu_ids, num_vqs); | ||
| 517 | |||
| 516 | vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL); | 518 | vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL); |
| 517 | if (!vblk->vqs) | 519 | if (!vblk->vqs) |
| 518 | return -ENOMEM; | 520 | return -ENOMEM; |
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c index 3789185144da..0b7d5fb4548d 100644 --- a/drivers/lightnvm/pblk-read.c +++ b/drivers/lightnvm/pblk-read.c | |||
| @@ -231,14 +231,14 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) | |||
| 231 | struct pblk_sec_meta *meta; | 231 | struct pblk_sec_meta *meta; |
| 232 | struct bio *new_bio = rqd->bio; | 232 | struct bio *new_bio = rqd->bio; |
| 233 | struct bio *bio = pr_ctx->orig_bio; | 233 | struct bio *bio = pr_ctx->orig_bio; |
| 234 | struct bio_vec src_bv, dst_bv; | ||
| 235 | void *meta_list = rqd->meta_list; | 234 | void *meta_list = rqd->meta_list; |
| 236 | int bio_init_idx = pr_ctx->bio_init_idx; | ||
| 237 | unsigned long *read_bitmap = pr_ctx->bitmap; | 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; | 238 | int nr_secs = pr_ctx->orig_nr_secs; |
| 239 | int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); | 239 | int nr_holes = nr_secs - bitmap_weight(read_bitmap, nr_secs); |
| 240 | void *src_p, *dst_p; | 240 | void *src_p, *dst_p; |
| 241 | int hole, i; | 241 | int bit, i; |
| 242 | 242 | ||
| 243 | if (unlikely(nr_holes == 1)) { | 243 | if (unlikely(nr_holes == 1)) { |
| 244 | struct ppa_addr ppa; | 244 | struct ppa_addr ppa; |
| @@ -257,33 +257,39 @@ static void pblk_end_partial_read(struct nvm_rq *rqd) | |||
| 257 | 257 | ||
| 258 | /* Fill the holes in the original bio */ | 258 | /* Fill the holes in the original bio */ |
| 259 | i = 0; | 259 | i = 0; |
| 260 | hole = find_first_zero_bit(read_bitmap, nr_secs); | 260 | for (bit = 0; bit < nr_secs; bit++) { |
| 261 | do { | 261 | if (!test_bit(bit, read_bitmap)) { |
| 262 | struct pblk_line *line; | 262 | struct bio_vec dst_bv, src_bv; |
| 263 | struct pblk_line *line; | ||
| 263 | 264 | ||
| 264 | line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]); | 265 | line = pblk_ppa_to_line(pblk, rqd->ppa_list[i]); |
| 265 | kref_put(&line->ref, pblk_line_put); | 266 | kref_put(&line->ref, pblk_line_put); |
| 266 | 267 | ||
| 267 | meta = pblk_get_meta(pblk, meta_list, hole); | 268 | meta = pblk_get_meta(pblk, meta_list, bit); |
| 268 | meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]); | 269 | meta->lba = cpu_to_le64(pr_ctx->lba_list_media[i]); |
| 269 | 270 | ||
| 270 | src_bv = new_bio->bi_io_vec[i++]; | 271 | dst_bv = bio_iter_iovec(bio, orig_iter); |
| 271 | dst_bv = bio->bi_io_vec[bio_init_idx + hole]; | 272 | src_bv = bio_iter_iovec(new_bio, new_iter); |
| 272 | 273 | ||
| 273 | src_p = kmap_atomic(src_bv.bv_page); | 274 | src_p = kmap_atomic(src_bv.bv_page); |
| 274 | dst_p = kmap_atomic(dst_bv.bv_page); | 275 | dst_p = kmap_atomic(dst_bv.bv_page); |
| 275 | 276 | ||
| 276 | memcpy(dst_p + dst_bv.bv_offset, | 277 | memcpy(dst_p + dst_bv.bv_offset, |
| 277 | src_p + src_bv.bv_offset, | 278 | src_p + src_bv.bv_offset, |
| 278 | PBLK_EXPOSED_PAGE_SIZE); | 279 | PBLK_EXPOSED_PAGE_SIZE); |
| 279 | 280 | ||
| 280 | kunmap_atomic(src_p); | 281 | kunmap_atomic(src_p); |
| 281 | kunmap_atomic(dst_p); | 282 | kunmap_atomic(dst_p); |
| 282 | 283 | ||
| 283 | mempool_free(src_bv.bv_page, &pblk->page_bio_pool); | 284 | flush_dcache_page(dst_bv.bv_page); |
| 285 | mempool_free(src_bv.bv_page, &pblk->page_bio_pool); | ||
| 284 | 286 | ||
| 285 | hole = find_next_zero_bit(read_bitmap, nr_secs, hole + 1); | 287 | bio_advance_iter(new_bio, &new_iter, |
| 286 | } while (hole < nr_secs); | 288 | PBLK_EXPOSED_PAGE_SIZE); |
| 289 | i++; | ||
| 290 | } | ||
| 291 | bio_advance_iter(bio, &orig_iter, PBLK_EXPOSED_PAGE_SIZE); | ||
| 292 | } | ||
| 287 | 293 | ||
| 288 | bio_put(new_bio); | 294 | bio_put(new_bio); |
| 289 | kfree(pr_ctx); | 295 | kfree(pr_ctx); |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 470601980794..2c43e12b70af 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -288,7 +288,7 @@ bool nvme_cancel_request(struct request *req, void *data, bool reserved) | |||
| 288 | "Cancelling I/O %d", req->tag); | 288 | "Cancelling I/O %d", req->tag); |
| 289 | 289 | ||
| 290 | nvme_req(req)->status = NVME_SC_ABORT_REQ; | 290 | nvme_req(req)->status = NVME_SC_ABORT_REQ; |
| 291 | blk_mq_complete_request(req); | 291 | blk_mq_complete_request_sync(req); |
| 292 | return true; | 292 | return true; |
| 293 | } | 293 | } |
| 294 | EXPORT_SYMBOL_GPL(nvme_cancel_request); | 294 | EXPORT_SYMBOL_GPL(nvme_cancel_request); |
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index f3b9d91ba0df..6d8451356eac 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c | |||
| @@ -1845,7 +1845,7 @@ nvme_fc_init_queue(struct nvme_fc_ctrl *ctrl, int idx) | |||
| 1845 | memset(queue, 0, sizeof(*queue)); | 1845 | memset(queue, 0, sizeof(*queue)); |
| 1846 | queue->ctrl = ctrl; | 1846 | queue->ctrl = ctrl; |
| 1847 | queue->qnum = idx; | 1847 | queue->qnum = idx; |
| 1848 | atomic_set(&queue->csn, 1); | 1848 | atomic_set(&queue->csn, 0); |
| 1849 | queue->dev = ctrl->dev; | 1849 | queue->dev = ctrl->dev; |
| 1850 | 1850 | ||
| 1851 | if (idx > 0) | 1851 | if (idx > 0) |
| @@ -1887,7 +1887,7 @@ nvme_fc_free_queue(struct nvme_fc_queue *queue) | |||
| 1887 | */ | 1887 | */ |
| 1888 | 1888 | ||
| 1889 | queue->connection_id = 0; | 1889 | queue->connection_id = 0; |
| 1890 | atomic_set(&queue->csn, 1); | 1890 | atomic_set(&queue->csn, 0); |
| 1891 | } | 1891 | } |
| 1892 | 1892 | ||
| 1893 | static void | 1893 | static void |
| @@ -2183,7 +2183,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, | |||
| 2183 | { | 2183 | { |
| 2184 | struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu; | 2184 | struct nvme_fc_cmd_iu *cmdiu = &op->cmd_iu; |
| 2185 | struct nvme_command *sqe = &cmdiu->sqe; | 2185 | struct nvme_command *sqe = &cmdiu->sqe; |
| 2186 | u32 csn; | ||
| 2187 | int ret, opstate; | 2186 | int ret, opstate; |
| 2188 | 2187 | ||
| 2189 | /* | 2188 | /* |
| @@ -2198,8 +2197,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, | |||
| 2198 | 2197 | ||
| 2199 | /* format the FC-NVME CMD IU and fcp_req */ | 2198 | /* format the FC-NVME CMD IU and fcp_req */ |
| 2200 | cmdiu->connection_id = cpu_to_be64(queue->connection_id); | 2199 | cmdiu->connection_id = cpu_to_be64(queue->connection_id); |
| 2201 | csn = atomic_inc_return(&queue->csn); | ||
| 2202 | cmdiu->csn = cpu_to_be32(csn); | ||
| 2203 | cmdiu->data_len = cpu_to_be32(data_len); | 2200 | cmdiu->data_len = cpu_to_be32(data_len); |
| 2204 | switch (io_dir) { | 2201 | switch (io_dir) { |
| 2205 | case NVMEFC_FCP_WRITE: | 2202 | case NVMEFC_FCP_WRITE: |
| @@ -2257,11 +2254,24 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, | |||
| 2257 | if (!(op->flags & FCOP_FLAGS_AEN)) | 2254 | if (!(op->flags & FCOP_FLAGS_AEN)) |
| 2258 | blk_mq_start_request(op->rq); | 2255 | blk_mq_start_request(op->rq); |
| 2259 | 2256 | ||
| 2257 | cmdiu->csn = cpu_to_be32(atomic_inc_return(&queue->csn)); | ||
| 2260 | ret = ctrl->lport->ops->fcp_io(&ctrl->lport->localport, | 2258 | ret = ctrl->lport->ops->fcp_io(&ctrl->lport->localport, |
| 2261 | &ctrl->rport->remoteport, | 2259 | &ctrl->rport->remoteport, |
| 2262 | queue->lldd_handle, &op->fcp_req); | 2260 | queue->lldd_handle, &op->fcp_req); |
| 2263 | 2261 | ||
| 2264 | if (ret) { | 2262 | if (ret) { |
| 2263 | /* | ||
| 2264 | * If the lld fails to send the command is there an issue with | ||
| 2265 | * the csn value? If the command that fails is the Connect, | ||
| 2266 | * no - as the connection won't be live. If it is a command | ||
| 2267 | * post-connect, it's possible a gap in csn may be created. | ||
| 2268 | * Does this matter? As Linux initiators don't send fused | ||
| 2269 | * commands, no. The gap would exist, but as there's nothing | ||
| 2270 | * that depends on csn order to be delivered on the target | ||
| 2271 | * side, it shouldn't hurt. It would be difficult for a | ||
| 2272 | * target to even detect the csn gap as it has no idea when the | ||
| 2273 | * cmd with the csn was supposed to arrive. | ||
| 2274 | */ | ||
| 2265 | opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE); | 2275 | opstate = atomic_xchg(&op->state, FCPOP_STATE_COMPLETE); |
| 2266 | __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); | 2276 | __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); |
| 2267 | 2277 | ||
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 76250181fee0..9f72d515fc4b 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c | |||
| @@ -24,6 +24,11 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd) | |||
| 24 | return len; | 24 | return len; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | u64 nvmet_get_log_page_offset(struct nvme_command *cmd) | ||
| 28 | { | ||
| 29 | return le64_to_cpu(cmd->get_log_page.lpo); | ||
| 30 | } | ||
| 31 | |||
| 27 | static void nvmet_execute_get_log_page_noop(struct nvmet_req *req) | 32 | static void nvmet_execute_get_log_page_noop(struct nvmet_req *req) |
| 28 | { | 33 | { |
| 29 | nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->data_len)); | 34 | nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->data_len)); |
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c index c872b47a88f3..33ed95e72d6b 100644 --- a/drivers/nvme/target/discovery.c +++ b/drivers/nvme/target/discovery.c | |||
| @@ -131,54 +131,76 @@ static void nvmet_set_disc_traddr(struct nvmet_req *req, struct nvmet_port *port | |||
| 131 | memcpy(traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE); | 131 | memcpy(traddr, port->disc_addr.traddr, NVMF_TRADDR_SIZE); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | static size_t discovery_log_entries(struct nvmet_req *req) | ||
| 135 | { | ||
| 136 | struct nvmet_ctrl *ctrl = req->sq->ctrl; | ||
| 137 | struct nvmet_subsys_link *p; | ||
| 138 | struct nvmet_port *r; | ||
| 139 | size_t entries = 0; | ||
| 140 | |||
| 141 | list_for_each_entry(p, &req->port->subsystems, entry) { | ||
| 142 | if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn)) | ||
| 143 | continue; | ||
| 144 | entries++; | ||
| 145 | } | ||
| 146 | list_for_each_entry(r, &req->port->referrals, entry) | ||
| 147 | entries++; | ||
| 148 | return entries; | ||
| 149 | } | ||
| 150 | |||
| 134 | static void nvmet_execute_get_disc_log_page(struct nvmet_req *req) | 151 | static void nvmet_execute_get_disc_log_page(struct nvmet_req *req) |
| 135 | { | 152 | { |
| 136 | const int entry_size = sizeof(struct nvmf_disc_rsp_page_entry); | 153 | const int entry_size = sizeof(struct nvmf_disc_rsp_page_entry); |
| 137 | struct nvmet_ctrl *ctrl = req->sq->ctrl; | 154 | struct nvmet_ctrl *ctrl = req->sq->ctrl; |
| 138 | struct nvmf_disc_rsp_page_hdr *hdr; | 155 | struct nvmf_disc_rsp_page_hdr *hdr; |
| 156 | u64 offset = nvmet_get_log_page_offset(req->cmd); | ||
| 139 | size_t data_len = nvmet_get_log_page_len(req->cmd); | 157 | size_t data_len = nvmet_get_log_page_len(req->cmd); |
| 140 | size_t alloc_len = max(data_len, sizeof(*hdr)); | 158 | size_t alloc_len; |
| 141 | int residual_len = data_len - sizeof(*hdr); | ||
| 142 | struct nvmet_subsys_link *p; | 159 | struct nvmet_subsys_link *p; |
| 143 | struct nvmet_port *r; | 160 | struct nvmet_port *r; |
| 144 | u32 numrec = 0; | 161 | u32 numrec = 0; |
| 145 | u16 status = 0; | 162 | u16 status = 0; |
| 163 | void *buffer; | ||
| 164 | |||
| 165 | /* Spec requires dword aligned offsets */ | ||
| 166 | if (offset & 0x3) { | ||
| 167 | status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; | ||
| 168 | goto out; | ||
| 169 | } | ||
| 146 | 170 | ||
| 147 | /* | 171 | /* |
| 148 | * Make sure we're passing at least a buffer of response header size. | 172 | * Make sure we're passing at least a buffer of response header size. |
| 149 | * If host provided data len is less than the header size, only the | 173 | * If host provided data len is less than the header size, only the |
| 150 | * number of bytes requested by host will be sent to host. | 174 | * number of bytes requested by host will be sent to host. |
| 151 | */ | 175 | */ |
| 152 | hdr = kzalloc(alloc_len, GFP_KERNEL); | 176 | down_read(&nvmet_config_sem); |
| 153 | if (!hdr) { | 177 | alloc_len = sizeof(*hdr) + entry_size * discovery_log_entries(req); |
| 178 | buffer = kzalloc(alloc_len, GFP_KERNEL); | ||
| 179 | if (!buffer) { | ||
| 180 | up_read(&nvmet_config_sem); | ||
| 154 | status = NVME_SC_INTERNAL; | 181 | status = NVME_SC_INTERNAL; |
| 155 | goto out; | 182 | goto out; |
| 156 | } | 183 | } |
| 157 | 184 | ||
| 158 | down_read(&nvmet_config_sem); | 185 | hdr = buffer; |
| 159 | list_for_each_entry(p, &req->port->subsystems, entry) { | 186 | list_for_each_entry(p, &req->port->subsystems, entry) { |
| 187 | char traddr[NVMF_TRADDR_SIZE]; | ||
| 188 | |||
| 160 | if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn)) | 189 | if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn)) |
| 161 | continue; | 190 | continue; |
| 162 | if (residual_len >= entry_size) { | 191 | |
| 163 | char traddr[NVMF_TRADDR_SIZE]; | 192 | nvmet_set_disc_traddr(req, req->port, traddr); |
| 164 | 193 | nvmet_format_discovery_entry(hdr, req->port, | |
| 165 | nvmet_set_disc_traddr(req, req->port, traddr); | 194 | p->subsys->subsysnqn, traddr, |
| 166 | nvmet_format_discovery_entry(hdr, req->port, | 195 | NVME_NQN_NVME, numrec); |
| 167 | p->subsys->subsysnqn, traddr, | ||
| 168 | NVME_NQN_NVME, numrec); | ||
| 169 | residual_len -= entry_size; | ||
| 170 | } | ||
| 171 | numrec++; | 196 | numrec++; |
| 172 | } | 197 | } |
| 173 | 198 | ||
| 174 | list_for_each_entry(r, &req->port->referrals, entry) { | 199 | list_for_each_entry(r, &req->port->referrals, entry) { |
| 175 | if (residual_len >= entry_size) { | 200 | nvmet_format_discovery_entry(hdr, r, |
| 176 | nvmet_format_discovery_entry(hdr, r, | 201 | NVME_DISC_SUBSYS_NAME, |
| 177 | NVME_DISC_SUBSYS_NAME, | 202 | r->disc_addr.traddr, |
| 178 | r->disc_addr.traddr, | 203 | NVME_NQN_DISC, numrec); |
| 179 | NVME_NQN_DISC, numrec); | ||
| 180 | residual_len -= entry_size; | ||
| 181 | } | ||
| 182 | numrec++; | 204 | numrec++; |
| 183 | } | 205 | } |
| 184 | 206 | ||
| @@ -190,8 +212,8 @@ static void nvmet_execute_get_disc_log_page(struct nvmet_req *req) | |||
| 190 | 212 | ||
| 191 | up_read(&nvmet_config_sem); | 213 | up_read(&nvmet_config_sem); |
| 192 | 214 | ||
| 193 | status = nvmet_copy_to_sgl(req, 0, hdr, data_len); | 215 | status = nvmet_copy_to_sgl(req, 0, buffer + offset, data_len); |
| 194 | kfree(hdr); | 216 | kfree(buffer); |
| 195 | out: | 217 | out: |
| 196 | nvmet_req_complete(req, status); | 218 | nvmet_req_complete(req, status); |
| 197 | } | 219 | } |
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 51e49efd7849..1653d19b187f 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h | |||
| @@ -428,6 +428,7 @@ u16 nvmet_copy_from_sgl(struct nvmet_req *req, off_t off, void *buf, | |||
| 428 | u16 nvmet_zero_sgl(struct nvmet_req *req, off_t off, size_t len); | 428 | u16 nvmet_zero_sgl(struct nvmet_req *req, off_t off, size_t len); |
| 429 | 429 | ||
| 430 | u32 nvmet_get_log_page_len(struct nvme_command *cmd); | 430 | u32 nvmet_get_log_page_len(struct nvme_command *cmd); |
| 431 | u64 nvmet_get_log_page_offset(struct nvme_command *cmd); | ||
| 431 | 432 | ||
| 432 | extern struct list_head *nvmet_ports; | 433 | extern struct list_head *nvmet_ports; |
| 433 | void nvmet_port_disc_changed(struct nvmet_port *port, | 434 | void nvmet_port_disc_changed(struct nvmet_port *port, |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 8af01777d09c..f8cb7c23305b 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
| @@ -793,6 +793,7 @@ static int virtscsi_probe(struct virtio_device *vdev) | |||
| 793 | 793 | ||
| 794 | /* We need to know how many queues before we allocate. */ | 794 | /* We need to know how many queues before we allocate. */ |
| 795 | num_queues = virtscsi_config_get(vdev, num_queues) ? : 1; | 795 | num_queues = virtscsi_config_get(vdev, num_queues) ? : 1; |
| 796 | num_queues = min_t(unsigned int, nr_cpu_ids, num_queues); | ||
| 796 | 797 | ||
| 797 | num_targets = virtscsi_config_get(vdev, max_target) + 1; | 798 | num_targets = virtscsi_config_get(vdev, max_target) + 1; |
| 798 | 799 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index 78d3257435c0..24615c76c1d0 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -307,10 +307,10 @@ static void blkdev_bio_end_io(struct bio *bio) | |||
| 307 | struct blkdev_dio *dio = bio->bi_private; | 307 | struct blkdev_dio *dio = bio->bi_private; |
| 308 | bool should_dirty = dio->should_dirty; | 308 | bool should_dirty = dio->should_dirty; |
| 309 | 309 | ||
| 310 | if (dio->multi_bio && !atomic_dec_and_test(&dio->ref)) { | 310 | if (bio->bi_status && !dio->bio.bi_status) |
| 311 | if (bio->bi_status && !dio->bio.bi_status) | 311 | dio->bio.bi_status = bio->bi_status; |
| 312 | dio->bio.bi_status = bio->bi_status; | 312 | |
| 313 | } else { | 313 | if (!dio->multi_bio || atomic_dec_and_test(&dio->ref)) { |
| 314 | if (!dio->is_sync) { | 314 | if (!dio->is_sync) { |
| 315 | struct kiocb *iocb = dio->iocb; | 315 | struct kiocb *iocb = dio->iocb; |
| 316 | ssize_t ret; | 316 | ssize_t ret; |
diff --git a/fs/io_uring.c b/fs/io_uring.c index 07d6ef195d05..89aa8412b5f5 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c | |||
| @@ -2245,6 +2245,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx, | |||
| 2245 | goto err; | 2245 | goto err; |
| 2246 | 2246 | ||
| 2247 | if (ctx->flags & IORING_SETUP_SQPOLL) { | 2247 | if (ctx->flags & IORING_SETUP_SQPOLL) { |
| 2248 | ret = -EPERM; | ||
| 2249 | if (!capable(CAP_SYS_ADMIN)) | ||
| 2250 | goto err; | ||
| 2251 | |||
| 2248 | if (p->flags & IORING_SETUP_SQ_AFF) { | 2252 | if (p->flags & IORING_SETUP_SQ_AFF) { |
| 2249 | int cpu; | 2253 | int cpu; |
| 2250 | 2254 | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index bb6090aa165d..e584673c1881 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
| @@ -120,19 +120,23 @@ static inline bool bio_full(struct bio *bio) | |||
| 120 | return bio->bi_vcnt >= bio->bi_max_vecs; | 120 | return bio->bi_vcnt >= bio->bi_max_vecs; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | #define mp_bvec_for_each_segment(bv, bvl, i, iter_all) \ | 123 | static inline bool bio_next_segment(const struct bio *bio, |
| 124 | for (bv = bvec_init_iter_all(&iter_all); \ | 124 | struct bvec_iter_all *iter) |
| 125 | (iter_all.done < (bvl)->bv_len) && \ | 125 | { |
| 126 | (mp_bvec_next_segment((bvl), &iter_all), 1); \ | 126 | if (iter->idx >= bio->bi_vcnt) |
| 127 | iter_all.done += bv->bv_len, i += 1) | 127 | return false; |
| 128 | |||
| 129 | bvec_advance(&bio->bi_io_vec[iter->idx], iter); | ||
| 130 | return true; | ||
| 131 | } | ||
| 128 | 132 | ||
| 129 | /* | 133 | /* |
| 130 | * drivers should _never_ use the all version - the bio may have been split | 134 | * drivers should _never_ use the all version - the bio may have been split |
| 131 | * before it got to the driver and the driver won't own all of it | 135 | * before it got to the driver and the driver won't own all of it |
| 132 | */ | 136 | */ |
| 133 | #define bio_for_each_segment_all(bvl, bio, i, iter_all) \ | 137 | #define bio_for_each_segment_all(bvl, bio, i, iter) \ |
| 134 | for (i = 0, iter_all.idx = 0; iter_all.idx < (bio)->bi_vcnt; iter_all.idx++) \ | 138 | for (i = 0, bvl = bvec_init_iter_all(&iter); \ |
| 135 | mp_bvec_for_each_segment(bvl, &((bio)->bi_io_vec[iter_all.idx]), i, iter_all) | 139 | bio_next_segment((bio), &iter); i++) |
| 136 | 140 | ||
| 137 | static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, | 141 | static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter, |
| 138 | unsigned bytes) | 142 | unsigned bytes) |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index cb2aa7ecafff..db29928de467 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
| @@ -302,6 +302,7 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list); | |||
| 302 | void blk_mq_kick_requeue_list(struct request_queue *q); | 302 | void blk_mq_kick_requeue_list(struct request_queue *q); |
| 303 | void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs); | 303 | void blk_mq_delay_kick_requeue_list(struct request_queue *q, unsigned long msecs); |
| 304 | bool blk_mq_complete_request(struct request *rq); | 304 | bool blk_mq_complete_request(struct request *rq); |
| 305 | void blk_mq_complete_request_sync(struct request *rq); | ||
| 305 | bool blk_mq_bio_list_merge(struct request_queue *q, struct list_head *list, | 306 | bool blk_mq_bio_list_merge(struct request_queue *q, struct list_head *list, |
| 306 | struct bio *bio); | 307 | struct bio *bio); |
| 307 | bool blk_mq_queue_stopped(struct request_queue *q); | 308 | bool blk_mq_queue_stopped(struct request_queue *q); |
diff --git a/include/linux/bvec.h b/include/linux/bvec.h index f6275c4da13a..3bc91879e1e2 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h | |||
| @@ -145,18 +145,18 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv, | |||
| 145 | 145 | ||
| 146 | static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all) | 146 | static inline struct bio_vec *bvec_init_iter_all(struct bvec_iter_all *iter_all) |
| 147 | { | 147 | { |
| 148 | iter_all->bv.bv_page = NULL; | ||
| 149 | iter_all->done = 0; | 148 | iter_all->done = 0; |
| 149 | iter_all->idx = 0; | ||
| 150 | 150 | ||
| 151 | return &iter_all->bv; | 151 | return &iter_all->bv; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static inline void mp_bvec_next_segment(const struct bio_vec *bvec, | 154 | static inline void bvec_advance(const struct bio_vec *bvec, |
| 155 | struct bvec_iter_all *iter_all) | 155 | struct bvec_iter_all *iter_all) |
| 156 | { | 156 | { |
| 157 | struct bio_vec *bv = &iter_all->bv; | 157 | struct bio_vec *bv = &iter_all->bv; |
| 158 | 158 | ||
| 159 | if (bv->bv_page) { | 159 | if (iter_all->done) { |
| 160 | bv->bv_page = nth_page(bv->bv_page, 1); | 160 | bv->bv_page = nth_page(bv->bv_page, 1); |
| 161 | bv->bv_offset = 0; | 161 | bv->bv_offset = 0; |
| 162 | } else { | 162 | } else { |
| @@ -165,6 +165,12 @@ static inline void mp_bvec_next_segment(const struct bio_vec *bvec, | |||
| 165 | } | 165 | } |
| 166 | bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset, | 166 | bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset, |
| 167 | bvec->bv_len - iter_all->done); | 167 | bvec->bv_len - iter_all->done); |
| 168 | iter_all->done += bv->bv_len; | ||
| 169 | |||
| 170 | if (iter_all->done == bvec->bv_len) { | ||
| 171 | iter_all->idx++; | ||
| 172 | iter_all->done = 0; | ||
| 173 | } | ||
| 168 | } | 174 | } |
| 169 | 175 | ||
| 170 | /* | 176 | /* |
diff --git a/include/linux/nvme.h b/include/linux/nvme.h index baa49e6a23cc..c40720cb59ac 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h | |||
| @@ -967,8 +967,13 @@ struct nvme_get_log_page_command { | |||
| 967 | __le16 numdl; | 967 | __le16 numdl; |
| 968 | __le16 numdu; | 968 | __le16 numdu; |
| 969 | __u16 rsvd11; | 969 | __u16 rsvd11; |
| 970 | __le32 lpol; | 970 | union { |
| 971 | __le32 lpou; | 971 | struct { |
| 972 | __le32 lpol; | ||
| 973 | __le32 lpou; | ||
| 974 | }; | ||
| 975 | __le64 lpo; | ||
| 976 | }; | ||
| 972 | __u32 rsvd14[2]; | 977 | __u32 rsvd14[2]; |
| 973 | }; | 978 | }; |
| 974 | 979 | ||
diff --git a/tools/io_uring/io_uring-bench.c b/tools/io_uring/io_uring-bench.c index 512306a37531..0f257139b003 100644 --- a/tools/io_uring/io_uring-bench.c +++ b/tools/io_uring/io_uring-bench.c | |||
| @@ -32,10 +32,6 @@ | |||
| 32 | #include "liburing.h" | 32 | #include "liburing.h" |
| 33 | #include "barrier.h" | 33 | #include "barrier.h" |
| 34 | 34 | ||
| 35 | #ifndef IOCQE_FLAG_CACHEHIT | ||
| 36 | #define IOCQE_FLAG_CACHEHIT (1U << 0) | ||
| 37 | #endif | ||
| 38 | |||
| 39 | #define min(a, b) ((a < b) ? (a) : (b)) | 35 | #define min(a, b) ((a < b) ? (a) : (b)) |
| 40 | 36 | ||
| 41 | struct io_sq_ring { | 37 | struct io_sq_ring { |
| @@ -85,7 +81,6 @@ struct submitter { | |||
| 85 | unsigned long reaps; | 81 | unsigned long reaps; |
| 86 | unsigned long done; | 82 | unsigned long done; |
| 87 | unsigned long calls; | 83 | unsigned long calls; |
| 88 | unsigned long cachehit, cachemiss; | ||
| 89 | volatile int finish; | 84 | volatile int finish; |
| 90 | 85 | ||
| 91 | __s32 *fds; | 86 | __s32 *fds; |
| @@ -270,10 +265,6 @@ static int reap_events(struct submitter *s) | |||
| 270 | return -1; | 265 | return -1; |
| 271 | } | 266 | } |
| 272 | } | 267 | } |
| 273 | if (cqe->flags & IOCQE_FLAG_CACHEHIT) | ||
| 274 | s->cachehit++; | ||
| 275 | else | ||
| 276 | s->cachemiss++; | ||
| 277 | reaped++; | 268 | reaped++; |
| 278 | head++; | 269 | head++; |
| 279 | } while (1); | 270 | } while (1); |
| @@ -489,7 +480,7 @@ static void file_depths(char *buf) | |||
| 489 | int main(int argc, char *argv[]) | 480 | int main(int argc, char *argv[]) |
| 490 | { | 481 | { |
| 491 | struct submitter *s = &submitters[0]; | 482 | struct submitter *s = &submitters[0]; |
| 492 | unsigned long done, calls, reap, cache_hit, cache_miss; | 483 | unsigned long done, calls, reap; |
| 493 | int err, i, flags, fd; | 484 | int err, i, flags, fd; |
| 494 | char *fdepths; | 485 | char *fdepths; |
| 495 | void *ret; | 486 | void *ret; |
| @@ -569,44 +560,29 @@ int main(int argc, char *argv[]) | |||
| 569 | pthread_create(&s->thread, NULL, submitter_fn, s); | 560 | pthread_create(&s->thread, NULL, submitter_fn, s); |
| 570 | 561 | ||
| 571 | fdepths = malloc(8 * s->nr_files); | 562 | fdepths = malloc(8 * s->nr_files); |
| 572 | cache_hit = cache_miss = reap = calls = done = 0; | 563 | reap = calls = done = 0; |
| 573 | do { | 564 | do { |
| 574 | unsigned long this_done = 0; | 565 | unsigned long this_done = 0; |
| 575 | unsigned long this_reap = 0; | 566 | unsigned long this_reap = 0; |
| 576 | unsigned long this_call = 0; | 567 | unsigned long this_call = 0; |
| 577 | unsigned long this_cache_hit = 0; | ||
| 578 | unsigned long this_cache_miss = 0; | ||
| 579 | unsigned long rpc = 0, ipc = 0; | 568 | unsigned long rpc = 0, ipc = 0; |
| 580 | double hit = 0.0; | ||
| 581 | 569 | ||
| 582 | sleep(1); | 570 | sleep(1); |
| 583 | this_done += s->done; | 571 | this_done += s->done; |
| 584 | this_call += s->calls; | 572 | this_call += s->calls; |
| 585 | this_reap += s->reaps; | 573 | this_reap += s->reaps; |
| 586 | this_cache_hit += s->cachehit; | ||
| 587 | this_cache_miss += s->cachemiss; | ||
| 588 | if (this_cache_hit && this_cache_miss) { | ||
| 589 | unsigned long hits, total; | ||
| 590 | |||
| 591 | hits = this_cache_hit - cache_hit; | ||
| 592 | total = hits + this_cache_miss - cache_miss; | ||
| 593 | hit = (double) hits / (double) total; | ||
| 594 | hit *= 100.0; | ||
| 595 | } | ||
| 596 | if (this_call - calls) { | 574 | if (this_call - calls) { |
| 597 | rpc = (this_done - done) / (this_call - calls); | 575 | rpc = (this_done - done) / (this_call - calls); |
| 598 | ipc = (this_reap - reap) / (this_call - calls); | 576 | ipc = (this_reap - reap) / (this_call - calls); |
| 599 | } else | 577 | } else |
| 600 | rpc = ipc = -1; | 578 | rpc = ipc = -1; |
| 601 | file_depths(fdepths); | 579 | file_depths(fdepths); |
| 602 | printf("IOPS=%lu, IOS/call=%ld/%ld, inflight=%u (%s), Cachehit=%0.2f%%\n", | 580 | printf("IOPS=%lu, IOS/call=%ld/%ld, inflight=%u (%s)\n", |
| 603 | this_done - done, rpc, ipc, s->inflight, | 581 | this_done - done, rpc, ipc, s->inflight, |
| 604 | fdepths, hit); | 582 | fdepths); |
| 605 | done = this_done; | 583 | done = this_done; |
| 606 | calls = this_call; | 584 | calls = this_call; |
| 607 | reap = this_reap; | 585 | reap = this_reap; |
| 608 | cache_hit = s->cachehit; | ||
| 609 | cache_miss = s->cachemiss; | ||
| 610 | } while (!finish); | 586 | } while (!finish); |
| 611 | 587 | ||
| 612 | pthread_join(s->thread, &ret); | 588 | pthread_join(s->thread, &ret); |
