1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! crate for the vmm-swap feature.
#![deny(missing_docs)]
cfg_if::cfg_if! {
    if #[cfg(all(unix, feature = "enable"))] {
        mod controller;
        mod file;
        mod file_truncator;
        mod pagesize;
        mod present_list;
        // this is public only for integration tests.
        pub mod page_handler;
        mod processes;
        mod staging;
        mod uffd_list;
        // this is public only for integration tests.
        pub mod userfaultfd;
        // this is public only for integration tests.
        pub mod worker;
        pub use crate::controller::SwapDeviceHelper;
        pub use crate::controller::PrepareFork;
        pub use crate::controller::SwapController;
        pub use crate::controller::SwapDeviceUffdSender;
    }
}
use serde::Deserialize;
use serde::Serialize;
/// Current state of vmm-swap.
///
/// This should not contain fields but be a plain enum because this will be displayed to user using
/// `serde_json` crate.
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum SwapState {
    /// vmm-swap is ready. userfaultfd is disabled until vmm-swap is enabled.
    Ready = 0,
    /// swap out failed.
    Failed = 1,
    /// Pages in guest memory are moved to the staging memory.
    Pending = 2,
    /// Trimming staging memory.
    TrimInProgress = 3,
    /// swap-out is in progress.
    SwapOutInProgress = 4,
    /// swap out succeeded.
    Active = 5,
    /// swap-in is in progress.
    SwapInInProgress = 6,
}
/// Latency and number of pages of swap operations (move to staging, swap out, swap in).
///
/// The meaning of `StateTransition` depends on `State`.
///
/// | `State`             | `StateTransition`                            |
/// |---------------------|----------------------------------------------|
/// | `Ready`             | empty or transition record of `swap disable` |
/// | `Pending`           | transition record of `swap enable`           |
/// | `SwapOutInProgress` | transition record of `swap out`              |
/// | `Active`            | transition record of `swap out`              |
/// | `SwapInInProgress`  | transition record of `swap disable`          |
/// | `Failed`            | empty                                        |
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)]
pub struct SwapStateTransition {
    /// The number of pages moved for the state transition.
    pub pages: u64,
    /// Time taken for the state transition.
    pub time_ms: u64,
}
/// Current metrics of vmm-swap.
///
/// This is only available while vmm-swap is enabled.
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)]
pub struct SwapMetrics {
    /// count of pages on RAM.
    pub resident_pages: u64,
    /// count of pages copied from the vmm-swap file.
    pub copied_from_file_pages: u64,
    /// count of pages copied from the staging memory.
    pub copied_from_staging_pages: u64,
    /// count of pages initialized with zero.
    pub zeroed_pages: u64,
    /// count of pages which were already initialized on page faults. This can happen when several
    /// threads/processes access the uninitialized/removed page at the same time.
    pub redundant_pages: u64,
    /// count of pages in staging memory.
    pub staging_pages: u64,
    /// count of pages in swap files.
    pub swap_pages: u64,
}
/// The response to `crosvm swap status` command.
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct SwapStatus {
    /// Current vmm-swap [SwapState].
    pub state: SwapState,
    /// Current [SwapMetrics] of vmm-swap.
    pub metrics: SwapMetrics,
    /// Latency and number of pages for current [SwapState]. See [SwapStateTransition] for details.
    pub state_transition: SwapStateTransition,
}
impl SwapStatus {
    /// Creates dummy [SwapStatus].
    pub fn dummy() -> Self {
        SwapStatus {
            state: SwapState::Pending,
            metrics: SwapMetrics::default(),
            state_transition: SwapStateTransition::default(),
        }
    }
}