Patchwork [5/9] event poll: enable event poll handle more than one event each time

login
register
mail settings
Submitter pingfan liu
Date Feb. 21, 2013, 12:54 p.m.
Message ID <1361451293-5181-6-git-send-email-qemulist@gmail.com>
Download mbox | patch
Permalink /patch/222280/
State New
Headers show

Comments

pingfan liu - Feb. 21, 2013, 12:54 p.m.
From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>

Set handled event count at initialized time for the dedicated
thread.

Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
 hw/dataplane/event-poll.c |   31 ++++++++++++++-----------------
 hw/dataplane/event-poll.h |    4 +++-
 hw/dataplane/virtio-blk.c |    2 +-
 3 files changed, 18 insertions(+), 19 deletions(-)
Michael Roth - Feb. 21, 2013, 8:24 p.m.
On Thu, Feb 21, 2013 at 08:54:49PM +0800, Liu Ping Fan wrote:
> From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> 
> Set handled event count at initialized time for the dedicated
> thread.
> 
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
>  hw/dataplane/event-poll.c |   31 ++++++++++++++-----------------
>  hw/dataplane/event-poll.h |    4 +++-
>  hw/dataplane/virtio-blk.c |    2 +-
>  3 files changed, 18 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/dataplane/event-poll.c b/hw/dataplane/event-poll.c
> index e19f3f3..3009787 100644
> --- a/hw/dataplane/event-poll.c
> +++ b/hw/dataplane/event-poll.c
> @@ -25,6 +25,7 @@ void event_poll_add(EventPoll *poll, EventHandler *handler,
>      };
>      handler->notifier = notifier;
>      handler->callback = callback;
> +
>      if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD,
>                    event_notifier_get_fd(notifier), &event) != 0) {
>          fprintf(stderr, "failed to add event handler to epoll: %m\n");
> @@ -74,7 +75,7 @@ static void handle_stop(EventHandler *handler, uint32_t events)
>      /* Do nothing */
>  }
> 
> -void event_poll_init(EventPoll *poll)
> +void event_poll_init(EventPoll *poll, int num)
>  {
>      /* Create epoll file descriptor */
>      poll->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
> @@ -83,6 +84,8 @@ void event_poll_init(EventPoll *poll)
>          exit(1);
>      }
> 
> +    poll->num = num + 1;
> +    poll->events = (struct epoll_event *)g_malloc(poll->num * sizeof(struct epoll_event));
>      /* Set up stop notifier */
>      if (event_notifier_init(&poll->stop_notifier, 0) < 0) {
>          fprintf(stderr, "failed to init stop notifier\n");
> @@ -103,27 +106,21 @@ void event_poll_cleanup(EventPoll *poll)
>  void event_poll(EventPoll *poll)
>  {
>      EventHandler *handler;
> -    struct epoll_event event;
> -    int nevents;
> +    struct epoll_event *events;
> +    int nevents, i;
> 
> -    /* Wait for the next event.  Only do one event per call to keep the
> -     * function simple, this could be changed later. */
> +    events = poll->events;
>      do {
> -        nevents = epoll_wait(poll->epoll_fd, &event, 1, -1);
> +        nevents = epoll_wait(poll->epoll_fd, events, poll->num, -1);
>      } while (nevents < 0 && errno == EINTR);
> -    if (unlikely(nevents != 1)) {
> -        fprintf(stderr, "epoll_wait failed: %m\n");
> -        exit(1); /* should never happen */
> -    }
> 
> -    /* Find out which event handler has become active */
> -    handler = event.data.ptr;
> +    for (i = 0; i < nevents; i++) {
> +        /* Find out which event handler has become active */
> +        handler = events[i].data.ptr;
> 
> -    /* Clear the eventfd */
> -    event_notifier_test_and_clear(handler->notifier);
> -
> -    /* Handle the event */
> -    handler->callback(handler, event.events);
> +        /* Handle the event */
> +        handler->callback(handler, events[i].events);
> +    }

I see where it's needed for vnet dataplane, but removing the test and
clear might cause problems for vblock dataplane. Perhaps we could add
a flag during notifier registration to control the behavior? Not sure
if the AioContext stuff has this already.

>  }
> 
>  /* Stop event_poll()
> diff --git a/hw/dataplane/event-poll.h b/hw/dataplane/event-poll.h
> index ff9712b..f08884b 100644
> --- a/hw/dataplane/event-poll.h
> +++ b/hw/dataplane/event-poll.h
> @@ -30,6 +30,8 @@ typedef struct {
>      int epoll_fd;                   /* epoll(2) file descriptor */
>      EventNotifier stop_notifier;    /* stop poll notifier */
>      EventHandler stop_handler;      /* stop poll handler */
> +    int num;
> +    struct epoll_event *events;
>  } EventPoll;
> 
>  void event_poll_add(EventPoll *poll, EventHandler *handler,
> @@ -40,7 +42,7 @@ void event_poll_del_fd(EventPoll *poll, int fd);
>  void event_poll_modify_fd(EventPoll *poll, int fd, uint32_t type,
>                      EventHandler *handler);
> 
> -void event_poll_init(EventPoll *poll);
> +void event_poll_init(EventPoll *poll, int num);
>  void event_poll_cleanup(EventPoll *poll);
>  void event_poll(EventPoll *poll);
>  void event_poll_notify(EventPoll *poll);
> diff --git a/hw/dataplane/virtio-blk.c b/hw/dataplane/virtio-blk.c
> index b60211a..c6a43d8 100644
> --- a/hw/dataplane/virtio-blk.c
> +++ b/hw/dataplane/virtio-blk.c
> @@ -395,7 +395,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
>          return;
>      }
> 
> -    event_poll_init(&s->event_poll);
> +    event_poll_init(&s->event_poll, 2);
> 
>      /* Set up guest notifier (irq) */
>      if (s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque,
> -- 
> 1.7.4.4
> 
>

Patch

diff --git a/hw/dataplane/event-poll.c b/hw/dataplane/event-poll.c
index e19f3f3..3009787 100644
--- a/hw/dataplane/event-poll.c
+++ b/hw/dataplane/event-poll.c
@@ -25,6 +25,7 @@  void event_poll_add(EventPoll *poll, EventHandler *handler,
     };
     handler->notifier = notifier;
     handler->callback = callback;
+
     if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD,
                   event_notifier_get_fd(notifier), &event) != 0) {
         fprintf(stderr, "failed to add event handler to epoll: %m\n");
@@ -74,7 +75,7 @@  static void handle_stop(EventHandler *handler, uint32_t events)
     /* Do nothing */
 }
 
