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() */ |