diff options
| -rw-r--r-- | drivers/vhost/net.c | 35 | ||||
| -rw-r--r-- | drivers/vhost/scsi.c | 26 | ||||
| -rw-r--r-- | drivers/vhost/test.c | 11 | ||||
| -rw-r--r-- | drivers/vhost/vhost.c | 97 | ||||
| -rw-r--r-- | drivers/vhost/vhost.h | 19 |
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 | ||
| 703 | static void vhost_net_free(void *addr) | ||
| 704 | { | ||
| 705 | if (is_vmalloc_addr(addr)) | ||
| 706 | vfree(addr); | ||
| 707 | else | ||
| 708 | kfree(addr); | ||
| 709 | } | ||
| 710 | |||
| 702 | static int vhost_net_open(struct inode *inode, struct file *f) | 711 | static 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 | ||
| 607 | again: | 607 | again: |
| 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 | ||
| 1374 | static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) | 1374 | static 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 | ||