-void event_poll_init(EventPoll *poll)
+void event_poll_init(EventPoll *poll, int num)
 {
     /* Create epoll file descriptor */
     poll->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
@@ -83,6 +84,8 @@  void event_poll_init(EventPoll *poll)
         exit(1);
     }
 
+    poll->num = num + 1;
+    poll->events = (struct epoll_event *)g_malloc(poll->num * sizeof(struct epoll_event));
     /* Set up stop notifier */
     if (event_notifier_init(&poll->stop_notifier, 0) < 0) {
         fprintf(stderr, "failed to init stop notifier\n");
@@ -103,27 +106,21 @@  void event_poll_cleanup(EventPoll *poll)
 void event_poll(EventPoll *poll)
 {
     EventHandler *handler;
-    struct epoll_event event;
-    int nevents;
+    struct epoll_event *events;
+    int nevents, i;
 
-    /* Wait for the next event.  Only do one event per call to keep the
-     * function simple, this could be changed later. */
+    events = poll->events;
     do {
-        nevents = epoll_wait(poll->epoll_fd, &event, 1, -1);
+        nevents = epoll_wait(poll->epoll_fd, events, poll->num, -1);
     } while (nevents < 0 && errno == EINTR);
-    if (unlikely(nevents != 1)) {
-        fprintf(stderr, "epoll_wait failed: %m\n");
-        exit(1); /* should never happen */
-    }
 
-    /* Find out which event handler has become active */
-    handler = event.data.ptr;
+    for (i = 0; i < nevents; i++) {
+        /* Find out which event handler has become active */
+        handler = events[i].data.ptr;
 
-    /* Clear the eventfd */
-    event_notifier_test_and_clear(handler->notifier);
-
-    /* Handle the event */
-    handler->callback(handler, event.events);
+        /* Handle the event */
+        handler->callback(handler, events[i].events);
+    }
 }
 
 /* Stop event_poll()
diff --git a/hw/dataplane/event-poll.h b/hw/dataplane/event-poll.h
index ff9712b..f08884b 100644
--- a/hw/dataplane/event-poll.h
+++ b/hw/dataplane/event-poll.h
@@ -30,6 +30,8 @@  typedef struct {
     int epoll_fd;                   /* epoll(2) file descriptor */
     EventNotifier stop_notifier;    /* stop poll notifier */
     EventHandler stop_handler;      /* stop poll handler */
+    int num;
+    struct epoll_event *events;
 } EventPoll;
 
 void event_poll_add(EventPoll *poll, EventHandler *handler,
@@ -40,7 +42,7 @@  void event_poll_del_fd(EventPoll *poll, int fd);
 void event_poll_modify_fd(EventPoll *poll, int fd, uint32_t type,
                     EventHandler *handler);
 
-void event_poll_init(EventPoll *poll);
+void event_poll_init(EventPoll *poll, int num);
 void event_poll_cleanup(EventPoll *poll);
 void event_poll(EventPoll *poll);
 void event_poll_notify(EventPoll *poll);
diff --git a/hw/dataplane/virtio-blk.c b/hw/dataplane/virtio-blk.c
index b60211a..c6a43d8 100644
--- a/hw/dataplane/virtio-blk.c
+++ b/hw/dataplane/virtio-blk.c
@@ -395,7 +395,7 @@  void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
         return;
     }
 
-    event_poll_init(&s->event_poll);
+    event_poll_init(&s->event_poll, 2);
 
     /* Set up guest notifier (irq) */
     if (s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque,