[dovecot-cvs] dovecot/src/lib mmap-anon.c,1.14,1.15

cras at procontrol.fi cras at procontrol.fi
Mon Oct 20 00:15:18 EEST 2003


Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv17143

Modified Files:
	mmap-anon.c 
Log Message:
MAP_FIXED didn't actually work the way I thought (should have looked the man
page more carefully..). Dropped that and now we'll always just memcpy() the
data when we want to grow a mmaping.



Index: mmap-anon.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/mmap-anon.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mmap-anon.c	26 Aug 2003 21:18:16 -0000	1.14
+++ mmap-anon.c	19 Oct 2003 20:15:15 -0000	1.15
@@ -22,88 +22,38 @@
 #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 @@
 	   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 @@
 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 @@
 
 	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 @@
 
 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");
 



More information about the dovecot-cvs mailing list