aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vhost/net.c35
-rw-r--r--drivers/vhost/scsi.c26
-rw-r--r--drivers/vhost/test.c11
-rw-r--r--drivers/vhost/vhost.c97
-rw-r--r--drivers/vhost/vhost.h19
5 files changed, 101 insertions, 87 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index be414d2b2b22..971a760af4a1 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -17,6 +17,7 @@
17#include <linux/workqueue.h> 17#include <linux/workqueue.h>
18#include <linux/file.h> 18#include <linux/file.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/vmalloc.h>
20 21
21#include <linux/net.h> 22#include <linux/net.h>
22#include <linux/if_packet.h> 23#include <linux/if_packet.h>
@@ -373,7 +374,7 @@ static void handle_tx(struct vhost_net *net)
373 % UIO_MAXIOV == nvq->done_idx)) 374 % UIO_MAXIOV == nvq->done_idx))
374 break; 375 break;
375 376
376 head = vhost_get_vq_desc(&net->dev, vq, vq->iov, 377 head = vhost_get_vq_desc(vq, vq->iov,
377 ARRAY_SIZE(vq->iov), 378 ARRAY_SIZE(vq->iov),
378 &out, &in, 379 &out, &in,
379 NULL, NULL); 380 NULL, NULL);
@@ -505,7 +506,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
505 r = -ENOBUFS; 506 r = -ENOBUFS;
506 goto err; 507 goto err;
507 } 508 }
508 r = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg, 509 r = vhost_get_vq_desc(vq, vq->iov + seg,
509 ARRAY_SIZE(vq->iov) - seg, &out, 510 ARRAY_SIZE(vq->iov) - seg, &out,
510 &in, log, log_num); 511 &in, log, log_num);
511 if (unlikely(r < 0)) 512 if (unlikely(r < 0))
@@ -584,9 +585,9 @@ static void handle_rx(struct vhost_net *net)
584 vhost_hlen = nvq->vhost_hlen; 585 vhost_hlen = nvq->vhost_hlen;
585 sock_hlen = nvq->sock_hlen; 586 sock_hlen = nvq->sock_hlen;
586 587
587 vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ? 588 vq_log = unlikely(vhost_has_feature(vq, VHOST_F_LOG_ALL)) ?
588 vq->log : NULL; 589 vq->log : NULL;
589 mergeable = vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF); 590 mergeable = vhost_has_feature(vq, VIRTIO_NET_F_MRG_RXBUF);
590 591
591 while ((sock_len = peek_head_len(sock->sk))) { 592 while ((sock_len = peek_head_len(sock->sk))) {
592 sock_len += sock_hlen; 593 sock_len += sock_hlen;
@@ -699,18 +700,30 @@ static void handle_rx_net(struct vhost_work *work)
699 handle_rx(net); 700 handle_rx(net);
700} 701}
701 702
703static void vhost_net_free(void *addr)
704{
705 if (is_vmalloc_addr(addr))
706 vfree(addr);
707 else
708 kfree(addr);
709}
710
702static int vhost_net_open(struct inode *inode, struct file *f) 711static int vhost_net_open(struct inode *inode, struct file *f)
703{ 712{
704 struct vhost_net *n = kmalloc(sizeof *n, GFP_KERNEL); 713 struct vhost_net *n;
705 struct vhost_dev *dev; 714 struct vhost_dev *dev;
706 struct vhost_virtqueue **vqs; 715 struct vhost_virtqueue **vqs;
707 int i; 716 int i;
708 717
709 if (!n) 718 n = kmalloc(sizeof *n, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
710 return -ENOMEM; 719 if (!n) {
720 n = vmalloc(sizeof *n);
721 if (!n)
722 return -ENOMEM;
723 }
711 vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL); 724 vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL);
712 if (!vqs) { 725 if (!vqs) {
713 kfree(n); 726 vhost_net_free(n);
714 return -ENOMEM; 727 return -ENOMEM;
715 } 728 }
716 729
@@ -827,7 +840,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
827 * since jobs can re-queue themselves. */ 840 * since jobs can re-queue themselves. */
828 vhost_net_flush(n); 841 vhost_net_flush(n);
829 kfree(n->dev.vqs); 842 kfree(n->dev.vqs);
830 kfree(n); 843 vhost_net_free(n);
831 return 0; 844 return 0;
832} 845}
833 846
@@ -1038,15 +1051,13 @@ static int vhost_net_set_features(struct vhost_net *n, u64 features)
1038 mutex_unlock(&n->dev.mutex); 1051 mutex_unlock(&n->dev.mutex);
1039 return -EFAULT; 1052 return -EFAULT;
1040 } 1053 }
1041 n->dev.acked_features = features;
1042 smp_wmb();
1043 for (i = 0; i < VHOST_NET_VQ_MAX; ++i) { 1054 for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
1044 mutex_lock(&n->vqs[i].vq.mutex); 1055 mutex_lock(&n->vqs[i].vq.mutex);
1056 n->vqs[i].vq.acked_features = features;
1045 n->vqs[i].vhost_hlen = vhost_hlen; 1057 n->vqs[i].vhost_hlen = vhost_hlen;
1046 n->vqs[i].sock_hlen = sock_hlen; 1058 n->vqs[i].sock_hlen = sock_hlen;
1047 mutex_unlock(&n->vqs[i].vq.mutex); 1059 mutex_unlock(&n->vqs[i].vq.mutex);
1048 } 1060 }
1049 vhost_net_flush(n);
1050 mutex_unlock(&n->dev.mutex); 1061 mutex_unlock(&n->dev.mutex);
1051 return 0; 1062 return 0;
1052} 1063}
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index aeb513108448..e9c280f55819 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -606,7 +606,7 @@ tcm_vhost_do_evt_work(struct vhost_scsi *vs, struct tcm_vhost_evt *evt)
606 606
607again: 607again:
608 vhost_disable_notify(&vs->dev, vq); 608 vhost_disable_notify(&vs->dev, vq);
609 head = vhost_get_vq_desc(&vs->dev, vq, vq->iov, 609 head = vhost_get_vq_desc(vq, vq->iov,
610 ARRAY_SIZE(vq->iov), &out, &in, 610 ARRAY_SIZE(vq->iov), &out, &in,
611 NULL, NULL); 611 NULL, NULL);
612 if (head < 0) { 612 if (head < 0) {
@@ -945,7 +945,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
945 vhost_disable_notify(&vs->dev, vq); 945 vhost_disable_notify(&vs->dev, vq);
946 946
947 for (;;) { 947 for (;;) {
948 head = vhost_get_vq_desc(&vs->dev, vq, vq->iov, 948 head = vhost_get_vq_desc(vq, vq->iov,
949 ARRAY_SIZE(vq->iov), &out, &in, 949 ARRAY_SIZE(vq->iov), &out, &in,
950 NULL, NULL); 950 NULL, NULL);
951 pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n", 951 pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n",
@@ -1373,6 +1373,9 @@ err_dev:
1373 1373
1374static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) 1374static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
1375{ 1375{
1376 struct vhost_virtqueue *vq;
1377 int i;
1378
1376 if (features & ~VHOST_SCSI_FEATURES) 1379 if (features & ~VHOST_SCSI_FEATURES)
1377 return -EOPNOTSUPP; 1380 return -EOPNOTSUPP;
1378 1381
@@ -1382,9 +1385,13 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
1382 mutex_unlock(&vs->dev.mutex); 1385 mutex_unlock(&vs->dev.mutex);
1383 return -EFAULT; 1386 return -EFAULT;
1384 } 1387 }
1385 vs->dev.acked_features = features; 1388
1386 smp_wmb(); 1389 for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
1387 vhost_scsi_flush(vs); 1390 vq = &vs->vqs[i].vq;
1391 mutex_lock(&vq->mutex);
1392 vq->acked_features = features;
1393 mutex_unlock(&vq->mutex);
1394 }
1388 mutex_unlock(&vs->dev.mutex); 1395 mutex_unlock(&vs->dev.mutex);
1389 return 0; 1396 return 0;
1390} 1397}
@@ -1591,10 +1598,6 @@ tcm_vhost_do_plug(struct tcm_vhost_tpg *tpg,
1591 return; 1598 return;
1592 1599
1593 mutex_lock(&vs->dev.mutex); 1600 mutex_lock(&vs->dev.mutex);
1594 if (!vhost_has_feature(&vs->dev, VIRTIO_SCSI_F_HOTPLUG)) {
1595 mutex_unlock(&vs->dev.mutex);
1596 return;
1597 }
1598 1601
1599 if (plug) 1602 if (plug)
1600 reason = VIRTIO_SCSI_EVT_RESET_RESCAN; 1603 reason = VIRTIO_SCSI_EVT_RESET_RESCAN;
@@ -1603,8 +1606,9 @@ tcm_vhost_do_plug(struct tcm_vhost_tpg *tpg,
1603 1606
1604 vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq; 1607 vq = &vs->vqs[VHOST_SCSI_VQ_EVT].vq;
1605 mutex_lock(&vq->mutex); 1608 mutex_lock(&vq->mutex);
1606 tcm_vhost_send_ev