summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2024-02-21 13:10:04 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-02-23 14:34:05 +0000
commit08aa69a1fd7983dcf93d283e47e3c5ac9bd377b1 (patch)
treedfc96f58db8676255cbe205e3fc01598610ab4d9
parent42242fb9ef844fa2ac56eebd02ead921c57dde93 (diff)
downloadpoky-08aa69a1fd7983dcf93d283e47e3c5ac9bd377b1.tar.gz
bitbake: runqueue: Add support for BB_LOADFACTOR_MAX
Some ditros don't enable /proc/pressure and it tends to be those which we see bitbake timeout issues on, seemingly as load gets too high and the bitbake processes don't get scheduled in for minutes at a time. Add support for stopping running extra tasks if the system load average goes above a certain threshold by setting BB_LOADFACTOR_MAX. The value used is scaled by CPU number, so a value of 1 would be when the load average equals the number of cpu cores of the system, under one only starts tasks when the load average is below the number of cores. This means you can centrally set a value such as 1.5 which will then scale correctly to different sized machines with differing numbers of CPUs. The pressure regulation is probably more accurate and responsive, however our graphs do show singificant load spikes on some workers and this patch is aimed at trying to avoid those. Pressure regulation is used where available in preference to this load factor regulation when both are set. (Bitbake rev: 14a27306f6dceb4999c2804ccae5a09cc3d8dd49) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/runqueue.py16
1 files changed, 16 insertions, 0 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index e86ccd8c61..6987de3e29 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -220,6 +220,16 @@ class RunQueueScheduler(object):
220 bb.note("Pressure status changed to CPU: %s, IO: %s, Mem: %s (CPU: %s/%s, IO: %s/%s, Mem: %s/%s) - using %s/%s bitbake threads" % (pressure_state + pressure_values + (len(self.rq.runq_running.difference(self.rq.runq_complete)), self.rq.number_tasks))) 220 bb.note("Pressure status changed to CPU: %s, IO: %s, Mem: %s (CPU: %s/%s, IO: %s/%s, Mem: %s/%s) - using %s/%s bitbake threads" % (pressure_state + pressure_values + (len(self.rq.runq_running.difference(self.rq.runq_complete)), self.rq.number_tasks)))
221 self.pressure_state = pressure_state 221 self.pressure_state = pressure_state
222 return (exceeds_cpu_pressure or exceeds_io_pressure or exceeds_memory_pressure) 222 return (exceeds_cpu_pressure or exceeds_io_pressure or exceeds_memory_pressure)
223 elif self.rq.max_loadfactor:
224 limit = False
225 loadfactor = float(os.getloadavg()[0]) / os.cpu_count()
226 # bb.warn("Comparing %s to %s" % (loadfactor, self.rq.max_loadfactor))
227 if loadfactor > self.rq.max_loadfactor:
228 limit = True
229 if hasattr(self, "loadfactor_limit") and limit != self.loadfactor_limit:
230 bb.note("Load average limiting set to %s as load average: %s - using %s/%s bitbake threads" % (limit, loadfactor, len(self.rq.runq_running.difference(self.rq.runq_complete)), self.rq.number_tasks))
231 self.loadfactor_limit = limit
232 return limit
223 return False 233 return False
224 234
225 def next_buildable_task(self): 235 def next_buildable_task(self):
@@ -1822,6 +1832,7 @@ class RunQueueExecute:
1822 self.max_cpu_pressure = self.cfgData.getVar("BB_PRESSURE_MAX_CPU") 1832 self.max_cpu_pressure = self.cfgData.getVar("BB_PRESSURE_MAX_CPU")
1823 self.max_io_pressure = self.cfgData.getVar("BB_PRESSURE_MAX_IO") 1833 self.max_io_pressure = self.cfgData.getVar("BB_PRESSURE_MAX_IO")
1824 self.max_memory_pressure = self.cfgData.getVar("BB_PRESSURE_MAX_MEMORY") 1834 self.max_memory_pressure = self.cfgData.getVar("BB_PRESSURE_MAX_MEMORY")
1835 self.max_loadfactor = self.cfgData.getVar("BB_LOADFACTOR_MAX")
1825 1836
1826 self.sq_buildable = set() 1837 self.sq_buildable = set()
1827 self.sq_running = set() 1838 self.sq_running = set()
@@ -1875,6 +1886,11 @@ class RunQueueExecute:
1875 bb.fatal("Invalid BB_PRESSURE_MAX_MEMORY %s, minimum value is %s." % (self.max_memory_pressure, lower_limit)) 1886 bb.fatal("Invalid BB_PRESSURE_MAX_MEMORY %s, minimum value is %s." % (self.max_memory_pressure, lower_limit))
1876 if self.max_memory_pressure > upper_limit: 1887 if self.max_memory_pressure > upper_limit:
1877 bb.warn("Your build will be largely unregulated since BB_PRESSURE_MAX_MEMORY is set to %s. It is very unlikely that such high pressure will be experienced." % (self.max_io_pressure)) 1888 bb.warn("Your build will be largely unregulated since BB_PRESSURE_MAX_MEMORY is set to %s. It is very unlikely that such high pressure will be experienced." % (self.max_io_pressure))
1889
1890 if self.max_loadfactor:
1891 self.max_loadfactor = float(self.max_loadfactor)
1892 if self.max_loadfactor <= 0:
1893 bb.fatal("Invalid BB_LOADFACTOR_MAX %s, needs to be greater than zero." % (self.max_loadfactor))
1878 1894
1879 # List of setscene tasks which we've covered 1895 # List of setscene tasks which we've covered
1880 self.scenequeue_covered = set() 1896 self.scenequeue_covered = set()