From 9812799b242758df412bdc1b53d325d8eb46b016 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Fri, 15 Nov 2019 11:07:52 +0100 Subject: [PATCH] seoul: reduce CPU load in graphic mode - Stop refreshing if all CPUs go to sleep, also in text mode. - Any input resets update rate to 100Hz in graphic mode, which gets decreased step by step down to 25Hz if no input is available (looking video without input by user). Fixes #3576 --- repos/ports/run/seoul-auto.run | 2 +- repos/ports/run/seoul.inc | 2 +- repos/ports/src/app/seoul/component.cc | 29 +++++++++-- repos/ports/src/app/seoul/console.cc | 72 ++++++++++++++++++-------- repos/ports/src/app/seoul/console.h | 5 +- 5 files changed, 81 insertions(+), 29 deletions(-) diff --git a/repos/ports/run/seoul-auto.run b/repos/ports/run/seoul-auto.run index 07fdd8984..bb7ecb314 100644 --- a/repos/ports/run/seoul-auto.run +++ b/repos/ports/run/seoul-auto.run @@ -71,7 +71,7 @@ foreach binary $guest_os_binaries { source ${genode_dir}/repos/ports/run/seoul.inc -append qemu_args " -cpu phenom " +append qemu_args " -cpu phenom -smp 2 " append qemu_args " -net nic,model=e1000 " append qemu_args " -nographic " diff --git a/repos/ports/run/seoul.inc b/repos/ports/run/seoul.inc index c69eebad1..1c7b51192 100644 --- a/repos/ports/run/seoul.inc +++ b/repos/ports/run/seoul.inc @@ -74,7 +74,7 @@ build $build_components # write Seoul config file set vm_cfg_fd [open "bin/vm_seoul.cfg" w] puts $vm_cfg_fd "" -puts $vm_cfg_fd { +puts $vm_cfg_fd { diff --git a/repos/ports/src/app/seoul/component.cc b/repos/ports/src/app/seoul/component.cc index d966095d5..40018f5ec 100644 --- a/repos/ports/src/app/seoul/component.cc +++ b/repos/ports/src/app/seoul/component.cc @@ -785,7 +785,9 @@ class Machine : public StaticReceiver Seoul::Network *_nic { nullptr }; Rtc::Session *_rtc { nullptr }; - Vcpu * _vcpus[32] { nullptr }; + enum { MAX_CPUS = 8 }; + Vcpu * _vcpus[MAX_CPUS] { nullptr }; + Genode::Bit_array<64> _vcpus_active { }; /* * Noncopyable @@ -907,6 +909,8 @@ class Machine : public StaticReceiver ep_name->string(), location); + _vcpus_active.set(_vcpus_up, 1); + Vcpu * vcpu = new Vcpu(*ep, _vm_con, _heap, _env, _motherboard_lock, msg.vcpu, _guest_memory, _motherboard, @@ -956,12 +960,26 @@ class Machine : public StaticReceiver if (!_vcpus[vcpu_id]) return false; + _vcpus_active.clear(vcpu_id, 1); + + if (!_vcpus_active.get(0, 64)) { + MessageConsole msgcon(MessageConsole::Type::TYPE_KILL); + _unsynchronized_motherboard.bus_console.send(msgcon); + } + _motherboard_lock.unlock(); _vcpus[vcpu_id]->block(); _motherboard_lock.lock(); + if (!_vcpus_active.get(0, 64)) { + MessageConsole msgcon(MessageConsole::Type::TYPE_RESET); + _unsynchronized_motherboard.bus_console.send(msgcon); + } + + _vcpus_active.set(vcpu_id, 1); + return true; } @@ -1218,6 +1236,8 @@ class Machine : public StaticReceiver { using namespace Genode; + bool const verbose = machine_node.attribute_value("verbose", false); + Xml_node node = machine_node.sub_node(); for (;; node = node.next()) { @@ -1225,7 +1245,9 @@ class Machine : public StaticReceiver char name[MODEL_NAME_MAX_LEN]; node.type_name(name, sizeof(name)); - Genode::log("device: ", (char const *)name); + if (verbose) + Genode::log("device: ", (char const *)name); + Device_model_info *dmi = device_model_registry()->lookup(name); if (!dmi) { @@ -1249,7 +1271,8 @@ class Machine : public StaticReceiver Xml_node::Attribute arg = node.attribute(dmi->arg_names[i]); arg.value(&argv[i]); - Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i])); + if (verbose) + Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i])); } catch (Xml_node::Nonexistent_attribute) { } } diff --git a/repos/ports/src/app/seoul/console.cc b/repos/ports/src/app/seoul/console.cc index 5e89e54ab..398181a34 100644 --- a/repos/ports/src/app/seoul/console.cc +++ b/repos/ports/src/app/seoul/console.cc @@ -38,13 +38,13 @@ static Tff_font::Static_glyph_buffer<4096> glyph_buffer { }; static Tff_font default_font(_binary_mono_tff_start, glyph_buffer); static struct { - Genode::uint64_t checksum1 = 0; - Genode::uint64_t checksum2 = 0; - unsigned unchanged = 0; - bool cmp_even = 1; - bool active = false; - bool revoked = false; - bool vga_update= false; /* update indirectly by vbios */ + Genode::uint64_t checksum1 = 0; + Genode::uint64_t checksum2 = 0; + unsigned unchanged = 0; + bool cmp_even = 1; + bool active = false; + bool vga_revoked = false; + bool vga_update = false; /* update indirectly by vbios */ } fb_state; @@ -153,15 +153,17 @@ unsigned Seoul::Console::_input_to_ps2wheel(Input::Event const &ev) bool Seoul::Console::receive(MessageConsole &msg) { - if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) { + switch (msg.type) { + case MessageConsole::TYPE_ALLOC_VIEW : _guest_fb = msg.ptr; _regs = msg.regs; msg.view = 0; - } else if (msg.type == MessageConsole::TYPE_SWITCH_VIEW) { + return true; + case MessageConsole::TYPE_SWITCH_VIEW: /* XXX: For now, we only have one view. */ - } else if (msg.type == MessageConsole::TYPE_GET_MODEINFO) { - + return true; + case MessageConsole::TYPE_GET_MODEINFO: enum { MEMORY_MODEL_TEXT = 0, MEMORY_MODEL_DIRECT_COLOR = 6, @@ -210,9 +212,18 @@ bool Seoul::Console::receive(MessageConsole &msg) msg.info->phys_base = 0xe0000000; msg.info->_phys_size = _fb_mode.width()*_fb_mode.height()*2; return true; - } else return false; + } + return false; + case MessageConsole::TYPE_KILL: /* all CPUs go idle */ + _handle_fb(); /* refresh before going to sleep */ + fb_state.active = false; + return true; + case MessageConsole::TYPE_RESET: /* first of all sleeping CPUs woke up */ + _reactivate(); + return true; + default: + return true; } - return true; } void Screen::vga_updated() @@ -220,6 +231,14 @@ void Screen::vga_updated() fb_state.vga_update = true; } +void Seoul::Console::_reactivate() +{ + fb_state.active = true; + + MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000)); + _unsynchronized_motherboard.bus_timer.send(msg); +} + bool Seoul::Console::receive(MessageMemRegion &msg) { /* we had a fault in the text framebuffer */ @@ -234,11 +253,11 @@ bool Seoul::Console::receive(MessageMemRegion &msg) } if (reactivate) { - if (!fb_state.active) fb_state.active = true; + fb_state.vga_revoked = false; + Logging::printf("Reactivating text buffer loop.\n"); - MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000)); - _unsynchronized_motherboard.bus_timer.send(msg); + _reactivate(); } return false; } @@ -254,8 +273,7 @@ unsigned Seoul::Console::_handle_fb() /* transfer text buffer content into chunky canvas */ if (_regs->mode == TEXT_MODE) { - if (fb_state.revoked || !fb_state.active) - return 0; + if (fb_state.vga_revoked || !fb_state.active) return 0; memset(_pixels, 0, _fb_size); @@ -299,24 +317,32 @@ unsigned Seoul::Console::_handle_fb() _memory.detach(PHYS_FRAME_VGA_COLOR << 12, FRAME_COUNT_COLOR << 12); + fb_state.vga_revoked = true; fb_state.unchanged = 0; - fb_state.active = false; + _framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); Logging::printf("Deactivated text buffer loop.\n"); return 0; } - if (!fb_state.revoked) { - + if (!fb_state.vga_revoked) { _memory.detach(PHYS_FRAME_VGA_COLOR << 12, FRAME_COUNT_COLOR << 12); - fb_state.revoked = true; + fb_state.vga_revoked = true; + } + + if (!fb_state.active) { + fb_state.unchanged = 0; + return 0; } _framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); - return 10; + + fb_state.unchanged++; + + return (fb_state.unchanged > 4) ? 4 * 10 : fb_state.unchanged * 10; } diff --git a/repos/ports/src/app/seoul/console.h b/repos/ports/src/app/seoul/console.h index bde96fbfc..946389631 100644 --- a/repos/ports/src/app/seoul/console.h +++ b/repos/ports/src/app/seoul/console.h @@ -25,6 +25,7 @@ #include #include #include +#include /* os includes */ #include @@ -64,13 +65,13 @@ class Seoul::Console : public StaticReceiver Genode::addr_t const _vm_phys_fb; short *_pixels; Genode::Surface _surface; + unsigned _timer { 0 }; Keyboard _vkeyb { _motherboard }; char *_guest_fb { nullptr }; VgaRegs *_regs { nullptr }; bool _left { false }; bool _middle { false }; bool _right { false }; - unsigned _timer { 0 }; unsigned _input_to_ps2mouse(Input::Event const &); unsigned _input_to_ps2wheel(Input::Event const &); @@ -81,6 +82,8 @@ class Seoul::Console : public StaticReceiver void _handle_input(); unsigned _handle_fb(); + void _reactivate(); + /* * Noncopyable */