mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mike Frysinger <vapier@gentoo.org>
To: uclinux-dev@uclinux.org, David Howells <dhowells@redhat.com>,
	David McCullough <davidm@snapgear.com>,
	Greg Ungerer <gerg@uclinux.org>, Paul Mundt <lethal@linux-sh.org>
Cc: linux-kernel@vger.kernel.org,
	uclinux-dist-devel@blackfin.uclinux.org,
	Jie Zhang <jie.zhang@analog.com>, Robin Getz <rgetz@analog.com>
Subject: [PATCH] NOMMU: fix malloc performance by adding uninitialized flag
Date: Tue, 13 Oct 2009 03:44:05 -0400	[thread overview]
Message-ID: <1255419845-30504-1-git-send-email-vapier@gentoo.org> (raw)
In-Reply-To: <12871.1175267477@redhat.com>

From: Jie Zhang <jie.zhang@analog.com>

The no-mmu code currently clears all anonymous mmap-ed memory.  While this
is what we want in the default case, all memory allocation from userspace
under no-mmu has to go through this interface, including malloc() which is
allowed to return uninitialized memory.  This can easily be a significant
performance slow down.  So for constrained embedded systems were security
is irrelevant, allow people to avoid unnecessarily clearing memory.

Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Robin Getz <rgetz@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 Documentation/nommu-mmap.txt      |   21 +++++++++++++++++++++
 fs/binfmt_elf_fdpic.c             |    2 +-
 include/asm-generic/mman-common.h |    5 +++++
 init/Kconfig                      |   16 ++++++++++++++++
 mm/nommu.c                        |    7 ++++---
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/Documentation/nommu-mmap.txt b/Documentation/nommu-mmap.txt
index b565e82..30d09e8 100644
--- a/Documentation/nommu-mmap.txt
+++ b/Documentation/nommu-mmap.txt
@@ -16,6 +16,27 @@ the CLONE_VM flag.
 The behaviour is similar between the MMU and no-MMU cases, but not identical;
 and it's also much more restricted in the latter case:
 
