Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

virtio: implement ACPI power-off #499

Open
mbacarella opened this issue Nov 12, 2021 · 8 comments · May be fixed by #500 or #501
Open

virtio: implement ACPI power-off #499

mbacarella opened this issue Nov 12, 2021 · 8 comments · May be fixed by #500 or #501

Comments

@mbacarella
Copy link

Currently, when unikernels terminate they just kind of hang forever on GCE instances instead of powering off.

Additionally, when a GCE instance receives a stop command, it sends an ACPI power-off signal to the instance. On Solo5 it appears this is ignored, so the GCE hypervisor waits up to 90 seconds before actually shutting down the instance.

Not sure if this requires a full ACPI implementation that matches the underlying hardware running the server, which would be a huge ordeal, or if GCE provides a more virtualized form that can be harmlessly targeted on non-GCE hosts.

@mbacarella
Copy link
Author

mbacarella commented Nov 12, 2021

According to this GCE doc, we would need to add support for the controller PCI Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)

Booting Linux on GCE f1-micro, the output of lspci is:

00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)
00:01.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 03)
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
00:03.0 Non-VGA unclassified device: Red Hat, Inc Virtio SCSI
00:04.0 Ethernet controller: Red Hat, Inc Virtio network device
00:05.0 Unclassified device [00ff]: Red Hat, Inc Virtio RNG

Which confirms the document.

So, perhaps it is not too hard to add some code that detects that 82371AB device and installs support for ACPI power events.

@hannesm
Copy link
Contributor

hannesm commented Nov 14, 2021

This sounds like a worthwhile feature request if anyone is interested in contributing such a driver, the current virtio drivers (net/block) are in bindings/virtio. The underlying design question is whether such a power-off event should be forwarded to the unikernel (thus, extending the solo5 API - and figuring out whether other bindings & tenders provide a similar interface) for potentially cleanly shutting down, or calling solo5_exit directly. Certainly calling solo5_exit could be done for a start.

@mbacarella
Copy link
Author

mbacarella commented Nov 14, 2021 via email

@hannesm
Copy link
Contributor

hannesm commented Nov 17, 2021

better as a Mirage library

Sure, althought we'd need to pass through the device / memory address than.

Currently I'm thinking: couldn't ACPI power-off for the Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03) (scoped very tightly) be very simple -- i.e. looking for a single io-port? It would be great to not have a full-blown ACPI implementation as dependency.

@mbacarella
Copy link
Author

mbacarella commented Nov 17, 2021 via email

@Kensan
Copy link
Contributor

Kensan commented Nov 17, 2021

I would strongly suggest to find a simpler way than integrating (parts of) ACPI.

According to the section Stopping and starting a VM of the GCE documentation, when one initiates a VM shutdown via the management interface and ACPI shutdown is raised in the VM. This lets me conclude that Linux is supposed to perform an orderly shutdown, which ultimately leads to this part in the Linux kernel. You could try the BOOT_KBD variant which is basically a few I/O port access to 0x64.

@mbacarella
Copy link
Author

mbacarella commented Nov 17, 2021

I would strongly suggest to find a simpler way than integrating (parts of) ACPI.

According to the section Stopping and starting a VM of the GCE documentation, when one initiates a VM shutdown via the management interface and ACPI shutdown is raised in the VM. This lets me conclude that Linux is supposed to perform an orderly shutdown, which ultimately leads to this part in the Linux kernel. You could try the BOOT_KBD variant which is basically a few I/O port access to 0x64.

I don't know enough to comment on the validity of this approach, but I would like to note here that the code you linked will actually call into the pm_power_off function defined in piix4-poweroff.c, assuming the device was detected and configured. (It calls pm_power_off from native_machine_power_off).

I posted my attempt to adapt that in #500

Along a separate vein, there's also a very hacky way to attempt an ACPI shut down without implementing an ACPI interpreter, as described here. https://forum.osdev.org/viewtopic.php?t=16990 It's possible that hack will work on GCE.

I tried adapting that code but it raises too many pointer size casts and pointer integer casts warnings-as-errors to compile. A naive attempt to fix them partially succeeds in finding the ACPI RSDP header but fails to find the FACP header, because it segfaults instead. I've posted that at #501

@kit-ty-kate
Copy link

I've noticed this issue as well and it's fairly annoying. Is there a working workaround by any chance? I wasn't able to understand the conclusion of the discussion above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants