aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-10-01 21:40:55 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-10-02 17:16:20 -0400
commit9f0abc1554cfedf2f2391f6ee54ae319441cd1b9 (patch)
treedf8e72708ef8dceb983cf4b166193070cac256ad /drivers/vhost
parent944981c7e106af2aa004847e9177497856630980 (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.c68
-rw-r--r--drivers/vhost/tcm_vhost.h8
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
613static void vhost_scsi_handle_vq(struct vhost_scsi *vs) 573static 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 @@
5struct tcm_vhost_cmd { 5struct 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() */