public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] elf: Don't cache symbol nor relocation tables with mmap
@ 2024-04-03 16:17 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2024-04-03 16:17 UTC (permalink / raw)
  To: binutils-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d41b7648558757dbfd0958335dba1406be60fb4f

commit d41b7648558757dbfd0958335dba1406be60fb4f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Feb 28 14:34:33 2024 -0800

    elf: Don't cache symbol nor relocation tables with mmap
    
    During a "-j 8" LLVM 17 debug build on a machine with 32GB RAM and 16GB
    swap, ld was killed by kernel because of out of memory:
    
    [79437.949336] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/session-9.scope,task=ld,pid=797431,uid=1000
    [79437.949349] Out of memory: Killed process 797431 (ld) total-vm:9219600kB, anon-rss:6558156kB, file-rss:1792kB, shmem-rss:0kB, UID:1000 pgtables:17552kB oom_score_adj:0
    
    Don't cache symbol nor relocation tables if they are mapped in.  Data to
    link the 3.5GB clang executable in LLVM 17 debug build on Linux/x86-64
    with 32GB RAM is:
    
                    stdio           mmap            improvement
    user            86.73           87.02           -0.3%
    system          9.55            9.21            3.6%
    total           100.40          97.66           0.7%
    maximum set(GB) 17.34           13.14           24%
    page faults     4047667         3042877         25%
    
    and data to link the 275M cc1plus executable in GCC 14 stage 1 build is:
    
    user            5.41            5.44            -0.5%
    system          0.80            0.76            5%
    total           6.25            6.26            -0.2%
    maximum set(MB) 1323            968             27%
    page faults     323451          236371          27%
    
    These improve the overall system performance for parallel build by
    reducing memory usage and page faults.
    
    Also rename _bfd_link_keep_memory to _bfd_elf_link_keep_memory.  Since
    the --no-keep-memory linker option causes:
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=31458
    
    this is opt-in by each backend.
    
    bfd/
    
            * elf32-i386.c (elf_i386_scan_relocs): Remove
            _bfd_link_keep_memory.
            * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
            * elflink.c (_bfd_elf_link_keep_memory): New.
            (_bfd_elf_link_iterate_on_relocs): Replace _bfd_link_keep_memory
            with _bfd_elf_link_keep_memory.
            (elf_link_add_object_symbols): Likewise.
            (init_reloc_cookie): Likewise.
            (init_reloc_cookie_rels): Likewise.
            * libbfd-in.h (_bfd_link_keep_memory): Removed.
            * linker.c (_bfd_link_keep_memory): Likewise.
            * libbfd.h: Regenerated.

