From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org, Anthony Liguori <anthony@codemonkey.ws>
Subject: [Qemu-devel] [PATCHv2 1/2] char: separate device and system fd handlers
Date: Thu, 4 Nov 2010 20:06:33 +0200 [thread overview]
Message-ID: <c2325ff14d996bc98318a94636c569e165fc1971.1288892773.git.mst@redhat.com> (raw)
In-Reply-To: <20101104180406.GA2820@redhat.com>
Create separate lists for system and device fd handlers.
Device handlers will not run while vm is stopped.
By default all fds are assumed system so they will
keep running as before.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
qemu-char.h | 6 +++-
qemu-kvm.c | 2 +-
qemu-tool.c | 10 +++++
vl.c | 117 ++++++++++++++++++++++++++++++++++++++---------------------
4 files changed, 92 insertions(+), 43 deletions(-)
diff --git a/qemu-char.h b/qemu-char.h
index 18ad12b..ad09f56 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -101,7 +101,11 @@ CharDriverState *qemu_chr_open_eventfd(int eventfd);
extern int term_escape_char;
/* async I/O support */
-
+int qemu_set_fd_handler3(bool device, int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque);
int qemu_set_fd_handler2(int fd,
IOCanReadHandler *fd_read_poll,
IOHandler *fd_read,
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 625f286..56924a9 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1621,7 +1621,7 @@ int kvm_main_loop(void)
fcntl(sigfd, F_SETFL, O_NONBLOCK);
- qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+ qemu_set_fd_handler3(true, sigfd, NULL, sigfd_handler, NULL,
(void *)(unsigned long) sigfd);
pthread_cond_broadcast(&qemu_system_cond);
diff --git a/qemu-tool.c b/qemu-tool.c
index b39af86..99d5938 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -111,6 +111,16 @@ int qemu_set_fd_handler2(int fd,
return 0;
}
+int qemu_set_fd_handler3(bool device,
+ int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque)
+{
+ return 0;
+}
+
int64_t qemu_get_clock(QEMUClock *clock)
{
qemu_timeval tv;
diff --git a/vl.c b/vl.c
index 42617c2..9e9e2a1 100644
--- a/vl.c
+++ b/vl.c
@@ -958,34 +958,39 @@ typedef struct IOHandlerRecord {
QLIST_ENTRY(IOHandlerRecord) next;
} IOHandlerRecord;
-static QLIST_HEAD(, IOHandlerRecord) io_handlers =
- QLIST_HEAD_INITIALIZER(io_handlers);
+typedef QLIST_HEAD(, IOHandlerRecord) IOHandlerRecordList;
+static IOHandlerRecordList device_io_handlers =
+ QLIST_HEAD_INITIALIZER(device_io_handlers);
+static IOHandlerRecordList system_io_handlers =
+ QLIST_HEAD_INITIALIZER(system_io_handlers);
-/* XXX: fd_read_poll should be suppressed, but an API change is
- necessary in the character devices to suppress fd_can_read(). */
-int qemu_set_fd_handler2(int fd,
+int qemu_set_fd_handler3(bool device,
+ int fd,
IOCanReadHandler *fd_read_poll,
IOHandler *fd_read,
IOHandler *fd_write,
void *opaque)
{
+ IOHandlerRecordList *list;
IOHandlerRecord *ioh;
+ list = device ? &device_io_handlers: &system_io_handlers;
+
if (!fd_read && !fd_write) {
- QLIST_FOREACH(ioh, &io_handlers, next) {
+ QLIST_FOREACH(ioh, list, next) {
if (ioh->fd == fd) {
ioh->deleted = 1;
break;
}
}
} else {
- QLIST_FOREACH(ioh, &io_handlers, next) {
+ QLIST_FOREACH(ioh, list, next) {
if (ioh->fd == fd)
goto found;
}
ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- QLIST_INSERT_HEAD(&io_handlers, ioh, next);
+ QLIST_INSERT_HEAD(list, ioh, next);
found:
ioh->fd = fd;
ioh->fd_read_poll = fd_read_poll;
@@ -998,6 +1003,19 @@ int qemu_set_fd_handler2(int fd,
return 0;
}
+
+/* XXX: fd_read_poll should be suppressed, but an API change is
+ necessary in the character devices to suppress fd_can_read(). */
+int qemu_set_fd_handler2(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque)
+{
+ return qemu_set_fd_handler3(false, fd, fd_read_poll, fd_read, fd_write,
+ opaque);
+}
+
int qemu_set_fd_handler(int fd,
IOHandler *fd_read,
IOHandler *fd_write,
@@ -1242,9 +1260,52 @@ void qemu_system_powerdown_request(void)
qemu_notify_event();
}
-void main_loop_wait(int nonblocking)
+static inline int get_ioh_fds(IOHandlerRecordList *list,
+ int nfds, fd_set *rfds, fd_set *wfds)
{
IOHandlerRecord *ioh;
+ QLIST_FOREACH(ioh, list, next) {
+ if (ioh->deleted)
+ continue;
+ if (ioh->fd_read &&
+ (!ioh->fd_read_poll ||
+ ioh->fd_read_poll(ioh->opaque) != 0)) {
+ FD_SET(ioh->fd, rfds);
+ if (ioh->fd > nfds)
+ nfds = ioh->fd;
+ }
+ if (ioh->fd_write) {
+ FD_SET(ioh->fd, wfds);
+ if (ioh->fd > nfds)
+ nfds = ioh->fd;
+ }
+ }
+ return nfds;
+}
+
+static inline void call_ioh_fds(IOHandlerRecordList *list,
+ fd_set *rfds, fd_set *wfds)
+{
+ IOHandlerRecord *ioh, *pioh;
+
+ QLIST_FOREACH_SAFE(ioh, list, next, pioh) {
+ if (ioh->deleted) {
+ QLIST_REMOVE(ioh, next);
+ qemu_free(ioh);
+ continue;
+ }
+ if (ioh->fd_read && FD_ISSET(ioh->fd, rfds)) {
+ ioh->fd_read(ioh->opaque);
+ if (!(ioh->fd_read_poll && ioh->fd_read_poll(ioh->opaque)))
+ FD_CLR(ioh->fd, rfds);
+ }
+ if (ioh->fd_write && FD_ISSET(ioh->fd, wfds)) {
+ ioh->fd_write(ioh->opaque);
+ }
+ }
+}
+void main_loop_wait(int nonblocking)
+{
fd_set rfds, wfds, xfds;
int ret, nfds;
struct timeval tv;
@@ -1260,26 +1321,13 @@ void main_loop_wait(int nonblocking)
os_host_main_loop_wait(&timeout);
/* poll any events */
- /* XXX: separate device handlers from system ones */
nfds = -1;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
- QLIST_FOREACH(ioh, &io_handlers, next) {
- if (ioh->deleted)
- continue;
- if (ioh->fd_read &&
- (!ioh->fd_read_poll ||
- ioh->fd_read_poll(ioh->opaque) != 0)) {
- FD_SET(ioh->fd, &rfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
- if (ioh->fd_write) {
- FD_SET(ioh->fd, &wfds);
- if (ioh->fd > nfds)
- nfds = ioh->fd;
- }
+ nfds = get_ioh_fds(&system_io_handlers, nfds, &rfds, &wfds);
+ if (vm_running) {
+ nfds = get_ioh_fds(&device_io_handlers, nfds, &rfds, &wfds);
}
tv.tv_sec = timeout / 1000;
@@ -1291,22 +1339,9 @@ void main_loop_wait(int nonblocking)
ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
qemu_mutex_lock_iothread();
if (ret > 0) {
- IOHandlerRecord *pioh;
-
- QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
- if (ioh->deleted) {
- QLIST_REMOVE(ioh, next);
- qemu_free(ioh);
- continue;
- }
- if (ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
- ioh->fd_read(ioh->opaque);
- if (!(ioh->fd_read_poll && ioh->fd_read_poll(ioh->opaque)))
- FD_CLR(ioh->fd, &rfds);
- }
- if (ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
- ioh->fd_write(ioh->opaque);
- }
+ call_ioh_fds(&system_io_handlers, &rfds, &wfds);
+ if (vm_running) {
+ call_ioh_fds(&device_io_handlers, &rfds, &wfds);
}
}
--
1.7.3.2.91.g446ac
next prev parent reply other threads:[~2010-11-04 18:06 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-04 18:04 [Qemu-devel] [PATCHv2 0/2] migration: stop dma while VM is stopped Michael S. Tsirkin
2010-11-04 18:06 ` Michael S. Tsirkin [this message]
2010-11-16 10:24 ` [Qemu-devel] Re: [PATCHv2 1/2] char: separate device and system fd handlers Juan Quintela
2010-11-04 18:06 ` [Qemu-devel] [PATCHv2 2/2] tap: mark fd handler as device Michael S. Tsirkin
2010-11-15 14:52 ` [Qemu-devel] " Juan Quintela
2010-11-15 14:55 ` Anthony Liguori
2010-11-15 15:18 ` Michael S. Tsirkin
2010-11-15 16:09 ` Anthony Liguori
2010-11-15 20:26 ` Michael S. Tsirkin
2010-11-15 20:37 ` Anthony Liguori
2010-11-15 20:53 ` Stefan Hajnoczi
2010-11-15 21:05 ` Anthony Liguori
2010-11-15 22:44 ` Michael S. Tsirkin
2010-11-15 23:46 ` Anthony Liguori
2010-11-15 15:21 ` Michael S. Tsirkin
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=c2325ff14d996bc98318a94636c569e165fc1971.1288892773.git.mst@redhat.com \
--to=mst@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).