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