Rtld object tasting [Was: Re: wired memory - again!]
Konstantin Belousov
kostikbel at gmail.com
Wed Jun 13 20:24:54 UTC 2012
On Wed, Jun 13, 2012 at 03:17:56PM -0500, Alan Cox wrote:
> On Wed, Jun 13, 2012 at 2:12 PM, Konstantin Belousov <kostikbel at gmail.com>wrote:
>
> > On Wed, Jun 13, 2012 at 07:14:09AM -0600, Ian Lepore wrote:
> > > http://lists.freebsd.org/pipermail/freebsd-arm/2012-January/003288.html
> >
> > The map_object.c patch is step in the almost right direction, I wanted
> > to remove the static page-sized buffer from get_elf_header for long time.
> > It works because rtld always holds bind_lock exclusively while loading
> > an object. There is no need to copy the first page after it is mapped.
> >
> > commit 0f6f8629af1345acded7c0c685d3ff7b4d9180d6
> > Author: Konstantin Belousov <kib at freebsd.org>
> > Date: Wed Jun 13 22:04:18 2012 +0300
> >
> > Eliminate the static buffer used to read the first page of the mapped
> > object, and eliminate the pread(2) call as well. Mmap the first page
> > of the object temporaly, and unmap it on error or last use.
> >
> > Fix several cases were the whole mapping of the object leaked on error.
> >
> > Potentially, this leaves one-page gap between succeeding dlopen(3),
> > but there are other mmap(2) consumers as well.
> >
> >
> I suggest adding MAP_PREFAULT_READ to the mmap(2) call. A heuristic in
> vm_map_pmap_enter() would trigger automatic mapping for small files, but if
> the object file is larger than 96 pages then you need to explicitly
> specific MAP_PREFAULT_READ.
Thank you for the suggestion.
commit 77de77b3124fb2742db1db72e9dfc47050c5ac36
Author: Konstantin Belousov <kib at freebsd.org>
Date: Wed Jun 13 23:22:27 2012 +0300
Use MAP_PREFAULT_READ for mmap(2) calls which map real object pages.
Suggested by: alc
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c
index 2afc88c..437e7c2 100644
--- a/libexec/rtld-elf/map_object.c
+++ b/libexec/rtld-elf/map_object.c
@@ -200,7 +200,7 @@ map_object(int fd, const char *path, const struct stat *sb)
data_prot = convert_prot(segs[i]->p_flags);
data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED;
if (mmap(data_addr, data_vlimit - data_vaddr, data_prot,
- data_flags, fd, data_offset) == (caddr_t) -1) {
+ data_flags | MAP_PREFAULT_READ, fd, data_offset) == (caddr_t) -1) {
_rtld_error("%s: mmap of data failed: %s", path,
rtld_strerror(errno));
goto error1;
@@ -307,7 +307,8 @@ get_elf_header(int fd, const char *path)
{
Elf_Ehdr *hdr;
- hdr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
+ hdr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE | MAP_PREFAULT_READ,
+ fd, 0);
if (hdr == (Elf_Ehdr *)MAP_FAILED) {
_rtld_error("%s: read error: %s", path, rtld_strerror(errno));
return NULL;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20120613/0f089e85/attachment.pgp
More information about the freebsd-hackers
mailing list