From: Steve Glass <stevie@sedition.org.au>
To: kvm@vger.kernel.org
Subject: vhost question
Date: Mon, 19 Mar 2012 10:18:38 +1000 [thread overview]
Message-ID: <4F667B5E.2060206@sedition.org.au> (raw)
Hi,
I'm using virtio to implement a mac80211 device in the guest. On the
host side I plan to use a simple network simulation to control delivery
of frames between guests. Right now I've used the vhost approach on the
host side and can pass buffers from guest to host and back using virtio.
My immediate problem is how to have the host-side tx kick handler get
the host-side rx kick handler to run in order to deliver a frame? In the
tx kick handler I copy the frame into a queue for the receiving guest.
In the rx_handler I take queued frames and copy them into the rx buffers
and wake the guest. The problem is that if no frames are ready for
delivery when the guest rx kick handler runs then it has to exit and
somehow I have to arrange that it runs again (in the receiver's process
context) when there are frames to deliver.
How can I get my host-side tx kick handler to wake the host-side rx kick
handler to deliver frames to the guest?
Steve
/* first-draft tx/rx handlers */
static void
handle_rx(struct vhost_work *work)
{
int n;
unsigned out, in;
struct transmission *t;
u16 frames = 0;
struct vhost_poll *p = container_of(work, struct vhost_poll, work);
struct vhost_virtqueue *vq = container_of(p, struct vhost_virtqueue, poll);
struct vhost_node *node = container_of(vq, struct vhost_node,
vqs[WLAN_VQ_RX]);
struct vhost_dev *dev = &node->vdev;
mutex_lock(&vq->mutex);
vhost_disable_notify(dev, vq);
while (!queue_empty(&node->rxq)) {
n = vhost_get_vq_desc(dev, vq, vq->iov, ARRAY_SIZE(vq->iov), &out, &in,
NULL, NULL);
if (0 < n || n == vq->num)
break;
if ((t = queue_pop(&node->rxq))) {
BUG_ON(copy_to_user(vq->iov[0].iov_base, t->buf, t->buf_sz));
vq->iov[0].iov_len = t->buf_sz;
// ToDo: copy_to_user the rx_status
vhost_add_used(vq, n, out);
transmission_free(t);
++frames;
}
}
if (frames)
vhost_signal(dev, vq);
vhost_enable_notify(dev, vq);
mutex_unlock(&vq->mutex);
}
static void
handle_tx(struct vhost_work *work)
{
int n;
unsigned out, in;
struct transmission *t;
struct vhost_poll *p = container_of(work, struct vhost_poll, work);
struct vhost_virtqueue *vq = container_of(p, struct vhost_virtqueue, poll);
struct vhost_node *w = container_of(vq, struct vhost_node, vqs[WLAN_VQ_TX]);
struct vhost_dev *dev = &w->vdev;
mutex_lock(&vq->mutex);
do {
vhost_disable_notify(dev, vq);
n = vhost_get_vq_desc(dev, vq, vq->iov, ARRAY_SIZE(vq->iov), &out, &in,
NULL, NULL);
while (n >= 0 && n != vq->num) {
struct vhost_node *receiver = net_get_receiver(w);
if(receiver) {
if((t = transmission_alloc())) {
BUG_ON(copy_from_user(t->buf, vq->iov[1].iov_base, vq->iov[1].iov_len));
t->buf_sz = vq->iov[1].iov_len;
queue_push(&receiver->rxq, t);
// ToDo: kick receiver's handle_rx
// ToDo: populate TX status
} else {
pr_warn("%s: out of memory - packet dropped!", __func__);
// ToDo: populate TX status
}
} else {
pr_debug("%s: no receivers in range!", __func__);
// ToDo: populate TX status
}
vhost_add_used(vq, n, out);
n = vhost_get_vq_desc(dev, vq, vq->iov, ARRAY_SIZE(vq->iov), &out, &in,
NULL, NULL);
}
vhost_signal(dev, vq);
} while (vhost_enable_notify(dev, vq));
mutex_unlock(&vq->mutex);
}
next reply other threads:[~2012-03-19 0:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-19 0:18 Steve Glass [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-03-22 1:48 vhost question Steve Glass
2012-03-22 9:52 ` Stefan Hajnoczi
[not found] ` <CADC0ay0ZRL79uMq72kAewOBTMCgMe1_1BLotdH9QnOwosJkTYQ@mail.gmail.com>
2012-03-25 16:18 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F667B5E.2060206@sedition.org.au \
--to=stevie@sedition.org.au \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox