summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2019-08-23 11:17:21 +0300
committerPanu Matilainen <pmatilai@redhat.com>2019-08-28 12:16:52 +0300
commitf333357a7719d8e5a7e63a29d8f78952ea1230b3 (patch)
treee6611e65c9b21c36c3e1495e4fb7c8aef2a1855d
parent9acc591bbcb2bbb748c8bc71db15b6805a722621 (diff)
downloadrpm-f333357a7719d8e5a7e63a29d8f78952ea1230b3.tar.gz
Cap number of threads on 32bit platforms, add tunables (RhBug:1729382)
On 32bit plaforms, address space is easily exhausted with multiple threads, causing arbitrary builds failure regressions (RhBug:1729382). Simply cap the number of threads to maximum of four on any 32bit platform to play it safe. It's still three more than we were able to use on older releases... In addition, introduce tunables for controlling the number of threads used similarly to what is available for number of CPUs: forced number and a separate ceiling. The max logic gets surprisingly tricky with the mixed OMP and rpm tunables and different semantics. Notably, OMP does not have a nice way to set a maximum from inside a program (this is only possible from an environment variable so we can't use it here), so we need to jump through a lot of hoops to figure out whether an *unlimited* setting would go above the platform limitation. I'm not entirely convinced this is 100% bulletproof, but then it's all going to change and become even more complicated when we start taking memory limitations into account... (cherry picked from commit 0488fdc927e6d31a0af55646fe51effe9592cb26)
-rw-r--r--build/parseSpec.c20
-rw-r--r--platform.in5
2 files changed, 22 insertions, 3 deletions
diff --git a/build/parseSpec.c b/build/parseSpec.c
index 737a1233c..ed5c3ef63 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -1035,9 +1035,23 @@ static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags,
#ifdef ENABLE_OPENMP
/* Set number of OMP threads centrally */
- int ncpus = rpmExpandNumeric("%{?_smp_build_ncpus}");
- if (ncpus > 0)
- omp_set_num_threads(ncpus);
+ int nthreads = rpmExpandNumeric("%{?_smp_build_nthreads}");
+ int nthreads_max = rpmExpandNumeric("%{?_smp_nthreads_max}");
+ if (nthreads <= 0)
+ nthreads = omp_get_max_threads();
+ if (nthreads_max > 0 && nthreads > nthreads_max)
+ nthreads = nthreads_max;
+#if __WORDSIZE == 32
+ /* On 32bit platforms, address space shortage is an issue. Play safe. */
+ int platlimit = 4;
+ if (nthreads > platlimit) {
+ nthreads = platlimit;
+ rpmlog(RPMLOG_DEBUG,
+ "limiting number of threads to %d due to platform\n", platlimit);
+ }
+#endif
+ if (nthreads > 0)
+ omp_set_num_threads(nthreads);
#endif
if (spec->clean == NULL) {
diff --git a/platform.in b/platform.in
index db6d2382f..61f5e18a0 100644
--- a/platform.in
+++ b/platform.in
@@ -59,6 +59,11 @@
%_smp_mflags -j%{_smp_build_ncpus}
+# Maximum number of threads to use when building, 0 for unlimited
+#%_smp_nthreads_max 0
+
+%_smp_build_nthreads %{_smp_build_ncpus}
+
#==============================================================================
# ---- Build policy macros.
#