Re: epoll_wait returning EFAULT on Linux 3.2.78 - Mailing list pgsql-hackers

From Andres Freund
Subject Re: epoll_wait returning EFAULT on Linux 3.2.78
Date
Msg-id 20160602173515.jsjj3m4quv75yszl@alap3.anarazel.de
Whole thread Raw
In response to Re: epoll_wait returning EFAULT on Linux 3.2.78  (Greg Stark <stark@mit.edu>)
Responses Re: epoll_wait returning EFAULT on Linux 3.2.78  (Greg Stark <stark@mit.edu>)
List 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



pgsql-hackers by date:

Previous
From: Andres Freund
Date:
Subject: Re: epoll_wait returning EFAULT on Linux 3.2.78
Next
From: Greg Stark
Date:
Subject: Re: epoll_wait returning EFAULT on Linux 3.2.78