Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove RawCpuid #3625

Merged

Conversation

zulinx86
Copy link
Contributor

@zulinx86 zulinx86 commented Apr 21, 2023

Changes

  • Add a bidirectional direct conversion between kvm_bindings::CpuId and Cpuid.
  • Remove RawCpuid.

Reason

RawCpuid type was relayed as an intermediate type when converting between kvm_bindings::CpuId and Cpuid. By deleting RawCpuid, we can reduce a bunch of lines and unsafe codes.

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following
Developer Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md.

PR Checklist

  • [ ] If a specific issue led to this PR, this PR closes the issue.
  • The description of changes is clear and encompassing.
  • [ ] Any required documentation changes (code and docs) are included in this PR.
  • [ ] API changes follow the Runbook for Firecracker API changes.
  • [ ] User-facing changes are mentioned in CHANGELOG.md.
  • All added/changed functionality is tested.
  • [ ] New TODOs link to an issue.
  • Commits meet contribution quality standards.

  • [ ] This functionality cannot be added in rust-vmm.

@zulinx86 zulinx86 added the Type: Enhancement Indicates new feature requests label Apr 21, 2023
@zulinx86 zulinx86 self-assigned this Apr 21, 2023
@zulinx86 zulinx86 marked this pull request as ready for review April 21, 2023 19:42
@zulinx86 zulinx86 force-pushed the remove_raw_cpuid branch 2 times, most recently from ae64b45 to 10117c1 Compare April 21, 2023 20:50
@zulinx86 zulinx86 changed the title Remove RawCpuid Remove RawCpuid / IntelCpuid / AmdCpuid Apr 21, 2023
@zulinx86 zulinx86 force-pushed the remove_raw_cpuid branch 3 times, most recently from 158c271 to f2ef069 Compare April 23, 2023 11:00
Copy link
Contributor

@JonathanWoollett-Light JonathanWoollett-Light left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like including the intel and amd in the function names, this is something I feel is more elegantly implemented by including this information in a type, hence the IntelCpuid and AmdCpuid types. This makes sense to me as these types have separate distinct functionality. In the proposed implementation here it would be possible to call normalize_intel on an AMD CPUID.

To avoid this would require something like:

impl Cpuid {
    pub fn normalize(&self) -> Result<(),NormalizeCpuidError> {
        match self.manufacturer() {
            CpuidManufacturer::Intel => self.normalize_intel()?,
            CpuidManufacturer::Amd => self.normalize_amd()?
        }
    }
    fn normalize_intel(&self) -> Result<(),IntelNormalizeCpuidError> { /* .. */ }
    fn normalize_amd(&self) -> Result<(),AmdNormalizeCpuidError> { /* .. */ }
}

but this is much worse in my opinion, it embeds a check inside normalize, a user may already be doing duplicating work (this check require matching the manufacturer id string from within cpuid, and itself can error, so we also duplicate the error type variants in our returned error type, although only 1 of them is ever likely to occur) e.g.

self.normalize()?;
match self.manufacturer() {
    CpuidManufacturer::Intel => {
        /* some intel specific work */
    }
    CpuidManufacturer::Amd => {
        /* some amd specific work */  
    }
}

and it force all functions which only work for 1 manufacturer to have to themselves check the manufacturer of CPUID (which leads to quite a bit of duplicated work), and it forces these functions to handle a larger combined NormalizeCpuidError that has both the error types of AMD and Intel when they may only care about Intel or AMD e.g.

fn my_function(cpuid: &Cpuid) -> Result<(),MyFunctionError> {
    match cpuid {
        // Here `MyFunctionError` is defined as bigger more complex type
        // with variants from `AmdNormalizeError` when in practicality it can
        // never be constructed with these variants being selected.
        Cpuid::Intel(intel_cpuid) => intel_cpuid.normalize().map_err(MyFunctionError),
        Cpuid::Amd(amd_cpuid) => Err(MyFunctionError::Amd)
    }
}

