Repository: firecracker-microvm/firecracker
File: src/vmm/src/vstate/vcpu/mod.rs (Rust)

Code before:
            if let Ok(VcpuEvent::Finish) = self.event_receiver.recv() {
                break;
            }
        }
        StateMachine::finish()
    }

    #[cfg(not(test))]
    /// Calls `KVM_RUN` with this [`Vcpu`]'s underlying file descriptor.
    ///
    /// Blocks until a `VM_EXIT` is received, in which case this function returns a [`VcpuExit`]
    /// containing the reason.
    pub fn emulate(&self) -> Result<VcpuExit, errno::Error> {
        self.kvm_vcpu.fd.run()
    }

    /// Runs the vCPU in KVM context and handles the kvm exit reason.
    ///
    /// Returns error or enum specifying whether emulation was handled or interrupted.
    pub fn run_emulation(&self) -> Result<VcpuEmulation, VcpuError> {
        match self.emulate() {
            Ok(run) => match run {
                VcpuExit::MmioRead(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        let start_time =
                            utils::time::get_time_us(utils::time::ClockType::Monotonic);
                        mmio_bus.read(addr, data);
                        METRICS.vcpu.exit_mmio_read.inc();
                        record_latency_summary!(METRICS.vcpu.exit_mmio_read_agg, start_time);
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::MmioWrite(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        let start_time =
                            utils::time::get_time_us(utils::time::ClockType::Monotonic);
                        mmio_bus.write(addr, data);
                        METRICS.vcpu.exit_mmio_write.inc();
                        record_latency_summary!(METRICS.vcpu.exit_mmio_write_agg, start_time);
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::Hlt => {
                    info!("Received KVM_EXIT_HLT signal");
                    Ok(VcpuEmulation::Stopped)
                }
                VcpuExit::Shutdown => {
                    info!("Received KVM_EXIT_SHUTDOWN signal");
                    Ok(VcpuEmulation::Stopped)
                }
                // Documentation specifies that below kvm exits are considered

Review comment (performance):
Maybe we can move this (and `record_latency_summary` line) into `LatencyAggregateMetricWriter`(naming is hard) so that it gets the current time on creation and writes to the metric on drop?

Code after:
            if let Ok(VcpuEvent::Finish) = self.event_receiver.recv() {
                break;
            }
        }
        StateMachine::finish()
    }

    #[cfg(not(test))]
    /// Calls `KVM_RUN` with this [`Vcpu`]'s underlying file descriptor.
    ///
    /// Blocks until a `VM_EXIT` is received, in which case this function returns a [`VcpuExit`]
    /// containing the reason.
    pub fn emulate(&self) -> Result<VcpuExit, errno::Error> {
        self.kvm_vcpu.fd.run()
    }

    /// Runs the vCPU in KVM context and handles the kvm exit reason.
    ///
    /// Returns error or enum specifying whether emulation was handled or interrupted.
    pub fn run_emulation(&self) -> Result<VcpuEmulation, VcpuError> {
        match self.emulate() {
            Ok(run) => match run {
                VcpuExit::MmioRead(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        let _metric = METRICS.vcpu.exit_mmio_read_agg.record_latency_metrics();
                        mmio_bus.read(addr, data);
                        METRICS.vcpu.exit_mmio_read.inc();
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::MmioWrite(addr, data) => {
                    if let Some(mmio_bus) = &self.kvm_vcpu.mmio_bus {
                        let _metric = METRICS.vcpu.exit_mmio_write_agg.record_latency_metrics();
                        mmio_bus.write(addr, data);
                        METRICS.vcpu.exit_mmio_write.inc();
                    }
                    Ok(VcpuEmulation::Handled)
                }
                VcpuExit::Hlt => {
                    info!("Received KVM_EXIT_HLT signal");
                    Ok(VcpuEmulation::Stopped)
                }
                VcpuExit::Shutdown => {
                    info!("Received KVM_EXIT_SHUTDOWN signal");
                    Ok(VcpuEmulation::Stopped)
                }
                // Documentation specifies that below kvm exits are considered
                // errors.
                VcpuExit::FailEntry(hardware_entry_failure_reason, cpu) => {
                    // Hardware entry failure.
                    METRICS.vcpu.failures.inc();