Patchwork [3/9] event poll: make epoll work for normal fd

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

Comments

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

When event poll can work with normal fd, we can port them
onto the event loop.

Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
 hw/dataplane/event-poll.c |   36 ++++++++++++++++++++++++++++++++++++
 hw/dataplane/event-poll.h |    8 ++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)
Paolo Bonzini - Feb. 21, 2013, 1:24 p.m.
Il 21/02/2013 13:54, Liu Ping Fan ha scritto:
> From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> 
> When event poll can work with normal fd, we can port them
> onto the event loop.

Please start transitioning to the AioContext API instead.  I doubt there
is any performance difference for 2-3 file descriptors between poll and
epoll, but if there were any we can introduce aio-linux.c that uses epoll.

I'll send later a patch to use AioContext instead of EventPoll for
virtio-blk dataplane.

Paolo

> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
>  hw/dataplane/event-poll.c |   36 ++++++++++++++++++++++++++++++++++++
>  hw/dataplane/event-poll.h |    8 ++++++++
>  2 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/dataplane/event-poll.c b/hw/dataplane/event-poll.c
> index 2b55c6e..b7dea53 100644
> --- a/hw/dataplane/event-poll.c
> +++ b/hw/dataplane/event-poll.c
> @@ -32,6 +32,42 @@ void event_poll_add(EventPoll *poll, EventHandler *handler,
>      }
>  }
>  
> +void event_poll_add_fd(EventPoll *poll, int fd, uint32_t type,
> +    EventHandler *handler)
> +{
> +    struct epoll_event event = {
> +        .events = type,
> +        .data.ptr = handler,
> +    };
> +
> +    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
> +        fprintf(stderr, "failed to add event fd handler to epoll: %m\n");
> +        exit(1);
> +    }
> +
> +}
> +void event_poll_del_fd(EventPoll *poll, int fd)
> +{
> +    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_DEL, fd, NULL) != 0) {
> +        fprintf(stderr, "failed to del event handler to epoll: %m\n");
> +        exit(1);
> +    }
> +}
> +
> +
> +void event_poll_modify_fd(EventPoll *poll, int fd, uint32_t type,
> +    EventHandler *handler)
> +{
> +    struct epoll_event event = {
> +        .events = type,
> +        .data.ptr = handler,
> +    };
> +    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_MOD, fd, &event) != 0) {
> +        fprintf(stderr, "failed to modify event handler to epoll: %m\n");
> +        exit(1);
> +    }
> +}
> +
>  /* Event callback for stopping event_poll() */
>  static void handle_stop(EventHandler *handler)
>  {
> diff --git a/hw/dataplane/event-poll.h b/hw/dataplane/event-poll.h
> index 3e8d3ec..606138c 100644
> --- a/hw/dataplane/event-poll.h
> +++ b/hw/dataplane/event-poll.h
> @@ -22,6 +22,8 @@ typedef void EventCallback(EventHandler *handler);
>  struct EventHandler {
>      EventNotifier *notifier;        /* eventfd */
>      EventCallback *callback;        /* callback function */
> +    void *opaque;
> +    int fd;                         /* normal fd*/
>  };
>  
>  typedef struct {
> @@ -32,6 +34,12 @@ typedef struct {
>  
>  void event_poll_add(EventPoll *poll, EventHandler *handler,
>                      EventNotifier *notifier, EventCallback *callback);
> +void event_poll_add_fd(EventPoll *poll, int fd, uint32_t type,
> +                    EventHandler *handler);
> +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_cleanup(EventPoll *poll);
>  void event_poll(EventPoll *poll);
>
Stefan Hajnoczi - Feb. 21, 2013, 3:41 p.m.
On Thu, Feb 21, 2013 at 02:24:21PM +0100, Paolo Bonzini wrote:
> Il 21/02/2013 13:54, Liu Ping Fan ha scritto:
> > From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> > 
> > When event poll can work with normal fd, we can port them
> > onto the event loop.
> 
> Please start transitioning to the AioContext API instead.  I doubt there
> is any performance difference for 2-3 file descriptors between poll and
> epoll, but if there were any we can introduce aio-linux.c that uses epoll.
> 
> I'll send later a patch to use AioContext instead of EventPoll for
> virtio-blk dataplane.

Thanks Paolo.  Although using AioContext for dataplane's event loop has
been on my TODO list I haven't written any code yet - so no duplicated
work if you have time to tackle this.

Stefan
Michael Roth - Feb. 21, 2013, 8:19 p.m.
On Thu, Feb 21, 2013 at 08:54:47PM +0800, Liu Ping Fan wrote:
> From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> 
> When event poll can work with normal fd, we can port them
> onto the event loop.
> 
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
>  hw/dataplane/event-poll.c |   36 ++++++++++++++++++++++++++++++++++++
>  hw/dataplane/event-poll.h |    8 ++++++++
>  2 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/dataplane/event-poll.c b/hw/dataplane/event-poll.c
> index 2b55c6e..b7dea53 100644
> --- a/hw/dataplane/event-poll.c
> +++ b/hw/dataplane/event-poll.c
> @@ -32,6 +32,42 @@ void event_poll_add(EventPoll *poll, EventHandler *handler,
>      }
>  }
> 
> +void event_poll_add_fd(EventPoll *poll, int fd, uint32_t type,
> +    EventHandler *handler)
> +{
> +    struct epoll_event event = {
> +        .events = type,
> +        .data.ptr = handler,
> +    };
> +
> +    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
> +        fprintf(stderr, "failed to add event fd handler to epoll: %m\n");
> +        exit(1);
> +    }
> +
> +}

An alternative to adding these interfaces would be initializing an
EventNotifier using event_notifier_init_fd() and then passing that in to
event_poll_add()

I think doing it this way would be applicable on top of Paolo's
patches to switch dataplane to using AioContext as well.

> +void event_poll_del_fd(EventPoll *poll, int fd)
> +{
> +    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_DEL, fd, NULL) != 0) {
> +        fprintf(stderr, "failed to del event handler to epoll: %m\n");
> +        exit(1);
> +    }
> +}
> +
> +
> +void event_poll_modify_fd(EventPoll *poll, int fd, uint32_t type,
> +    EventHandler *handler)
> +{
> +    struct epoll_event event = {
> +        .events = type,
> +        .data.ptr = handler,
> +    };
> +    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_MOD, fd, &event) != 0) {
> +        fprintf(stderr, "failed to modify event handler to epoll: %m\n");
> +        exit(1);
> +    }
> +}
> +
>  /* Event callback for stopping event_poll() */
>  static void handle_stop(EventHandler *handler)
>  {
> diff --git a/hw/dataplane/event-poll.h b/hw/dataplane/event-poll.h
> index 3e8d3ec..606138c 100644
> --- a/hw/dataplane/event-poll.h
> +++ b/hw/dataplane/event-poll.h
> @@ -22,6 +22,8 @@ typedef void EventCallback(EventHandler *handler);
>  struct EventHandler {
>      EventNotifier *notifier;        /* eventfd */
>      EventCallback *callback;        /* callback function */
> +    void *opaque;
> +    int fd;                         /* normal fd*/
>  };
> 
>  typedef struct {
> @@ -32,6 +34,12 @@ typedef struct {
> 
>  void event_poll_add(EventPoll *poll, EventHandler *handler,
>                      EventNotifier *notifier, EventCallback *callback);
> +void event_poll_add_fd(EventPoll *poll, int fd, uint32_t type,
> +                    EventHandler *handler);
> +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_cleanup(EventPoll *poll);
>  void event_poll(EventPoll *poll);
> -- 
> 1.7.4.4
> 
>

Patch

diff --git a/hw/dataplane/event-poll.c b/hw/dataplane/event-poll.c
index 2b55c6e..b7dea53 100644
--- a/hw/dataplane/event-poll.c
+++ b/hw/dataplane/event-poll.c
@@ -32,6 +32,42 @@  void event_poll_add(EventPoll *poll, EventHandler *handler,
     }
 }
 
+void event_poll_add_fd(EventPoll *poll, int fd, uint32_t type,
+    EventHandler *handler)
+{
+    struct epoll_event event = {
+        .events = type,
+        .data.ptr = handler,
+    };
+
+    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD, fd, &event) != 0) {
+        fprintf(stderr, "failed to add event fd handler to epoll: %m\n");
+        exit(1);
+    }
+
+}
+void event_poll_del_fd(EventPoll *poll, int fd)
+{
+    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_DEL, fd, NULL) != 0) {
+        fprintf(stderr, "failed to del event handler to epoll: %m\n");
+        exit(1);
+    }
+}
+
+
+void event_poll_modify_fd(EventPoll *poll, int fd, uint32_t type,
+    EventHandler *handler)
+{
+    struct epoll_event event = {
+        .events = type,
+        .data.ptr = handler,
+    };
+    if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_MOD, fd, &event) != 0) {
+        fprintf(stderr, "failed to modify event handler to epoll: %m\n");
+        exit(1);
+    }
+}
+
 /* Event callback for stopping event_poll() */
 static void handle_stop(EventHandler *handler)
 {
diff --git a/hw/dataplane/event-poll.h b/hw/dataplane/event-poll.h
index 3e8d3ec..606138c 100644
--- a/hw/dataplane/event-poll.h
+++ b/hw/dataplane/event-poll.h
@@ -22,6 +22,8 @@  typedef void EventCallback(EventHandler *handler);
 struct EventHandler {
     EventNotifier *notifier;        /* eventfd */
     EventCallback *callback;        /* callback function */
+    void *opaque;
+    int fd;                         /* normal fd*/
 };
 
 typedef struct {
@@ -32,6 +34,12 @@  typedef struct {
 
 void event_poll_add(EventPoll *poll, EventHandler *handler,
                     EventNotifier *notifier, EventCallback *callback);
+void event_poll_add_fd(EventPoll *poll, int fd, uint32_t type,
+                    EventHandler *handler);
+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_cleanup(EventPoll *poll);
 void event_poll(EventPoll *poll);