Diff:
---
 bfd/elf32-i386.c   |  2 +-
 bfd/elf64-x86-64.c |  2 +-
 bfd/elflink.c      | 69 ++++++++++++++++++++++++++++++++++++++++++++----------
 bfd/libbfd-in.h    |  3 ---
 bfd/libbfd.h       |  3 ---
 bfd/linker.c       | 35 ---------------------------
 6 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index fa1846881d3..6183d962a83 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1932,7 +1932,7 @@ elf_i386_scan_relocs (bfd *abfd,
 
   if (elf_section_data (sec)->this_hdr.contents != contents)
     {
-      if (!converted && !_bfd_link_keep_memory (info))
+      if (!converted)
 	_bfd_elf_munmap_section_contents (sec, contents);
       else
 	{
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index ebfd455a822..60aa1802552 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2590,7 +2590,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
 
   if (elf_section_data (sec)->this_hdr.contents != contents)
     {
-      if (!converted && !_bfd_link_keep_memory (info))
+      if (!converted)
 	_bfd_elf_munmap_section_contents (sec, contents);
       else
 	{
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7e9f4c7f0b0..7a33da0a96c 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -49,6 +49,53 @@ struct elf_info_failed
 static bool _bfd_elf_fix_symbol_flags
   (struct elf_link_hash_entry *, struct elf_info_failed *);
 
+/* Return false if linker should avoid caching relocation information
+   and symbol tables of input files in memory.  */
+
+static bool
+_bfd_elf_link_keep_memory (struct bfd_link_info *info)
+{
+#ifdef USE_MMAP
+  /* Don't cache symbol nor relocation tables if they are mapped in.
+     NB: Since the --no-keep-memory linker option causes:
+
+     https://sourceware.org/bugzilla/show_bug.cgi?id=31458
+
+     this is opt-in by each backend.  */
+  const struct elf_backend_data *bed
+    = get_elf_backend_data (info->output_bfd);
+  if (bed->use_mmap)
+    return false;
+#endif
+  bfd *abfd;
+  bfd_size_type size;
+
+  if (!info->keep_memory)
+    return false;
+
+  if (info->max_cache_size == (bfd_size_type) -1)
+    return true;
+
+  abfd = info->input_bfds;
+  size = info->cache_size;
+  do
+    {
+      if (size >= info->max_cache_size)
+	{
+	  /* Over the limit.  Reduce the memory usage.  */
+	  info->keep_memory = false;
+	  return false;
+	}
+      if (!abfd)
+	break;
+      size += abfd->alloc_size;
+      abfd = abfd->link.next;
+    }
+  while (1);
+
+  return true;
+}
+
 asection *
 _bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie,
 			     unsigned long r_symndx,
@@ -4182,10 +4229,9 @@ _bfd_elf_link_iterate_on_relocs
 	      || bfd_is_abs_section (o->output_section))
 	    continue;
 
-	  internal_relocs = _bfd_elf_link_info_read_relocs (abfd, info,
-							    o, NULL,
-							    NULL,
-							    _bfd_link_keep_memory (info));
+	  internal_relocs = _bfd_elf_link_info_read_relocs
+	    (abfd, info, o, NULL, NULL,
+	     _bfd_elf_link_keep_memory (info));
 	  if (internal_relocs == NULL)
 	    return false;
 
@@ -5551,10 +5597,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 		  && (s->flags & SEC_DEBUGGING) != 0))
 	    continue;
 
-	  internal_relocs = _bfd_elf_link_info_read_relocs (abfd, info,
-							    s, NULL,
-							    NULL,
-							    _bfd_link_keep_memory (info));
+	  internal_relocs = _bfd_elf_link_info_read_relocs
+	    (abfd, info, s, NULL, NULL,
+	     _bfd_elf_link_keep_memory (info));
 	  if (internal_relocs == NULL)
 	    goto error_free_vers;
 
@@ -13616,7 +13661,7 @@ init_reloc_cookie (struct elf_reloc_cookie *cookie,
 	  info->callbacks->einfo (_("%P%X: can not read symbols: %E\n"));
 	  return false;
 	}
-      if (_bfd_link_keep_memory (info) )
+      if (_bfd_elf_link_keep_memory (info) )
 	{
 	  symtab_hdr->contents = (bfd_byte *) cookie->locsyms;
 	  info->cache_size += (cookie->locsymcount
@@ -13653,9 +13698,9 @@ init_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
     }
   else
     {
-      cookie->rels = _bfd_elf_link_info_read_relocs (abfd, info, sec,
-						     NULL, NULL,
-						     _bfd_link_keep_memory (info));
+      cookie->rels = _bfd_elf_link_info_read_relocs
+	(abfd, info, sec, NULL, NULL,
+	 _bfd_elf_link_keep_memory (info));
       if (cookie->rels == NULL)
 	return false;
       cookie->rel = cookie->rels;
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 889b221a950..7bfc58f12d8 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -848,9 +848,6 @@ extern bfd_byte * _bfd_write_unsigned_leb128
 extern struct bfd_link_info *_bfd_get_link_info (bfd *)
   ATTRIBUTE_HIDDEN;
 
-extern bool _bfd_link_keep_memory (struct bfd_link_info *)
-  ATTRIBUTE_HIDDEN;
-
 extern uintptr_t _bfd_pagesize ATTRIBUTE_HIDDEN;
 extern uintptr_t _bfd_pagesize_m1 ATTRIBUTE_HIDDEN;
 extern uintptr_t _bfd_minimum_mmap_size ATTRIBUTE_HIDDEN;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 0676f461382..bed7d88d4ec 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -854,9 +854,6 @@ extern bfd_byte * _bfd_write_unsigned_leb128
 extern struct bfd_link_info *_bfd_get_link_info (bfd *)
   ATTRIBUTE_HIDDEN;
 
-extern bool _bfd_link_keep_memory (struct bfd_link_info *)
-  ATTRIBUTE_HIDDEN;
-
 extern uintptr_t _bfd_pagesize ATTRIBUTE_HIDDEN;
 extern uintptr_t _bfd_pagesize_m1 ATTRIBUTE_HIDDEN;
 extern uintptr_t _bfd_minimum_mmap_size ATTRIBUTE_HIDDEN;
diff --git a/bfd/linker.c b/bfd/linker.c
index 36cca9624c2..eb42a78b622 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -3556,38 +3556,3 @@ _bfd_nolink_bfd_define_start_stop (struct bfd_link_info *info ATTRIBUTE_UNUSED,
 {
   return (struct bfd_link_hash_entry *) _bfd_ptr_bfd_null_error (sec->owner);
 }
-
-/* Return false if linker should avoid caching relocation infomation
-   and symbol tables of input files in memory.  */
-
-bool
-_bfd_link_keep_memory (struct bfd_link_info * info)
-{
-  bfd *abfd;
-  bfd_size_type size;
-
-  if (!info->keep_memory)
-    return false;
-
-  if (info->max_cache_size == (bfd_size_type) -1)
-    return true;
-
-  abfd = info->input_bfds;
-  size = info->cache_size;
-  do
-    {
-      if (size >= info->max_cache_size)
-	{
-	  /* Over the limit.  Reduce the memory usage.  */
-	  info->keep_memory = false;
-	  return false;
-	}
-      if (!abfd)
-	break;
-      size += abfd->alloc_size;
-      abfd = abfd->link.next;
-    }
-  while (1);
-
-  return true;
-}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-03 16:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-03 16:17 [binutils-gdb] elf: Don't cache symbol nor relocation tables with mmap H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).