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;
|
return;
|
||||||
}
|
}
|
||||||
if (!n->vhost_started) {
|
if (!n->vhost_started) {
|
||||||
int r;
|
int r, i;
|
||||||
|
|
||||||
if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {
|
if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {
|
||||||
return;
|
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;
|
n->vhost_started = 1;
|
||||||
r = vhost_net_start(vdev, n->nic->ncs, queues);
|
r = vhost_net_start(vdev, n->nic->ncs, queues);
|
||||||
if (r < 0) {
|
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));
|
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
||||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||||
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
|
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
|
||||||
vdev->vm_running = running;
|
|
||||||
|
if (running) {
|
||||||
|
vdev->vm_running = running;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend_run) {
|
if (backend_run) {
|
||||||
virtio_set_status(vdev, vdev->status);
|
virtio_set_status(vdev, vdev->status);
|
||||||
|
@ -1121,6 +1124,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
|
||||||
if (!backend_run) {
|
if (!backend_run) {
|
||||||
virtio_set_status(vdev, vdev->status);
|
virtio_set_status(vdev, vdev->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!running) {
|
||||||
|
vdev->vm_running = running;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_init(VirtIODevice *vdev, const char *name,
|
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-visit.h"
|
||||||
#include "qapi/opts-visitor.h"
|
#include "qapi/opts-visitor.h"
|
||||||
#include "qapi/dealloc-visitor.h"
|
#include "qapi/dealloc-visitor.h"
|
||||||
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
/* Net bridge is currently not supported for W32. */
|
/* Net bridge is currently not supported for W32. */
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
# define CONFIG_NET_BRIDGE
|
# define CONFIG_NET_BRIDGE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static VMChangeStateEntry *net_change_state_entry;
|
||||||
static QTAILQ_HEAD(, NetClientState) net_clients;
|
static QTAILQ_HEAD(, NetClientState) net_clients;
|
||||||
|
|
||||||
const char *host_net_devices[] = {
|
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 qemu_can_send_packet(NetClientState *sender)
|
||||||
{
|
{
|
||||||
|
int vm_running = runstate_is_running();
|
||||||
|
|
||||||
|
if (!vm_running) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sender->peer) {
|
if (!sender->peer) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -504,7 +512,8 @@ void qemu_purge_queued_packets(NetClientState *nc)
|
||||||
qemu_net_queue_purge(nc->peer->incoming_queue, 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;
|
nc->receive_disabled = 0;
|
||||||
|
|
||||||
|
@ -518,9 +527,17 @@ void qemu_flush_queued_packets(NetClientState *nc)
|
||||||
* the file descriptor (for tap, for example).
|
* the file descriptor (for tap, for example).
|
||||||
*/
|
*/
|
||||||
qemu_notify_event();
|
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,
|
static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
const uint8_t *buf, int size,
|
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)
|
void net_cleanup(void)
|
||||||
{
|
{
|
||||||
NetClientState *nc;
|
NetClientState *nc;
|
||||||
|
@ -1183,6 +1216,8 @@ void net_cleanup(void)
|
||||||
qemu_del_net_client(nc);
|
qemu_del_net_client(nc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemu_del_vm_change_state_handler(net_change_state_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_check_clients(void)
|
void net_check_clients(void)
|
||||||
|
@ -1268,6 +1303,9 @@ int net_init_clients(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net_change_state_entry =
|
||||||
|
qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL);
|
||||||
|
|
||||||
QTAILQ_INIT(&net_clients);
|
QTAILQ_INIT(&net_clients);
|
||||||
|
|
||||||
if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
|
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) {
|
if (packet->sender == from) {
|
||||||
QTAILQ_REMOVE(&queue->packets, packet, entry);
|
QTAILQ_REMOVE(&queue->packets, packet, entry);
|
||||||
queue->nq_count--;
|
queue->nq_count--;
|
||||||
|
if (packet->sent_cb) {
|
||||||
|
packet->sent_cb(packet->sender, 0);
|
||||||
|
}
|
||||||
g_free(packet);
|
g_free(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue