hybrid: a modeset, from a process
H3 of docs/plan/hybrid.md -- "a modeset API, which is the thing an
out-of-kernel GPU driver makes affordable and an in-kernel one never got".
# schmode modes
1280x800 *
1280x720
1024x768
800x600
640x480
# schmode 1024 768
1024x768 ok
Captured off the virtio-gpu head, the frames really come back 1280x800,
1024x768, 640x480 and 1280x800 again, with the checkerboard band showing no
shear at any of them.
Nothing in the kernel changed for this. No syscall on the path has heard of
a scanout: schmode writes a line to a socket and vgpud sends five commands
to the device. The comparison is the point -- the same five commands in the
kernel would have been the same five commands *and a reason to be nervous*,
because a wrong one there takes the machine instead of one process. That is
why the in-kernel driver never grew one: not difficulty, exposure.
The framebuffer is allocated once, at the largest mode, and every smaller
mode reuses it. PCIIOC_DMA has no free -- a driver's blocks come back when
it exits and not before -- so a modeset that allocated would spend sixteen
slots and then the arena, and the failure would look like a GPU bug rather
than like counting. A larger mode is refused and says why.
vgpud used to end in for(;;) sleep(100) under a comment arguing that
building a control socket before there is a compositor to judge it is the
mistake this plan warns about. That was right about a *compositor protocol*
and wrong as a reason to have no socket: a modeset has a consumer that
exists, somebody changing the mode and looking at the screen, and schmode
is small enough to judge an interface this small. What is deliberately not
on that socket is everything a compositor would need -- no buffer
submission, no damage, no vblank -- which still waits, for the original
reason.
H4, the USB eviction, is now the only milestone left on the plan and is by
some distance the largest thing on the register.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
parent
415df0fd4d
commit
ef3e191c6f
7 changed files with 467 additions and 21 deletions
|
|
@ -113,6 +113,14 @@ console falls back to the VBE framebuffer.
|
|||
**No syscall on that path knows it is talking about a GPU.** The kernel hands
|
||||
over a PCI device; the process decides what it is.
|
||||
|
||||
It also **changes the display mode**, on a control socket, with `schmode` as the
|
||||
client — and that is worth a sentence here because it is the thing the device
|
||||
model makes possible rather than the thing it does. A modeset is five commands
|
||||
to the device. In the kernel those five commands are also a reason to be
|
||||
nervous, because a wrong one takes the machine; in a process the worst case is
|
||||
that `schinit` starts another one. See
|
||||
[../plan/hybrid.md](../plan/hybrid.md), "A modeset, from a process".
|
||||
|
||||
### Taking it back
|
||||
|
||||
A driver that dies is the case this whole arrangement exists for, so release is a
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ The galling ones. The work exists, is tested, and nothing uses it.
|
|||
| | Where it stopped |
|
||||
|---|---|
|
||||
| **`foundations.md`** | Item 1 built. Items 2 (a shareable memory object), 3 (`AF_UNIX` in the filesystem namespace), 4 and 5 open. **Wayland stops at item 2.** |
|
||||
| **`hybrid.md`** | All four mechanisms built. H1 and H2 done — the driver can be killed and comes back, which is the milestone the plan calls the one that proves the whole idea. H3 (a modeset API) and H4 (USB) open. |
|
||||
| **`hybrid.md`** | All four mechanisms built. H1, H2 and H3 done — the driver can be killed and comes back, and the display mode can be changed from a process. **H4, the USB eviction, is the only one left and is much the largest thing on this register**: `xhci.c` plus a USB core and three class drivers, all of which are on the path to a shell on real hardware. |
|
||||
| **Schcom v0** | 715 lines that composite, over a wire format that is superseded. Frozen: it runs, nothing more is added, and it is kept only because it is the one thing in the tree that has ever put a client's pixels on screen. |
|
||||
| **`debugger.md`** | D0 through D4 built and described in [../architecture/debugging.md](../architecture/debugging.md). Only the network transport is open — a userspace daemon bridging TCP to `/dev/dbg`, which is deliberately last. |
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ is that the storm detector built for history/kernel.md section 13 named the
|
|||
line, the rate and the neighbour without anyone having to look.
|
||||
|
||||
**All four mechanisms now exist.** What remains on this plan is the second
|
||||
eviction and then the foreign driver host.
|
||||
eviction -- USB -- and then the foreign driver host.
|
||||
|
||||
### One thing the interface is deliberately not
|
||||
|
||||
|
|
@ -245,6 +245,73 @@ way rather than counted here.
|
|||
|
||||
---
|
||||
|
||||
## A modeset, from a process
|
||||
|
||||
H3 is one sentence in the milestone table -- *"a modeset API, which is the
|
||||
thing an out-of-kernel GPU driver makes affordable and an in-kernel one never
|
||||
got"* -- and the claim in it is worth testing rather than repeating.
|
||||
|
||||
```
|
||||
# schmode
|
||||
1280x800 current
|
||||
1280x800 maximum, framebuffer 4000 KB
|
||||
# schmode modes
|
||||
1280x800 *
|
||||
1280x720
|
||||
1024x768
|
||||
800x600
|
||||
640x480
|
||||
# schmode 1024 768
|
||||
1024x768 ok
|
||||
```
|
||||
|
||||
The scanout really resizes: captured from the virtio-gpu head, the frames come
|
||||
back 1280x800, then 1024x768, then 640x480, then 1280x800 again, with the
|
||||
checkerboard band showing no shear at any of them.
|
||||
|
||||
**Nothing in the kernel changed for this.** No syscall on the path has heard of
|
||||
a scanout; `schmode` writes a line to a socket and `vgpud` sends five commands
|
||||
to the device. That is the whole of the milestone, and the reason it is
|
||||
interesting is the comparison: the same five commands in the kernel would have
|
||||
been the same five commands *and a reason to be nervous*, because getting the
|
||||
sequence wrong there takes the machine instead of one process. **That is why
|
||||
the in-kernel driver never grew one** -- not difficulty, exposure.
|
||||
|
||||
### What it costs, and what it refuses
|
||||
|
||||
The framebuffer is allocated **once, at the largest mode**, and every smaller
|
||||
mode reuses it. `PCIIOC_DMA` has no free -- a driver's blocks come back when it
|
||||
exits and not before -- so a modeset that allocated would spend sixteen slots
|
||||
and then the arena, and the failure would look like a GPU bug rather than like
|
||||
counting. A mode larger than the initial allocation is refused, and says why:
|
||||
|
||||
```
|
||||
# schmode 1920 1080
|
||||
refused: larger than the framebuffer, which is fixed at startup
|
||||
```
|
||||
|
||||
That bound is 4 MB, `PCIIOC_DMA`'s cap, which at 32 bits per pixel is about
|
||||
1280x800. Raising it is a one-line change to a constant and a question about
|
||||
how much of a 16 MB arena one driver should be able to take, which is a better
|
||||
question than it looks and is not answered here.
|
||||
|
||||
### The socket, and the argument it settles
|
||||
|
||||
`vgpud` used to end in `for(;;) sleep(100);` under a comment arguing that
|
||||
building a control socket before there is a compositor to judge it is exactly
|
||||
the mistake this document spends a section warning about.
|
||||
|
||||
That argument was right about a *compositor protocol* and wrong as a reason to
|
||||
have no socket at all. A modeset API has a consumer that exists -- somebody
|
||||
changing the mode and looking at the screen -- and `schmode` is small enough
|
||||
that it can judge an interface this small. So the socket is there, it speaks
|
||||
lines of text for the same reasons
|
||||
[../architecture/debugging.md](../architecture/debugging.md) gives, and what is
|
||||
deliberately **not** on it is everything a compositor would need: no buffer
|
||||
submission, no damage, no vblank. Those still wait, for the original reason.
|
||||
|
||||
---
|
||||
|
||||
## The mechanisms
|
||||
|
||||
Four, and only the fourth is large.
|
||||
|
|
@ -357,8 +424,8 @@ start because the display driver is a process that needs a compositor.
|
|||
| **H0** | Mechanisms 2, 3 and 4, each with a test that exercises it from a userspace program against a device nothing else is using. | done |
|
||||
| **H1** | A userspace virtio-gpu driver, publishing `display_ops` across the channel. Schcom talks to it and does not know the difference. | done, except that Schcom does not talk to it -- `cmd/vgpud` holds the device and draws its own frame |
|
||||
| **H2** | Kill the driver process on purpose. The screen falls back to VBE, the driver restarts, the compositor reattaches. **This is the milestone that proves the whole idea**, and it is the one that cannot be skipped. | done, less the compositor -- see "The driver came back" |
|
||||
| **H3** | A modeset API, which is the thing an out-of-kernel GPU driver makes affordable and an in-kernel one never got. | |
|
||||
| **H4** | USB, same shape. | |
|
||||
| **H3** | A modeset API, which is the thing an out-of-kernel GPU driver makes affordable and an in-kernel one never got. | done -- see "A modeset, from a process" |
|
||||
| **H4** | USB, same shape. | the one left, and much the largest |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue