aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/tcm_vhost.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vhost/tcm_vhost.c')
-rw-r--r--drivers/vhost/tcm_vhost.c287
1 files changed, 161 insertions, 126 deletions
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 22321cf84fbe..9951297b2427 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -47,6 +47,8 @@
47#include <linux/vhost.h> 47#include <linux/vhost.h>
48#include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */ 48#include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */
49#include <linux/virtio_scsi.h> 49#include <linux/virtio_scsi.h>
50#include <linux/llist.h>
51#include <linux/bitmap.h>
50 52
51#include "vhost.c" 53#include "vhost.c"
52#include "vhost.h" 54#include "vhost.h"
@@ -58,14 +60,20 @@ enum {
58 VHOST_SCSI_VQ_IO = 2, 60 VHOST_SCSI_VQ_IO = 2,
59}; 61};
60 62
63#define VHOST_SCSI_MAX_TARGET 256
64#define VHOST_SCSI_MAX_VQ 128
65
61struct vhost_scsi { 66struct vhost_scsi {
62 struct tcm_vhost_tpg *vs_tpg; /* Protected by vhost_scsi->dev.mutex */ 67 /* Protected by vhost_scsi->dev.mutex */
68 struct tcm_vhost_tpg *vs_tpg[VHOST_SCSI_MAX_TARGET];
69 char vs_vhost_wwpn[TRANSPORT_IQN_LEN];
70 bool vs_endpoint;
71
63 struct vhost_dev dev; 72 struct vhost_dev dev;
64 struct vhost_virtqueue vqs[3]; 73 struct vhost_virtqueue vqs[VHOST_SCSI_MAX_VQ];
65 74
66 struct vhost_work vs_completion_work; /* cmd completion work item */ 75 struct vhost_work vs_completion_work; /* cmd completion work item */
67 struct list_head vs_completion_list; /* cmd completion queue */ 76 struct llist_head vs_completion_list; /* cmd completion queue */
68 spinlock_t vs_completion_lock; /* protects s_completion_list */
69}; 77};
70 78
71/* Local pointer to allocated TCM configfs fabric module */ 79/* Local pointer to allocated TCM configfs fabric module */
@@ -77,6 +85,12 @@ static struct workqueue_struct *tcm_vhost_workqueue;
77static DEFINE_MUTEX(tcm_vhost_mutex); 85static DEFINE_MUTEX(tcm_vhost_mutex);
78static LIST_HEAD(tcm_vhost_list); 86static LIST_HEAD(tcm_vhost_list);
79 87
88static int iov_num_pages(struct iovec *iov)
89{
90 return (PAGE_ALIGN((unsigned long)iov->iov_base + iov->iov_len) -
91 ((unsigned long)iov->iov_base & PAGE_MASK)) >> PAGE_SHIFT;
92}
93
80static int tcm_vhost_check_true(struct se_portal_group *se_tpg) 94static int tcm_vhost_check_true(struct se_portal_group *se_tpg)
81{ 95{
82 return 1; 96 return 1;
@@ -301,9 +315,7 @@ static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd)
301{ 315{
302 struct vhost_scsi *vs = tv_cmd->tvc_vhost; 316 struct vhost_scsi *vs = tv_cmd->tvc_vhost;
303 317
304 spin_lock_bh(&vs->vs_completion_lock); 318 llist_add(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
305 list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
306 spin_unlock_bh(&vs->vs_completion_lock);
307 319
308 vhost_work_queue(&vs->dev, &vs->vs_completion_work); 320 vhost_work_queue(&vs->dev, &vs->vs_completion_work);
309} 321}
@@ -347,27 +359,6 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
347 kfree(tv_cmd); 359 kfree(tv_cmd);
348} 360}
349 361
350/* Dequeue a command from the completion list */
351static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion(
352 struct vhost_scsi *vs)
353{
354 struct tcm_vhost_cmd *tv_cmd = NULL;
355
356 spin_lock_bh(&vs->vs_completion_lock);
357 if (list_empty(&vs->vs_completion_list)) {
358 spin_unlock_bh(&vs->vs_completion_lock);
359 return NULL;
360 }
361
362 list_for_each_entry(tv_cmd, &vs->vs_completion_list,
363 tvc_completion_list) {
364 list_del(&tv_cmd->tvc_completion_list);
365 break;
366 }
367 spin_unlock_bh(&vs->vs_completion_lock);
368 return tv_cmd;
369}
370
371/* Fill in status and signal that we are done processing this command 362/* Fill in status and signal that we are done processing this command
372 * 363 *
373 * This is scheduled in the vhost work queue so we are called with the owner 364 * This is scheduled in the vhost work queue so we are called with the owner
@@ -377,12 +368,20 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
377{ 368{
378 struct vhost_scsi *vs = container_of(work, struct vhost_scsi, 369 struct vhost_scsi *vs = container_of(work, struct vhost_scsi,
379 vs_completion_work); 370 vs_completion_work);
371 DECLARE_BITMAP(signal, VHOST_SCSI_MAX_VQ);
372 struct virtio_scsi_cmd_resp v_rsp;
380 struct tcm_vhost_cmd *tv_cmd; 373 struct tcm_vhost_cmd *tv_cmd;
381 374 struct llist_node *llnode;
382 while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs))) { 375 struct se_cmd *se_cmd;
383 struct virtio_scsi_cmd_resp v_rsp; 376 int ret, vq;
384 struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; 377
385 int ret; 378 bitmap_zero(signal, VHOST_SCSI_MAX_VQ);
379 llnode = llist_del_all(&vs->vs_completion_list);
380 while (llnode) {
381 tv_cmd = llist_entry(llnode, struct tcm_vhost_cmd,
382 tvc_completion_list);
383 llnode = llist_next(llnode);
384 se_cmd = &tv_cmd->tvc_se_cmd;
386 385
387 pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, 386 pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
388 tv_cmd, se_cmd->residual_count, se_cmd->scsi_status); 387 tv_cmd, se_cmd->residual_count, se_cmd->scsi_status);
@@ -395,15 +394,20 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
395 memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf, 394 memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf,
396 v_rsp.sense_len); 395 v_rsp.sense_len);
397 ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); 396 ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
398 if (likely(ret == 0)) 397 if (likely(ret == 0)) {
399 vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0); 398 vhost_add_used(tv_cmd->tvc_vq, tv_cmd->tvc_vq_desc, 0);
400 else 399 vq = tv_cmd->tvc_vq - vs->vqs;
400 __set_bit(vq, signal);
401 } else
401 pr_err("Faulted on virtio_scsi_cmd_resp\n"); 402 pr_err("Faulted on virtio_scsi_cmd_resp\n");
402 403
403 vhost_scsi_free_cmd(tv_cmd); 404 vhost_scsi_free_cmd(tv_cmd);
404 } 405 }
405 406
406 vhost_signal(&vs->dev, &vs->vqs[2]); 407 vq = -1;
408 while ((vq = find_next_bit(signal, VHOST_SCSI_MAX_VQ, vq + 1))
409 < VHOST_SCSI_MAX_VQ)
410 vhost_signal(&vs->dev, &vs->vqs[vq]);
407} 411}
408 412
409static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( 413static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
@@ -426,7 +430,6 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
426 pr_err("Unable to allocate struct tcm_vhost_cmd\n"); 430 pr_err("Unable to allocate struct tcm_vhost_cmd\n");
427 return ERR_PTR(-ENOMEM); 431 return ERR_PTR(-ENOMEM);
428 } 432 }
429 INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
430 tv_cmd->tvc_tag = v_req->tag; 433 tv_cmd->tvc_tag = v_req->tag;
431 tv_cmd->tvc_task_attr = v_req->task_attr; 434 tv_cmd->tvc_task_attr = v_req->task_attr;
432 tv_cmd->tvc_exp_data_len = exp_data_len; 435 tv_cmd->tvc_exp_data_len = exp_data_len;
@@ -442,40 +445,47 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
442 * Returns the number of scatterlist entries used or -errno on error. 445 * Returns the number of scatterlist entries used or -errno on error.
443 */ 446 */
444static int vhost_scsi_map_to_sgl(struct scatterlist *sgl, 447static int vhost_scsi_map_to_sgl(struct scatterlist *sgl,
445 unsigned int sgl_count, void __user *ptr, size_t len, int write) 448 unsigned int sgl_count, struct iovec *iov, int write)
446{ 449{
450 unsigned int npages = 0, pages_nr, offset, nbytes;
447 struct scatterlist *sg = sgl; 451 struct scatterlist *sg = sgl;
448 unsigned int npages = 0; 452 void __user *ptr = iov->iov_base;
449 int ret; 453 size_t len = iov->iov_len;
454 struct page **pages;
455 int ret, i;
450 456
451 while (len > 0) { 457 pages_nr = iov_num_pages(iov);
452 struct page *page; 458 if (pages_nr > sgl_count)
453 unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK; 459 return -ENOBUFS;
454 unsigned int nbytes = min_t(unsigned int,
455 PAGE_SIZE - offset, len);
456 460
457 if (npages == sgl_count) { 461 pages = kmalloc(pages_nr * sizeof(struct page *), GFP_KERNEL);
458 ret = -ENOBUFS; 462 if (!pages)
459 goto err; 463 return -ENOMEM;
460 }
461 464
462 ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page); 465 ret = get_user_pages_fast((unsigned long)ptr, pages_nr, write, pages);
463 BUG_ON(ret == 0); /* we should either get our page or fail */ 466 /* No pages were pinned */
464 if (ret < 0) 467 if (ret < 0)
465 goto err; 468 goto out;
469 /* Less pages pinned than wanted */
470 if (ret != pages_nr) {
471 for (i = 0; i < ret; i++)
472 put_page(pages[i]);
473 ret = -EFAULT;
474 goto out;
475 }
466 476
467 sg_set_page(sg, page, nbytes, offset); 477 while (len > 0) {
478 offset = (uintptr_t)ptr & ~PAGE_MASK;
479 nbytes = min_t(unsigned int, PAGE_SIZE - offset, len);
480 sg_set_page(sg, pages[npages], nbytes, offset);
468 ptr += nbytes; 481 ptr += nbytes;
469 len -= nbytes; 482 len -= nbytes;
470 sg++; 483 sg++;
471 npages++; 484 npages++;
472 } 485 }
473 return npages;
474 486
475err: 487out:
476 /* Put pages that we hold */ 488 kfree(pages);
477 for (sg = sgl; sg != &sgl[npages]; sg++)
478 put_page(sg_page(sg));
479 return ret; 489 return ret;
480} 490}
481 491
@@ -491,11 +501,9 @@ static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd,
491 * Find out how long sglist needs to be 501 * Find out how long sglist needs to be
492 */ 502 */
493 sgl_count = 0; 503 sgl_count = 0;
494 for (i = 0; i < niov; i++) { 504 for (i = 0; i < niov; i++)
495 sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len + 505 sgl_count += iov_num_pages(&iov[i]);
496 PAGE_SIZE - 1) >> PAGE_SHIFT) - 506
497 ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT);
498 }
499 /* TODO overflow checking */ 507 /* TODO overflow checking */
500 508
501 sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); 509 sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC);
@@ -510,8 +518,7 @@ static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd,
510 518
511 pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count); 519 pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count);
512 for (i = 0; i < niov; i++) { 520 for (i = 0; i < niov; i++) {
513 ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base, 521 ret = vhost_scsi_map_to_sgl(sg, sgl_count, &iov[i], write);
514 iov[i].iov_len, write);
515 if (ret < 0) { 522 if (ret < 0) {
516 for (i = 0; i < tv_cmd->tvc_sgl_count; i++) 523 for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
517 put_page(sg_page(&tv_cmd->tvc_sgl[i])); 524 put_page(sg_page(&tv_cmd->tvc_sgl[i]));
@@ -563,19 +570,19 @@ static void tcm_vhost_submission_work(struct work_struct *work)
563 } 570 }
564} 571}
565 572
566static void vhost_scsi_handle_vq(struct vhost_scsi *vs) 573static void vhost_scsi_handle_vq(struct vhost_scsi *vs,
574 struct vhost_virtqueue *vq)
567{ 575{
568 struct vhost_virtqueue *vq = &vs->vqs[2];
569 struct virtio_scsi_cmd_req v_req; 576 struct virtio_scsi_cmd_req v_req;
570 struct tcm_vhost_tpg *tv_tpg; 577 struct tcm_vhost_tpg *tv_tpg;
571 struct tcm_vhost_cmd *tv_cmd; 578 struct tcm_vhost_cmd *tv_cmd;
572 u32 exp_data_len, data_first, data_num, data_direction; 579 u32 exp_data_len, data_first, data_num, data_direction;
573 unsigned out, in, i; 580 unsigned out, in, i;
574 int head, ret; 581 int head, ret;
582 u8 target;
575 583
576 /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ 584 /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
577 tv_tpg = vs->vs_tpg; 585 if (unlikely(!vs->vs_endpoint))
578 if (unlikely(!tv_tpg))
579 return; 586 return;
580 587
581 mutex_lock(&vq->mutex); 588 mutex_lock(&vq->mutex);
@@ -643,6 +650,28 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
643 break; 650 break;
644 } 651 }
645 652
653 /* Extract the tpgt */
654 target = v_req.lun[1];
655 tv_tpg = vs->vs_tpg[target];
656
657 /* Target does not exist, fail the request */
658 if (unlikely(!tv_tpg)) {
659 struct virtio_scsi_cmd_resp __user *resp;
660 struct virtio_scsi_cmd_resp rsp;
661
662 memset(&rsp, 0, sizeof(rsp));
663 rsp.response = VIRTIO_SCSI_S_BAD_TARGET;
664 resp = vq->iov[out].iov_base;
665 ret = __copy_to_user(resp, &rsp, sizeof(rsp));
666 if (!ret)
667 vhost_add_used_and_signal(&vs->dev,
668 vq, head, 0);
669 else
670 pr_err("Faulted on virtio_scsi_cmd_resp\n");
671
672 continue;
673 }
674
646 exp_data_len = 0; 675 exp_data_len = 0;
647 for (i = 0; i < data_num; i++) 676 for (i = 0; i < data_num; i++)
648 exp_data_len += vq->iov[data_first + i].iov_len; 677 exp_data_len += vq->iov[data_first + i].iov_len;
@@ -658,6 +687,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
658 ": %d\n", tv_cmd, exp_data_len, data_direction); 687 ": %d\n", tv_cmd, exp_data_len, data_direction);
659 688
660 tv_cmd->tvc_vhost = vs; 689 tv_cmd->tvc_vhost = vs;
690 tv_cmd->tvc_vq = vq;
661 691
662 if (unlikely(vq->iov[out].iov_len != 692 if (unlikely(vq->iov[out].iov_len !=
663 sizeof(struct virtio_scsi_cmd_resp))) { 693 sizeof(struct virtio_scsi_cmd_resp))) {
@@ -738,7 +768,7 @@ static void vhost_scsi_handle_kick(struct vhost_work *work)
738 poll.work); 768 poll.work);
739 struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev); 769 struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
740 770
741 vhost_scsi_handle_vq(vs); 771 vhost_scsi_handle_vq(vs, vq);
742} 772}
743 773
744/* 774/*
@@ -751,7 +781,8 @@ static int vhost_scsi_set_endpoint(
751{ 781{
752 struct tcm_vhost_tport *tv_tport; 782 struct tcm_vhost_tport *tv_tport;
753 struct tcm_vhost_tpg *tv_tpg; 783 struct tcm_vhost_tpg *tv_tpg;
754 int index; 784 bool match = false;
785 int index, ret;
755 786
756 mutex_lock(&vs->dev.mutex); 787 mutex_lock(&vs->dev.mutex);
757 /* Verify that ring has been setup correctly. */ 788 /* Verify that ring has been setup correctly. */
@@ -762,7 +793,6 @@ static int vhost_scsi_set_endpoint(
762 return -EFAULT; 793 return -EFAULT;
763 } 794 }
764 } 795 }
765 mutex_unlock(&vs->dev.mutex);
766 796
767 mutex_lock(&tcm_vhost_mutex); 797 mutex_lock(&tcm_vhost_mutex);
768 list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { 798 list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
@@ -777,30 +807,33 @@ static int vhost_scsi_set_endpoint(
777 } 807 }
778 tv_tport = tv_tpg->tport; 808 tv_tport = tv_tpg->tport;
779 809
780 if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) && 810 if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
781 (tv_tpg->tport_tpgt == t->vhost_tpgt)) { 811 if (vs->vs_tpg[tv_tpg->tport_tpgt]) {
782 tv_tpg->tv_tpg_vhost_count++;
783 mutex_unlock(&tv_tpg->tv_tpg_mutex);
784 mutex_unlock(&tcm_vhost_mutex);
785
786 mutex_lock(&vs->dev.mutex);
787 if (vs->vs_tpg) {
788 mutex_unlock(&vs->dev.mutex);
789 mutex_lock(&tv_tpg->tv_tpg_mutex);
790 tv_tpg->tv_tpg_vhost_count--;
791 mutex_unlock(&tv_tpg->tv_tpg_mutex); 812 mutex_unlock(&tv_tpg->tv_tpg_mutex);
813 mutex_unlock(&tcm_vhost_mutex);
814 mutex_unlock(&vs->dev.mutex);
792 return -EEXIST; 815 return -EEXIST;
793 } 816 }
794 817 tv_tpg->tv_tpg_vhost_count++;
795 vs->vs_tpg = tv_tpg; 818 vs->vs_tpg[tv_tpg->tport_tpgt] = tv_tpg;
796 smp_mb__after_atomic_inc(); 819 smp_mb__after_atomic_inc();
797 mutex_unlock(&vs->dev.mutex); 820 match = true;
798 return 0;
799 } 821 }
800 mutex_unlock(&tv_tpg->tv_tpg_mutex); 822 mutex_unlock(&tv_tpg->tv_tpg_mutex);
801 } 823 }
802 mutex_unlock(&tcm_vhost_mutex); 824 mutex_unlock(&tcm_vhost_mutex);
803 return -EINVAL; 825
826 if (match) {
827 memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn,
828 sizeof(vs->vs_vhost_wwpn));
829 vs->vs_endpoint = true;
830 ret = 0;
831 } else {
832 ret = -EEXIST;
833 }
834
835 mutex_unlock(&vs->dev.mutex);
836 return ret;
804} 837}
805 838
806static int vhost_scsi_clear_endpoint( 839static int vhost_scsi_clear_endpoint(
@@ -809,7 +842,8 @@ static int vhost_scsi_clear_endpoint(
809{ 842{
810 struct tcm_vhost_tport *tv_tport; 843 struct tcm_vhost_tport *tv_tport;
811 struct tcm_vhost_tpg *tv_tpg; 844 struct tcm_vhost_tpg *tv_tpg;
812 int index, ret; 845 int index, ret, i;
846 u8 target;
813 847
814 mutex_lock(&vs->dev.mutex); 848 mutex_lock(&vs->dev.mutex);
815 /* Verify that ring has been setup correctly. */ 849 /* Verify that ring has been setup correctly. */
@@ -819,27 +853,32 @@ static int vhost_scsi_clear_endpoint(
819 goto err; 853 goto err;
820 } 854 }
821 } 855 }
856 for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) {
857 target = i;
822 858
823 if (!vs->vs_tpg) { 859 tv_tpg = vs->vs_tpg[target];
824 ret = -ENODEV; 860 if (!tv_tpg)
825 goto err; 861 continue;
826 } 862
827 tv_tpg = vs->vs_tpg; 863 tv_tport = tv_tpg->tport;
828 tv_tport = tv_tpg->tport; 864 if (!tv_tport) {
829 865 ret = -ENODEV;
830 if (strcmp(tv_tport->tport_name, t->vhost_wwpn) || 866 goto err;
831 (tv_tpg->tport_tpgt != t->vhost_tpgt)) { 867 }
832 pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu" 868
833 " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", 869 if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) {
834 tv_tport->tport_name, tv_tpg->tport_tpgt, 870 pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu"
835 t->vhost_wwpn, t->vhost_tpgt); 871 " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n",
836 ret = -EINVAL; 872 tv_tport->tport_name, tv_tpg->tport_tpgt,
837 goto err; 873 t->vhost_wwpn, t->vhost_tpgt);
874 ret = -EINVAL;
875 goto err;
876 }
877 tv_tpg->tv_tpg_vhost_count--;
878 vs->vs_tpg[target] = NULL;
879 vs->vs_endpoint = false;
838 } 880 }
839 tv_tpg->tv_tpg_vhost_count--;
840 vs->vs_tpg = NULL;
841 mutex_unlock(&vs->dev.mutex); 881 mutex_unlock(&vs->dev.mutex);
842
843 return 0; 882 return 0;
844 883
845err: 884err:
@@ -850,20 +889,19 @@ err:
850static int vhost_scsi_open(struct inode *inode, struct file *f) 889static int vhost_scsi_open(struct inode *inode, struct file *f)
851{ 890{
852 struct vhost_scsi *s; 891 struct vhost_scsi *s;
853 int r; 892 int r, i;
854 893
855 s = kzalloc(sizeof(*s), GFP_KERNEL); 894 s = kzalloc(sizeof(*s), GFP_KERNEL);
856 if (!s) 895 if (!s)
857 return -ENOMEM; 896 return -ENOMEM;
858 897
859 vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work); 898 vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work);
860 INIT_LIST_HEAD(&s->vs_completion_list);
861 spin_lock_init(&s->vs_completion_lock);
862 899
863 s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick; 900 s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick;
864 s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick; 901 s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick;
865 s->vqs[VHOST_SCSI_VQ_IO].handle_kick = vhost_scsi_handle_kick; 902 for (i = VHOST_SCSI_VQ_IO; i < VHOST_SCSI_MAX_VQ; i++)
866 r = vhost_dev_init(&s->dev, s->vqs, 3); 903 s->vqs[i].handle_kick = vhost_scsi_handle_kick;
904 r = vhost_dev_init(&s->dev, s->vqs, VHOST_SCSI_MAX_VQ);
867 if (r < 0) { 905 if (r < 0) {
868 kfree(s); 906 kfree(s);
869 return r; 907 return r;
@@ -876,16 +914,12 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
876static int vhost_scsi_release(struct inode *inode, struct file *f) 914static int vhost_scsi_release(struct inode *inode, struct file *f)
877{ 915{
878 struct vhost_scsi *s = f->private_data; 916 struct vhost_scsi *s = f->private_data;
917 struct vhost_scsi_target t;
879 918
880 if (s->vs_tpg && s->vs_tpg->tport) { 919 mutex_lock(&s->dev.mutex);
881 struct vhost_scsi_target backend; 920 memcpy(t.vhost_wwpn, s->vs_vhost_wwpn, sizeof(t.vhost_wwpn));
882 921 mutex_unlock(&s->dev.mutex);
883 memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name, 922 vhost_scsi_clear_endpoint(s, &t);
884 sizeof(backend.vhost_wwpn));
885 backend.vhost_tpgt = s->vs_tpg->tport_tpgt;
886 vhost_scsi_clear_endpoint(s, &backend);
887 }
888
889 vhost_dev_stop(&s->dev); 923 vhost_dev_stop(&s->dev);
890 vhost_dev_cleanup(&s->dev, false); 924 vhost_dev_cleanup(&s->dev, false);
891 kfree(s); 925 kfree(s);
@@ -899,9 +933,10 @@ static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
899 933
900static void vhost_scsi_flush(struct vhost_scsi *vs) 934static void vhost_scsi_flush(struct vhost_scsi *vs)
901{ 935{
902 vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_CTL); 936 int i;
903 vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_EVT); 937
904 vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_IO); 938 for (i = 0; i < VHOST_SCSI_MAX_VQ; i++)
939 vhost_scsi_flush_vq(vs, i);
905} 940}
906 941
907static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) 942static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)