Message ID | 1361451293-5181-6-git-send-email-qemulist@gmail.com |
---|---|
State | New |
Headers | show |
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 > >
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,