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 <jian.jun.chen@intel.com>
Acked-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
Jian Jun Chen 2018-12-12 14:41:01 +08:00 committed by wenlingz
parent 4f36244fef
commit b29fc619af

View File

@ -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