]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
debuginfod PR29975 & PR29976: decrease default concurrency
authorFrank Ch. Eigler <fche@redhat.com>
Tue, 10 Jan 2023 22:59:35 +0000 (17:59 -0500)
committerFrank Ch. Eigler <fche@redhat.com>
Wed, 11 Jan 2023 15:32:34 +0000 (10:32 -0500)
... based on rlimit (rlimig -n NUM)
... based on cpu-affinity (taskset -c A,B,C,D ...)

Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
ChangeLog
configure.ac
debuginfod/ChangeLog
debuginfod/debuginfod.cxx
doc/ChangeLog
doc/debuginfod.8

index 52efca04406c674662da47679d98b83778df0064..a46cca6cbaed85c2d5807cef674c0be6be58b2e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2023-01-11  Frank Ch. Eigler  <fche@redhat.com>
+
+       * configure.ac: Add some rlimit/affinity checks.
+
 2022-11-02  Mark Wielaard  <mark@klomp.org>
 
        * configure.ac (AC_INIT): Set version to 0.188.
index b2597f8b095e0edc4041005fdf7a363d809817fc..8fe8baee69c8bfb4e6ae839524a364bb38bf1957 100644 (file)
@@ -455,6 +455,12 @@ AS_IF([test "x$ac_cv_func_mremap" = "xno"],
 AC_CHECK_HEADERS([error.h])
 AC_CHECK_HEADERS([err.h])
 
+dnl for debuginfod concurrency heuristics
+AC_CHECK_HEADERS([sched.h])
+AC_CHECK_FUNCS([sched_getaffinity])
+AC_CHECK_HEADERS([sys/resource.h])
+AC_CHECK_FUNCS([getrlimit])
+
 old_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 AC_FUNC_STRERROR_R()
index 8f9637f503bab6252983ef8c4575711dfbea5341..fc44e03964e55a0e38e9d75512ae38cf7818b667 100644 (file)
@@ -3,6 +3,12 @@
        * debuginfod-client.c (debuginfod_query_server): Use
        CURL_AT_LEAST_VERSION(7.85.0) for CURLOPT_PROTOCOLS_STR.
 
+2023-01-11  Frank Ch. Eigler  <fche@redhat.com>
+
+       PR29975 & PR29976
+       * debuginfod.cxx (default_concurrency): New function to guess a
+       reasonable default for -c/-C on large but constrained machines.
+
 2022-12-21  Mark Wielaard  <mark@klomp.org>
 
        * debuginfod-client.c: Define CURL_AT_LEAST_VERSION.
index 02a11477a51554e711480bf0b2f39266240359db..4271acf453ed2188d6ccdbaf8f75e2caa7b944e8 100644 (file)
   #include "config.h"
 #endif
 
+// #define _GNU_SOURCE
+#ifdef HAVE_SCHED_H
+extern "C" {
+#include <sched.h>
+}
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+extern "C" {
+#include <sys/resource.h>
+}
+#endif
+
 extern "C" {
 #include "printversion.h"
 #include "system.h"
@@ -398,6 +410,8 @@ static const char args_doc[] = "[PATH ...]";
 /* Prototype for option handler.  */
 static error_t parse_opt (int key, char *arg, struct argp_state *state);
 
+static unsigned default_concurrency();
+
 /* Data structure to communicate with argp functions.  */
 static struct argp argp =
   {
@@ -418,7 +432,7 @@ static unsigned http_port = 8002;
 static unsigned rescan_s = 300;
 static unsigned groom_s = 86400;
 static bool maxigroom = false;
-static unsigned concurrency = std::thread::hardware_concurrency() ?: 1;
+static unsigned concurrency = default_concurrency();
 static int connection_pool = 0;
 static set<string> source_paths;
 static bool scan_files = false;
@@ -4082,6 +4096,47 @@ static void sqlite3_sharedprefix_fn (sqlite3_context* c, int argc, sqlite3_value
 }
 
 
+static unsigned
+default_concurrency() // guaranteed >= 1
+{
+  // Prior to PR29975 & PR29976, we'd just use this: 
+  unsigned sth = std::thread::hardware_concurrency();
+  // ... but on many-CPU boxes, admins or distros may throttle
+  // resources in such a way that debuginfod would mysteriously fail.
+  // So we reduce the defaults:
+
+  unsigned aff = 0;
+#ifdef HAVE_SCHED_GETAFFINITY
+  {
+    int ret;
+    cpu_set_t mask;
+    CPU_ZERO(&mask);
+    ret = sched_getaffinity(0, sizeof(mask), &mask);
+    if (ret == 0)
+      aff = CPU_COUNT(&mask);
+  }
+#endif
+  
+  unsigned fn = 0;
+#ifdef HAVE_GETRLIMIT
+  {
+    struct rlimit rlim;
+    int rc = getrlimit(RLIMIT_NOFILE, &rlim);
+    if (rc == 0)
+      fn = max((rlim_t)1, (rlim.rlim_cur - 100) / 4);
+    // at least 2 fds are used by each listener thread etc.
+    // plus a bunch to account for shared libraries and such
+  }
+#endif
+
+  unsigned d = min(max(sth, 1U),
+                   min(max(aff, 1U),
+                       max(fn, 1U)));
+  return d;
+}
+
+
+
 int
 main (int argc, char *argv[])
 {
@@ -4207,7 +4262,7 @@ main (int argc, char *argv[])
   /* If '-C' wasn't given or was given with no arg, pick a reasonable default
      for the number of worker threads.  */
   if (connection_pool == 0)
-    connection_pool = std::thread::hardware_concurrency() * 2 ?: 2;
+    connection_pool = default_concurrency();
 
   /* Note that MHD_USE_EPOLL and MHD_USE_THREAD_PER_CONNECTION don't
      work together.  */
index 7b18dbef96d12c807022f476e0f7ecf41ba5e72b..b2ef357a973b11173fc0c52fc8f33e79973adf52 100644 (file)
@@ -1,3 +1,7 @@
+2023-01-11  Frank Ch. Eigler  <fche@redhat.com>
+
+       * debuginfod.8: Tweak -c/-C documentation for heuristic defaults.
+
 2022-10-31  Aaron Merey  <amerey@redhat.com>
 
        * Makefile.am (notrans_dist_man3_MANS): Add debuginfod_find_section.3.
index 93db47e1bc2cb74b92e90eb2188c8be1082126b7..1aa8bc1423bd4d43c110963c079413bd8b153d74 100644 (file)
@@ -202,8 +202,9 @@ do maximal-grooming.  See also the \fIDATA MANAGEMENT\fP section.
 Set the concurrency limit for the scanning queue threads, which work
 together to process archives & files located by the traversal thread.
 This important for controlling CPU-intensive operations like parsing
-an ELF file and especially decompressing archives.  The default is the
-number of processors on the system; the minimum is 1.
+an ELF file and especially decompressing archives.  The default is
+related to the number of processors on the system and other
+constraints; the minimum is 1.
 
 .TP
 .B "\-C" "\-C=NUM" "\-\-connection\-pool" "\-\-connection\-pool=NUM"
@@ -216,9 +217,9 @@ no option, \-C      use a fixed thread pool sized automatically
 \-C=NUM        use a fixed thread pool sized NUM, minimum 2
 .TE
 
-The first mode is a simple and safe configuration based on the number
-of processors. The second mode is suitable for tuned load-limiting
-configurations facing unruly traffic.
+The first mode is a simple and safe configuration related to the
+number of processors and other constraints. The second mode is
+suitable for tuned load-limiting configurations facing unruly traffic.
 
 .TP
 .B "\-L"