Net patches
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJUCJQsAAoJEJykq7OBq3PIFs4H/jHdJ65oXUeS8REtDwsRaU/q Ftny6suH0j8XYh/zFSppNFHprX/i2AB7oJpHS8MzVjglxQ06OT/BQWSb2NA99URD PARU0/Ijn2ZgReCiMS3qBGotYLJV/pJsZRtmi6xc/v9Zz/LlziBo1J/ZsZeMkhiP RL/Q5ySixyWGx32989YcTmn98aCc4nvG70pE3dz3I3PPYQtUn38uqTltYPORaOgy txhIOxeyvwgL+jwYvoJq5UgDpOw/QNtLRzN0+YydRUs5ad7roSlRX4PvlBgXxfWc NPxt/wM+OPEyN029KLV8IjVNvxxM/QRNFqksabnmJIS/SgBaiSRPHZuHR5po8C4= =cCXt -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging Net patches # gpg: Signature made Thu 04 Sep 2014 17:32:44 BST using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" * remotes/stefanha/tags/net-pull-request: virtio-net: purge outstanding packets when starting vhost net: complete all queued packets on VM stop net: invoke callback when purging queue virtio: don't call device on !vm_running virtio-net: don't run bh on vm stopped net: Forbid dealing with packets when VM is not running Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8cf8c92e77
@ -125,10 +125,23 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
|
||||
return;
|
||||
}
|
||||
if (!n->vhost_started) {
|
||||
int r;
|
||||
int r, i;
|
||||
|
||||
if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Any packets outstanding? Purge them to avoid touching rings
|
||||
* when vhost is running.
|
||||
*/
|
||||
for (i = 0; i < queues; i++) {
|
||||
NetClientState *qnc = qemu_get_subqueue(n->nic, i);
|
||||
|
||||
/* Purge both directions: TX and RX. */
|
||||
qemu_net_queue_purge(qnc->peer->incoming_queue, qnc);
|
||||
qemu_net_queue_purge(qnc->incoming_queue, qnc->peer);
|
||||
}
|
||||
|
||||
n->vhost_started = 1;
|
||||
r = vhost_net_start(vdev, n->nic->ncs, queues);
|
||||
if (r < 0) {
|
||||
|
@ -1108,7 +1108,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
|
||||
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
|
||||
vdev->vm_running = running;
|
||||
|
||||
if (running) {
|
||||
vdev->vm_running = running;
|
||||
}
|
||||
|
||||
if (backend_run) {
|
||||
virtio_set_status(vdev, vdev->status);
|
||||
@ -1121,6 +1124,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
|
||||
if (!backend_run) {
|
||||
virtio_set_status(vdev, vdev->status);
|
||||
}
|
||||
|
||||
if (!running) {
|
||||
vdev->vm_running = running;
|
||||
}
|
||||
}
|
||||
|
||||
void virtio_init(VirtIODevice *vdev, const char *name,
|
||||
|
40
net/net.c
40
net/net.c
@ -41,12 +41,14 @@
|
||||
#include "qapi-visit.h"
|
||||
#include "qapi/opts-visitor.h"
|
||||
#include "qapi/dealloc-visitor.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
/* Net bridge is currently not supported for W32. */
|
||||
#if !defined(_WIN32)
|
||||
# define CONFIG_NET_BRIDGE
|
||||
#endif
|
||||
|
||||
static VMChangeStateEntry *net_change_state_entry;
|
||||
static QTAILQ_HEAD(, NetClientState) net_clients;
|
||||
|
||||
const char *host_net_devices[] = {
|
||||
@ -452,6 +454,12 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
|
||||
|
||||
int qemu_can_send_packet(NetClientState *sender)
|
||||
{
|
||||
int vm_running = runstate_is_running();
|
||||
|
||||
if (!vm_running) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sender->peer) {
|
||||
return 1;
|
||||
}
|
||||
@ -504,7 +512,8 @@ void qemu_purge_queued_packets(NetClientState *nc)
|
||||
qemu_net_queue_purge(nc->peer->incoming_queue, nc);
|
||||
}
|
||||
|
||||
void qemu_flush_queued_packets(NetClientState *nc)
|
||||
static
|
||||
void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge)
|
||||
{
|
||||
nc->receive_disabled = 0;
|
||||
|
||||
@ -518,9 +527,17 @@ void qemu_flush_queued_packets(NetClientState *nc)
|
||||
* the file descriptor (for tap, for example).
|
||||
*/
|
||||
qemu_notify_event();
|
||||
} else if (purge) {
|
||||
/* Unable to empty the queue, purge remaining packets */
|
||||
qemu_net_queue_purge(nc->incoming_queue, nc);
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_flush_queued_packets(NetClientState *nc)
|
||||
{
|
||||
qemu_flush_or_purge_queued_packets(nc, false);
|
||||
}
|
||||
|
||||
static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
|
||||
unsigned flags,
|
||||
const uint8_t *buf, int size,
|
||||
@ -1168,6 +1185,22 @@ void qmp_set_link(const char *name, bool up, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static void net_vm_change_state_handler(void *opaque, int running,
|
||||
RunState state)
|
||||
{
|
||||
/* Complete all queued packets, to guarantee we don't modify
|
||||
* state later when VM is not running.
|
||||
*/
|
||||
if (!running) {
|
||||
NetClientState *nc;
|
||||
NetClientState *tmp;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(nc, &net_clients, next, tmp) {
|
||||
qemu_flush_or_purge_queued_packets(nc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void net_cleanup(void)
|
||||
{
|
||||
NetClientState *nc;
|
||||
@ -1183,6 +1216,8 @@ void net_cleanup(void)
|
||||
qemu_del_net_client(nc);
|
||||
}
|
||||
}
|
||||
|
||||
qemu_del_vm_change_state_handler(net_change_state_entry);
|
||||
}
|
||||
|
||||
void net_check_clients(void)
|
||||
@ -1268,6 +1303,9 @@ int net_init_clients(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
net_change_state_entry =
|
||||
qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL);
|
||||
|
||||
QTAILQ_INIT(&net_clients);
|
||||
|
||||
if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
|
||||
|
@ -233,6 +233,9 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
|
||||
if (packet->sender == from) {
|
||||
QTAILQ_REMOVE(&queue->packets, packet, entry);
|
||||
queue->nq_count--;
|
||||
if (packet->sent_cb) {
|
||||
packet->sent_cb(packet->sender, 0);
|
||||
}
|
||||
g_free(packet);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user