[PATCH] qemu: add support for max-ram-below-4g option

Zhiyong Ye yezhiyong at bytedance.com
Tue Apr 27 06:53:04 UTC 2021


I'm sorry that the format of the last email seems to be problematic, so 
I sent it again.

On 4/26/21 3:55 PM, Peter Krempa wrote:
> On Sun, Apr 25, 2021 at 17:33:31 +0800, Zhiyong Ye wrote:
>> Limit the amount of ram below 4G. This can increase the address space
>> used by PCI devices below 4G and it can be used by adding attributes in
>> XML like this:
>> <domain>
>>    ...
>>    <memory unit="MiB" below4g="2048">4096</memory>
> 
> This illustrates that sharing the 'unit' argument between 'below4g' and
> the actual memory size is wrong (pointed out also below). In case the
> user modifies the unit but doesn't change below4g value it may be
> misrepresented and since below4g is new some tools might not actually
> know how to handle that.
> 
> below4g must either be by default in kiB, or have an own unit (which
> will probably be ugly).
> 

So, how should we place 'blow4g'? I have summarized that we may have two 
ways:

The first way is to put 'below4g' in the existing element, as Daniel 
suggested, that 'below4g' does not have its own 'unit' and let it 
default to KiB, e.g, <memory unit="MiB" below4g="2048"> 4096 </memory>

The second way is to add a new element and 'below4g' has its own 'unit', 
such as:
<memory unit='MiB'> 4096 </memory>
<below4gMemory unit='MiB'> 2048 </below4gMemory>

>>    ...
>> </domain>
>>
>> Signed-off-by: Zhiyong Ye <yezhiyong at bytedance.com>
>> Signed-off-by: zhenwei pi <pizhenwei at bytedance.com>
>> Signed-off-by: zhangruien <zhangruien at bytedance.com>
>> ---
>>   src/conf/domain_conf.c  | 19 +++++++++++++++++++
>>   src/conf/domain_conf.h  |  3 +++
>>   src/qemu/qemu_command.c |  4 ++++
> 
> Missing docs (doc/formatdomain.rst) and test changes. Also we usually
> don't mix conf and qemu changes.
> 
> You need at least a test case for qemuxml2argvtest and qemuxml2xmltest.
> 
> The conf change is also missing a check in the ABI stability checking
> code.
> 
> 
>>   3 files changed, 26 insertions(+)
>>
>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index a72d58f488..c211a69ed1 100644
>> --- a/src/conf/domain_conf.c
>> +++ b/src/conf/domain_conf.c
>> @@ -4720,6 +4720,19 @@ virDomainDefPostParseMemory(virDomainDef *def,
>>           return -1;
>>       }
>>   
>> +    if (def->mem.max_ram_below_4g &&
>> +        def->mem.max_ram_below_4g < (1ULL << 10)) {
>> +        virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                       _("maximum memory size below the 4GiB boundary is too small, "
>> +                         "BIOS may not work with less than 1MiB"));
> 
> "may not work" seems like you picked an arbitrary limit, and the same
> way it may not work with more than 1MiB. In cases when there isn't a
> strict technical limit, but rather "it usually doesn't work" like this
> the check is almost pointless.
> 

This is seen from QEMU code. When it is less than 1MiB, QEMU cannot 
create a new virtual machine.

>> +        return -1;
>> +    } else if (def->mem.max_ram_below_4g > (1ULL << 22)) {
> 
> we usually prefer to describe the limit as 4 * 1024 * 1024
> 
>> +        virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                       _("maximum memory size below the 4GiB boundary must be "
>> +                         "less than or equal to 4GiB"));
> 
> don't break up error messages into multiple lines
> 
>> +        return -1;
> 
> This belongs to conf/domain_validate.c
> 
> You'll need to add a new function e.g. 'virDomainDefValidateMemory' call
> it from virDomainDefValidateInternal and add those checks there.
> 
>> +    }
>> +
>>       return 0;
>>   }
>>   
>> @@ -19786,6 +19799,10 @@ virDomainDefParseMemory(virDomainDef *def,
>>                                &def->mem.max_memory, false, false) < 0)
>>           goto error;
>>   
>> +    if (virDomainParseMemory("./memory[1]/@below4g", "./memory[1]/@unit", ctxt,
>> +                             &def->mem.max_ram_below_4g, false, true) < 0)
> 
> This uses the 'unit' which is used for memory for the 'below4g'
> attribute.
> 
> 
>> +        goto error;
>> +
>>       if (virXPathUInt("string(./maxMemory[1]/@slots)", ctxt, &def->mem.memory_slots) == -2) {
>>           virReportError(VIR_ERR_XML_ERROR, "%s",
>>                          _("Failed to parse memory slot count"));
>> @@ -28844,6 +28861,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
>>       if (def->mem.dump_core)
>>           virBufferAsprintf(buf, " dumpCore='%s'",
>>                             virTristateSwitchTypeToString(def->mem.dump_core));
>> +    if (def->mem.max_ram_below_4g > 0)
>> +        virBufferAsprintf(buf, " below4g='%llu'", def->mem.max_ram_below_4g);
>>       virBufferAsprintf(buf, " unit='KiB'>%llu</memory>\n",
>>                         virDomainDefGetMemoryTotal(def));
>>   
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index 4838687edf..a939d43e93 100644
>> --- a/src/conf/domain_conf.h
>> +++ b/src/conf/domain_conf.h
>> @@ -2597,6 +2597,9 @@ struct _virDomainMemtune {
>>       unsigned long long max_memory; /* in kibibytes */
>>       unsigned int memory_slots; /* maximum count of RAM memory slots */
>>   
>> +    /* maximum memory below the 4GiB boundary (32bit boundary) */
>> +    unsigned long long max_ram_below_4g; /* in kibibytes */
>> +
>>       bool nosharepages;
>>       bool locked;
>>       int dump_core; /* enum virTristateSwitch */
>> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>> index be93182092..c69ad781e6 100644
>> --- a/src/qemu/qemu_command.c
>> +++ b/src/qemu/qemu_command.c
>> @@ -6961,6 +6961,10 @@ qemuBuildMachineCommandLine(virCommand *cmd,
>>                             cfg->dumpGuestCore ? "on" : "off");
>>       }
>>   
>> +    if (def->mem.max_ram_below_4g > 0)
>> +        virBufferAsprintf(&buf, ",max-ram-below-4g=%llu",
>> +                          def->mem.max_ram_below_4g * 1024);
>> +
>>       if (def->mem.nosharepages)
>>           virBufferAddLit(&buf, ",mem-merge=off");
>>   
>> -- 
>> 2.24.3 (Apple Git-128)
>>
> 




More information about the libvir-list mailing list