summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-11-21 13:10:19 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-11-24 15:25:19 +0000
commit6282ef6c7c0748a5ea40bc528d1c0cf2d7eecc3a (patch)
tree9bceb0c07045976e690b9005273fbe6ea84f3a98 /bitbake
parentf98db02718944865811d3daf6404ab23bbb655b8 (diff)
downloadpoky-6282ef6c7c0748a5ea40bc528d1c0cf2d7eecc3a.tar.gz
bitbake: runqueue: Fix race issues around hash equivalence and sstate reuse
We identified a use case where a native recipe (autoconf-native) was rebuilt with no change in output yet the sstate for do_package tasks wasn't being used. The issue is that do_package tasks have a hard dependency on pseudo-native:do_populate_sysroot. That task was one of the many tasks being rehashed when autoconf-native's hash was changed. If update_tasks processed a recipe before it had processed pseudo-native, that recipe would be marked as not possible from sstate and would run the full tasks. The fix is to split the processing into two passes, first to handle the existing covered/notcovered updates, then in the second pass, check whether there are "harddep" issues. This defers the do_package tasks until after pseudo-native is installed from sstate as expected and everything works well again. (Bitbake rev: 72a3afd99e8b785cb2a2f687e71a58e08cdd9c74) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> (cherry picked from commit e479d1e418a7d34f0a4663b4a0e22bb11503c8ab) Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/runqueue.py36
1 files changed, 20 insertions, 16 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 48e25401ba..ba75660555 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -2489,17 +2489,6 @@ class RunQueueExecute:
2489 self.sq_buildable.remove(tid) 2489 self.sq_buildable.remove(tid)
2490 if tid in self.sq_running: 2490 if tid in self.sq_running:
2491 self.sq_running.remove(tid) 2491 self.sq_running.remove(tid)
2492 harddepfail = False
2493 for t in self.sqdata.sq_harddeps:
2494 if tid in self.sqdata.sq_harddeps[t] and t in self.scenequeue_notcovered:
2495 harddepfail = True
2496 break
2497 if not harddepfail and self.sqdata.sq_revdeps[tid].issubset(self.scenequeue_covered | self.scenequeue_notcovered):
2498 if tid not in self.sq_buildable:
2499 self.sq_buildable.add(tid)
2500 if not self.sqdata.sq_revdeps[tid]:
2501 self.sq_buildable.add(tid)
2502
2503 if tid in self.sqdata.outrightfail: 2492 if tid in self.sqdata.outrightfail:
2504 self.sqdata.outrightfail.remove(tid) 2493 self.sqdata.outrightfail.remove(tid)
2505 if tid in self.scenequeue_notcovered: 2494 if tid in self.scenequeue_notcovered:
@@ -2518,21 +2507,36 @@ class RunQueueExecute:
2518 if tid in self.build_stamps: 2507 if tid in self.build_stamps:
2519 del self.build_stamps[tid] 2508 del self.build_stamps[tid]
2520 2509
2521 update_tasks.append((tid, harddepfail, tid in self.sqdata.valid)) 2510 update_tasks.append(tid)
2511
2512 update_tasks2 = []
2513 for tid in update_tasks:
2514 harddepfail = False
2515 for t in self.sqdata.sq_harddeps:
2516 if tid in self.sqdata.sq_harddeps[t] and t in self.scenequeue_notcovered:
2517 harddepfail = True
2518 break
2519 if not harddepfail and self.sqdata.sq_revdeps[tid].issubset(self.scenequeue_covered | self.scenequeue_notcovered):
2520 if tid not in self.sq_buildable:
2521 self.sq_buildable.add(tid)
2522 if not self.sqdata.sq_revdeps[tid]:
2523 self.sq_buildable.add(tid)
2524
2525 update_tasks2.append((tid, harddepfail, tid in self.sqdata.valid))
2522 2526
2523 if update_tasks: 2527 if update_tasks2:
2524 self.sqdone = False 2528 self.sqdone = False
2525 for mc in sorted(self.sqdata.multiconfigs): 2529 for mc in sorted(self.sqdata.multiconfigs):
2526 for tid in sorted([t[0] for t in update_tasks]): 2530 for tid in sorted([t[0] for t in update_tasks2]):
2527 if mc_from_tid(tid) != mc: 2531 if mc_from_tid(tid) != mc:
2528 continue 2532 continue
2529 h = pending_hash_index(tid, self.rqdata) 2533 h = pending_hash_index(tid, self.rqdata)
2530 if h in self.sqdata.hashes and tid != self.sqdata.hashes[h]: 2534 if h in self.sqdata.hashes and tid != self.sqdata.hashes[h]:
2531 self.sq_deferred[tid] = self.sqdata.hashes[h] 2535 self.sq_deferred[tid] = self.sqdata.hashes[h]
2532 bb.note("Deferring %s after %s" % (tid, self.sqdata.hashes[h])) 2536 bb.note("Deferring %s after %s" % (tid, self.sqdata.hashes[h]))
2533 update_scenequeue_data([t[0] for t in update_tasks], self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self, summary=False) 2537 update_scenequeue_data([t[0] for t in update_tasks2], self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self, summary=False)
2534 2538
2535 for (tid, harddepfail, origvalid) in update_tasks: 2539 for (tid, harddepfail, origvalid) in update_tasks2:
2536 if tid in self.sqdata.valid and not origvalid: 2540 if tid in self.sqdata.valid and not origvalid:
2537 hashequiv_logger.verbose("Setscene task %s became valid" % tid) 2541 hashequiv_logger.verbose("Setscene task %s became valid" % tid)
2538 if harddepfail: 2542 if harddepfail: