@@ -38,6 +38,9 @@ pub struct SingleCgroupModel {
38
38
pub pressure : Option < CgroupPressureModel > ,
39
39
#[ queriable( subquery) ]
40
40
pub cgroup_stat : Option < CgroupStatModel > ,
41
+ #[ queriable( subquery) ]
42
+ #[ queriable( preferred_name = mem_numa) ]
43
+ pub memory_numa_stat : Option < BTreeMap < u32 , CgroupMemoryNumaModel > > ,
41
44
}
42
45
43
46
/// A model that represents a cgroup subtree. Each instance is a node that uses
@@ -225,6 +228,24 @@ impl CgroupModel {
225
228
226
229
let cgroup_stat = sample. cgroup_stat . as_ref ( ) . map ( CgroupStatModel :: new) ;
227
230
231
+ let memory_numa_stat = {
232
+ sample. memory_numa_stat . as_ref ( ) . map ( |end_numa_nodes| {
233
+ let begin_numa_nodes = last_if_inode_matches. and_then ( |( s, d) | {
234
+ s. memory_numa_stat
235
+ . as_ref ( )
236
+ . map ( |numa_nodes| ( numa_nodes, d) )
237
+ } ) ;
238
+ end_numa_nodes
239
+ . iter ( )
240
+ . map ( |( node_id, stat) | {
241
+ let begin_numa_stat = begin_numa_nodes
242
+ . and_then ( |( nodes, d) | nodes. get ( node_id) . map ( |stat| ( stat, d) ) ) ;
243
+ ( * node_id, CgroupMemoryNumaModel :: new ( stat, begin_numa_stat) )
244
+ } )
245
+ . collect ( )
246
+ } )
247
+ } ;
248
+
228
249
// recursively calculate view of children
229
250
// `children` is optional, but we treat it the same as an empty map
230
251
let empty = BTreeMap :: new ( ) ;
@@ -262,6 +283,7 @@ impl CgroupModel {
262
283
pressure,
263
284
depth,
264
285
cgroup_stat,
286
+ memory_numa_stat,
265
287
} ,
266
288
children,
267
289
count : nr_descendants + 1 ,
@@ -653,6 +675,119 @@ impl CgroupPressureModel {
653
675
}
654
676
}
655
677
}
678
+ #[ derive(
679
+ Clone ,
680
+ Debug ,
681
+ Default ,
682
+ PartialEq ,
683
+ Serialize ,
684
+ Deserialize ,
685
+ below_derive:: Queriable
686
+ ) ]
687
+ pub struct CgroupMemoryNumaModel {
688
+ pub total : Option < u64 > ,
689
+ pub anon : Option < u64 > ,
690
+ pub file : Option < u64 > ,
691
+ pub kernel_stack : Option < u64 > ,
692
+ pub pagetables : Option < u64 > ,
693
+ pub shmem : Option < u64 > ,
694
+ pub file_mapped : Option < u64 > ,
695
+ pub file_dirty : Option < u64 > ,
696
+ pub file_writeback : Option < u64 > ,
697
+ pub swapcached : Option < u64 > ,
698
+ pub anon_thp : Option < u64 > ,
699
+ pub file_thp : Option < u64 > ,
700
+ pub shmem_thp : Option < u64 > ,
701
+ pub inactive_anon : Option < u64 > ,
702
+ pub active_anon : Option < u64 > ,
703
+ pub inactive_file : Option < u64 > ,
704
+ pub active_file : Option < u64 > ,
705
+ pub unevictable : Option < u64 > ,
706
+ pub slab_reclaimable : Option < u64 > ,
707
+ pub slab_unreclaimable : Option < u64 > ,
708
+ pub workingset_refault_anon : Option < f64 > ,
709
+ pub workingset_refault_file : Option < f64 > ,
710
+ pub workingset_activate_anon : Option < f64 > ,
711
+ pub workingset_activate_file : Option < f64 > ,
712
+ pub workingset_restore_anon : Option < f64 > ,
713
+ pub workingset_restore_file : Option < f64 > ,
714
+ pub workingset_nodereclaim : Option < f64 > ,
715
+ }
716
+
717
+ impl CgroupMemoryNumaModel {
718
+ pub fn new (
719
+ begin : & cgroupfs:: MemoryNumaStat ,
720
+ last : Option < ( & cgroupfs:: MemoryNumaStat , Duration ) > ,
721
+ ) -> CgroupMemoryNumaModel {
722
+ let mut model = CgroupMemoryNumaModel {
723
+ total : None ,
724
+ anon : begin. anon ,
725
+ file : begin. file ,
726
+ kernel_stack : begin. kernel_stack ,
727
+ pagetables : begin. pagetables ,
728
+ shmem : begin. shmem ,
729
+ file_mapped : begin. file_mapped ,
730
+ file_dirty : begin. file_dirty ,
731
+ file_writeback : begin. file_writeback ,
732
+ swapcached : begin. swapcached ,
733
+ anon_thp : begin. anon_thp ,
734
+ file_thp : begin. file_thp ,
735
+ shmem_thp : begin. shmem_thp ,
736
+ inactive_anon : begin. inactive_anon ,
737
+ active_anon : begin. active_anon ,
738
+ inactive_file : begin. inactive_file ,
739
+ active_file : begin. active_file ,
740
+ unevictable : begin. unevictable ,
741
+ slab_reclaimable : begin. slab_reclaimable ,
742
+ slab_unreclaimable : begin. slab_unreclaimable ,
743
+ ..Default :: default ( )
744
+ } ;
745
+ if let ( Some ( anon) , Some ( file) , Some ( kernel_stack) , Some ( pagetables) ) =
746
+ ( model. anon , model. file , model. kernel_stack , model. pagetables )
747
+ {
748
+ model. total = Some ( anon + file + kernel_stack + pagetables) ;
749
+ }
750
+
751
+ if let Some ( ( l, delta) ) = last {
752
+ model. workingset_refault_anon = count_per_sec ! (
753
+ begin. workingset_refault_anon,
754
+ l. workingset_refault_anon,
755
+ delta
756
+ ) ;
757
+ model. workingset_refault_file = count_per_sec ! (
758
+ begin. workingset_refault_file,
759
+ l. workingset_refault_file,
760
+ delta
761
+ ) ;
762
+ model. workingset_activate_anon = count_per_sec ! (
763
+ begin. workingset_activate_anon,
764
+ l. workingset_activate_anon,
765
+ delta
766
+ ) ;
767
+ model. workingset_activate_file = count_per_sec ! (
768
+ begin. workingset_activate_file,
769
+ l. workingset_activate_file,
770
+ delta
771
+ ) ;
772
+ model. workingset_restore_anon = count_per_sec ! (
773
+ begin. workingset_restore_anon,
774
+ l. workingset_restore_anon,
775
+ delta
776
+ ) ;
777
+ model. workingset_restore_file = count_per_sec ! (
778
+ begin. workingset_restore_file,
779
+ l. workingset_restore_file,
780
+ delta
781
+ ) ;
782
+ model. workingset_nodereclaim = count_per_sec ! (
783
+ begin. workingset_nodereclaim,
784
+ l. workingset_nodereclaim,
785
+ delta
786
+ ) ;
787
+ }
788
+ model
789
+ }
790
+ }
656
791
657
792
#[ cfg( test) ]
658
793
mod tests {
0 commit comments