]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
MAP_FIXED didn't actually work the way I thought (should have looked the man
authorTimo Sirainen <tss@iki.fi>
Sun, 19 Oct 2003 20:15:15 +0000 (23:15 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 19 Oct 2003 20:15:15 +0000 (23:15 +0300)
page more carefully..). Dropped that and now we'll always just memcpy() the
data when we want to grow a mmaping.

--HG--
branch : HEAD

src/lib/mmap-anon.c

index 940b85fbf82a8aedba9535c60e324cd04d4c55fb..0211d1b04afecab83b08c9e862fa31e4f06a2ff1 100644 (file)
 #include <stdlib.h>
 #include <sys/mman.h>
 
-/* MMAP_BASE_MOVE may be set to negative as well */
-#if SSIZE_T_MAX > 2147483647L
-   /* 64bit or more */
-#  define MMAP_BASE_MOVE (1024ULL*1024ULL*1024ULL*128ULL) /* 128GB */
-#else
-   /* 32bit most likely */
-#  define MMAP_BASE_MOVE (1024UL*1024UL*128UL) /* 128M */
-#endif
-
 #define MMAP_SIGNATURE 0xdeadbeef
 
 #define PAGE_ALIGN(size) \
        (((size) + (size_t)page_size-1) & ~(size_t)(page_size-1))
 
