All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <levinsasha928@gmail.com>
To: penberg@kernel.org
Cc: mingo@elte.hu, gorcunov@gmail.com, asias.hejun@gmail.com,
	kvm@vger.kernel.org, Sasha Levin <levinsasha928@gmail.com>
Subject: [RFC 06/12] kvm tools: Fixes for ioeventfd module
Date: Mon, 19 Dec 2011 15:58:28 +0200	[thread overview]
Message-ID: <1324303114-5948-7-git-send-email-levinsasha928@gmail.com> (raw)
In-Reply-To: <1324303114-5948-1-git-send-email-levinsasha928@gmail.com>

Fixes include:
 - Error handling
 - Cleanup
 - Standard init/uninit

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/builtin-run.c           |   12 ++-
 tools/kvm/include/kvm/ioeventfd.h |    8 +-
 tools/kvm/ioeventfd.c             |  158 ++++++++++++++++++++++++++-----------
 tools/kvm/virtio/pci.c            |    5 +-
 4 files changed, 128 insertions(+), 55 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 5388171..b7e7977 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -958,7 +958,11 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 
 	kvm->single_step = single_step;
 
-	ioeventfd__init(kvm);
+	r = ioeventfd__init(kvm);
+	if (r < 0) {
+		pr_error("ioeventfd__init() failed with error %d\n", r);
+		goto fail;
+	}
 
 	max_cpus = kvm__max_cpus(kvm);
 	recommended_cpus = kvm__recommended_cpus(kvm);
@@ -1158,8 +1162,6 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 	}
 
 	thread_pool__init(nr_online_cpus);
-	ioeventfd__start();
-
 fail:
 	return r;
 }
@@ -1216,6 +1218,10 @@ static void kvm_cmd_run_uninit(int guest_ret)
 	if (r < 0)
 		pr_warning("ioport__uninit() failed with error %d\n", r);
 
+	r = ioeventfd__uninit(kvm);
+	if (r < 0)
+		pr_warning("ioeventfd__uninit() failed with error %d\n", r);
+
 	kvm__delete(kvm);
 
 	if (guest_ret == 0)
diff --git a/tools/kvm/include/kvm/ioeventfd.h b/tools/kvm/include/kvm/ioeventfd.h
index 3a95788..cb8a21b 100644
--- a/tools/kvm/include/kvm/ioeventfd.h
+++ b/tools/kvm/include/kvm/ioeventfd.h
@@ -19,9 +19,9 @@ struct ioevent {
 	struct list_head	list;
 };
 
-void ioeventfd__init(struct kvm *kvm);
-void ioeventfd__start(void);
-void ioeventfd__add_event(struct ioevent *ioevent);
-void ioeventfd__del_event(u64 addr, u64 datamatch);
+int ioeventfd__init(struct kvm *kvm);
+int ioeventfd__uninit(struct kvm *kvm);
+int ioeventfd__add_event(struct ioevent *ioevent);
+int ioeventfd__del_event(u64 addr, u64 datamatch);
 
 #endif
diff --git a/tools/kvm/ioeventfd.c b/tools/kvm/ioeventfd.c
index 1d6a7ac..bb248d7 100644
--- a/tools/kvm/ioeventfd.c
+++ b/tools/kvm/ioeventfd.c
@@ -16,34 +16,117 @@
 #define IOEVENTFD_MAX_EVENTS	20
 
 static struct	epoll_event events[IOEVENTFD_MAX_EVENTS];
-static int	epoll_fd;
+static int	epoll_fd, epoll_stop_fd;
 static LIST_HEAD(used_ioevents);
 static bool	ioeventfd_avail;
 
