From b29fc619af16d8f6559114e9f0fd66ef9360b446 Mon Sep 17 00:00:00 2001 From: Jian Jun Chen Date: Wed, 12 Dec 2018 14:41:01 +0800 Subject: [PATCH] dm: virtio-net: apply new mevent API to avoid race issue Teardown callback is provided when mevent_add is called and it is used to free the virtio-net resources. Tracked-On: #1877 Signed-off-by: Jian Jun Chen Acked-by: Yin Fengwei --- devicemodel/hw/pci/virtio/virtio_net.c | 38 +++++++++++++++++--------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/devicemodel/hw/pci/virtio/virtio_net.c b/devicemodel/hw/pci/virtio/virtio_net.c index 62ef5530a..d5f0cc012 100644 --- a/devicemodel/hw/pci/virtio/virtio_net.c +++ b/devicemodel/hw/pci/virtio/virtio_net.c @@ -180,6 +180,7 @@ static int virtio_net_cfgwrite(void *vdev, int offset, int size, uint32_t value); static void virtio_net_neg_features(void *vdev, uint64_t negotiated_features); static void virtio_net_set_status(void *vdev, uint64_t status); +static void virtio_net_teardown(void *param); static struct vhost_net *vhost_net_init(struct virtio_base *base, int vhostfd, int tapfd, int vq_idx); static int vhost_net_deinit(struct vhost_net *vhost_net); @@ -707,7 +708,8 @@ virtio_net_tap_setup(struct virtio_net *net, char *devname) if (vhost_fd < 0) { net->mevp = mevent_add(net->tapfd, EVF_READ, - virtio_net_rx_callback, net, NULL, NULL); + virtio_net_rx_callback, net, + virtio_net_teardown, net); if (net->mevp == NULL) { WPRINTF(("Could not register event\n")); close(net->tapfd); @@ -934,10 +936,8 @@ virtio_net_set_status(void *vdev, uint64_t status) if (!net->vhost_net->vhost_started && (status & VIRTIO_CR_STATUS_DRIVER_OK)) { - if (net->mevp) { - mevent_delete(net->mevp); - net->mevp = NULL; - } + if (net->mevp) + mevent_disable(net->mevp); rc = vhost_net_start(net->vhost_net); if (rc < 0) { @@ -952,6 +952,24 @@ virtio_net_set_status(void *vdev, uint64_t status) } } +static void +virtio_net_teardown(void *param) +{ + struct virtio_net *net; + + net = (struct virtio_net *)param; + if (!net) + return; + + if (net->tapfd >= 0) { + close(net->tapfd); + net->tapfd = -1; + } else + fprintf(stderr, "net->tapfd is -1!\n"); + + free(net); +} + static void virtio_net_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) { @@ -969,16 +987,10 @@ virtio_net_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts) net->vhost_net = NULL; } - if (net->tapfd >= 0) { - close(net->tapfd); - net->tapfd = -1; - } else - fprintf(stderr, "net->tapfd is -1!\n"); - if (net->mevp != NULL) mevent_delete(net->mevp); - - free(net); + else + virtio_net_teardown(net); DPRINTF(("%s: done\n", __func__)); } else