banner: every line says where its fact came from - #67
Merged
Conversation
The banner is the first cell of every lesson and it had four facts in it, two of them asserted in a string. It now reads the release and the preemption model off /proc/version on both backends, takes the architecture off the config fragments and says so, and never fills the release in from pin.toml. Verified against a real v86 boot in headless Chrome, which is the only place the live wording exists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The banner is the first cell of every lesson. It is the thing a reader looks at before deciding whether to believe a single line of anything below it, and it had four facts in it, two of which were a string somebody typed.
M1 asks for it to show version, architecture, profile, preemption model and which backend is live. It now shows all five, and the part worth having is that every line says where its fact came from.
What it looks like
This is the real output of a real boot in headless Chrome, not an example typed into a README:
Off a recording it says
the recorded kernel saidinstead ofthe kernel says, then why the emulator was not used and whether what it is handing back is evidence.Where each fact comes from
The release and the preemption model are read off
/proc/version. That is the kernel's own one line description of itself and it is the only part of the banner a kernel can answer.Versiongrew three properties for it:tagsis the shouted words the build appended after the build number,smpis whetherSMPis among them, andpreemptionis whichever of them starts withPREEMPT.Absence is the answer in two places and both are said out loud rather than guessed at. A kernel with no
SMPin its banner is a uniprocessor build and there is nothing that says so positively. A kernel built with no preemption says nothing rather than sayingPREEMPT_NONE, so the banner printsno preemption model in its banner, so PREEMPT_NONEinstead of pretending it read one.The preemption model is not decoration. On a
PREEMPT_RTkernel most spinlocks sleep, and on aPREEMPT_NONEkernel a task in the kernel runs until it gives way, so a whole class of race cannot be reproduced. A reader who tries anyway concludes the book is wrong.The architecture is copied out of the config fragments, and the line says
per its fragments. There is nothing in/proc/versionthat names an architecture and nowhere else in the guest says it plainly, so this one cannot be asked of a running kernel. Printing it next to two facts that were read off a kernel, in the same voice, would let a reader believe a config file had been checked against something. It has not been. This is not like the KASAN story either: an architecture is a choice Kconfig either honours or refuses to configure at all, so what the fragment asked for is what the kernel is.The release is never filled in from
pin.toml. The pin is what somebody asked to be built and this project has already had one case of a build quietly not being that, which is the whole of the KASAN story inkernel/README.md. When the kernel that answered disagrees with the version the pin asks for, the banner says so and says that nothing in the session backs a claim about the pinned kernel.Getting that comparison right needed a second thing. A pin row does not name a version, it names a tree: five rows say
kernel = "kernel"and mean 7.2.2, andC-longtermsayskernel = "fallback"and means 6.18.48. The first version of this read the version off the top of the file and would have held the longterm build to the wrong number.Two hardcoded claims went away.
LIMITSused to sayuniprocessor, 32 bit x86, emulated timingandV86.describe()used to enduniprocessor, 32 bit, emulated timing. Two of those three are now read, so what is left in each is the one thing no file in the guest can tell you: a number of seconds measured inside an emulator is a number about the emulator.A session that cannot read
/proc/versionat all prints one line saying so.banner()never raises, because a session that cannot say what it is running is still a session worth having, and a lesson whose first cell throws is a lesson the reader closes.The recipe
A sixth Tier 0 recipe,
banner, pointing at the/proc/versioncapture that came off the same boot as the three traces beside it. It is the only recipe in the file that exists for something other than a lesson, and it isrepeatablein a way none of the others are: nothing about that file changes between the first read of a boot and the thousandth, which is what makes it safe for a call every lesson makes in its first cell.Two things only the browser could find
Neither of these can fail on a machine running the test suite. Both fail on the first machine a reader uses, which is why the run in a real browser is part of this.
Adding the recipe hung the comparison.
bothwaystraces whatever it is given, and a trace with no function filter is a trace of the whole kernel. The guest filled its ring buffer faster than the serial line drained it, and the run came back sixty one seconds later withthe guest did not finish ": > /tmp/.kx.b64" within 20000ms, which is a timeout on an unrelated shell line three files from the cause. A recipe that records a file rather than a tape now goes throughby_file, which runs the command and compares the bytes of every file it captured, exactly, because there is nothing there two honest runs are expected to disagree about. Back to seventeen seconds, and the comparison it does is the one that was meant.The two lockdep recipes were in the same position and nobody had noticed, because they are a different profile and
comparehad never been pointed at them.import kxwidgetsdied in Pyodide.kxray.replay.recorddrives a pseudo terminal, so it importsfcntlandtermios, and a browser has neither. It was imported at the top ofkxray/replay/__init__.py, whichkxwidgetsreaches through on the way to the session player, so a page that only wanted to draw a call tree gotModuleNotFoundError: No module named 'fcntl'and no toolkit at all. It is loaded on demand now. A test blocksfcntl,termiosandptyand imports every package the worker imports, so the next module that reaches for one of them fails on a laptop.The Colab reader
profileslooked forkxbox/kernel/pin.tomlunder the working directory and nowhere else. The badge on the front page runspip install git+https://...on a machine with no checkout on it, so every one of those readers would have been told the architecture wasan architecture nothing in the fragments names. The wheel carries the pin and the fragments next toprofiles.pyand it only needed asking for. A checkout still wins when there is one, because that is the copy somebody might be editing.Verification
node kxbox/web/measure.jsin headless Chrome on the pinnedA-fullimage, which is where the block at the top came from:The row is in
kernel/RESULTS.mdwith the note about why it counts four recipes and eleven checks where the rows above it count three and ten.The live wording of the banner exists only on a machine with a kernel behind it, so
first-tape.pyprints it andindex.htmlshows it under The banner, off a live kernel. A test holds the page to printing it, because the live branch is the one no test on a laptop can reach and it is the branch every reader gets.Checked
1508 pytest tests, 63 node tests, ruff clean and formatted, and every gate: baseline 41 artefacts and 7968 lines with 0 unparsed, claimledger, bpc, kconfig, refcheck, lintnb, lintprose, kxmanim, and the six
--checkruns.measure.jsalso takesKXBOX_PORTnow. The failure when something else holds 8123 isthe server did not come up within 30s, which points at the emulator and the wheel long before it points at another program holding a socket.