[ovs-dev] [bug14616 2/5] worker: Do not use poll_block() in worker_send_iovec().
Ben Pfaff
blp at nicira.com
Fri Jan 11 04:24:58 UTC 2013
Thanks, I pushed these first two patches to master and branch-1.9.
On Thu, Jan 10, 2013 at 05:31:17PM -0800, Ethan Jackson wrote:
> Acked-by: Ethan Jackson <ethan at nicira.com>
>
>
> On Thu, Jan 10, 2013 at 5:23 PM, Ben Pfaff <blp at nicira.com> wrote:
>
> > The following call stack was possible:
> >
> > poll_block()
> > -> vlog
> > -> worker_send_iovec()
> > -> poll_block()
> >
> > which caused corruption because poll_block() is not reentrant.
> >
> > Bug #14616.
> > Signed-off-by: Ben Pfaff <blp at nicira.com>
> > ---
> > lib/worker.c | 20 +++++++++++++++++---
> > 1 files changed, 17 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/worker.c b/lib/worker.c
> > index f2b896e..b281d70 100644
> > --- a/lib/worker.c
> > +++ b/lib/worker.c
> > @@ -1,4 +1,4 @@
> > -/* Copyright (c) 2012 Nicira, Inc.
> > +/* Copyright (c) 2012, 2013 Nicira, Inc.
> > *
> > * Licensed under the Apache License, Version 2.0 (the "License");
> > * you may not use this file except in compliance with the License.
> > @@ -198,6 +198,7 @@ worker_send_iovec(const struct iovec iovs[], size_t
> > n_iovs,
> > size_t sent = 0;
> >
> > for (;;) {
> > + struct pollfd pfd;
> > int error;
> >
> > /* Try to send the rest of the request. */
> > @@ -210,8 +211,21 @@ worker_send_iovec(const struct iovec iovs[], size_t
> > n_iovs,
> > /* Process replies to avoid deadlock. */
> > worker_run();
> >
> > - poll_fd_wait(client_sock, POLLIN | POLLOUT);
> > - poll_block();
> > + /* Wait for 'client_sock' to become ready before trying again. We
> > + * can't use poll_block() because it sometimes calls into vlog,
> > which
> > + * calls indirectly into worker_send_iovec(). To be usable here,
> > + * poll_block() would therefore need to be reentrant, but it isn't
> > + * (calling it recursively causes memory corruption and an
> > eventual
> > + * crash). */
> > + pfd.fd = client_sock;
> > + pfd.events = POLLIN | POLLOUT;
> > + do {
> > + error = poll(&pfd, 1, -1) < 0 ? errno : 0;
> > + } while (error == EINTR);
> > + if (error) {
> > + worker_broke();
> > + VLOG_ABORT("poll failed (%s)", strerror(error));
> > + }
> > }
> > }
> >
> > --
> > 1.7.2.5
> >
> > _______________________________________________
> > dev mailing list
> > dev at openvswitch.org
> > http://openvswitch.org/mailman/listinfo/dev
> >
More information about the dev
mailing list