summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vhost/net.c22
-rw-r--r--drivers/vhost/scsi.c9
-rw-r--r--drivers/vhost/vhost.c20
-rw-r--r--drivers/vhost/vhost.h5
-rw-r--r--drivers/vhost/vsock.c12
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
607static 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
613static int get_tx_bufs(struct vhost_net *net, 607static 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
60struct vhost_scsi_inflight { 66struct 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
416bool 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}
429EXPORT_SYMBOL_GPL(vhost_exceeds_weight);
430
416void vhost_dev_init(struct vhost_dev *dev, 431void 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
178bool vhost_exceeds_weight(struct vhost_virtqueue *vq, int pkts, int total_len);
176void vhost_dev_init(struct vhost_dev *, struct vhost_virtqueue **vqs, 179void 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);
178long vhost_dev_set_owner(struct vhost_dev *dev); 181long vhost_dev_set_owner(struct vhost_dev *dev);
179bool vhost_dev_has_owner(struct vhost_dev *dev); 182bool vhost_dev_has_owner(struct vhost_dev *dev);
180long vhost_dev_check_owner(struct vhost_dev *); 183long 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
25enum { 33enum {
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);