// SPDX-License-Identifier: GPL-2.0-only /* Copyright (C) 2009 Red Hat, Inc. * Author: Michael S. Tsirkin <mst@redhat.com> * * test virtio server in host kernel.
*/
/* Max number of bytes transferred before requeueing the job.
* Using this limit prevents one virtqueue from starving others. */ #define VHOST_TEST_WEIGHT 0x80000
/* Max number of packets transferred before requeueing the job. * Using this limit prevents one virtqueue from starving others with * pkts.
*/ #define VHOST_TEST_PKT_WEIGHT 256
/* Expects to be always run from workqueue - which acts as
* read-size critical section for our kind of RCU. */ staticvoid handle_vq(struct vhost_test *n)
{ struct vhost_virtqueue *vq = &n->vqs[VHOST_TEST_VQ]; unsigned out, in; int head;
size_t len, total_len = 0; void *private;
mutex_lock(&vq->mutex); private = vhost_vq_get_backend(vq); if (!private) {
mutex_unlock(&vq->mutex); return;
}
vhost_disable_notify(&n->dev, vq);
for (;;) {
head = vhost_get_vq_desc(vq, vq->iov,
ARRAY_SIZE(vq->iov),
&out, &in,
NULL, NULL); /* On error, stop handling until the next kick. */ if (unlikely(head < 0)) break; /* Nothing new? Wait for eventfd to tell us they refilled. */ if (head == vq->num) { if (unlikely(vhost_enable_notify(&n->dev, vq))) {
vhost_disable_notify(&n->dev, vq); continue;
} break;
} if (in) {
vq_err(vq, "Unexpected descriptor format for TX: " "out %d, int %d\n", out, in); break;
}
len = iov_length(vq->iov, out); /* Sanity check */ if (!len) {
vq_err(vq, "Unexpected 0 len for TX\n"); break;
}
vhost_add_used_and_signal(&n->dev, vq, head, 0);
total_len += len; if (unlikely(vhost_exceeds_weight(vq, 0, total_len))) break;
}
staticlong vhost_test_run(struct vhost_test *n, int test)
{ void *priv, *oldpriv; struct vhost_virtqueue *vq; int r, index;
if (test < 0 || test > 1) return -EINVAL;
mutex_lock(&n->dev.mutex);
r = vhost_dev_check_owner(&n->dev); if (r) goto err;
for (index = 0; index < n->dev.nvqs; ++index) { /* Verify that ring has been setup correctly. */ if (!vhost_vq_access_ok(&n->vqs[index])) {
r = -EFAULT; goto err;
}
}
for (index = 0; index < n->dev.nvqs; ++index) {
vq = n->vqs + index;
mutex_lock(&vq->mutex);
priv = test ? n : NULL;
mutex_lock(&n->dev.mutex);
r = vhost_dev_check_owner(&n->dev); if (r) goto err;
if (index >= VHOST_TEST_VQ_MAX) {
r = -ENOBUFS; goto err;
}
vq = &n->vqs[index];
mutex_lock(&vq->mutex);
/* Verify that ring has been setup correctly. */ if (!vhost_vq_access_ok(vq)) {
r = -EFAULT; goto err_vq;
} if (!enable) {
vhost_poll_stop(&vq->poll);
backend = vhost_vq_get_backend(vq);
vhost_vq_set_backend(vq, NULL);
} else {
vhost_vq_set_backend(vq, backend);
r = vhost_vq_init_access(vq); if (r == 0)
r = vhost_poll_start(&vq->poll, vq->kick);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.