-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathlib.rs
148 lines (136 loc) · 5.32 KB
/
lib.rs
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
cfg_if::cfg_if! {
if #[cfg(target_os = "illumos")] {
mod illumos;
pub use illumos::*;
} else {
mod non_illumos;
pub use non_illumos::*;
}
}
pub mod cleanup;
pub mod disk;
pub use disk::*;
pub mod underlay;
/// Provides information from the underlying hardware about updates
/// which may require action on behalf of the Sled Agent.
///
/// These updates should generally be "non-opinionated" - the higher
/// layers of the sled agent can make the call to ignore these updates
/// or not.
#[derive(Clone, Debug)]
#[allow(dead_code)]
pub enum HardwareUpdate {
TofinoDeviceChange,
TofinoLoaded,
TofinoUnloaded,
DiskAdded(UnparsedDisk),
DiskRemoved(UnparsedDisk),
DiskUpdated(UnparsedDisk),
}
// The type of networking 'ASIC' the Dendrite service is expected to manage
#[derive(
Copy, Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "snake_case")]
pub enum DendriteAsic {
TofinoAsic,
TofinoStub,
SoftNpuZone,
SoftNpuPropolisDevice,
}
impl std::fmt::Display for DendriteAsic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
DendriteAsic::TofinoAsic => "tofino_asic",
DendriteAsic::TofinoStub => "tofino_stub",
DendriteAsic::SoftNpuZone => "soft_npu_zone",
DendriteAsic::SoftNpuPropolisDevice =>
"soft_npu_propolis_device",
}
)
}
}
/// Configuration for forcing a sled to run as a Scrimlet or Gimlet
#[derive(Copy, Clone, Debug)]
pub enum SledMode {
/// Automatically detect whether to run as a Gimlet or Scrimlet (w/ real Tofino ASIC)
Auto,
/// Force sled to run as a Gimlet
Gimlet,
/// Force sled to run as a Scrimlet
Scrimlet { asic: DendriteAsic },
}
/// Accounting for high watermark memory usage for various system purposes
#[derive(Copy, Clone, Debug)]
pub struct MemoryReservations {
/// Installed physical memory in this sled. Probably should hold a
/// [`HardwareManager`] and call `usable_physical_ram_bytes()` instead of
/// this.
hardware_physical_ram_bytes: u64,
/// The amount of memory expected to be used if "control plane" services all
/// running on this sled. "control plane" here refers to services that have
/// roughly fixed memory use given differing sled hardware configurations.
/// DNS (internal, external), Nexus, Cockroach, or ClickHouse are all
/// examples of "control plane" here.
///
/// This is a pessimistic overestimate; it is unlikely
/// (and one might say undesirable) that all such services are colocated on
/// a sled, and (as described in RFD 413) the budgeting for each service's
/// RAM must include headroom for those services potentially forking and
/// bursting required swap or resident pages.
//
// XXX: This is really something we should be told by Neuxs, perhaps after
// starting with this conservative estimate to get the sled started.
control_plane_earmark_bytes: u64,
/// The amount of memory used for `page_t` structures, assuming a distinct
/// `page_t` for each 4k page in the system. If we use larger pages, like
/// 2MiB pages, this will be potentially a gross overestimate.
max_page_t_space: u64,
// XXX: Crucible involves some amount of memory in support of the volumes it
// manages. We should collect zpool size and estimate the memory that would
// be used if all available storage was dedicated to Crucible volumes. For
// now this is part of the control plane earmark.
}
impl MemoryReservations {
pub fn new(
hardware_manager: HardwareManager,
control_plane_earmark_mib: Option<u32>,
) -> MemoryReservations {
let hardware_physical_ram_bytes =
hardware_manager.usable_physical_ram_bytes();
// Don't like hardcoding a struct size from the host OS here like
// this, maybe we shuffle some bits around before merging.. On the
// other hand, the last time page_t changed was illumos-gate commit
// a5652762e5 from 2006.
const PAGE_T_SIZE: u64 = 120;
let max_page_t_space =
hardware_manager.usable_physical_pages() * PAGE_T_SIZE;
const MIB: u64 = 1024 * 1024;
let control_plane_earmark_bytes =
u64::from(control_plane_earmark_mib.unwrap_or(0)) * MIB;
Self {
hardware_physical_ram_bytes,
max_page_t_space,
control_plane_earmark_bytes,
}
}
/// Compute the amount of physical memory that could be set aside for the
/// VMM reservoir.
///
/// The actual VMM reservoir will be smaller than this amount, and is either
/// a fixed amount of memory specified by `ReservoirMode::Size` or
/// a percentage of this amount specified by `ReservoirMode::Percentage`.
pub fn vmm_eligible(&self) -> u64 {
self.hardware_physical_ram_bytes
- self.max_page_t_space
- self.control_plane_earmark_bytes
}
}