[pve-devel] [PATCH v4 qemu-server 09/12] Add helpers to better structure CPU option handling

Fabian Grünbichler f.gruenbichler at proxmox.com
Mon Oct 14 13:12:35 CEST 2019


On October 7, 2019 2:47 pm, Stefan Reiter wrote:
> To avoid hardcoding even more CPU-flag related things for custom CPU
> models, introduce a dynamic approach to resolving flags.
> 
> resolve_cpu_flags takes a list of hashes (as documented in the
> comment) and resolves them to a valid "-cpu" argument without
> duplicates. This also helps by providing a reason why specific CPU flags
> have been added, and thus allows for useful warning messages should a
> flag be overwritten by another.
> 
> Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
> ---
>  PVE/QemuServer/CPUConfig.pm | 67 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 67 insertions(+)
> 
> diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm
> index fb8e852..405ad86 100644
> --- a/PVE/QemuServer/CPUConfig.pm
> +++ b/PVE/QemuServer/CPUConfig.pm
> @@ -298,6 +298,73 @@ sub print_cpu_device {
>      return "$cpu-x86_64-cpu,id=cpu$id,socket-id=$current_socket,core-id=$current_core,thread-id=0";
>  }
>  
> +# Resolves multiple arrays of hashes representing CPU flags with metadata to a
> +# single string in QEMU "-cpu" compatible format. Later arrays have higher
> +# priority.
> +#
> +# Hashes take the following format:
> +# {
> +#     aes => {
> +#         op => "+", # defaults to "" if undefined
> +#         reason => "to support AES acceleration", # for override warnings
> +#         value => "" # needed for kvm=off (value: off) etc...
> +#     },
> +#     ...
> +# }
> +sub resolve_cpu_flags {
> +    my $flag_hashes = \@_;

why? it's only used once two lines below, where you immediately 
derefence it again.

> +
> +    my $flags = {};
> +
> +    for my $hash (@$flag_hashes) {
> +	for my $flag_name (keys %$hash) {
> +	    my $flag = $hash->{$flag_name};
> +	    my $old_flag = $flags->{$flag_name};
> +
> +	    $flag->{op} //= "";
> +
> +	    if ($old_flag) {
> +		my $value_changed = defined($flag->{value}) != defined($old_flag->{value});
> +		if (!$value_changed && defined($flag->{value})) {
> +		    $value_changed = $flag->{value} eq $old_flag->{value};
> +		}

eq should be ne, right? either the definedness changed, or it was and is 
defined and the value changed?

AFAICT, this is in fact the following nested conditional:

my $value_changed = (defined($flag->{value}) != defined($old_flag->{value})) ||
                    (defined($flag->{value}) && $flag->{value} ne $old_flag->{value});

which is more readable IMHO, but you could also expand it more with 
additional variables.

> +
> +		if ($old_flag->{op} eq $flag->{op} && !$value_changed) {
> +		    $flags->{$flag_name}->{reason} .= " & $flag->{reason}";
> +		    next;
> +		}
> +
> +		my $old = print_cpuflag_hash($flag_name, $flags->{$flag_name});
> +		my $new = print_cpuflag_hash($flag_name, $flag);
> +		warn "warning: CPU flag/setting $new overwrites $old\n";
> +	    }
> +
> +	    $flags->{$flag_name} = $flag;
> +	}
> +    }
> +
> +    my $flag_str = '';
> +    # sort for command line stability
> +    for my $flag_name (sort keys %$flags) {
> +	$flag_str .= ',';
> +	$flag_str .= $flags->{$flag_name}->{op};
> +	$flag_str .= $flag_name;
> +	$flag_str .= "=$flags->{$flag_name}->{value}"
> +	    if $flags->{$flag_name}->{value};
> +    }
> +
> +    return $flag_str;
> +}
> +
> +sub print_cpuflag_hash {
> +    my ($flag_name, $flag) = @_;
> +    my $formatted = "'$flag->{op}$flag_name";
> +    $formatted .= "=$flag->{value}" if defined($flag->{value});
> +    $formatted .= "'";
> +    $formatted .= " ($flag->{reason})" if defined($flag->{reason});
> +    return $formatted;
> +}
> +
>  # Calculate QEMU's '-cpu' argument from a given VM configuration
>  sub get_cpu_options {
>      my ($conf, $arch, $kvm, $machine_type, $kvm_off, $kvmver, $winversion, $gpu_passthrough) = @_;
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 




More information about the pve-devel mailing list