From 5dce61563eaeb26a28c478cf0eb49f724a0a7c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Fri, 12 Apr 2024 14:21:56 +0200 Subject: [PATCH] pc_intel_fb: configure max framebuffer memory This commit introduces the means to configure the framebuffer memory used by the driver for sizing its buffers. Originally the avail memory was derived from the avail ram in the PD session, which roughly corresponds to configured RAM quota. However, since it is only used in a virtual capacity, we can decouple it from the actual memory and set to a value that accommodates larger framebuffer resolutions like 3840x2160. If the configured RAM quota is not enough to satisfy an allocation request the client will issue a resource request. Issue #5174. --- .../src/drivers/framebuffer/intel/pc/README | 10 +++++ .../src/drivers/framebuffer/intel/pc/emul.cc | 4 +- .../src/drivers/framebuffer/intel/pc/main.cc | 44 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/README b/repos/pc/src/drivers/framebuffer/intel/pc/README index bb951c161a..9154856e12 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/README +++ b/repos/pc/src/drivers/framebuffer/intel/pc/README @@ -49,6 +49,16 @@ The virtual resolution can be enforced by: ! ! +The amount of memory used by the driver for the accounting of its available +buffer space is set by: + +! +! + +The default and minimal value is '64M' and suffices for resolutions of at +least '3840x2160'. How much actual memory is used depends on the configured +resolution. + To present all available connectors and their possible resolutions to the user, the driver is able to deliver a corresponding report, which can be enabled in the configuration as follows: diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc index 429e5c9500..55c718b869 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc @@ -17,6 +17,8 @@ /* local includes */ #include "lx_emul.h" +extern unsigned long long driver_max_framebuffer_memory(void); + unsigned short emul_intel_gmch_control_reg() { @@ -39,5 +41,5 @@ unsigned short emul_intel_gmch_control_reg() unsigned long long emul_avail_ram() { - return Lx_kit::env().env.pd().avail_ram().value; + return driver_max_framebuffer_memory(); } diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc index f8a57f2d01..fe5690ce43 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc @@ -164,6 +164,43 @@ struct Framebuffer::Driver if (force_width && force_height) fn(force_width, force_height); } + + unsigned long long max_framebuffer_memory() + { + /* + * The max framebuffer memory is virtual in nature and denotes how + * the driver sizes its buffer space. When actual memory is used and + * the available RAM quota is not enough the component will issue a + * resource request. + * + * As the available memory is used during the initialization of the + * driver and is not queried afterwards it is safe to acquired it + * only once. Since it is used to size the GEM buffer pool set the amount + * of memory so that it includes the currently anticipated resolutions + * (e.g. 3840x2160) and is in line with the default value of the Intel GPU + * multiplexer. + */ + static unsigned long long _framebuffer_memory = 0; + + if (_framebuffer_memory) + return _framebuffer_memory; + + enum : unsigned { DEFAULT_FB_MEMORY = 64u << 20, }; + auto framebuffer_memory = Number_of_bytes(DEFAULT_FB_MEMORY); + if (config.valid()) + framebuffer_memory = + config.xml().attribute_value("max_framebuffer_memory", + framebuffer_memory); + + if (framebuffer_memory < DEFAULT_FB_MEMORY) { + warning("configured framebuffer memory too small, use default of ", + Number_of_bytes(DEFAULT_FB_MEMORY)); + framebuffer_memory = Number_of_bytes(DEFAULT_FB_MEMORY); + } + _framebuffer_memory = framebuffer_memory; + + return _framebuffer_memory; + } }; @@ -267,6 +304,13 @@ void Framebuffer::Driver::lookup_config(char const * const name, } +unsigned long long driver_max_framebuffer_memory(void) +{ + Genode::Env &env = Lx_kit::env().env; + return driver(env).max_framebuffer_memory(); +} + + /** * Can be called already as side-effect of `lx_emul_start_kernel`, * that's why the Driver object needs to be constructed already here.