I do not think it makes sense to remove IntelCpuid or AmdCpuid as they allow for a better implementation.

My concerns here are only exaggerated further when we consider implementing compatibility checking and serialization/de-serialization with named keys and fields.

@zulinx86
Copy link
Contributor Author

I do not like including the intel and amd in the function names, this is something I feel is more elegantly implemented by including this information in a type, hence the IntelCpuid and AmdCpuid types. This makes sense to me as these types have separate distinct functionality. In the proposed implementation here it would be possible to call normalize_intel on an AMD CPUID.

To avoid this would require something like:

impl Cpuid {
    pub fn normalize(&self) -> Result<(),NormalizeCpuidError> {
        match self.manufacturer() {
            CpuidManufacturer::Intel => self.normalize_intel()?,
            CpuidManufacturer::Amd => self.normalize_amd()?
        }
    }
    fn normalize_intel(&self) -> Result<(),IntelNormalizeCpuidError> { /* .. */ }
    fn normalize_amd(&self) -> Result<(),AmdNormalizeCpuidError> { /* .. */ }
}

but this is much worse in my opinion, it embeds a check inside normalize, a user may already be doing duplicating work (this check require matching the manufacturer id string from within cpuid, and itself can error, so we also duplicate the error type variants in our returned error type, although only 1 of them is ever likely to occur) e.g.

self.normalize()?;
match self.manufacturer() {
    CpuidManufacturer::Intel => {
        /* some intel specific work */
    }
    CpuidManufacturer::Amd => {
        /* some amd specific work */  
    }
}

and it force all functions which only work for 1 manufacturer to have to themselves check the manufacturer of CPUID (which leads to quite a bit of duplicated work), and it forces these functions to handle a larger combined NormalizeCpuidError that has both the error types of AMD and Intel when they may only care about Intel or AMD e.g.

fn my_function(cpuid: &Cpuid) -> Result<(),MyFunctionError> {
    match cpuid {
        // Here `MyFunctionError` is defined as bigger more complex type
        // with variants from `AmdNormalizeError` when in practicality it can
        // never be constructed with these variants being selected.
        Cpuid::Intel(intel_cpuid) => intel_cpuid.normalize().map_err(MyFunctionError),
        Cpuid::Amd(amd_cpuid) => Err(MyFunctionError::Amd)
    }
}

I do not think it makes sense to remove IntelCpuid or AmdCpuid as they allow for a better implementation.

My concerns here are only exaggerated further when we consider implementing compatibility checking and serialization/de-serialization with named keys and fields.

Thanks for sharing your good opinion! Let's make this PR focus on the removal of RawCpuid here, and discuss and consider the removal of IntelCpuid and AmdCpuid in a follow-up PR.

Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
Currently, when converting `kvm_bindings::CpuId` to `Cpuid`, it is
relaying `RawCpuid` as an intermediate type. To remove this, this commit
adds bidirectional direct type conversion between them.

Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
`RawCpuid` was relayed as an intermediate type when conversion between
`kvm_bindings::CpuId` and `Cpuid`. Deleting `RawCpuid` reduces a bunch
of lines and unsafe code.

Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
@zulinx86 zulinx86 force-pushed the remove_raw_cpuid branch 2 times, most recently from 6259377 to 118c48a Compare April 24, 2023 10:08
@zulinx86 zulinx86 changed the title Remove RawCpuid / IntelCpuid / AmdCpuid Remove RawCpuid Apr 24, 2023
Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
Signed-off-by: Takahiro Itazuri <itazur@amazon.com>
@zulinx86 zulinx86 added the Status: Awaiting review Indicates that a pull request is ready to be reviewed label Apr 24, 2023
@zulinx86 zulinx86 merged commit 7bd43f9 into firecracker-microvm:feature/cpu-templates Apr 24, 2023
@zulinx86 zulinx86 deleted the remove_raw_cpuid branch April 24, 2023 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting review Indicates that a pull request is ready to be reviewed Type: Enhancement Indicates new feature requests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants