From 6f366bb5e02140bce2a8543c130e4b874804c15b Mon Sep 17 00:00:00 2001 Message-Id: <6f366bb5e02140bce2a8543c130e4b874804c15b.1430412215.git.jen@redhat.com> From: Amos Kong Date: Wed, 1 Apr 2015 08:30:16 -0500 Subject: [CHANGE] virtio-pci: avoid repeatedly deassigning notifers of vhost device To: rhvirt-patches@redhat.com, jen@redhat.com RH-Author: Amos Kong Message-id: <1427877016-13288-1-git-send-email-akong@redhat.com> Patchwork-id: 64660 O-Subject: [RHEL-6.7 qemu-kvm PATCH v2] virtio-pci: avoid repeatedly deassigning notifers of vhost device Bugzilla: 1124311 RH-Acked-by: Marcel Apfelbaum RH-Acked-by: Vlad Yasevich RH-Acked-by: Juan Quintela Bugzilla: 1124311 Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=8932591 Upstream: only for rhel6, upstream uses new memory API, that's fine. Launch guest with 232 virtio nics (vhost=on), we will see two errors, kernel doesn't have enough ioeventfd and return ENOSPC error, the opened file descriptors might also reach to the MAX number of open file for single process in userspace. The notifiers will be deassigned after ENOSPC error. The second error will cause vhost device fails to start, then repeatedly deassign notifiers and get EMFILE error. The notifiers will be redisabled in vhost_net_stop() when guest exits or device is hotunplugged. So we should avoid repeat deassign notifiers of vhost device. Upstream uses new memory API, it didn't check deassign result. Signed-off-by: Amos Kong --- v2: remove redundant variable init (Fam) --- hw/event_notifier.c | 2 ++ hw/virtio-pci.c | 4 ++++ 2 files changed, 6 insertions(+), 0 deletions(-) Signed-off-by: Jeff E. Nelson --- hw/event_notifier.c | 2 ++ hw/virtio-pci.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/hw/event_notifier.c b/hw/event_notifier.c index 10ffb65..d02ae90 100644 --- a/hw/event_notifier.c +++ b/hw/event_notifier.c @@ -18,6 +18,7 @@ int event_notifier_init(EventNotifier *e, int active) { + e->fd = -1; #ifdef CONFIG_EVENTFD int fd = eventfd(!!active, EFD_NONBLOCK | EFD_CLOEXEC); if (fd < 0) @@ -32,6 +33,7 @@ int event_notifier_init(EventNotifier *e, int active) void event_notifier_cleanup(EventNotifier *e) { close(e->fd); + e->fd = -1; } int event_notifier_get_fd(EventNotifier *e) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 15b1d67..3a72e1e 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -212,6 +212,10 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, event_notifier_cleanup(notifier); } } else { + /* Skip repeat deassigning of notifier */ + if (event_notifier_get_fd(notifier) == -1) { + return 0; + } r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier), proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY, n, assign); -- 2.1.0