[uClinux-dev] [PATCH] NOMMU: fix malloc performance by adding uninitialized flag

2009-10-13 Thread Mike Frysinger
From: Jie Zhang jie.zh...@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.zh...@analog.com
Signed-off-by: Robin Getz rg...@analog.com
Signed-off-by: Mike Frysinger vap...@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 0x400/* 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
   

[uClinux-dev] Re: [PATCH v2] NOMMU: fix malloc performance by adding uninitialized flag

2009-10-13 Thread Paul Mundt
On Tue, Oct 13, 2009 at 07:20:21AM -0400, Mike Frysinger wrote:
 From: Jie Zhang jie.zh...@analog.com
 
 The NOMMU code currently clears all anonymous mmapped memory.  While this
 is what we want in the default case, all memory allocation from userspace
 under NOMMU has to go through this interface, including malloc() which is
 allowed to return uninitialized memory.  This can easily be a significant
 performance penalty.  So for constrained embedded systems were security is
 irrelevant, allow people to avoid clearing memory unnecessarily.
 
 This also alters the ELF-FDPIC binfmt such that it obtains uninitialised
 memory for the brk and stack region.
 
 Signed-off-by: Jie Zhang jie.zh...@analog.com
 Signed-off-by: Robin Getz rg...@analog.com
 Signed-off-by: Mike Frysinger vap...@gentoo.org
 Signed-off-by: David Howells dhowe...@redhat.com

Acked-by: Paul Mundt let...@linux-sh.org
___
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev


Re: [uClinux-dev] building uClibc

2009-10-13 Thread Lennart Sorensen
On Mon, Oct 12, 2009 at 11:53:45AM +0100, Philip Nye wrote:
 I am trying to build a system for Coldfire with an up-to-date kernel, tools
 and library. I have the latest uClinux dist (patched to 20090810) and
 Codesourcery tools 4.3-209. This refused to build with an error of limits.h
 not found.

 Rather than a symlink hack, this led me to try a recent release of uClibc as
 the one in the uClinux dist is not so new (and I found this:
 http://gcc.gnu.org/ml/gcc/2008-08/msg00273.html), but I now get failures
 down the line because uClibc headers contain lots of libc_hidden_proto()
 declarations. As I understand it, these headers should be sanitized to
 remove this internal code for public use, but this is not happening, and I
 cannot see where it should be carried out. If I simply enter the uClibc
 directory and try to build from there, I get a different set of errors with
 missing header files.

 Can anyone suggest what I am doing wrong? Does the uClibc tree need to be
 patched for uClinux? Is there some extra configuration or build stage I need
 to do? Is there more to installing Codesourcery toolchain than simply
 setting PATH so it can be found?

I am currently using a coldfire (5270/5271) with gcc 4.3.3, binutils
2.19.1, elf2flt (blackfin version from a late april checkout, other
versions didn't work with gcc 4.3 at the time), 2.6.30 kernel, and
uclibc 0.9.30.1 (with daemon() function #ifdef'd out to fix compile
error).

Anything you need?

-- 
Len Sorensen
___
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev


Re: [uClinux-dev] [PATCH] NOMMU: fix malloc performance by addinguninitialized flag

2009-10-13 Thread Robin Getz
On Tue 13 Oct 2009 03:44, Mike Frysinger pondered:
 From: Jie Zhang jie.zh...@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.zh...@analog.com
 Signed-off-by: Robin Getz rg...@analog.com

Should be rg...@blackfin.uclinux.org -- rg...@analog.com does not exist and 
will bounce.

___
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev


[uClinux-dev] Re: [PATCH v3] NOMMU: fix malloc performance by adding uninitialized flag

2009-10-13 Thread David McCullough

Jivin Mike Frysinger lays it down ...
 From: Jie Zhang jie.zh...@analog.com
 
 The NOMMU code currently clears all anonymous mmapped memory.  While this
 is what we want in the default case, all memory allocation from userspace
 under NOMMU has to go through this interface, including malloc() which is
 allowed to return uninitialized memory.  This can easily be a significant
 performance penalty.  So for constrained embedded systems were security is
 irrelevant, allow people to avoid clearing memory unnecessarily.
 
 This also alters the ELF-FDPIC binfmt such that it obtains uninitialised
 memory for the brk and stack region.
 
 Signed-off-by: Jie Zhang jie.zh...@analog.com
 Signed-off-by: Robin Getz robin.g...@analog.com
 Signed-off-by: Mike Frysinger vap...@gentoo.org
 Signed-off-by: David Howells dhowe...@redhat.com
 Acked-by: Paul Mundt let...@linux-sh.org

Acked-by: David McCullough dav...@snapgear.com

Cheers,
Davidm

 v3
   - tweak kconfig desc
 
  Documentation/nommu-mmap.txt  |   26 ++
  fs/binfmt_elf_fdpic.c |3 ++-
  include/asm-generic/mman-common.h |5 +
  init/Kconfig  |   22 ++
  mm/nommu.c|8 +---
  5 files changed, 60 insertions(+), 4 deletions(-)
 
 diff --git a/Documentation/nommu-mmap.txt b/Documentation/nommu-mmap.txt
 index b565e82..8e1ddec 100644
 --- a/Documentation/nommu-mmap.txt
 +++ b/Documentation/nommu-mmap.txt
 @@ -119,6 +119,32 @@ FURTHER NOTES ON NO-MMU MMAP
   granule but will only discard the excess if appropriately configured as
   this has an effect on fragmentation.
  
 + (*) The memory allocated by a request for an anonymous mapping will normally
 + be cleared by the kernel before being returned in accordance with the
 + Linux man pages (ver 2.22 or later).
 +
 + In the MMU case this can be achieved with reasonable performance as
 + regions are backed by virtual pages, with the contents only being mapped
 + to cleared physical pages when a write happens on that specific page
 + (prior to which, the pages are effectively mapped to the global zero 
 page
 + from which reads can take place).  This spreads out the time it takes to
 + initialize the contents of a page - depending on the write-usage of the
 + mapping.
 +
 + In the no-MMU case, however, anonymous mappings are backed by physical
 + pages, and the entire map is cleared at allocation time.  This can cause
 + significant delays during a userspace malloc() as the C library does an
 + anonymous mapping and the kernel then does a memset for the entire map.
 +
 + However, for memory that isn't required to be precleared - such as that
 + returned by malloc() - mmap() can take a MAP_UNINITIALIZED flag to
 + indicate to the kernel that it shouldn't bother clearing the memory 
 before
 + returning it.  Note that CONFIG_MMAP_ALLOW_UNINITIALIZED must be enabled
 + to permit this, otherwise the flag will be ignored.
 +
 + uClibc uses this to speed up malloc(), and the ELF-FDPIC binfmt uses 
 this
 + to allocate the brk and stack region.
 +
   (*) A list of all the private copy and anonymous mappings on the system is
   visible through /proc/maps in no-MMU mode.
  
 diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
 index 38502c6..79d2b1a 100644
 --- a/fs/binfmt_elf_fdpic.c
 +++ b/fs/binfmt_elf_fdpic.c
 @@ -380,7 +380,8 @@ 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_UNINITIALIZED | 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..2011126 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_FIXED0x10/* Interpret addr exactly */
  #define MAP_ANONYMOUS0x20/* don't use a file */
 +#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED
 +# define MAP_UNINITIALIZED 0x400 /* For anonymous mmap, memory could be 
 uninitialized */
 +#else
 +# define MAP_UNINITIALIZED 0x0   /* Don't support this flag */
 +#endif
  
  #define MS_ASYNC 1   /* sync memory asynchronously */
  #define MS_INVALIDATE2   /* invalidate the caches */
 diff --git a/init/Kconfig b/init/Kconfig
 index 09c5c64..309cd9a 100644
 --- a/init/Kconfig
 +++ b/init/Kconfig
 @@ -1069,6 +1069,28