+ (*) Anonymous mappings - general case
+
+	Anonymous mappings are  not  backed  by any file, and according to the
+	Linux man pages (ver 2.22 or later) contents are initialized to zero.
+
+	In the MMU case, regions are backed by arbitrary virtual pages, and the
+	contents are only mapped with physical pages and initialized to zero
+	when a read or write happens in that specific page. This spreads out
+	the time it takes to initialize the contents depending on the
+	read/write usage of the map.
+
+	In the no-MMU case, anonymous mappings are backed by physical pages,
+	and the entire map is initialized to zero at allocation time. This
+	can cause significant delays in userspace during malloc() as the C
+	library does an anonymous mapping, and the kernel is doing a memset
+	for the entire map. Since malloc's memory is not required to be
+	cleared, an (optional) flag MAP_UNINITIALIZE can be passed to the
+	kernel's do_mmap, which will not initialize the contents to zero.
+
+	uClibc supports this to provide a pretty significant speedup for malloc().
+
  (*) Anonymous mapping, MAP_PRIVATE
 
 	In the MMU case: VM regions backed by arbitrary pages; copy-on-write
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 38502c6..85db4a4 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -380,7 +380,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
 	down_write(&current->mm->mmap_sem);
 	current->mm->start_brk = do_mmap(NULL, 0, stack_size,
 					 PROT_READ | PROT_WRITE | PROT_EXEC,
-					 MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN,
+					 MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE | MAP_GROWSDOWN,
 					 0);
 
 	if (IS_ERR_VALUE(current->mm->start_brk)) {
diff --git a/include/asm-generic/mman-common.h b/include/asm-generic/mman-common.h
index 5ee13b2..dddf626 100644
--- a/include/asm-generic/mman-common.h
+++ b/include/asm-generic/mman-common.h
@@ -19,6 +19,11 @@
 #define MAP_TYPE	0x0f		/* Mask for type of mapping */
 #define MAP_FIXED	0x10		/* Interpret addr exactly */
 #define MAP_ANONYMOUS	0x20		/* don't use a file */
+#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZE
+# define MAP_UNINITIALIZE 0x4000000	/* For anonymous mmap, memory could be uninitialized */
+#else
+# define MAP_UNINITIALIZE 0x0		/* Don't support this flag */
+#endif
 
 #define MS_ASYNC	1		/* sync memory asynchronously */
 #define MS_INVALIDATE	2		/* invalidate the caches */
diff --git a/init/Kconfig b/init/Kconfig
index 09c5c64..ae15849 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1069,6 +1069,22 @@ config SLOB
 
 endchoice
 
+config MMAP_ALLOW_UNINITIALIZE
+	bool "Allow mmaped anonymous memory to be un-initialized"
+	depends on EMBEDDED && ! MMU
+	default n
+	help
+	   Normally (and according to the Linux spec) mmap'ed MAP_ANONYMOUS
+	   memory has it's contents initialized to zero. This kernel option
+	   gives you the option of not doing that by adding a MAP_UNINITIALIZE
+	   mmap flag (which uClibc's malloc() takes takes advantage of)
+	   which provides a huge performance boost.
+
+	   Because of the obvious security issues, this option should only be
+	   enabled on embedded devices which you control what is run in
+	   userspace. Since that isn't a problem on no-MMU systems, it is
+	   normally safe to say Y here.
+
 config PROFILING
 	bool "Profiling support (EXPERIMENTAL)"
 	help
diff --git a/mm/nommu.c b/mm/nommu.c
index 5189b5a..b62bd9d 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1143,9 +1143,6 @@ static int do_mmap_private(struct vm_area_struct *vma,
 		if (ret < rlen)
 			memset(base + ret, 0, rlen - ret);
 
-	} else {
-		/* if it's an anonymous mapping, then just clear it */
-		memset(base, 0, rlen);
 	}
 
 	return 0;
@@ -1343,6 +1340,10 @@ unsigned long do_mmap_pgoff(struct file *file,
 		goto error_just_free;
 	add_nommu_region(region);
 
+	/* clear anonymous mappings that don't ask for un-initialized data */
+	if (!(vma->vm_file) && !(flags & MAP_UNINITIALIZE))
+		memset((void *)region->vm_start, 0, region->vm_end - region->vm_start);
+
 	/* okay... we have a mapping; now we have to register it */
 	result = vma->vm_start;
 
-- 
1.6.5


  parent reply	other threads:[~2009-10-13  7:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-30  3:42 [PATCH] nommu arch dont zero the anonymous mapping by adding UNINITIALIZE flag Wu, Bryan
2007-03-30  3:53 ` Mike Frysinger
2007-03-30  9:39 ` David Howells
2007-03-30 10:34   ` Aubrey Li
2007-03-30 11:24   ` David Howells
2007-03-30 13:44     ` Aubrey Li
2007-03-30 14:56       ` Alan Cox
2007-03-30 14:38         ` Aubrey Li
2007-03-30 18:13           ` Alan Cox
2007-03-30 15:11         ` David Howells
2007-03-30 15:46           ` Aubrey Li
2009-10-13  7:44           ` Mike Frysinger [this message]
2009-10-13 15:20             ` [uClinux-dev] [PATCH] NOMMU: fix malloc performance by addinguninitialized flag Robin Getz
2009-10-13 10:10           ` [PATCH] NOMMU: fix malloc performance by adding uninitialized flag David Howells
2009-10-13 11:20             ` [PATCH v2] " Mike Frysinger
2009-10-13 13:03               ` Paul Mundt
2009-10-13 16:03             ` David Howells
2009-10-13 21:31               ` [PATCH v3] " Mike Frysinger
2009-10-13 23:04                 ` David McCullough
2009-10-14  0:25                 ` Greg Ungerer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1255419845-30504-1-git-send-email-vapier@gentoo.org \
    --to=vapier@gentoo.org \
    --cc=davidm@snapgear.com \
    --cc=dhowells@redhat.com \
    --cc=gerg@uclinux.org \
    --cc=jie.zhang@analog.com \
    --cc=lethal@linux-sh.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rgetz@analog.com \
    --cc=uclinux-dev@uclinux.org \
    --cc=uclinux-dist-devel@blackfin.uclinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®