diff options
-rw-r--r-- | drivers/vhost/net.c | 22 | ||||
-rw-r--r-- | drivers/vhost/scsi.c | 9 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 20 | ||||
-rw-r--r-- | drivers/vhost/vhost.h | 5 | ||||
-rw-r--r-- | drivers/vhost/vsock.c | 12 |
5 files changed, 48 insertions, 20 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index df51a35cf537..061a06dc12a3 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -604,12 +604,6 @@ static size_t init_iov_iter(struct vhost_virtqueue *vq, struct iov_iter *iter, | |||
604 | return iov_iter_count(iter); | 604 | return iov_iter_count(iter); |
605 | } | 605 | } |
606 | 606 | ||
607 | static bool vhost_exceeds_weight(int pkts, int total_len) | ||
608 | { | ||
609 | return total_len >= VHOST_NET_WEIGHT || | ||
610 | pkts >= VHOST_NET_PKT_WEIGHT; | ||
611 | } | ||
612 | |||
613 | static int get_tx_bufs(struct vhost_net *net, | 607 | static int get_tx_bufs(struct vhost_net *net, |
614 | struct vhost_net_virtqueue *nvq, | 608 | struct vhost_net_virtqueue *nvq, |
615 | struct msghdr *msg, | 609 | struct msghdr *msg, |
@@ -845,10 +839,8 @@ done: | |||
845 | vq->heads[nvq->done_idx].id = cpu_to_vhost32(vq, head); | 839 | vq->heads[nvq->done_idx].id = cpu_to_vhost32(vq, head); |
846 | vq->heads[nvq->done_idx].len = 0; | 840 | vq->heads[nvq->done_idx].len = 0; |
847 | ++nvq->done_idx; | 841 | ++nvq->done_idx; |
848 | if (vhost_exceeds_weight(++sent_pkts, total_len)) { | 842 | if (vhost_exceeds_weight(vq, ++sent_pkts, total_len)) |
849 | vhost_poll_queue(&vq->poll); | ||
850 | break; | 843 | break; |
851 | } | ||
852 | } | 844 | } |
853 | 845 | ||
854 | vhost_tx_batch(net, nvq, sock, &msg); | 846 | vhost_tx_batch(net, nvq, sock, &msg); |
@@ -951,10 +943,9 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock) | |||
951 | else | 943 | else |
952 | vhost_zerocopy_signal_used(net, vq); | 944 | vhost_zerocopy_signal_used(net, vq); |
953 | vhost_net_tx_packet(net); | 945 | vhost_net_tx_packet(net); |
954 | if (unlikely(vhost_exceeds_weight(++sent_pkts, total_len))) { | 946 | if (unlikely(vhost_exceeds_weight(vq, ++sent_pkts, |
955 | vhost_poll_queue(&vq->poll); | 947 | total_len))) |
956 | break; | 948 | break; |
957 | } | ||
958 | } | 949 | } |
959 | } | 950 | } |
960 | 951 | ||
@@ -1239,10 +1230,8 @@ static void handle_rx(struct vhost_net *net) | |||
1239 | vhost_log_write(vq, vq_log, log, vhost_len, | 1230 | vhost_log_write(vq, vq_log, log, vhost_len, |
1240 | vq->iov, in); | 1231 | vq->iov, in); |
1241 | total_len += vhost_len; | 1232 | total_len += vhost_len; |
1242 | if (unlikely(vhost_exceeds_weight(++recv_pkts, total_len))) { | 1233 | if (unlikely(vhost_exceeds_weight(vq, ++recv_pkts, total_len))) |
1243 | vhost_poll_queue(&vq->poll); | ||
1244 | goto out; | 1234 | goto out; |
1245 | } | ||
1246 | } | 1235 | } |
1247 | if (unlikely(busyloop_intr)) | 1236 | if (unlikely(busyloop_intr)) |
1248 | vhost_poll_queue(&vq->poll); | 1237 | vhost_poll_queue(&vq->poll); |
@@ -1338,7 +1327,8 @@ static int vhost_net_open(struct inode *inode, struct file *f) | |||
1338 | vhost_net_buf_init(&n->vqs[i].rxq); | 1327 | vhost_net_buf_init(&n->vqs[i].rxq); |
1339 | } | 1328 | } |
1340 | vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX, | 1329 | vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX, |
1341 | UIO_MAXIOV + VHOST_NET_BATCH); | 1330 | UIO_MAXIOV + VHOST_NET_BATCH, |
1331 | VHOST_NET_WEIGHT, VHOST_NET_PKT_WEIGHT); | ||
1342 | 1332 | ||
1343 | vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, EPOLLOUT, dev); | 1333 | vhost_poll_init(n->poll + VHOST_NET_VQ_TX, handle_tx_net, EPOLLOUT, dev); |
1344 | vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, EPOLLIN, dev); | 1334 | vhost_poll_init(n->poll + VHOST_NET_VQ_RX, handle_rx_net, EPOLLIN, dev); |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index c090d177bd75..27c9dac9f518 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -57,6 +57,12 @@ | |||
57 | #define VHOST_SCSI_PREALLOC_UPAGES 2048 | 57 | #define VHOST_SCSI_PREALLOC_UPAGES 2048 |
58 | #define VHOST_SCSI_PREALLOC_PROT_SGLS 2048 | 58 | #define VHOST_SCSI_PREALLOC_PROT_SGLS 2048 |
59 | 59 | ||
60 | /* Max number of requests before requeueing the job. | ||
61 | * Using this limit prevents one virtqueue from starving others with | ||
62 | * request. | ||
63 | */ | ||
64 | #define VHOST_SCSI_WEIGHT 256 | ||
65 | |||
60 | struct vhost_scsi_inflight { | 66 | struct vhost_scsi_inflight { |
61 | /* Wait for the flush operation to finish */ | 67 | /* Wait for the flush operation to finish */ |
62 | struct completion comp; | 68 | struct completion comp; |
@@ -1621,7 +1627,8 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) | |||
1621 | vqs[i] = &vs->vqs[i].vq; | 1627 | vqs[i] = &vs->vqs[i].vq; |
1622 | vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick; | 1628 | vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick; |
1623 | } | 1629 | } |
1624 | vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV); | 1630 | vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV, |
1631 | VHOST_SCSI_WEIGHT, 0); | ||
1625 | 1632 | ||
1626 | vhost_scsi_init_inflight(vs, NULL); | 1633 | vhost_scsi_init_inflight(vs, NULL); |
1627 | 1634 | ||
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 1e3ed41ae1f3..3f3eac4bcc58 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -413,8 +413,24 @@ static void vhost_dev_free_iovecs(struct vhost_dev *dev) | |||
413 | vhost_vq_free_iovecs(dev->vqs[i]); | 413 | vhost_vq_free_iovecs(dev->vqs[i]); |
414 | } | 414 | } |
415 | 415 | ||
416 | bool vhost_exceeds_weight(struct vhost_virtqueue *vq, | ||
417 | int pkts, int total_len) | ||
418 | { | ||
419 | struct vhost_dev *dev = vq->dev; | ||
420 | |||
421 | if ((dev->byte_weight && total_len >= dev->byte_weight) || | ||
422 | pkts >= dev->weight) { | ||
423 | vhost_poll_queue(&vq->poll); | ||
424 | return true; | ||
425 | } | ||
426 | |||
427 | return false; | ||
428 | } | ||
429 | EXPORT_SYMBOL_GPL(vhost_exceeds_weight); | ||
430 | |||
416 | void vhost_dev_init(struct vhost_dev *dev, | 431 | void vhost_dev_init(struct vhost_dev *dev, |
417 | struct vhost_virtqueue **vqs, int nvqs, int iov_limit) | 432 | struct vhost_virtqueue **vqs, int nvqs, |
433 | int iov_limit, int weight, int byte_weight) | ||
418 | { | 434 | { |
419 | struct vhost_virtqueue *vq; | 435 | struct vhost_virtqueue *vq; |
420 | int i; | 436 | int i; |
@@ -428,6 +444,8 @@ void vhost_dev_init(struct vhost_dev *dev, | |||
428 | dev->mm = NULL; | 444 | dev->mm = NULL; |
429 | dev->worker = NULL; | 445 | dev->worker = NULL; |
430 | dev->iov_limit = iov_limit; | 446 | dev->iov_limit = iov_limit; |
447 | dev->weight = weight; | ||
448 | dev->byte_weight = byte_weight; | ||
431 | init_llist_head(&dev->work_list); | 449 | init_llist_head(&dev->work_list); |
432 | init_waitqueue_head(&dev->wait); | 450 | init_waitqueue_head(&dev->wait); |
433 | INIT_LIST_HEAD(&dev->read_list); | 451 | INIT_LIST_HEAD(&dev->read_list); |
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 9490e7ddb340..27a78a9b8cc7 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -171,10 +171,13 @@ struct vhost_dev { | |||
171 | struct list_head pending_list; | 171 | struct list_head pending_list; |
172 | wait_queue_head_t wait; | 172 | wait_queue_head_t wait; |
173 | int iov_limit; | 173 | int iov_limit; |
174 | int weight; | ||
175 | int byte_weight; | ||
174 | }; | 176 | }; |
175 | 177 | ||
178 | bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len); | ||
176 | void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, | 179 | void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, |
177 | int nvqs, int iov_limit); | 180 | int nvqs, int iov_limit, int weight, int byte_weight); |
178 | long vhost_dev_set_owner(struct vhost_dev *dev); | 181 | long vhost_dev_set_owner(struct vhost_dev *dev); |
179 | bool vhost_dev_has_owner(struct vhost_dev *dev); | 182 | bool vhost_dev_has_owner(struct vhost_dev *dev); |
180 | long vhost_dev_check_owner(struct vhost_dev *); | 183 | long vhost_dev_check_owner(struct vhost_dev *); |
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index bb5fc0e9fbc2..47c6d4d43c70 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c | |||
@@ -21,6 +21,14 @@ | |||
21 | #include "vhost.h" | 21 | #include "vhost.h" |
22 | 22 | ||
23 | #define VHOST_VSOCK_DEFAULT_HOST_CID 2 | 23 | #define VHOST_VSOCK_DEFAULT_HOST_CID 2 |
24 | /* Max number of bytes transferred before requeueing the job. | ||
25 | * Using this limit prevents one virtqueue from starving others. */ | ||
26 | #define VHOST_VSOCK_WEIGHT 0x80000 | ||
27 | /* Max number of packets transferred before requeueing the job. | ||
28 | * Using this limit prevents one virtqueue from starving others with | ||
29 | * small pkts. | ||
30 | */ | ||
31 | #define VHOST_VSOCK_PKT_WEIGHT 256 | ||
24 | 32 | ||
25 | enum { | 33 | enum { |
26 | VHOST_VSOCK_FEATURES = VHOST_FEATURES, | 34 | VHOST_VSOCK_FEATURES = VHOST_FEATURES, |
@@ -531,7 +539,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) | |||
531 | vsock->vqs[VSOCK_VQ_TX].handle_kick = vhost_vsock_handle_tx_kick; | 539 | vsock->vqs[VSOCK_VQ_TX].handle_kick = vhost_vsock_handle_tx_kick; |
532 | vsock->vqs[VSOCK_VQ_RX].handle_kick = vhost_vsock_handle_rx_kick; | 540 | vsock->vqs[VSOCK_VQ_RX].handle_kick = vhost_vsock_handle_rx_kick; |
533 | 541 | ||
534 | vhost_dev_init(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs), UIO_MAXIOV); | 542 | vhost_dev_init(&vsock->dev, vqs, ARRAY_SIZE(vsock->vqs), |
543 | UIO_MAXIOV, VHOST_VSOCK_PKT_WEIGHT, | ||
544 | VHOST_VSOCK_WEIGHT); | ||
535 | 545 | ||
536 | file->private_data = vsock; | 546 | file->private_data = vsock; |
537 | spin_lock_init(&vsock->send_pkt_list_lock); | 547 | spin_lock_init(&vsock->send_pkt_list_lock); |