-void ioeventfd__init(struct kvm *kvm)
+static void *ioeventfd__thread(void *param)
 {
+	u64 tmp = 1;
+
+	for (;;) {
+		int nfds, i;
+
+		nfds = epoll_wait(epoll_fd, events, IOEVENTFD_MAX_EVENTS, -1);
+		for (i = 0; i < nfds; i++) {
+			struct ioevent *ioevent;
+
+			if (events[i].data.fd == epoll_stop_fd)
+				goto done;
+
+			ioevent = events[i].data.ptr;
+
+			if (read(ioevent->fd, &tmp, sizeof(tmp)) < 0)
+				die("Failed reading event");
+
+			ioevent->fn(ioevent->fn_kvm, ioevent->fn_ptr);
+		}
+	}
+
+done:
+	tmp = 1;
+	tmp = write(epoll_stop_fd, &tmp, sizeof(tmp));
+
+	return NULL;
+}
+
+static int ioeventfd__start(void)
+{
+	pthread_t thread;
+
+	if (!ioeventfd_avail)
+		return -ENOSYS;
+
+	return pthread_create(&thread, NULL, ioeventfd__thread, NULL);
+}
+
+int ioeventfd__init(struct kvm *kvm)
+{
+	struct epoll_event epoll_event = {.events = EPOLLIN};
+	int r;
+
 	ioeventfd_avail = kvm__supports_extension(kvm, KVM_CAP_IOEVENTFD);
 	if (!ioeventfd_avail)
-		return;
+		return -ENOSYS;
 
 	epoll_fd = epoll_create(IOEVENTFD_MAX_EVENTS);
 	if (epoll_fd < 0)
-		die("Failed creating epoll fd");
+		return -errno;
+
+	epoll_stop_fd = eventfd(0, 0);
+	epoll_event.data.fd = epoll_stop_fd;
+
+	r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, epoll_stop_fd, &epoll_event);
+	if (r < 0)
+		goto cleanup;
+
+	r = ioeventfd__start();
+	if (r < 0)
+		goto cleanup;
+
+	r = 0;
+
+	return r;
+
+cleanup:
+	close(epoll_stop_fd);
+	close(epoll_fd);
+
+	return r;
 }
 
-void ioeventfd__add_event(struct ioevent *ioevent)
+int ioeventfd__uninit(struct kvm *kvm)
+{
+	u64 tmp = 1;
+	int r;
+
+	r = write(epoll_stop_fd, &tmp, sizeof(tmp));
+	if (r < 0)
+		return r;
+
+	r = read(epoll_stop_fd, &tmp, sizeof(tmp));
+	if (r < 0)
+		return r;
+
+	close(epoll_fd);
+	close(epoll_stop_fd);
+
+	return 0;
+}
+
+int ioeventfd__add_event(struct ioevent *ioevent)
 {
 	struct kvm_ioeventfd kvm_ioevent;
 	struct epoll_event epoll_event;
 	struct ioevent *new_ioevent;
-	int event;
+	int event, r;
 
 	if (!ioeventfd_avail)
-		return;
+		return -ENOSYS;
 
 	new_ioevent = malloc(sizeof(*new_ioevent));
 	if (new_ioevent == NULL)
-		die("Failed allocating memory for new ioevent");
+		return -ENOMEM;
 
 	*new_ioevent = *ioevent;
 	event = new_ioevent->fd;
@@ -56,28 +139,40 @@ void ioeventfd__add_event(struct ioevent *ioevent)
 		.flags			= KVM_IOEVENTFD_FLAG_PIO | KVM_IOEVENTFD_FLAG_DATAMATCH,
 	};
 
-	if (ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent) != 0)
-		die("Failed creating new ioeventfd");
+	r = ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent);
+	if (r) {
+		r = -errno;
+		goto cleanup;
+	}
 
 	epoll_event = (struct epoll_event) {
 		.events			= EPOLLIN,
 		.data.ptr		= new_ioevent,
 	};
 
-	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event, &epoll_event) != 0)
-		die("Failed assigning new event to the epoll fd");
+	r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event, &epoll_event);
+	if (r) {
+		r = -errno;
+		goto cleanup;
+	}
 
 	list_add_tail(&new_ioevent->list, &used_ioevents);
+
+	return 0;
+
+cleanup:
+	free(new_ioevent);
+	return r;
 }
 