-struct movable_header {
+struct anon_header {
        unsigned int signature;
        size_t size;
 };
 
 static int page_size = 0;
 static int header_size = 0;
-static void *movable_mmap_base = NULL;
-static void *mmap_top_limit, *mmap_heap_bottom, *mmap_heap_top;
 static int zero_fd = -1;
 
 static void movable_mmap_init(void)
 {
-       ssize_t abs_base_move;
-       char x;
-
 #if MAP_ANONYMOUS == 0
        /* mmap()ing /dev/zero should be the same with some platforms */
        zero_fd = open("/dev/zero", O_RDWR);
        if (zero_fd == -1)
-               i_fatal("Can't open /dev/zero for creating anonymous mmap");
+               i_fatal("Can't open /dev/zero for creating anonymous mmap: %m");
        fd_close_on_exec(zero_fd, TRUE);
 #endif
 
-       abs_base_move = MMAP_BASE_MOVE;
-       if (abs_base_move < 0)
-                abs_base_move = -abs_base_move;
-
        page_size = getpagesize();
        header_size = page_size;
-
-       /* keep our allocations far below stack. assumes the stack is
-          growing down. */
-       mmap_top_limit = &x - abs_base_move*2;
-
-       /* keep our allocations far from heap */
-       mmap_heap_bottom = malloc(1);
-       mmap_heap_top = (char *) mmap_heap_bottom + abs_base_move*2;
-       free(mmap_heap_bottom);
-}
-
-static int anon_mmap_fixed(void *address, size_t length)
-{
-       void *base;
-
-       i_assert(address != NULL);
-
-       base = mmap(address, length, PROT_READ | PROT_WRITE,
-                   MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, zero_fd, 0);
-
-       if (base != MAP_FAILED && base != address) {
-               /* shouldn't happen with MAP_FIXED, but who knows.. */
-               if (munmap(base, length) < 0)
-                       i_panic("munmap() failed: %m");
-               base = MAP_FAILED;
-               errno = EINVAL;
-       }
-
-       return base == MAP_FAILED ? -1 : 0;
 }
 
 void *mmap_anon(size_t length)
 {
-       struct movable_header *hdr;
-       void *next_mmap_base, *base;
-       ssize_t offset;
-       unsigned int count;
-       int ret;
+       struct anon_header *hdr;
+       void *base;
 
        if (header_size == 0)
                movable_mmap_init();
@@ -112,101 +62,20 @@ void *mmap_anon(size_t length)
           the full mmap. also allocate only page-aligned mmap sizes. */
        length = PAGE_ALIGN(length + header_size);
 
-       if (movable_mmap_base == NULL) {
-               /* this is fully guessing */
-               movable_mmap_base = (char *) NULL +
-                       PAGE_ALIGN((size_t)((char *)mmap_anon - (char *)NULL));
-       }
-
-       offset = MMAP_BASE_MOVE; count = 0;
-       for (;;) {
-               next_mmap_base = (char *) movable_mmap_base + offset;
-               if ((char *) next_mmap_base < (char *) movable_mmap_base) {
-                       /* we're wrapping, fix the offset a bit so we won't
-                          just loop with same addresses.. */
-                       offset /= 2;
-                       if (offset/10 < page_size) {
-                               /* enough tries */
-                               errno = ENOMEM;
-                               return MAP_FAILED;
-                       }
-               }
-
-               movable_mmap_base = next_mmap_base;
-
-               if ((char *) movable_mmap_base >
-                   (char *) movable_mmap_base + length) {
-                       /* too high, would wrap */
-                       continue;
-               }
-
-               if ((char *) movable_mmap_base + length >=
-                   (char *) mmap_top_limit) {
-                       /* too high, stack could grow over it */
-                       continue;
-               }
-
-               if ((char *) movable_mmap_base >= (char *) mmap_heap_bottom &&
-                   (char *) movable_mmap_base < (char *) mmap_heap_top) {
-                       /* too near heap */
-                       continue;
-               }
-
-               if (movable_mmap_base == NULL)
-                       continue;
-
-               ret = anon_mmap_fixed(movable_mmap_base, length);
-               if (ret == 0)
-                       break;
-
-               if (errno != EINVAL && errno != ENOMEM)
-                       return MAP_FAILED;
-
-               if (++count == 100) {
-                       /* enough tries, try non-fixed mmap() */
-                       base = mmap(NULL, length, PROT_READ | PROT_WRITE,
-                                   MAP_ANONYMOUS | MAP_PRIVATE, zero_fd, 0);
-                       if (base == MAP_FAILED)
-                               return MAP_FAILED;
-
-                       movable_mmap_base = base;
-                       break;
-               }
-       }
+       base = mmap(NULL, length, PROT_READ | PROT_WRITE,
+                   MAP_ANONYMOUS | MAP_PRIVATE, zero_fd, 0);
+       if (base == MAP_FAILED)
+               return MAP_FAILED;
 
        /* initialize the header */
-       hdr = movable_mmap_base;
+       hdr = base;
        hdr->signature = MMAP_SIGNATURE;
        hdr->size = length - header_size;
 
        return (char *) hdr + header_size;
 }
 
-static int mremap_try_grow(struct movable_header *hdr, size_t new_size)
-{
-       void *grow_base;
-
-       grow_base = (char *) hdr + header_size + hdr->size;
-       if ((char *) grow_base <= (char *) hdr + header_size ||
-           (char *) grow_base >= (char *) mmap_top_limit) {
-               /* overflows valid address range */
-               return 0;
-       }
-
-       if (anon_mmap_fixed(grow_base, new_size - hdr->size) < 0) {
-               if (errno == EINVAL || errno == ENOMEM) {
-                       /* can't grow, wanted address space is already in use */
-                       return 0;
-               }
-
-               return -1;
-       }
-
-       hdr->size = new_size;
-       return 1;
-}
-
-static void *mremap_move(struct movable_header *hdr, size_t new_size)
+static void *mremap_move(struct anon_header *hdr, size_t new_size)
 {
        void *new_base;
        char *p;
@@ -242,15 +111,14 @@ static void *mremap_move(struct movable_header *hdr, size_t new_size)
 void *mremap_anon(void *old_address, size_t old_size  __attr_unused__,
                  size_t new_size, unsigned long flags)
 {
-       struct movable_header *hdr;
-       int ret;
+       struct anon_header *hdr;
 
        if (old_address == NULL || old_address == MAP_FAILED) {
                errno = EINVAL;
                return MAP_FAILED;
        }
 
-       hdr = (struct movable_header *) ((char *) old_address - header_size);
+       hdr = (struct anon_header *) ((char *) old_address - header_size);
        if (hdr->signature != MMAP_SIGNATURE)
                i_panic("movable_mremap(): Invalid old_address");
 
@@ -258,12 +126,6 @@ void *mremap_anon(void *old_address, size_t old_size  __attr_unused__,
 
        if (new_size > hdr->size) {
                /* grow */
-               ret = mremap_try_grow(hdr, new_size);
-               if (ret > 0)
-                       return old_address;
-               if (ret < 0)
-                       return MAP_FAILED;
-
                if ((flags & MREMAP_MAYMOVE) == 0) {
                        errno = ENOMEM;
                        return MAP_FAILED;
@@ -285,14 +147,14 @@ void *mremap_anon(void *old_address, size_t old_size  __attr_unused__,
 
 int munmap_anon(void *start, size_t length __attr_unused__)
 {
-       struct movable_header *hdr;
+       struct anon_header *hdr;
 
        if (start == NULL || start == MAP_FAILED) {
                errno = EINVAL;
                return -1;
        }
 
-       hdr = (struct movable_header *) ((char *) start - header_size);
+       hdr = (struct anon_header *) ((char *) start - header_size);
        if (hdr->signature != MMAP_SIGNATURE)
                i_panic("movable_munmap(): Invalid address");