diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-01 21:40:55 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-10-02 17:16:20 -0400 |
| commit | 9f0abc1554cfedf2f2391f6ee54ae319441cd1b9 (patch) | |
| tree | df8e72708ef8dceb983cf4b166193070cac256ad /drivers/vhost | |
| parent | 944981c7e106af2aa004847e9177497856630980 (diff) | |
tcm_vhost: Convert I/O path to use target_submit_cmd_map_sgls
This patch converts tcm_vhost to use target_submit_cmd_map_sgls() for
I/O submission and mapping of pre-allocated SGL memory from incoming
virtio-scsi SGL memory -> se_cmd descriptors.
This includes removing the original open-coded fabric uses of target
core callers to support transport_generic_map_mem_to_cmd() between
target_setup_cmd_from_cdb() and transport_handle_cdb_direct() logic.
It also includes adding a handful of new tcm_vhost_cmnd member +
assignments in vhost_scsi_allocate_cmd() used from cmwq process
context I/O submission within tcm_vhost_submission_work()
(v2: Use renamed target_submit_cmd_map_sgls)
Reported-by: Christoph Hellwig <hch@lst.de>
Cc: Christoph Hellwig <hch@lst.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Stefan Hajnoczi <stefanha@gmail.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/vhost')
| -rw-r--r-- | drivers/vhost/tcm_vhost.c | 68 | ||||
| -rw-r--r-- | drivers/vhost/tcm_vhost.h | 8 |
2 files changed, 22 insertions, 54 deletions
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 89dc99baca80..aa31692064dd 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c | |||
| @@ -415,10 +415,7 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( | |||
| 415 | { | 415 | { |
| 416 | struct tcm_vhost_cmd *tv_cmd; | 416 | struct tcm_vhost_cmd *tv_cmd; |
| 417 | struct tcm_vhost_nexus *tv_nexus; | 417 | struct tcm_vhost_nexus *tv_nexus; |
| 418 | struct se_portal_group *se_tpg = &tv_tpg->se_tpg; | ||
| 419 | struct se_session *se_sess; | 418 | struct se_session *se_sess; |
| 420 | struct se_cmd *se_cmd; | ||
| 421 | int sam_task_attr; | ||
| 422 | 419 | ||
| 423 | tv_nexus = tv_tpg->tpg_nexus; | 420 | tv_nexus = tv_tpg->tpg_nexus; |
| 424 | if (!tv_nexus) { | 421 | if (!tv_nexus) { |
| @@ -434,23 +431,11 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( | |||
| 434 | } | 431 | } |
| 435 | INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); | 432 | INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); |
| 436 | tv_cmd->tvc_tag = v_req->tag; | 433 | tv_cmd->tvc_tag = v_req->tag; |
| 434 | tv_cmd->tvc_task_attr = v_req->task_attr; | ||
| 435 | tv_cmd->tvc_exp_data_len = exp_data_len; | ||
| 436 | tv_cmd->tvc_data_direction = data_direction; | ||
| 437 | tv_cmd->tvc_nexus = tv_nexus; | ||
| 437 | 438 | ||
| 438 | se_cmd = &tv_cmd->tvc_se_cmd; | ||
| 439 | /* | ||
| 440 | * Locate the SAM Task Attr from virtio_scsi_cmd_req | ||
| 441 | */ | ||
| 442 | sam_task_attr = v_req->task_attr; | ||
| 443 | /* | ||
| 444 | * Initialize struct se_cmd descriptor from TCM infrastructure | ||
| 445 | */ | ||
| 446 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len, | ||
| 447 | data_direction, sam_task_attr, | ||
| 448 | &tv_cmd->tvc_sense_buf[0]); | ||
| 449 | |||
| 450 | #if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */ | ||
| 451 | if (bidi) | ||
| 452 | se_cmd->se_cmd_flags |= SCF_BIDI; | ||
| 453 | #endif | ||
| 454 | return tv_cmd; | 439 | return tv_cmd; |
| 455 | } | 440 | } |
| 456 | 441 | ||
| @@ -549,37 +534,10 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
| 549 | { | 534 | { |
| 550 | struct tcm_vhost_cmd *tv_cmd = | 535 | struct tcm_vhost_cmd *tv_cmd = |
| 551 | container_of(work, struct tcm_vhost_cmd, work); | 536 | container_of(work, struct tcm_vhost_cmd, work); |
| 537 | struct tcm_vhost_nexus *tv_nexus; | ||
| 552 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | 538 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; |
| 553 | struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; | 539 | struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; |
| 554 | int rc, sg_no_bidi = 0; | 540 | int rc, sg_no_bidi = 0; |
| 555 | /* | ||
| 556 | * Locate the struct se_lun pointer based on v_req->lun, and | ||
| 557 | * attach it to struct se_cmd | ||
| 558 | */ | ||
| 559 | rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun); | ||
| 560 | if (rc < 0) { | ||
| 561 | pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun); | ||
| 562 | transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd, | ||
| 563 | tv_cmd->tvc_se_cmd.scsi_sense_reason, 0); | ||
| 564 | transport_generic_free_cmd(se_cmd, 0); | ||
| 565 | return; | ||
| 566 | } | ||
| 567 | |||
| 568 | rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb); | ||
| 569 | if (rc == -ENOMEM) { | ||
| 570 | transport_send_check_condition_and_sense(se_cmd, | ||
| 571 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); | ||
| 572 | transport_generic_free_cmd(se_cmd, 0); | ||
| 573 | return; | ||
| 574 | } else if (rc < 0) { | ||
| 575 | if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) | ||
| 576 | tcm_vhost_queue_status(se_cmd); | ||
| 577 | else | ||
| 578 | transport_send_check_condition_and_sense(se_cmd, | ||
| 579 | se_cmd->scsi_sense_reason, 0); | ||
| 580 | transport_generic_free_cmd(se_cmd, 0); | ||
| 581 | return; | ||
| 582 | } | ||
| 583 | 541 | ||
| 584 | if (tv_cmd->tvc_sgl_count) { | 542 | if (tv_cmd->tvc_sgl_count) { |
| 585 | sg_ptr = tv_cmd->tvc_sgl; | 543 | sg_ptr = tv_cmd->tvc_sgl; |
| @@ -597,17 +555,19 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
| 597 | } else { | 555 | } else { |
| 598 | sg_ptr = NULL; | 556 | sg_ptr = NULL; |
| 599 | } | 557 | } |
| 600 | 558 | tv_nexus = tv_cmd->tvc_nexus; | |
| 601 | rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr, | 559 | |
| 602 | tv_cmd->tvc_sgl_count, sg_bidi_ptr, | 560 | rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, |
| 603 | sg_no_bidi); | 561 | tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0], |
| 562 | tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len, | ||
| 563 | tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction, | ||
| 564 | 0, sg_ptr, tv_cmd->tvc_sgl_count, | ||
| 565 | sg_bidi_ptr, sg_no_bidi); | ||
| 604 | if (rc < 0) { | 566 | if (rc < 0) { |
| 605 | transport_send_check_condition_and_sense(se_cmd, | 567 | transport_send_check_condition_and_sense(se_cmd, |
| 606 | se_cmd->scsi_sense_reason, 0); | 568 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); |
| 607 | transport_generic_free_cmd(se_cmd, 0); | 569 | transport_generic_free_cmd(se_cmd, 0); |
| 608 | return; | ||
| 609 | } | 570 | } |
| 610 | transport_handle_cdb_direct(se_cmd); | ||
| 611 | } | 571 | } |
| 612 | 572 | ||
| 613 | static void vhost_scsi_handle_vq(struct vhost_scsi *vs) | 573 | static void vhost_scsi_handle_vq(struct vhost_scsi *vs) |
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h index d9e93557d669..7e87c63ecbcd 100644 --- a/drivers/vhost/tcm_vhost.h +++ b/drivers/vhost/tcm_vhost.h | |||
| @@ -5,6 +5,12 @@ | |||
| 5 | struct tcm_vhost_cmd { | 5 | struct tcm_vhost_cmd { |
| 6 | /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ | 6 | /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ |
| 7 | int tvc_vq_desc; | 7 | int tvc_vq_desc; |
| 8 | /* virtio-scsi initiator task attribute */ | ||
| 9 | int tvc_task_attr; | ||
| 10 | /* virtio-scsi initiator data direction */ | ||
| 11 | enum dma_data_direction tvc_data_direction; | ||
| 12 | /* Expected data transfer length from virtio-scsi header */ | ||
| 13 | u32 tvc_exp_data_len; | ||
| 8 | /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ | 14 | /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ |
| 9 | u64 tvc_tag; | 15 | u64 tvc_tag; |
| 10 | /* The number of scatterlists associated with this cmd */ | 16 | /* The number of scatterlists associated with this cmd */ |
| @@ -17,6 +23,8 @@ struct tcm_vhost_cmd { | |||
| 17 | struct virtio_scsi_cmd_resp __user *tvc_resp; | 23 | struct virtio_scsi_cmd_resp __user *tvc_resp; |
| 18 | /* Pointer to vhost_scsi for our device */ | 24 | /* Pointer to vhost_scsi for our device */ |
| 19 | struct vhost_scsi *tvc_vhost; | 25 | struct vhost_scsi *tvc_vhost; |
| 26 | /* Pointer to vhost nexus memory */ | ||
| 27 | struct tcm_vhost_nexus *tvc_nexus; | ||
| 20 | /* The TCM I/O descriptor that is accessed via container_of() */ | 28 | /* The TCM I/O descriptor that is accessed via container_of() */ |
| 21 | struct se_cmd tvc_se_cmd; | 29 | struct se_cmd tvc_se_cmd; |
| 22 | /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ | 30 | /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ |
