From a6a923c31bebc2940418a6ea58b35a4ca27c45c0 Mon Sep 17 00:00:00 2001 From: Norman Feske <norman.feske@genode-labs.com> Date: Mon, 11 Jan 2021 16:53:21 +0100 Subject: [PATCH] driver manager: restart intel_fb when frozen This patch introduces heartbeat monitoring and automated restarting of the intel framebuffer driver. --- .../raw/drivers_managed-pc/drivers.config | 49 ++++++----- repos/gems/src/app/driver_manager/main.cc | 86 +++++++++++++++---- 2 files changed, 97 insertions(+), 38 deletions(-) diff --git a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config index 772dfee9c4..14c68b4e76 100644 --- a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config +++ b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config @@ -39,17 +39,19 @@ <resource name="RAM" quantum="2M"/> <provides> <service name="Report"/> <service name="ROM"/> </provides> <config verbose="no"> - <policy label="platform_drv -> acpi" report="acpi_drv -> acpi"/> - <policy label="driver_manager -> pci_devices" report="platform_drv -> pci"/> - <policy label="usb_drv -> config" report="driver_manager -> usb_drv.config"/> - <policy label="driver_manager -> usb_devices" report="usb_drv -> devices"/> - <policy label="dynamic -> config" report="driver_manager -> init.config"/> - <policy label="driver_manager -> ahci_ports" report="dynamic -> ahci_ports"/> - <policy label="driver_manager -> nvme_ns" report="dynamic -> nvme_ns"/> - <policy label="rom_reporter -> acpi" report="acpi_drv -> acpi"/> - <policy label="rom_reporter -> pci_devices" report="platform_drv -> pci"/> - <policy label="rom_reporter -> usb_devices" report="usb_drv -> devices"/> - <policy label="usb_hid_drv -> report" report="usb_drv -> devices"/> + <policy label="platform_drv -> acpi" report="acpi_drv -> acpi"/> + <policy label="driver_manager -> pci_devices" report="platform_drv -> pci"/> + <policy label="usb_drv -> config" report="driver_manager -> usb_drv.config"/> + <policy label="driver_manager -> usb_devices" report="usb_drv -> devices"/> + <policy label="driver_manager -> dynamic_state" report="dynamic -> state"/> + <policy label="dynamic -> config" report="driver_manager -> init.config"/> + <policy label="driver_manager -> ahci_ports" report="dynamic -> ahci_ports"/> + <policy label="driver_manager -> nvme_ns" report="dynamic -> nvme_ns"/> + <policy label="rom_reporter -> acpi" report="acpi_drv -> acpi"/> + <policy label="rom_reporter -> pci_devices" report="platform_drv -> pci"/> + <policy label="rom_reporter -> usb_devices" report="usb_drv -> devices"/> + <policy label="rom_reporter -> dynamic_state" report="dynamic -> state"/> + <policy label="usb_hid_drv -> report" report="usb_drv -> devices"/> </config> </start> @@ -59,14 +61,17 @@ <rom label="acpi"/> <rom label="pci_devices"/> <rom label="usb_devices"/> + <rom label="dynamic_state"/> </config> <route> - <service name="ROM" label="acpi"> <child name="report_rom"/> </service> - <service name="ROM" label="pci_devices"> <child name="report_rom"/> </service> - <service name="ROM" label="usb_devices"> <child name="report_rom"/> </service> - <service name="Report" label="acpi"> <parent label="acpi"/> </service> - <service name="Report" label="pci_devices"> <parent label="pci_devices"/> </service> - <service name="Report" label="usb_devices"> <parent label="usb_devices"/> </service> + <service name="ROM" label="acpi"> <child name="report_rom"/> </service> + <service name="ROM" label="pci_devices"> <child name="report_rom"/> </service> + <service name="ROM" label="usb_devices"> <child name="report_rom"/> </service> + <service name="ROM" label="dynamic_state"> <child name="report_rom"/> </service> + <service name="Report" label="acpi"> <parent label="acpi"/> </service> + <service name="Report" label="pci_devices"> <parent label="pci_devices"/> </service> + <service name="Report" label="usb_devices"> <parent label="usb_devices"/> </service> + <service name="Report" label="dynamic_state"> <parent label="dynamic -> state"/> </service> <service name="LOG"> <parent/> </service> <service name="PD"> <parent/> </service> <service name="CPU"> <parent/> </service> @@ -226,10 +231,11 @@ <service name="Report" label="init.config"> <child name="report_rom"/> </service> <service name="Report" label="usb_drv.config"> <child name="report_rom"/> </service> <service name="Report" label="block_devices"> <parent label="block_devices"/> </service> - <service name="ROM" label="usb_devices"> <child name="report_rom"/> </service> - <service name="ROM" label="pci_devices"> <child name="report_rom"/> </service> - <service name="ROM" label="ahci_ports"> <child name="report_rom"/> </service> - <service name="ROM" label="nvme_ns"> <child name="report_rom"/> </service> + <service name="ROM" label="usb_devices"> <child name="report_rom"/> </service> + <service name="ROM" label="pci_devices"> <child name="report_rom"/> </service> + <service name="ROM" label="ahci_ports"> <child name="report_rom"/> </service> + <service name="ROM" label="nvme_ns"> <child name="report_rom"/> </service> + <service name="ROM" label="dynamic_state"> <child name="report_rom"/> </service> <service name="LOG"> <parent/> </service> <service name="PD"> <parent/> </service> <service name="CPU"> <parent/> </service> @@ -248,6 +254,7 @@ <service name="Platform"> <child name="platform_drv"/> </service> <service name="Report" label="ahci_ports"> <child name="report_rom"/> </service> <service name="Report" label="nvme_ns"> <child name="report_rom"/> </service> + <service name="Report" label="state"> <child name="report_rom"/> </service> <service name="Report"> <parent/> </service> <service name="Usb"> <child name="usb_drv"/> </service> <service name="ROM" label="config"> <child name="report_rom"/> </service> diff --git a/repos/gems/src/app/driver_manager/main.cc b/repos/gems/src/app/driver_manager/main.cc index 348b334f6e..3c0902227e 100644 --- a/repos/gems/src/app/driver_manager/main.cc +++ b/repos/gems/src/app/driver_manager/main.cc @@ -38,6 +38,8 @@ namespace Driver_manager { struct Nvme_driver; struct Priority { int value; }; + + struct Version { unsigned value; }; } @@ -62,11 +64,13 @@ class Driver_manager::Device_driver : Noncopyable Binary const &binary, Ram_quota ram, Cap_quota caps, - Priority priority) + Priority priority, + Version version) { xml.attribute("name", name); xml.attribute("caps", String<64>(caps)); xml.attribute("priority", priority.value); + xml.attribute("version", version.value); xml.node("binary", [&] () { xml.attribute("name", binary); }); xml.node("resource", [&] () { xml.attribute("name", "RAM"); @@ -122,12 +126,15 @@ class Driver_manager::Device_driver : Noncopyable struct Driver_manager::Intel_fb_driver : Device_driver { + Version version { 0 }; + void generate_start_node(Xml_generator &xml) const override { xml.node("start", [&] () { _gen_common_start_node_content(xml, "intel_fb_drv", "intel_fb_drv", Ram_quota{42*1024*1024}, Cap_quota{800}, - Priority{0}); + Priority{0}, version); + xml.node("heartbeat", [&] () { }); xml.node("route", [&] () { _gen_config_route(xml, "fb_drv.config"); _gen_default_parent_route(xml); @@ -144,7 +151,7 @@ struct Driver_manager::Vesa_fb_driver : Device_driver xml.node("start", [&] () { _gen_common_start_node_content(xml, "vesa_fb_drv", "vesa_fb_drv", Ram_quota{8*1024*1024}, Cap_quota{100}, - Priority{-1}); + Priority{-1}, Version{0}); xml.node("route", [&] () { _gen_config_route(xml, "fb_drv.config"); _gen_default_parent_route(xml); @@ -188,7 +195,7 @@ struct Driver_manager::Boot_fb_driver : Device_driver xml.node("start", [&] () { _gen_common_start_node_content(xml, "boot_fb_drv", "boot_fb_drv", _ram_quota, Cap_quota{100}, - Priority{-1}); + Priority{-1}, Version{0}); xml.node("route", [&] () { _gen_config_route(xml, "fb_drv.config"); _gen_default_parent_route(xml); @@ -205,7 +212,7 @@ struct Driver_manager::Ahci_driver : Device_driver xml.node("start", [&] () { _gen_common_start_node_content(xml, "ahci_drv", "ahci_drv", Ram_quota{10*1024*1024}, Cap_quota{100}, - Priority{-1}); + Priority{-1}, Version{0}); _gen_provides_node<Block::Session>(xml); xml.node("config", [&] () { xml.node("report", [&] () { xml.attribute("ports", "yes"); }); @@ -217,6 +224,7 @@ struct Driver_manager::Ahci_driver : Device_driver }); } }); + xml.node("heartbeat", [&] () { }); xml.node("route", [&] () { xml.node("service", [&] () { xml.attribute("name", "Report"); @@ -260,7 +268,7 @@ struct Driver_manager::Nvme_driver : Device_driver xml.node("start", [&] () { _gen_common_start_node_content(xml, "nvme_drv", "nvme_drv", Ram_quota{8*1024*1024}, Cap_quota{100}, - Priority{-1}); + Priority{-1}, Version{0}); _gen_provides_node<Block::Session>(xml); xml.node("config", [&] () { xml.node("report", [&] () { xml.attribute("namespaces", "yes"); }); @@ -308,12 +316,13 @@ struct Driver_manager::Main : private Block_devices_generator { Env &_env; - Attached_rom_dataspace _platform { _env, "platform_info" }; - Attached_rom_dataspace _usb_devices { _env, "usb_devices" }; - Attached_rom_dataspace _usb_policy { _env, "usb_policy" }; - Attached_rom_dataspace _pci_devices { _env, "pci_devices" }; - Attached_rom_dataspace _ahci_ports { _env, "ahci_ports" }; - Attached_rom_dataspace _nvme_ns { _env, "nvme_ns" }; + Attached_rom_dataspace _platform { _env, "platform_info" }; + Attached_rom_dataspace _usb_devices { _env, "usb_devices" }; + Attached_rom_dataspace _usb_policy { _env, "usb_policy" }; + Attached_rom_dataspace _pci_devices { _env, "pci_devices" }; + Attached_rom_dataspace _ahci_ports { _env, "ahci_ports" }; + Attached_rom_dataspace _nvme_ns { _env, "nvme_ns" }; + Attached_rom_dataspace _dynamic_state { _env, "dynamic_state" }; Reporter _init_config { _env, "config", "init.config" }; Reporter _usb_drv_config { _env, "config", "usb_drv.config" }; @@ -359,6 +368,11 @@ struct Driver_manager::Main : private Block_devices_generator Signal_handler<Main> _nvme_ns_update_handler { _env.ep(), *this, &Main::_handle_nvme_ns_update }; + Signal_handler<Main> _dynamic_state_handler { + _env.ep(), *this, &Main::_handle_dyanmic_state }; + + void _handle_dyanmic_state(); + static void _gen_parent_service_xml(Xml_generator &xml, char const *name) { xml.node("service", [&] () { xml.attribute("name", name); }); @@ -381,10 +395,11 @@ struct Driver_manager::Main : private Block_devices_generator _usb_drv_config.enabled(true); _block_devices.enabled(true); - _pci_devices.sigh(_pci_devices_update_handler); - _usb_policy .sigh(_usb_policy_update_handler); - _ahci_ports .sigh(_ahci_ports_update_handler); - _nvme_ns .sigh(_nvme_ns_update_handler); + _pci_devices .sigh(_pci_devices_update_handler); + _usb_policy .sigh(_usb_policy_update_handler); + _ahci_ports .sigh(_ahci_ports_update_handler); + _nvme_ns .sigh(_nvme_ns_update_handler); + _dynamic_state.sigh(_dynamic_state_handler); _generate_init_config(_init_config); @@ -518,7 +533,12 @@ void Driver_manager::Main::_generate_init_config(Reporter &init_config) const xml.attribute("verbose", false); xml.attribute("prio_levels", 2); - xml.node("report", [&] () { xml.attribute("child_ram", true); }); + xml.node("report", [&] () { + xml.attribute("child_ram", true); + xml.attribute("delay_ms", 2500); + }); + + xml.node("heartbeat", [&] () { xml.attribute("rate_ms", 2500); }); xml.node("parent-provides", [&] () { _gen_parent_service_xml(xml, Rom_session::service_name()); @@ -708,4 +728,36 @@ void Driver_manager::Main::_generate_usb_drv_config(Reporter &usb_drv_config, } +void Driver_manager::Main::_handle_dyanmic_state() +{ + _dynamic_state.update(); + + bool reconfigure_dynamic_init = false; + + _dynamic_state.xml().for_each_sub_node([&] (Xml_node child) { + + using Name = Device_driver::Name; + + Name const name = child.attribute_value("name", Name()); + + if (name == "intel_fb_drv") { + + unsigned long const skipped_heartbeats = + child.attribute_value("skipped_heartbeats", 0U); + + if (skipped_heartbeats >= 2) { + + if (_intel_fb_driver.constructed()) { + _intel_fb_driver->version.value++; + reconfigure_dynamic_init = true; + } + } + } + }); + + if (reconfigure_dynamic_init) + _generate_init_config(_init_config); +} + + void Component::construct(Genode::Env &env) { static Driver_manager::Main main(env); }