dma: the 4 MB cap was the refusal, not the arena
vgpud: wanted 7365 KB of DMA memory for a 1920x982 framebuffer
vgpud: not enough contiguous DMA memory
schinitd: restarting os.schos.vgpud (and again, and again, until
schinit: supervisor stopped answering schinit replaced schinitd)
Every number in that diagnostic was about the arena, and the arena had 61 MB
free. The refusal came from do_dma()'s per-request cap, which was 4 MB --
exactly one framebuffer at 1280x800, chosen when that was the only thing
anybody asked for.
virtio-gpu's display size is the size of the **host's window**. Drag it out and
the guest is asked for 1920x982x4 in one contiguous piece, and no amount of
free arena helps. 32 MB now, which is 2560x1600 with room over. The cap is not
there to ration memory -- the arena does that and says so properly -- it is
there so a wild size cannot ask for everything by accident.
DMA_ARENA_BYTES 16 -> 64 MB alongside, for the reason its own comment already
gave and then got the arithmetic wrong on: either side of the handover *both*
drivers hold a framebuffer, so the requirement is two at the largest mode, not
one. 16 MB is two at 1280x800 and nothing bigger. Verified booting at 256M and
512M as well as 1G.
And vgpud no longer dies when it cannot have what it asked for. It claims the
framebuffer before creating the resource, and if the full size cannot be had it
steps down by thirds to 640x480 before giving up -- and gives up with
SCHINIT_EXIT_NORESTART rather than die(), because a driver that will fail
identically on every restart should not be restarted. That loop is what made
schinit replace the supervisor mid-boot.
vgpud: the display is 1920x1080 but only 1280x720 of DMA could be had
is what it says when it steps down. With the cap raised it does not need to:
1920x1080 now allocates its full 8100 KB, 0 restarts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
parent
ff7afa746e
commit
ca28978995
4 changed files with 121 additions and 34 deletions
|
|
@ -21,18 +21,32 @@
|
|||
// will happily reorder stores to a ring, so a driver still needs a barrier
|
||||
// between filling a descriptor and telling the device about it.
|
||||
|
||||
// 16 MB, not 4.
|
||||
// 64 MB, and the arithmetic is worth writing down because it has been got
|
||||
// wrong twice.
|
||||
//
|
||||
// 4 MB was one framebuffer at 1280x800, and that was fine while exactly one
|
||||
// driver wanted one. It stopped being fine the day a display driver could be
|
||||
// handed to userspace (docs/plan/hybrid.md): for the moment either side of the
|
||||
// handover both drivers exist, and the incoming one has to allocate its
|
||||
// framebuffer before the outgoing one is gone.
|
||||
// 4 MB was one framebuffer at 1280x800, which was fine while exactly one driver
|
||||
// wanted one. It stopped being fine the day a display driver could be handed to
|
||||
// userspace (docs/plan/hybrid.md): either side of that handover **both drivers
|
||||
// exist**, and the incoming one has to allocate its framebuffer before the
|
||||
// outgoing one lets go of its own. So the real requirement is two framebuffers
|
||||
// at once, not one.
|
||||
//
|
||||
// It is carved off the top of physical memory at boot and never grows, so the
|
||||
// cost of being wrong in this direction is 12 MB and the cost of being wrong
|
||||
// in the other is a driver that cannot start.
|
||||
#define DMA_ARENA_BYTES (16*1024*1024)
|
||||
// 16 MB was chosen for two at 1280x800 (4 MB each) and that is what it holds.
|
||||
// It does not hold two of anything larger, and virtio-gpu's size is **the size
|
||||
// of the host's window**, which the user resizes. A 1920x982 window is 7365 KB
|
||||
// a copy, so the handover needs 14.4 MB of a 16 MB arena and then fails on the
|
||||
// rings and the alignment:
|
||||
//
|
||||
// vgpud: wanted 7365 KB of DMA memory for a 1920x982 framebuffer
|
||||
// vgpud: not enough contiguous DMA memory
|
||||
// schinitd: restarting os.schos.vgpud (and again, and again)
|
||||
//
|
||||
// 64 MB is two framebuffers at 2560x1440 with room to spare, which covers any
|
||||
// window somebody is likely to drag out on a desktop. It is carved off the top
|
||||
// of physical memory at boot and never grows, so it is 64 MB this kernel cannot
|
||||
// use for anything else -- 6% of the 1 GB this is usually run with, against a
|
||||
// display driver that otherwise cannot start at all.
|
||||
#define DMA_ARENA_BYTES (64*1024*1024)
|
||||
|
||||
void dma_init(void *vstart, void *vend);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue