<div dir="ltr"><div><div><div><div>Hi, <br><br></div>See <a href="http://www.yoctoproject.org/docs/2.0/bitbake-user-manual/bitbake-user-manual.html#var-BB_TASK_IONICE_LEVEL">http://www.yoctoproject.org/docs/2.0/bitbake-user-manual/bitbake-user-manual.html#var-BB_TASK_IONICE_LEVEL</a> for the new variable description in the BitBake User Manual. Note that I did not include the future implementation information at the bottom of Richard's explanation. Also, there is a bit about the 'cfq scheduler' near the end. I did not know how to properly format this string (e.g. CFG Scheduler).<br><br></div>Let me know of any changes or fixes. <br><br></div>Thanks, <br></div>Scott<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Oct 24, 2015 at 3:19 AM, Richard Purdie <span dir="ltr"><<a href="mailto:richard.purdie@linuxfoundation.org" target="_blank">richard.purdie@linuxfoundation.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Similarly to BB_TASK_NICE_LEVEL, add BB_TASK_IONICE_LEVEL which allows the ioprio<br>
of tasks to be adjusted. This is in response to various qemu runtime timeouts<br>
which have been witnessed on the autobuilder, seemingly due to IO starvation (we<br>
already use NICE_LEVEL to adjust tasks). This has a fairly urgent need to deal<br>
with certain 'random' failures we're seeing on the autobuilders in testing.<br>
<br>
The format of the data in the variable is BB_TASK_IONICE_LEVEL = "<class>.<prio>".<br>
<br>
For <class>, 2 is best effort (the default), 1 is real time and 3 is idle. You'd<br>
need superuser privileges to use realtime. The <prio> value is a default of 4,<br>
and can be set between 0 and 7 with 7 being lowest priority and 0 the highest.<br>
The user can set this freely with normal privileges<br>
<br>
Note that in order for this to take effect, you need the cfq scheduler selected<br>
for the backing block device.<br>
<br>
We could use nice wrapper functions for ioprio from modules like psutil however<br>
that would complicate bitbake dependencies. This version has some magic numbers<br>
but works on the main 32 and 64 bit x86 build architectures and can easily be<br>
extended if ever needed. When we move to python 3.x, we can likely replace this<br>
with standard calls.<br>
<br>
Signed-off-by: Richard Purdie <<a href="mailto:richard.purdie@linuxfoundation.org">richard.purdie@linuxfoundation.org</a>><br>
<br>
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py<br>
index 948c395..22428a6 100644<br>
--- a/bitbake/lib/bb/build.py<br>
+++ b/bitbake/lib/bb/build.py<br>
@@ -413,6 +413,13 @@ def _exec_task(fn, task, d, quieterr):<br>
nice = int(nice) - curnice<br>
newnice = os.nice(nice)<br>
logger.debug(1, "Renice to %s " % newnice)<br>
+ ionice = localdata.getVar("BB_TASK_IONICE_LEVEL", True)<br>
+ if ionice:<br>
+ try:<br>
+ cls, prio = ionice.split(".", 1)<br>
+ bb.utils.ioprio_set(os.getpid(), int(cls), int(prio))<br>
+ except:<br>
+ bb.warn("Invalid ionice level %s" % ionice)<br>
<br>
bb.utils.mkdirhier(tempdir)<br>
<br>
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py<br>
index eb219c1..86a5328 100644<br>
--- a/bitbake/lib/bb/utils.py<br>
+++ b/bitbake/lib/bb/utils.py<br>
@@ -1310,3 +1310,27 @@ def signal_on_parent_exit(signame):<br>
result = cdll['libc.so.6'].prctl(PR_SET_PDEATHSIG, signum)<br>
if result != 0:<br>
raise PrCtlError('prctl failed with error code %s' % result)<br>
+<br>
+#<br>
+# Manually call the ioprio syscall. We could depend on other libs like psutil<br>
+# however this gets us enough of what we need to bitbake for now without the<br>
+# dependency<br>
+#<br>
+_unamearch = os.uname()[4]<br>
+IOPRIO_WHO_PROCESS = 1<br>
+IOPRIO_CLASS_SHIFT = 13<br>
+<br>
+def ioprio_set(who, cls, value):<br>
+ NR_ioprio_set = None<br>
+ if _unamearch == "x86_64":<br>
+ NR_ioprio_set = 251<br>
+ elif _unamearch[0] == "i" and _unamearch[2:3] == "86":<br>
+ NR_ioprio_set = 289<br>
+<br>
+ if NR_ioprio_set:<br>
+ ioprio = value | (cls << IOPRIO_CLASS_SHIFT)<br>
+ rc = cdll['libc.so.6'].syscall(NR_ioprio_set, IOPRIO_WHO_PROCESS, who, ioprio)<br>
+ if rc != 0:<br>
+ raise ValueError("Unable to set ioprio, syscall returned %s" % rc)<br>
+ else:<br>
+ bb.warn("Unable to set IO Prio for arch %s" % _unamearch)<br>
<br>
<br>
</blockquote></div><br></div>