[lttng-dev] [PATCH urcu v2] Fix: don't use overlapping mmap mappings on Cygwin
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Tue Nov 7 22:10:35 UTC 2017
Merged into master, 0.10, 0.9, 0.8, thanks!
Mathieu
----- On Jul 28, 2017, at 11:51 AM, Michael Jeanson mjeanson at efficios.com wrote:
> The allocation scheme used by the mmap based RCU hash table is to make a
> large unaccessible mapping to reserve memory without allocating it.
> Then smaller chunks are allocated by overlapping read/write mappings which
> do allocate memory. Deallocation is done by an overlapping unaccessible
> mapping.
>
> This scheme was tested on Linux, macOS and Solaris. However, on Cygwin the
> mmap wrapper is based on the Windows NtMapViewOfSection API which doesn't
> support overlapping mappings.
>
> An alternative to the overlapping mappings is to use mprotect to change the
> protection on chunks of the large mapping, read/write to allocate and none
> to deallocate. This works perfecty on Cygwin and Solaris but on Linux a
> call to madvise is also required to deallocate and it just doesn't work on
> macOS.
>
> For this reason, we keep to original scheme on all platforms except Cygwin.
>
> Signed-off-by: Michael Jeanson <mjeanson at efficios.com>
> ---
> src/rculfhash-mm-mmap.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 56 insertions(+), 5 deletions(-)
>
> diff --git a/src/rculfhash-mm-mmap.c b/src/rculfhash-mm-mmap.c
> index 3cc3fa0..a8fadf0 100644
> --- a/src/rculfhash-mm-mmap.c
> +++ b/src/rculfhash-mm-mmap.c
> @@ -28,8 +28,30 @@
> #define MAP_ANONYMOUS MAP_ANON
> #endif
>
> -/* reserve inaccessible memory space without allocation any memory */
> -static void *memory_map(size_t length)
> +/*
> + * The allocation scheme used by the mmap based RCU hash table is to make a
> + * large unaccessible mapping to reserve memory without allocating it.
> + * Then smaller chunks are allocated by overlapping read/write mappings which
> + * do allocate memory. Deallocation is done by an overlapping unaccessible
> + * mapping.
> + *
> + * This scheme was tested on Linux, macOS and Solaris. However, on Cygwin the
> + * mmap wrapper is based on the Windows NtMapViewOfSection API which doesn't
> + * support overlapping mappings.
> + *
> + * An alternative to the overlapping mappings is to use mprotect to change the
> + * protection on chunks of the large mapping, read/write to allocate and none
> + * to deallocate. This works perfecty on Cygwin and Solaris but on Linux a
> + * call to madvise is also required to deallocate and it just doesn't work on
> + * macOS.
> + *
> + * For this reason, we keep to original scheme on all platforms except Cygwin.
> + */
> +
> +
> +/* Reserve inaccessible memory space without allocating it */
> +static
> +void *memory_map(size_t length)
> {
> void *ret = mmap(NULL, length, PROT_NONE,
> MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> @@ -38,7 +60,8 @@ static void *memory_map(size_t length)
> return ret;
> }
>
> -static void memory_unmap(void *ptr, size_t length)
> +static
> +void memory_unmap(void *ptr, size_t length)
> {
> int ret __attribute__((unused));
>
> @@ -47,7 +70,33 @@ static void memory_unmap(void *ptr, size_t length)
> assert(ret == 0);
> }
>
> -static void memory_populate(void *ptr, size_t length)
> +#ifdef __CYGWIN__
> +/* Set protection to read/write to allocate a memory chunk */
> +static
> +void memory_populate(void *ptr, size_t length)
> +{
> + int ret __attribute__((unused));
> +
> + ret = mprotect(ptr, length, PROT_READ | PROT_WRITE);
> +
> + assert(!ret);
> +}
> +
> +/* Set protection to none to deallocate a memory chunk */
> +static
> +void memory_discard(void *ptr, size_t length)
> +{
> + int ret __attribute__((unused));
> +
> + ret = mprotect(ptr, length, PROT_NONE);
> +
> + assert(!ret);
> +}
> +
> +#else /* __CYGWIN__ */
> +
> +static
> +void memory_populate(void *ptr, size_t length)
> {
> void *ret __attribute__((unused));
>
> @@ -61,7 +110,8 @@ static void memory_populate(void *ptr, size_t length)
> * Discard garbage memory and avoid system save it when try to swap it out.
> * Make it still reserved, inaccessible.
> */
> -static void memory_discard(void *ptr, size_t length)
> +static
> +void memory_discard(void *ptr, size_t length)
> {
> void *ret __attribute__((unused));
>
> @@ -70,6 +120,7 @@ static void memory_discard(void *ptr, size_t length)
>
> assert(ret == ptr);
> }
> +#endif /* __CYGWIN__ */
>
> static
> void cds_lfht_alloc_bucket_table(struct cds_lfht *ht, unsigned long order)
> --
> 2.7.4
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list