diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-10-24 11:19:06 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-10-29 07:35:52 +0000 |
commit | 290534d3ff53b3c0a50e480863474d1785088c5a (patch) | |
tree | 011b9a73cbcf7c40fa6807716377a6355d408337 /bitbake | |
parent | 3ebf7617d6c869f798807792918e1030b3ab66de (diff) | |
download | poky-290534d3ff53b3c0a50e480863474d1785088c5a.tar.gz |
bitbake: build/utils: Add BB_TASK_IONICE_LEVEL support
Similarly to BB_TASK_NICE_LEVEL, add BB_TASK_IONICE_LEVEL which allows the ioprio
of tasks to be adjusted. This is in response to various qemu runtime timeouts
which have been witnessed on the autobuilder, seemingly due to IO starvation (we
already use NICE_LEVEL to adjust tasks). This has a fairly urgent need to deal
with certain 'random' failures we're seeing on the autobuilders in testing.
The format of the data in the variable is BB_TASK_IONICE_LEVEL = "<class>.<prio>".
For <class>, 2 is best effort (the default), 1 is real time and 3 is idle. You'd
need superuser privileges to use realtime. The <prio> value is a default of 4,
and can be set between 0 and 7 with 7 being lowest priority and 0 the highest.
The user can set this freely with normal privileges
Note that in order for this to take effect, you need the cfq scheduler selected
for the backing block device.
We could use nice wrapper functions for ioprio from modules like psutil however
that would complicate bitbake dependencies. This version has some magic numbers
but works on the main 32 and 64 bit x86 build architectures and can easily be
extended if ever needed. When we move to python 3.x, we can likely replace this
with standard calls.
(Bitbake rev: b9471ad147b102c45d65f5ffd9521864df7ff9c1)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/build.py | 7 | ||||
-rw-r--r-- | bitbake/lib/bb/utils.py | 24 |
2 files changed, 31 insertions, 0 deletions
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py index 948c3951f4..22428a649c 100644 --- a/bitbake/lib/bb/build.py +++ b/bitbake/lib/bb/build.py | |||
@@ -413,6 +413,13 @@ def _exec_task(fn, task, d, quieterr): | |||
413 | nice = int(nice) - curnice | 413 | nice = int(nice) - curnice |
414 | newnice = os.nice(nice) | 414 | newnice = os.nice(nice) |
415 | logger.debug(1, "Renice to %s " % newnice) | 415 | logger.debug(1, "Renice to %s " % newnice) |
416 | ionice = localdata.getVar("BB_TASK_IONICE_LEVEL", True) | ||
417 | if ionice: | ||
418 | try: | ||
419 | cls, prio = ionice.split(".", 1) | ||
420 | bb.utils.ioprio_set(os.getpid(), int(cls), int(prio)) | ||
421 | except: | ||
422 | bb.warn("Invalid ionice level %s" % ionice) | ||
416 | 423 | ||
417 | bb.utils.mkdirhier(tempdir) | 424 | bb.utils.mkdirhier(tempdir) |
418 | 425 | ||
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index 9b550ef3f1..7f82687ae4 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
@@ -1311,3 +1311,27 @@ def signal_on_parent_exit(signame): | |||
1311 | result = cdll['libc.so.6'].prctl(PR_SET_PDEATHSIG, signum) | 1311 | result = cdll['libc.so.6'].prctl(PR_SET_PDEATHSIG, signum) |
1312 | if result != 0: | 1312 | if result != 0: |
1313 | raise PrCtlError('prctl failed with error code %s' % result) | 1313 | raise PrCtlError('prctl failed with error code %s' % result) |
1314 | |||
1315 | # | ||
1316 | # Manually call the ioprio syscall. We could depend on other libs like psutil | ||
1317 | # however this gets us enough of what we need to bitbake for now without the | ||
1318 | # dependency | ||
1319 | # | ||
1320 | _unamearch = os.uname()[4] | ||
1321 | IOPRIO_WHO_PROCESS = 1 | ||
1322 | IOPRIO_CLASS_SHIFT = 13 | ||
1323 | |||
1324 | def ioprio_set(who, cls, value): | ||
1325 | NR_ioprio_set = None | ||
1326 | if _unamearch == "x86_64": | ||
1327 | NR_ioprio_set = 251 | ||
1328 | elif _unamearch[0] == "i" and _unamearch[2:3] == "86": | ||
1329 | NR_ioprio_set = 289 | ||
1330 | |||
1331 | if NR_ioprio_set: | ||
1332 | ioprio = value | (cls << IOPRIO_CLASS_SHIFT) | ||
1333 | rc = cdll['libc.so.6'].syscall(NR_ioprio_set, IOPRIO_WHO_PROCESS, who, ioprio) | ||
1334 | if rc != 0: | ||
1335 | raise ValueError("Unable to set ioprio, syscall returned %s" % rc) | ||
1336 | else: | ||
1337 | bb.warn("Unable to set IO Prio for arch %s" % _unamearch) | ||