Re: epoll_wait returning EFAULT on Linux 3.2.78

From: Andres Freund <andres(at)anarazel(dot)de>
To: Greg Stark <stark(at)mit(dot)edu>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: epoll_wait returning EFAULT on Linux 3.2.78
Date: 2016-06-02 17:35:15
Message-ID: 20160602173515.jsjj3m4quv75yszl@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2016-06-02 18:15:54 +0100, Greg Stark wrote:
> I just threw maxalign everywhere but I was going to comment that we
> might need to put a double in for the subsequent struct elements to
> end up aligned as well.

Hm. Shouldn't be needed if you MAXALIGN the sz computation, because
that'll mean each struct will start at the proper offset.

> But I guess that's not true due to the u64
> element. I'm not sure I've completely grokked all the bits and pieces
> here so I may have added a few too many maxaligns. I put them on all
> the size and offset calculations before the multiplications.

They should be *after* the multiplications. If arrays of structs are
internally misaligned there's nothing we can do.

> diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
> index 3fbe0e5..5e69a5a 100644
> --- a/src/backend/storage/ipc/latch.c
> +++ b/src/backend/storage/ipc/latch.c
> @@ -485,35 +485,35 @@ CreateWaitEventSet(MemoryContext context, int nevents)
> char *data;
> Size sz = 0;
>
> - sz += sizeof(WaitEventSet);
> - sz += sizeof(WaitEvent) * nevents;
> + sz += MAXALIGN(sizeof(WaitEventSet));
> + sz += MAXALIGN(sizeof(WaitEvent)) * nevents;
>
> #if defined(WAIT_USE_EPOLL)
> - sz += sizeof(struct epoll_event) * nevents;
> + sz += MAXALIGN(sizeof(struct epoll_event)) * nevents;

So this needs to include the '* nevents' inside the MAXALIGN.

> #elif defined(WAIT_USE_POLL)
> - sz += sizeof(struct pollfd) * nevents;
> + sz += MAXALIGN(sizeof(struct pollfd)) * nevents;

Same.

> #elif defined(WAIT_USE_WIN32)
> /* need space for the pgwin32_signal_event */
> - sz += sizeof(HANDLE) * (nevents + 1);
> + sz += MAXALIGN(sizeof(HANDLE)) * (nevents + 1);
> #endif

same.

>
> #if defined(WAIT_USE_EPOLL)
> set->epoll_ret_events = (struct epoll_event *) data;
> - data += sizeof(struct epoll_event) * nevents;
> + data += MAXALIGN(sizeof(struct epoll_event)) * nevents;
> #elif defined(WAIT_USE_POLL)
> set->pollfds = (struct pollfd *) data;
> - data += sizeof(struct pollfd) * nevents;
> + data += MAXALIGN(sizeof(struct pollfd)) * nevents;
> #elif defined(WAIT_USE_WIN32)
> set->handles = (HANDLE) data;
> - data += sizeof(HANDLE) * nevents;
> + data += MAXALIGN(sizeof(HANDLE)) * nevents;
> #endif

same.

Want me to polish that up and push, or do you want to go back and forth
and push yourself?

Greetings,

Andres Freund

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Greg Stark 2016-06-02 17:41:00 Re: epoll_wait returning EFAULT on Linux 3.2.78
Previous Message Andres Freund 2016-06-02 17:26:24 Re: epoll_wait returning EFAULT on Linux 3.2.78