-void ioeventfd__del_event(u64 addr, u64 datamatch)
+int ioeventfd__del_event(u64 addr, u64 datamatch)
 {
 	struct kvm_ioeventfd kvm_ioevent;
 	struct ioevent *ioevent;
 	u8 found = 0;
 
 	if (!ioeventfd_avail)
-		return;
+		return -ENOSYS;
 
 	list_for_each_entry(ioevent, &used_ioevents, list) {
 		if (ioevent->io_addr == addr) {
@@ -87,7 +182,7 @@ void ioeventfd__del_event(u64 addr, u64 datamatch)
 	}
 
 	if (found == 0 || ioevent == NULL)
-		return;
+		return -ENOENT;
 
 	kvm_ioevent = (struct kvm_ioeventfd) {
 		.addr			= ioevent->io_addr,
@@ -106,37 +201,6 @@ void ioeventfd__del_event(u64 addr, u64 datamatch)
 
 	close(ioevent->fd);
 	free(ioevent);
-}
-
-static void *ioeventfd__thread(void *param)
-{
-	for (;;) {
-		int nfds, i;
-
-		nfds = epoll_wait(epoll_fd, events, IOEVENTFD_MAX_EVENTS, -1);
-		for (i = 0; i < nfds; i++) {
-			u64 tmp;
-			struct ioevent *ioevent;
-
-			ioevent = events[i].data.ptr;
-
-			if (read(ioevent->fd, &tmp, sizeof(tmp)) < 0)
-				die("Failed reading event");
-
-			ioevent->fn(ioevent->fn_kvm, ioevent->fn_ptr);
-		}
-	}
-
-	return NULL;
-}
-
-void ioeventfd__start(void)
-{
-	pthread_t thread;
-
-	if (!ioeventfd_avail)
-		return;
 
-	if (pthread_create(&thread, NULL, ioeventfd__thread, NULL) != 0)
-		die("Failed starting ioeventfd thread");
+	return 0;
 }
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 2643d8a..7cc014e 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -34,6 +34,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
 {
 	struct ioevent ioevent;
 	struct virtio_pci *vpci = vtrans->virtio;
+	int r;
 
 	vpci->ioeventfds[vq] = (struct virtio_pci_ioevent_param) {
 		.vtrans		= vtrans,
@@ -50,7 +51,9 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
 		.fd		= eventfd(0, 0),
 	};
 
-	ioeventfd__add_event(&ioevent);
+	r = ioeventfd__add_event(&ioevent);
+	if (r)
+		return r;
 
 	if (vtrans->virtio_ops->notify_vq_eventfd)
 		vtrans->virtio_ops->notify_vq_eventfd(kvm, vpci->dev, vq, ioevent.fd);
-- 
1.7.8


  parent reply	other threads:[~2011-12-19 13:59 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-19 13:58 [RFC 00/12] Overhaul of error handling and module init/uninit Sasha Levin
2011-12-19 13:58 ` [RFC 01/12] kvm tools: Split kvm_cmd_run into init, work and uninit Sasha Levin
2011-12-19 21:26   ` Pekka Enberg
2011-12-20 10:09     ` Sasha Levin
2011-12-20  8:55       ` Asias He
2011-12-19 13:58 ` [RFC 02/12] kvm tools: Fixes for symbol resolving module Sasha Levin
2011-12-19 13:58 ` [RFC 03/12] kvm tools: Fixes for IRQ module Sasha Levin
2011-12-19 13:58 ` [RFC 04/12] kvm tools: Fixes for UI modules Sasha Levin
2011-12-19 13:58 ` [RFC 05/12] kvm tools: Fixes for ioport module Sasha Levin
2011-12-19 13:58 ` Sasha Levin [this message]
2011-12-19 13:58 ` [RFC 07/12] kvm tools: Fixes for serial module Sasha Levin
2011-12-19 13:58 ` [RFC 08/12] kvm tools: Fixes for mptable module Sasha Levin
2011-12-19 13:58 ` [RFC 09/12] kvm tools: Fixes for ioeventfd module Sasha Levin
2011-12-19 13:58 ` [RFC 10/12] kvm tools: Fixes for disk image module Sasha Levin
2011-12-19 13:58 ` [RFC 11/12] kvm tools: Fixes for rtc module Sasha Levin
2011-12-19 13:58 ` [RFC 12/12] kvm tools: Fixes for ioeventfd module Sasha Levin
2011-12-19 21:29 ` [RFC 00/12] Overhaul of error handling and module init/uninit Pekka Enberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1324303114-5948-7-git-send-email-levinsasha928@gmail.com \
    --to=levinsasha928@gmail.com \
    --cc=asias.hejun@gmail.com \
    --cc=gorcunov@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=penberg@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.