Skip to content

Commit

Permalink
Store slabinfo in vec
Browse files Browse the repository at this point in the history
Summary:
Looks like /proc/slabinfo may contain rows with same name. Therefore, it may not be the best idea to store the rows in a map keyed by the name column. Just store the slabinfo entries in a vec instead and preserve the order.
Update the slabinfo field name in the recorded sample so that we don't try to deserialize and map into a vec. Previously recorded slabinfo data will be ignored.

Reviewed By: hnaz

Differential Revision: D66518742

fbshipit-source-id: d30423b91c48410011c9f53ad3195e145947c8f8
  • Loading branch information
lnyng authored and facebook-github-bot committed Nov 27, 2024
1 parent 3fc645d commit 8591979
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 134 deletions.
2 changes: 1 addition & 1 deletion below/model/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ fn collect_sample(
stat: reader.read_stat()?,
meminfo: reader.read_meminfo()?,
vmstat: reader.read_vmstat()?,
slabinfo: reader.read_slabinfo().unwrap_or_default(),
slabinfo_vec: reader.read_slabinfo().unwrap_or_default(),
ksm: if !options.enable_ksm_stats {
None
} else {
Expand Down
20 changes: 10 additions & 10 deletions below/model/src/common_field_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ pub const COMMON_MODEL_FIELD_IDS: [&str; 478] = [
"system.vm.pgscan_kswapd",
"system.vm.pgscan_direct",
"system.vm.oom_kill",
"system.slab.<key>.name",
"system.slab.<key>.active_objs",
"system.slab.<key>.num_objs",
"system.slab.<key>.obj_size",
"system.slab.<key>.obj_per_slab",
"system.slab.<key>.num_slabs",
"system.slab.<key>.active_caches",
"system.slab.<key>.num_caches",
"system.slab.<key>.active_size",
"system.slab.<key>.total_size",
"system.slab.<idx>.name",
"system.slab.<idx>.active_objs",
"system.slab.<idx>.num_objs",
"system.slab.<idx>.obj_size",
"system.slab.<idx>.obj_per_slab",
"system.slab.<idx>.num_slabs",
"system.slab.<idx>.active_caches",
"system.slab.<idx>.num_caches",
"system.slab.<idx>.active_size",
"system.slab.<idx>.total_size",
"system.ksm.advisor_max_cpu",
"system.ksm.advisor_max_pages_to_scan",
"system.ksm.advisor_min_pages_to_scan",
Expand Down
4 changes: 3 additions & 1 deletion below/model/src/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ pub struct SystemSample {
pub stat: procfs::Stat,
pub meminfo: procfs::MemInfo,
pub vmstat: procfs::VmStat,
// Previously named slabinfo as a BTreeMap. Updated to a Vec with a new name
// to avoid breaking replay due to deserialization errors.
#[serde(default)]
pub slabinfo: procfs::SlabInfoMap,
pub slabinfo_vec: Vec<procfs::SlabInfo>,
pub ksm: Option<procfs::Ksm>,
pub hostname: String,
pub disks: procfs::DiskMap,
Expand Down
8 changes: 4 additions & 4 deletions below/model/src/sample_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,24 @@ pub const SAMPLE_MODEL_JSON: &str = r#"
"pgscan_direct": 0,
"oom_kill": 0
},
"slab": {
"task_struct": {
"slab": [
{
"name": "task_group",
"active_objs": 13000,
"num_objs": 14000,
"obj_size": 6000,
"obj_per_slab": 5,
"num_slabs": 3000
},
"vmap_area": {
{
"name": "vmap_area",
"active_objs": 4000000,
"num_objs": 6000000,
"obj_size": 64,
"obj_per_slab": 64,
"num_slabs": 100000
}
},
],
"ksm": {
"advisor_max_cpu": 70,
"advisor_max_pages_to_scan": 30000,
Expand Down
14 changes: 7 additions & 7 deletions below/model/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct SystemModel {
#[queriable(subquery)]
pub vm: VmModel,
#[queriable(subquery)]
pub slab: BTreeMap<String, SingleSlabModel>,
pub slab: Vec<SingleSlabModel>,
#[queriable(subquery)]
pub ksm: Option<KsmModel>,
#[queriable(subquery)]
Expand Down Expand Up @@ -76,17 +76,17 @@ impl SystemModel {
.unwrap_or_default();

let mut slab = sample
.slabinfo
.slabinfo_vec
.iter()
.map(|(name, slab_info)| (name.to_owned(), SingleSlabModel::new(slab_info)))
.collect::<BTreeMap<String, SingleSlabModel>>();
.map(SingleSlabModel::new)
.collect::<Vec<SingleSlabModel>>();

let slab_total = slab.iter().fold(
SingleSlabModel {
name: Some(String::from("TOTAL")),
..Default::default()
},
|mut acc, (_, slabinfo)| {
|mut acc, slabinfo| {
acc.active_objs = opt_add(acc.active_objs, slabinfo.active_objs);
acc.num_objs = opt_add(acc.num_objs, slabinfo.num_objs);
acc.num_slabs = opt_add(acc.num_slabs, slabinfo.num_slabs);
Expand All @@ -97,7 +97,7 @@ impl SystemModel {
acc
},
);
slab.insert(String::from("TOTAL"), slab_total);
slab.insert(0, slab_total);

let ksm = sample.ksm.as_ref().map(KsmModel::new);

Expand Down Expand Up @@ -591,7 +591,7 @@ mod test {
"cpus": {},
"mem": {},
"vm": {},
"slab": {},
"slab": [],
"ksm": {},
"disks": {
"sda": {
Expand Down
28 changes: 14 additions & 14 deletions below/procfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,10 @@ impl ProcReader {
}
}

pub fn read_slabinfo(&self) -> Result<SlabInfoMap> {
pub fn read_slabinfo(&self) -> Result<Vec<SlabInfo>> {
let path = self.path.join("slabinfo");
let content = self.read_file_to_str(&path)?;
let mut slab_info_map: SlabInfoMap = Default::default();
let mut slab_info_vec = vec![];

// The first line is version, second line is headers:
//
Expand All @@ -415,19 +415,19 @@ impl ProcReader {
//
for line in content.lines().skip(2) {
let mut items = line.split_ascii_whitespace();
let mut slab_info: SlabInfo = Default::default();
let name = items.next().unwrap().to_owned();
slab_info.name = Some(name.clone());
slab_info.active_objs = parse_item!(path, items.next(), u64, line)?;
slab_info.num_objs = parse_item!(path, items.next(), u64, line)?;
slab_info.obj_size = parse_item!(path, items.next(), u64, line)?;
slab_info.obj_per_slab = parse_item!(path, items.next(), u64, line)?;
slab_info.pages_per_slab = parse_item!(path, items.next(), u64, line)?;
slab_info.active_slabs = parse_item!(path, items.nth(7), u64, line)?;
slab_info.num_slabs = parse_item!(path, items.next(), u64, line)?;
slab_info_map.insert(name, slab_info);
let slab_info = SlabInfo {
name: Some(items.next().unwrap().to_owned()),
active_objs: parse_item!(path, items.next(), u64, line)?,
num_objs: parse_item!(path, items.next(), u64, line)?,
obj_size: parse_item!(path, items.next(), u64, line)?,
obj_per_slab: parse_item!(path, items.next(), u64, line)?,
pages_per_slab: parse_item!(path, items.next(), u64, line)?,
active_slabs: parse_item!(path, items.nth(7), u64, line)?,
num_slabs: parse_item!(path, items.next(), u64, line)?,
};
slab_info_vec.push(slab_info);
}
Ok(slab_info_map)
Ok(slab_info_vec)
}

fn read_disk_fsinfo(&self, mount_info: &MountInfo) -> Option<(f32, u64)> {
Expand Down
201 changes: 106 additions & 95 deletions below/procfs/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,10 @@ swap_ra_hit 139012
fn test_read_slabinfo() {
let slabinfo = b"slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
zs_handle 3860100 6265344 8 512 1 : tunables 0 0 0 : slabdata 12237 12237 0
zspage 22225 24382 56 73 1 : tunables 0 0 0 : slabdata 334 334 0
zs_handle 157071 246784 8 512 1 : tunables 0 0 0 : slabdata 482 482 0
zspage 23311 24820 56 73 1 : tunables 0 0 0 : slabdata 340 340 0
zs_handle 160665 253440 8 512 1 : tunables 0 0 0 : slabdata 495 495 0
kvm_async_pf 0 0 136 30 1 : tunables 0 0 0 : slabdata 0 0 0
kvm_vcpu 0 0 9792 3 8 : tunables 0 0 0 : slabdata 0 0 0
kvm_mmu_page_header 0 0 184 44 2 : tunables 0 0 0 : slabdata 0 0 0
Expand All @@ -486,100 +489,108 @@ fn test_read_slabinfo() {
let slabinfo = reader
.read_slabinfo()
.expect("Failed to read slabinfo file");
let expected_slabinfo = std::collections::BTreeMap::from([
(
"zs_handle".to_string(),
SlabInfo {
name: Some("zs_handle".to_string()),
active_objs: Some(3860100),
num_objs: Some(6265344),
obj_size: Some(8),
obj_per_slab: Some(512),
pages_per_slab: Some(1),
active_slabs: Some(12237),
num_slabs: Some(12237),
},
),
(
"kvm_async_pf".to_string(),
SlabInfo {
name: Some("kvm_async_pf".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(136),
obj_per_slab: Some(30),
pages_per_slab: Some(1),
active_slabs: Some(0),
num_slabs: Some(0),
},
),
(
"kvm_vcpu".to_string(),
SlabInfo {
name: Some("kvm_vcpu".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(9792),
obj_per_slab: Some(3),
pages_per_slab: Some(8),
active_slabs: Some(0),
num_slabs: Some(0),
},
),
(
"kvm_mmu_page_header".to_string(),
SlabInfo {
name: Some("kvm_mmu_page_header".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(184),
obj_per_slab: Some(44),

pages_per_slab: Some(2),
active_slabs: Some(0),
num_slabs: Some(0),
},
),
(
"x86_emulator".to_string(),
SlabInfo {
name: Some("x86_emulator".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(2672),
obj_per_slab: Some(12),
pages_per_slab: Some(8),
active_slabs: Some(0),
num_slabs: Some(0),
},
),
(
"x86_fpu".to_string(),
SlabInfo {
name: Some("x86_fpu".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(4160),
obj_per_slab: Some(7),
pages_per_slab: Some(8),
active_slabs: Some(0),
num_slabs: Some(0),
},
),
(
"ext4_groupinfo_1k".to_string(),
SlabInfo {
name: Some("ext4_groupinfo_1k".to_string()),
active_objs: Some(90),
num_objs: Some(90),
obj_size: Some(136),
obj_per_slab: Some(30),
pages_per_slab: Some(1),
active_slabs: Some(3),
num_slabs: Some(3),
},
),
]);
let expected_slabinfo = vec![
SlabInfo {
name: Some("zspage".to_string()),
active_objs: Some(22225),
num_objs: Some(24382),
obj_size: Some(56),
obj_per_slab: Some(73),
pages_per_slab: Some(1),
active_slabs: Some(334),
num_slabs: Some(334),
},
SlabInfo {
name: Some("zs_handle".to_string()),
active_objs: Some(157071),
num_objs: Some(246784),
obj_size: Some(8),
obj_per_slab: Some(512),
pages_per_slab: Some(1),
active_slabs: Some(482),
num_slabs: Some(482),
},
SlabInfo {
name: Some("zspage".to_string()),
active_objs: Some(23311),
num_objs: Some(24820),
obj_size: Some(56),
obj_per_slab: Some(73),
pages_per_slab: Some(1),
active_slabs: Some(340),
num_slabs: Some(340),
},
SlabInfo {
name: Some("zs_handle".to_string()),
active_objs: Some(160665),
num_objs: Some(253440),
obj_size: Some(8),
obj_per_slab: Some(512),
pages_per_slab: Some(1),
active_slabs: Some(495),
num_slabs: Some(495),
},
SlabInfo {
name: Some("kvm_async_pf".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(136),
obj_per_slab: Some(30),
pages_per_slab: Some(1),
active_slabs: Some(0),
num_slabs: Some(0),
},
SlabInfo {
name: Some("kvm_vcpu".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(9792),
obj_per_slab: Some(3),
pages_per_slab: Some(8),
active_slabs: Some(0),
num_slabs: Some(0),
},
SlabInfo {
name: Some("kvm_mmu_page_header".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(184),
obj_per_slab: Some(44),
pages_per_slab: Some(2),
active_slabs: Some(0),
num_slabs: Some(0),
},
SlabInfo {
name: Some("x86_emulator".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(2672),
obj_per_slab: Some(12),
pages_per_slab: Some(8),
active_slabs: Some(0),
num_slabs: Some(0),
},
SlabInfo {
name: Some("x86_fpu".to_string()),
active_objs: Some(0),
num_objs: Some(0),
obj_size: Some(4160),
obj_per_slab: Some(7),
pages_per_slab: Some(8),
active_slabs: Some(0),
num_slabs: Some(0),
},
SlabInfo {
name: Some("ext4_groupinfo_1k".to_string()),
active_objs: Some(90),
num_objs: Some(90),
obj_size: Some(136),
obj_per_slab: Some(30),
pages_per_slab: Some(1),
active_slabs: Some(3),
num_slabs: Some(3),
},
];
assert_eq!(slabinfo, expected_slabinfo);
}

Expand Down
1 change: 0 additions & 1 deletion below/procfs/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,6 @@ pub struct PidInfo {
pub type PidMap = BTreeMap<i32, PidInfo>;
pub type NetMap = BTreeMap<String, InterfaceStat>;
pub type DiskMap = BTreeMap<String, DiskStat>;
pub type SlabInfoMap = BTreeMap<String, SlabInfo>;

#[derive(Default, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct NetStat {
Expand Down
Loading

0 comments on commit 8591979

Please sign in to comment.