├── test └── data │ ├── resctrl.l2 │ ├── cpus │ ├── cpus_list │ ├── mode │ ├── info │ │ ├── L2 │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ └── last_cmd_status │ ├── schemata │ ├── size │ └── tasks │ ├── resctrl.l2cdp │ ├── cpus │ ├── cpus_list │ ├── mode │ ├── info │ │ ├── L3 │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── L2CODE │ │ │ ├── num_closids │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── L2DATA │ │ │ ├── num_closids │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ └── last_cmd_status │ ├── schemata │ ├── size │ └── tasks │ ├── resctrl.full │ ├── Guaranteed │ │ ├── tasks │ │ ├── cpus_list │ │ ├── mode │ │ ├── mon_data │ │ │ ├── mon_L3_00 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_01 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_02 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ └── mon_L3_03 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ ├── mon_groups │ │ │ └── non_goresctrl.group │ │ │ │ ├── tasks │ │ │ │ ├── cpus_list │ │ │ │ ├── mon_data │ │ │ │ ├── mon_L3_00 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_01 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_02 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── mon_L3_03 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── cpus │ │ ├── cpus │ │ ├── schemata │ │ └── size │ ├── cpus_list │ ├── mode │ ├── goresctrl.Stale │ │ ├── tasks │ │ ├── cpus_list │ │ ├── mode │ │ ├── mon_data │ │ │ ├── mon_L3_00 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_01 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_02 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ └── mon_L3_03 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ ├── mon_groups │ │ │ └── non_goresctrl.group │ │ │ │ ├── tasks │ │ │ │ ├── cpus_list │ │ │ │ ├── mon_data │ │ │ │ ├── mon_L3_00 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_01 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_02 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── mon_L3_03 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── cpus │ │ ├── cpus │ │ ├── schemata │ │ └── size │ ├── info │ │ ├── MB │ │ │ ├── num_closids │ │ │ ├── bandwidth_gran │ │ │ ├── delay_linear │ │ │ └── min_bandwidth │ │ ├── L3 │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── L3_MON │ │ │ ├── num_rmids │ │ │ ├── max_threshold_occupancy │ │ │ └── mon_features │ │ └── last_cmd_status │ ├── non_goresctrl.Group │ │ ├── tasks │ │ ├── cpus_list │ │ ├── mode │ │ ├── mon_data │ │ │ ├── mon_L3_00 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_01 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_02 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ └── mon_L3_03 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ ├── cpus │ │ ├── schemata │ │ └── size │ ├── goresctrl.Guaranteed │ │ ├── tasks │ │ ├── cpus_list │ │ ├── mode │ │ ├── mon_groups │ │ │ ├── non_goresctrl.group │ │ │ │ ├── tasks │ │ │ │ ├── cpus_list │ │ │ │ ├── mon_data │ │ │ │ │ ├── mon_L3_00 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ │ ├── mon_L3_01 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ │ ├── mon_L3_02 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ │ └── mon_L3_03 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── cpus │ │ │ ├── goresctrl.predefined_group_empty │ │ │ │ ├── tasks │ │ │ │ ├── cpus_list │ │ │ │ ├── mon_data │ │ │ │ │ ├── mon_L3_00 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ │ ├── mon_L3_01 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ │ ├── mon_L3_02 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ │ └── mon_L3_03 │ │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── cpus │ │ │ └── goresctrl.predefined_group_live │ │ │ │ ├── cpus_list │ │ │ │ ├── tasks │ │ │ │ ├── mon_data │ │ │ │ ├── mon_L3_00 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_01 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_02 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── mon_L3_03 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── cpus │ │ ├── mon_data │ │ │ ├── mon_L3_00 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ ├── mbm_total_bytes │ │ │ │ └── xxx_new_metric │ │ │ ├── mon_L3_01 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ ├── mbm_total_bytes │ │ │ │ └── xxx_new_metric │ │ │ ├── mon_L3_02 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ ├── mbm_total_bytes │ │ │ │ └── xxx_new_metric │ │ │ └── mon_L3_03 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ ├── mbm_total_bytes │ │ │ │ └── xxx_new_metric │ │ ├── cpus │ │ ├── schemata │ │ └── size │ ├── mon_groups │ │ ├── example │ │ │ ├── tasks │ │ │ ├── cpus_list │ │ │ ├── mon_data │ │ │ │ ├── mon_L3_00 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_01 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ ├── mon_L3_02 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ │ └── mon_L3_03 │ │ │ │ │ ├── llc_occupancy │ │ │ │ │ ├── mbm_local_bytes │ │ │ │ │ └── mbm_total_bytes │ │ │ └── cpus │ │ └── non_goresctrl.group │ │ │ ├── tasks │ │ │ ├── cpus_list │ │ │ ├── mon_data │ │ │ ├── mon_L3_00 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_01 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ ├── mon_L3_02 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ └── mon_L3_03 │ │ │ │ ├── llc_occupancy │ │ │ │ ├── mbm_local_bytes │ │ │ │ └── mbm_total_bytes │ │ │ └── cpus │ ├── mon_data │ │ ├── mon_L3_00 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_01 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_02 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ └── mon_L3_03 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ ├── cpus │ ├── schemata │ ├── size │ └── tasks │ ├── resctrl.nol3 │ ├── cpus_list │ ├── mode │ ├── info │ │ ├── MB │ │ │ ├── num_closids │ │ │ ├── bandwidth_gran │ │ │ ├── delay_linear │ │ │ └── min_bandwidth │ │ ├── L3_MON │ │ │ ├── num_rmids │ │ │ ├── max_threshold_occupancy │ │ │ └── mon_features │ │ └── last_cmd_status │ ├── size │ ├── schemata │ ├── mon_data │ │ ├── mon_L3_00 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_01 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_02 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ └── mon_L3_03 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ ├── cpus │ └── tasks │ ├── resctrl.nomb │ ├── cpus_list │ ├── mode │ ├── info │ │ ├── L3 │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── L3_MON │ │ │ ├── num_rmids │ │ │ ├── max_threshold_occupancy │ │ │ └── mon_features │ │ └── last_cmd_status │ ├── mon_data │ │ ├── mon_L3_00 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_01 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_02 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ └── mon_L3_03 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ ├── schemata │ ├── cpus │ ├── size │ └── tasks │ ├── resctrl.nol3.mbps │ ├── cpus_list │ ├── mode │ ├── info │ │ ├── MB │ │ │ ├── num_closids │ │ │ ├── bandwidth_gran │ │ │ ├── delay_linear │ │ │ └── min_bandwidth │ │ ├── L3_MON │ │ │ ├── num_rmids │ │ │ ├── max_threshold_occupancy │ │ │ └── mon_features │ │ └── last_cmd_status │ ├── mon_data │ │ ├── mon_L3_00 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_01 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_02 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ └── mon_L3_03 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ ├── cpus │ ├── schemata │ ├── size │ └── tasks │ ├── resctrl.nomb.cdp │ ├── cpus_list │ ├── mode │ ├── info │ │ ├── L3CODE │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── L3DATA │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── L3_MON │ │ │ ├── num_rmids │ │ │ ├── max_threshold_occupancy │ │ │ └── mon_features │ │ └── last_cmd_status │ ├── mon_data │ │ ├── mon_L3_00 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_01 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ ├── mon_L3_02 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ │ └── mon_L3_03 │ │ │ ├── llc_occupancy │ │ │ ├── mbm_local_bytes │ │ │ └── mbm_total_bytes │ ├── size │ ├── cpus │ ├── schemata │ └── tasks │ ├── resctrl.l2l3mb │ ├── info │ │ ├── L2 │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── shareable_bits │ │ │ ├── sparse_masks │ │ │ └── bit_usage │ │ ├── L3 │ │ │ ├── cbm_mask │ │ │ ├── min_cbm_bits │ │ │ ├── num_closids │ │ │ ├── sparse_masks │ │ │ ├── shareable_bits │ │ │ └── bit_usage │ │ ├── MB │ │ │ ├── delay_linear │ │ │ ├── min_bandwidth │ │ │ ├── num_closids │ │ │ ├── bandwidth_gran │ │ │ └── thread_throttle_mode │ │ ├── last_cmd_status │ │ └── L3_MON │ │ │ ├── num_rmids │ │ │ ├── max_threshold_occupancy │ │ │ └── mon_features │ ├── tasks │ └── schemata │ └── rdt.go ├── cmd ├── blockio │ ├── sample.cfg │ └── main.go └── rdt │ └── sample-conf.yaml ├── doc ├── sst.md └── blockio.md ├── .github ├── workflows │ ├── scan-periodic.yaml │ ├── release.yaml │ ├── trivy-csv.tpl │ ├── common-codeql.yaml │ ├── verify.yaml │ └── common-trivy.yaml └── dependabot.yml ├── security.md ├── README.md ├── Makefile ├── pkg ├── sst │ ├── gen_sst_types.sh │ ├── sst_types_amd64.go │ ├── _sst_types_amd64.go │ ├── sst_types_priv.go │ ├── sysfs.go │ ├── _sst_types_priv.go │ ├── fuzz_test.go │ └── sst_if.go ├── utils │ ├── json.go │ ├── sort.go │ ├── msr.go │ ├── sysfs.go │ └── idset.go ├── testutils │ ├── file.go │ └── verify.go ├── path │ ├── path_test.go │ └── path.go ├── blockio │ ├── config.go │ ├── kubernetes.go │ ├── oci.go │ ├── cgroups.go │ └── oci_test.go ├── kubernetes │ ├── annotations.go │ └── annotations_test.go ├── log │ └── log.go ├── rdt │ ├── kubernetes.go │ ├── bitmask.go │ ├── kubernetes_test.go │ ├── prometheus.go │ └── otel.go └── cstates │ ├── sysfs.go │ ├── filter.go │ ├── filter_test.go │ └── cstates_test.go └── go.mod /test/data/resctrl.l2/cpus: -------------------------------------------------------------------------------- 1 | f 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/cpus_list: -------------------------------------------------------------------------------- 1 | 0-3 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/cpus: -------------------------------------------------------------------------------- 1 | ff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/cpus_list: -------------------------------------------------------------------------------- 1 | 0-191 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/cpus_list: -------------------------------------------------------------------------------- 1 | 0-7 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/cpus_list: -------------------------------------------------------------------------------- 1 | 0-191 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/cpus_list: -------------------------------------------------------------------------------- 1 | 0-191 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/MB/num_closids: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/info/L2/cbm_mask: -------------------------------------------------------------------------------- 1 | ff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/info/L2/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/info/L2/num_closids: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/schemata: -------------------------------------------------------------------------------- 1 | L2:0=ff;1=ff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L3/cbm_mask: -------------------------------------------------------------------------------- 1 | fff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/cpus_list: -------------------------------------------------------------------------------- 1 | 0-191 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/MB/num_closids: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/cpus_list: -------------------------------------------------------------------------------- 1 | 0-191 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3/num_closids: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3_MON/num_rmids: -------------------------------------------------------------------------------- 1 | 192 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/MB/bandwidth_gran: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/MB/delay_linear: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/MB/min_bandwidth: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/tasks: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/info/L2/shareable_bits: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/size: -------------------------------------------------------------------------------- 1 | L2:0=1048576;1=1048576 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2CODE/num_closids: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2DATA/num_closids: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L3/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L3/num_closids: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L2/cbm_mask: -------------------------------------------------------------------------------- 1 | ffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L2/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L2/num_closids: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L2/shareable_bits: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L2/sparse_masks: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3/num_closids: -------------------------------------------------------------------------------- 1 | 15 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3/sparse_masks: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/MB/delay_linear: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/MB/min_bandwidth: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/MB/num_closids: -------------------------------------------------------------------------------- 1 | 15 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/MB/num_closids: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/L3_MON/num_rmids: -------------------------------------------------------------------------------- 1 | 192 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/MB/bandwidth_gran: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/MB/delay_linear: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/MB/min_bandwidth: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3/num_closids: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3_MON/num_rmids: -------------------------------------------------------------------------------- 1 | 192 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3/shareable_bits: -------------------------------------------------------------------------------- 1 | c0000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2CODE/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2CODE/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2CODE/shareable_bits: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2DATA/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2DATA/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2DATA/shareable_bits: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L3/shareable_bits: -------------------------------------------------------------------------------- 1 | 400 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3/shareable_bits: -------------------------------------------------------------------------------- 1 | c0001 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3_MON/num_rmids: -------------------------------------------------------------------------------- 1 | 512 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/MB/bandwidth_gran: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/L3_MON/num_rmids: -------------------------------------------------------------------------------- 1 | 160 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/MB/bandwidth_gran: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/MB/delay_linear: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/MB/min_bandwidth: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/size: -------------------------------------------------------------------------------- 1 | MB:0=100;1=100;2=100;3=100 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3CODE/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3CODE/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3CODE/num_closids: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3DATA/cbm_mask: -------------------------------------------------------------------------------- 1 | fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3DATA/min_cbm_bits: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3DATA/num_closids: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3_MON/num_rmids: -------------------------------------------------------------------------------- 1 | 176 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/last_cmd_status: -------------------------------------------------------------------------------- 1 | ok 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3/shareable_bits: -------------------------------------------------------------------------------- 1 | c0000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mode: -------------------------------------------------------------------------------- 1 | shareable 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L3/bit_usage: -------------------------------------------------------------------------------- 1 | 0=SXSSSSSSSSSS 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/MB/thread_throttle_mode: -------------------------------------------------------------------------------- 1 | max 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/schemata: -------------------------------------------------------------------------------- 1 | MB:0=100;1=100;2=100;3=100 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3CODE/shareable_bits: -------------------------------------------------------------------------------- 1 | c0000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3DATA/shareable_bits: -------------------------------------------------------------------------------- 1 | c0000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3_MON/max_threshold_occupancy: -------------------------------------------------------------------------------- 1 | 98304 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 32440320 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 28901376 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 34406400 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 31260672 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/info/L2/bit_usage: -------------------------------------------------------------------------------- 1 | 0=SSSSSSSS;1=SSSSSSSS 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/L3_MON/max_threshold_occupancy: -------------------------------------------------------------------------------- 1 | 98304 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 32440320 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 28901376 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 34406400 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 31260672 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3_MON/max_threshold_occupancy: -------------------------------------------------------------------------------- 1 | 98304 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 32440320 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 28901376 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 34406400 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 31260672 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 48365568 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 264830976 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 3342336 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 208404480 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 603881472 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 974782464 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 693239808 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 760479744 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3_MON/max_threshold_occupancy: -------------------------------------------------------------------------------- 1 | 655360 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 32440320 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 28901376 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 34406400 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 31260672 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 48365568 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 264830976 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 3342336 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 208404480 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 603881472 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 974782464 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 693239808 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 760479744 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3_MON/max_threshold_occupancy: -------------------------------------------------------------------------------- 1 | 270336 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 32440320 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 28901376 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 3342336 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 34406400 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 31260672 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 48365568 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 264830976 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 3342336 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 208404480 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 603881472 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 974782464 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 693239808 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 760479744 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/schemata: -------------------------------------------------------------------------------- 1 | L3:0=fffff;1=fffff;2=fffff;3=fffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/L3_MON/max_threshold_occupancy: -------------------------------------------------------------------------------- 1 | 163840 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 48365568 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 264830976 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 3342336 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 208404480 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 603881472 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 974782464 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 693239808 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 760479744 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 48365568 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 264830976 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 208404480 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 603881472 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 974782464 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 693239808 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 760479744 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/size: -------------------------------------------------------------------------------- 1 | L3DATA:0=25952256 2 | L3CODE:0=25952256 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 3 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 13 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 21 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 23 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 31 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 32 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 33 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/cpus: -------------------------------------------------------------------------------- 1 | ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 100 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 101 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 102 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_00/xxx_new_metric: -------------------------------------------------------------------------------- 1 | 1000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 110 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 111 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 112 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_01/xxx_new_metric: -------------------------------------------------------------------------------- 1 | 1100 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 120 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 121 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 122 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_02/xxx_new_metric: -------------------------------------------------------------------------------- 1 | 1200 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 130 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 131 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 132 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_data/mon_L3_03/xxx_new_metric: -------------------------------------------------------------------------------- 1 | 1300 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/cpus: -------------------------------------------------------------------------------- 1 | ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/cpus: -------------------------------------------------------------------------------- 1 | ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/tasks: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3/bit_usage: -------------------------------------------------------------------------------- 1 | 0=XXSSSSSSSSSSSSSSSSSX;1=HH00SSSSSSSS0000000H 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/cpus: -------------------------------------------------------------------------------- 1 | ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/cpus: -------------------------------------------------------------------------------- 1 | ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 9 9 | 10 10 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/schemata: -------------------------------------------------------------------------------- 1 | MB:0=4294967295;1=4294967295;2=4294967295;3=4294967295 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/cpus_list: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/tasks: -------------------------------------------------------------------------------- 1 | 100 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/schemata: -------------------------------------------------------------------------------- 1 | L3:0=fffff;1=fffff;2=fffff;3=fffff 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/size: -------------------------------------------------------------------------------- 1 | L3:0=28835840;1=28835840 2 | MB:0=4294967295;1=4294967295 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3_MON/mon_features: -------------------------------------------------------------------------------- 1 | llc_occupancy 2 | mbm_total_bytes 3 | mbm_local_bytes 4 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/example/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L3_MON/mon_features: -------------------------------------------------------------------------------- 1 | llc_occupancy 2 | mbm_total_bytes 3 | mbm_local_bytes 4 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/info/L3_MON/mon_features: -------------------------------------------------------------------------------- 1 | llc_occupancy 2 | mbm_total_bytes 3 | mbm_local_bytes 4 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3_MON/mon_features: -------------------------------------------------------------------------------- 1 | llc_occupancy 2 | mbm_total_bytes 3 | mbm_local_bytes 4 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/schemata: -------------------------------------------------------------------------------- 1 | L3:0=fffff;1=fffff;2=fffff;3=fffff 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/size: -------------------------------------------------------------------------------- 1 | L3:0=57671680;1=57671680;2=57671680;3=57671680 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/info/L3_MON/mon_features: -------------------------------------------------------------------------------- 1 | llc_occupancy 2 | mbm_total_bytes 3 | mbm_local_bytes 4 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3_MON/mon_features: -------------------------------------------------------------------------------- 1 | llc_occupancy 2 | mbm_total_bytes 3 | mbm_local_bytes 4 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/size: -------------------------------------------------------------------------------- 1 | L3:0=57671680;1=57671680;2=57671680;3=57671680 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/schemata: -------------------------------------------------------------------------------- 1 | L3:0=fffff;1=fffff;2=fffff;3=fffff 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/mon_groups/non_goresctrl.group/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/size: -------------------------------------------------------------------------------- 1 | L3:0=57671680;1=57671680;2=57671680;3=57671680 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/schemata: -------------------------------------------------------------------------------- 1 | L3:0=fffff;1=fffff;2=fffff;3=fffff 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/schemata: -------------------------------------------------------------------------------- 1 | L3:0=fffff;1=fffff;2=fffff;3=fffff 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/schemata: -------------------------------------------------------------------------------- 1 | L3DATA:0=001ff;1=001ff;2=001ff;3=001ff 2 | L3CODE:0=001ff;1=001ff;2=001ff;3=001ff 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/Guaranteed/mon_groups/non_goresctrl.group/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_00/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_00/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_00/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_01/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_01/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_01/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_02/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_02/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_02/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_03/llc_occupancy: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_03/mbm_local_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/mon_data/mon_L3_03/mbm_total_bytes: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/size: -------------------------------------------------------------------------------- 1 | L3:0=57671680;1=57671680;2=57671680;3=57671680 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/size: -------------------------------------------------------------------------------- 1 | L3:0=57671680;1=57671680;2=57671680;3=57671680 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Stale/mon_groups/non_goresctrl.group/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/non_goresctrl.Group/size: -------------------------------------------------------------------------------- 1 | L3:0=57671680;1=57671680;2=57671680;3=57671680 2 | MB:0=100;1=100;2=100;3=100 3 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/non_goresctrl.group/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/schemata: -------------------------------------------------------------------------------- 1 | L3:0=00fff 2 | L2DATA:0=fffff;1=fffff;2=fffff;3=fffff 3 | L2CODE:0=fffff;1=fffff;2=fffff;3=fffff 4 | -------------------------------------------------------------------------------- /test/data/resctrl.full/info/L3/bit_usage: -------------------------------------------------------------------------------- 1 | 0=XXSSSSSSSSSSSSSSSSSS;1=XXSSSSSSSSSSSSSSSSSS;2=XXSSSSSSSSSSSSSSSSSS;3=XXSSSSSSSSSSSSSSSSSS 2 | 3 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2CODE/bit_usage: -------------------------------------------------------------------------------- 1 | 0=SSSSSSSSSSSSSSSSSSSS;1=SSSSSSSSSSSSSSSSSSSS;2=SSSSSSSSSSSSSSSSSSSS;3=SSSSSSSSSSSSSSSSSSSS 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/info/L2DATA/bit_usage: -------------------------------------------------------------------------------- 1 | 0=SSSSSSSSSSSSSSSSSSSS;1=SSSSSSSSSSSSSSSSSSSS;2=SSSSSSSSSSSSSSSSSSSS;3=SSSSSSSSSSSSSSSSSSSS 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/info/L3/bit_usage: -------------------------------------------------------------------------------- 1 | 0=XXSSSSSSSSSSSSSSSSSS;1=XXSSSSSSSSSSSSSSSSSS;2=XXSSSSSSSSSSSSSSSSSS;3=XXSSSSSSSSSSSSSSSSSS 2 | 3 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3CODE/bit_usage: -------------------------------------------------------------------------------- 1 | 0=HH000000000SSSSSSSSS;1=HH000000000SSSSSSSSS;2=HH000000000SSSSSSSSS;3=HH000000000SSSSSSSSS 2 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/info/L3DATA/bit_usage: -------------------------------------------------------------------------------- 1 | 0=HH000000000SSSSSSSSS;1=HH000000000SSSSSSSSS;2=HH000000000SSSSSSSSS;3=HH000000000SSSSSSSSS 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_empty/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.full/goresctrl.Guaranteed/mon_groups/goresctrl.predefined_group_live/cpus: -------------------------------------------------------------------------------- 1 | 00000000,00000000,00000000,00000000,00000000,00000000 2 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/size: -------------------------------------------------------------------------------- 1 | L3:0=12582912 2 | L2DATA:0=1310720;1=1310720;2=1310720;3=1310720 3 | L2CODE:0=1310720;1=1310720;2=1310720;3=1310720 4 | -------------------------------------------------------------------------------- /cmd/blockio/sample.cfg: -------------------------------------------------------------------------------- 1 | classes: 2 | slowread: 3 | - devices: 4 | - /dev/[hsv]d[a-z] 5 | throttlereadbps: 5M 6 | highprio: 7 | - weight: 400 8 | nolimit: 9 | -------------------------------------------------------------------------------- /doc/sst.md: -------------------------------------------------------------------------------- 1 | # Intel SST (Speed Select Technology) 2 | 3 | ## Background 4 | 5 | Intel® SST provides capabilities for managing CPU core frequency. 6 | 7 | ## API 8 | 9 | The API is described in 10 | [pkg.go.dev](https://pkg.go.dev/github.com/intel/goresctrl/pkg/sst). 11 | -------------------------------------------------------------------------------- /.github/workflows/scan-periodic.yaml: -------------------------------------------------------------------------------- 1 | name: Scan periodic 2 | on: 3 | schedule: 4 | - cron: '15 3 * * *' 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | trivy: 11 | permissions: 12 | contents: read 13 | security-events: write 14 | uses: "./.github/workflows/common-trivy.yaml" 15 | with: 16 | upload-to-github-security-tab: true 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | target-branch: main 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | # Disable version updates (we're a library) 9 | open-pull-requests-limit: 0 10 | 11 | - package-ecosystem: "github-actions" 12 | target-branch: main 13 | directory: "/" 14 | schedule: 15 | interval: "daily" 16 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/schemata: -------------------------------------------------------------------------------- 1 | MB:0= 100;1= 100 2 | L2:0=0ffff;1=0ffff;2=0ffff;3=0ffff;4=0ffff;5=0ffff;6=0ffff;7=0ffff;8=0ffff;9=0ffff;10=0ffff;11=0ffff;12=0ffff;13=0ffff;14=0ffff;15=0ffff;16=0ffff;17=0ffff;18=0ffff;19=0ffff;20=0ffff;21=0ffff;22=0ffff;23=0ffff;24=0ffff;25=0ffff;26=0ffff;27=0ffff;28=0ffff;29=0ffff;30=0ffff;31=0ffff;32=0ffff;33=0ffff;34=0ffff;35=0ffff;36=0ffff;37=0ffff;38=0ffff;39=0ffff 3 | L3:0=fffff;1=fffff 4 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Intel is committed to rapidly addressing security vulnerabilities affecting our 4 | customers and providing clear guidance on the solution, impact, severity and 5 | mitigation. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | Please report any security vulnerabilities in this project 10 | [utilizing the guidelines here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go Resource Control 2 | 3 | The goresctrl library provides Go interface to manage following resources. 4 | 5 | - CPU cache allocation and memory bandwidth, see the [rdt](doc/rdt.md) 6 | (Intel Resource Director Technology) package. 7 | 8 | - CPU frequency in core granularity, see the [sst](doc/sst.md) (Intel 9 | Speed Select Technology) package. 10 | 11 | - Storage I/O scheduler priority and bandwidth, see the 12 | [blockio](doc/blockio.md) package. 13 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: [ 'v*' ] 6 | 7 | permissions: 8 | contents: read 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref_name }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | trivy: 16 | permissions: 17 | contents: read 18 | security-events: write 19 | uses: "./.github/workflows/common-trivy.yaml" 20 | with: 21 | export-csv: true 22 | 23 | codeql: 24 | permissions: 25 | contents: read 26 | security-events: write 27 | uses: "./.github/workflows/common-codeql.yaml" 28 | with: 29 | export-report: true 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GO_CMD := go 2 | CMDS := $(shell ls cmd) 3 | 4 | Q := @ 5 | 6 | .PHONY: all 7 | all: test build 8 | 9 | .PHONY: build 10 | build: $(foreach cmd,$(CMDS),bin/$(cmd)) 11 | 12 | FORCE: 13 | 14 | bin/%: FORCE 15 | $(GO_CMD) build -o $@ ./cmd/$(notdir $@) 16 | 17 | .PHONY: verify 18 | verify: gofmt-verify ci-lint 19 | 20 | .PHONY: gofmt-verify 21 | gofmt-verify: 22 | @out=`gofmt -w -l -d $$(find . -name '*.go')`; \ 23 | if [ -n "$$out" ]; then \ 24 | echo "$$out"; \ 25 | exit 1; \ 26 | fi 27 | 28 | .PHONY: ci-lint 29 | ci-lint: 30 | golangci-lint run 31 | 32 | .PHONY: test 33 | test: 34 | $(Q)$(GO_CMD) test -v -coverprofile=coverage.txt ./pkg/... 35 | -------------------------------------------------------------------------------- /cmd/rdt/sample-conf.yaml: -------------------------------------------------------------------------------- 1 | options: 2 | l2: 3 | optional: true 4 | l3: 5 | optional: true 6 | mb: 7 | optional: true 8 | partitions: 9 | default: 10 | l2Allocation: "100%" 11 | l3Allocation: "100%" 12 | mbAllocation: ["100%", "4000000000MBps"] 13 | classes: 14 | Guaranteed: 15 | l3Allocation: "100%" 16 | l2Allocation: "100%" 17 | mbAllocation: ["100%", "4000000000MBps"] 18 | Burstable: 19 | l3Allocation: "60%" 20 | l2Allocation: "60%" 21 | mbAllocation: ["60%", "10000MBps"] 22 | Besteffort: 23 | l3Allocation: "30%" 24 | l2Allocation: "30%" 25 | mbAllocation: ["30%", "4000MBps"] 26 | -------------------------------------------------------------------------------- /test/data/resctrl.l2/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.full/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.l2cdp/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb.cdp/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.nomb/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.nol3.mbps/tasks: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 6 6 | 8 7 | 10 8 | 11 9 | 12 10 | 13 11 | 14 12 | 15 13 | 16 14 | 17 15 | 19 16 | 20 17 | 21 18 | 22 19 | 23 20 | 24 21 | 25 22 | 26 23 | 27 24 | 28 25 | 29 26 | 30 27 | 31 28 | 32 29 | 33 30 | 34 31 | 35 32 | 36 33 | 37 34 | 38 35 | 39 36 | 40 37 | 41 38 | 42 39 | 43 40 | 44 41 | 45 42 | 46 43 | 47 44 | 49 45 | 50 46 | 51 47 | 52 48 | 53 49 | 54 50 | 55 51 | 56 52 | 57 53 | 58 54 | 59 55 | 60 56 | 61 57 | 62 58 | 64 59 | 65 60 | 66 61 | 67 62 | 68 63 | 69 64 | 70 65 | 71 66 | 72 67 | 73 68 | 74 69 | 75 70 | 76 71 | 77 72 | 78 73 | 79 74 | 80 75 | 81 76 | 82 77 | 83 78 | 84 79 | 85 80 | 86 81 | 87 82 | 88 83 | 89 84 | 90 85 | 91 86 | 92 87 | 93 88 | 94 89 | 95 90 | 96 91 | 97 92 | 99 93 | -------------------------------------------------------------------------------- /test/data/resctrl.l2l3mb/info/L2/bit_usage: -------------------------------------------------------------------------------- 1 | 0=SSSSSSSSSSSSSSSS;1=SSSSSSSSSSSSSSSS;2=SSSSSSSSSSSSSSSS;3=SSSSSSSSSSSSSSSS;4=SSSSSSSSSSSSSSSS;5=SSSSSSSSSSSSSSSS;6=SSSSSSSSSSSSSSSS;7=SSSSSSSSSSSSSSSS;8=SSSSSSSSSSSSSSSS;9=SSSSSSSSSSSSSSSS;10=SSSSSSSSSSSSSSSS;11=SSSSSSSSSSSSSSSS;12=SSSSSSSSSSSSSSSS;13=SSSSSSSSSSSSSSSS;14=SSSSSSSSSSSSSSSS;15=SSSSSSSSSSSSSSSS;16=SSSSSSSSSSSSSSSS;17=SSSSSSSSSSSSSSSS;18=SSSSSSSSSSSSSSSS;19=SSSSSSSSSSSSSSSS;20=SSSSSSSSSSSSSSSS;21=SSSSSSSSSSSSSSSS;22=SSSSSSSSSSSSSSSS;23=SSSSSSSSSSSSSSSS;24=SSSSSSSSSSSSSSSS;25=SSSSSSSSSSSSSSSS;26=SSSSSSSSSSSSSSSS;27=SSSSSSSSSSSSSSSS;28=SSSSSSSSSSSSSSSS;29=SSSSSSSSSSSSSSSS;30=SSSSSSSSSSSSSSSS;31=SSSSSSSSSSSSSSSS;32=SSSSSSSSSSSSSSSS;33=SSSSSSSSSSSSSSSS;34=SSSSSSSSSSSSSSSS;35=SSSSSSSSSSSSSSSS;36=SSSSSSSSSSSSSSSS;37=SSSSSSSSSSSSSSSS;38=SSSSSSSSSSSSSSSS;39=SSSSSSSSSSSSSSSS 2 | -------------------------------------------------------------------------------- /pkg/sst/gen_sst_types.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | set -o pipefail 4 | 5 | tmpfile="_sst_types_out.go" 6 | trap "rm -f $tmpfile" EXIT 7 | 8 | generate() { 9 | local target="$1" 10 | shift 11 | local copts=$@ 12 | 13 | echo "Generating $target..." 14 | 15 | go tool cgo -godefs -- $copts _"$target" | gofmt > "$tmpfile" 16 | mv "$tmpfile" "$target" 17 | } 18 | 19 | KERNEL_SRC_DIR="${KERNEL_SRC_DIR:-/usr/src/linux}" 20 | 21 | echo "INFO: using kernel sources at $KERNEL_SRC_DIR" 22 | 23 | # Generate types from Linux kernel (public) headers 24 | generate sst_types_amd64.go -I"$KERNEL_SRC_DIR/include/uapi" "-I$KERNEL_SRC_DIR/include" 25 | 26 | # Generate types from Linux kernel private headers 27 | generate sst_types_priv.go -I"$KERNEL_SRC_DIR" "-I$KERNEL_SRC_DIR/include -I$KERNEL_SRC_DIR/arch/x86/include/generated/" 28 | -------------------------------------------------------------------------------- /.github/workflows/trivy-csv.tpl: -------------------------------------------------------------------------------- 1 | {{ range . }} 2 | Trivy Vulnerability Scan Results ({{- .Target -}}) 3 | VulnerabilityID,Severity,CVSS Score,Title,Library,Vulnerable Version,Fixed Version,Information URL,Triage Information 4 | {{ range .Vulnerabilities }} 5 | {{- .VulnerabilityID }}, 6 | {{- .Severity }}, 7 | {{- range $key, $value := .CVSS }} 8 | {{- if (eq $key "nvd") }} 9 | {{- .V3Score -}} 10 | {{- end }} 11 | {{- end }}, 12 | {{- quote .Title }}, 13 | {{- quote .PkgName }}, 14 | {{- quote .InstalledVersion }}, 15 | {{- quote .FixedVersion }}, 16 | {{- .PrimaryURL }} 17 | {{ else -}} 18 | No vulnerabilities found at this time. 19 | {{ end }} 20 | Trivy Dependency Scan Results ({{ .Target }}) 21 | ID,Name,Version,Notes 22 | {{ range .Packages -}} 23 | {{- quote .ID }}, 24 | {{- quote .Name }}, 25 | {{- quote .Version }} 26 | {{ else -}} 27 | No dependencies found at this time. 28 | {{ end }} 29 | {{ end }} 30 | -------------------------------------------------------------------------------- /pkg/utils/json.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "fmt" 21 | 22 | "sigs.k8s.io/yaml" 23 | ) 24 | 25 | // DumpJSON dumps a json-compatible struct in human-readable form 26 | func DumpJSON(r interface{}) string { 27 | out, err := yaml.Marshal(r) 28 | if err != nil { 29 | return fmt.Sprintf("!!!!!\nUnable to stringify %T: %v\n!!!!!", r, err) 30 | } 31 | return string(out) 32 | } 33 | -------------------------------------------------------------------------------- /test/data/rdt.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rdtdata 18 | 19 | import ( 20 | "path/filepath" 21 | "runtime" 22 | ) 23 | 24 | var thisDir []string 25 | 26 | func init() { 27 | _, this, _, _ := runtime.Caller(0) 28 | thisDir = []string{filepath.Dir(this)} 29 | } 30 | 31 | // Path returns an absolute path to test data 32 | func Path(elem ...string) string { 33 | return filepath.Join(append(thisDir, elem...)...) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/sst/sst_types_amd64.go: -------------------------------------------------------------------------------- 1 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 2 | // cgo -godefs -- -I/usr/src/linux/include/uapi -I/usr/src/linux/include _sst_types_amd64.go 3 | 4 | package sst 5 | 6 | const ( 7 | ISST_IF_GET_PHY_ID = 0xc008fe01 8 | ISST_IF_IO_CMD = 0x4008fe02 9 | ISST_IF_MBOX_COMMAND = 0xc008fe03 10 | ) 11 | 12 | type isstIfCPUMaps struct { 13 | Cmd_count uint32 14 | Cpu_map [1]isstIfCPUMap 15 | } 16 | type isstIfCPUMap struct { 17 | Logical_cpu uint32 18 | Physical_cpu uint32 19 | } 20 | 21 | type isstIfIoReg struct { 22 | Read_write uint32 23 | Logical_cpu uint32 24 | Reg uint32 25 | Value uint32 26 | } 27 | type isstIfIoRegs struct { 28 | Req_count uint32 29 | Io_reg [1]isstIfIoReg 30 | } 31 | 32 | type isstIfMboxCmd struct { 33 | Logical_cpu uint32 34 | Parameter uint32 35 | Req_data uint32 36 | Resp_data uint32 37 | Command uint16 38 | Sub_command uint16 39 | Reserved uint32 40 | } 41 | type isstIfMboxCmds struct { 42 | Cmd_count uint32 43 | Mbox_cmd [1]isstIfMboxCmd 44 | } 45 | -------------------------------------------------------------------------------- /pkg/testutils/file.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 Intel Corporation. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testutils 16 | 17 | import ( 18 | "os" 19 | "testing" 20 | ) 21 | 22 | func CreateTempFile(t *testing.T, data string) string { 23 | f, err := os.CreateTemp("", "goresctrl-testutils-") 24 | if err != nil { 25 | t.Fatal(err) 26 | } 27 | if _, err := f.WriteString(data); err != nil { 28 | t.Fatal(err) 29 | } 30 | if err := f.Close(); err != nil { 31 | t.Fatal(err) 32 | } 33 | return f.Name() 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/common-codeql.yaml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | on: 3 | workflow_call: 4 | inputs: 5 | export-report: 6 | default: false 7 | required: false 8 | type: boolean 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | codeql-scan: 15 | runs-on: ubuntu-22.04 16 | permissions: 17 | security-events: write 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v6 21 | 22 | - name: Initialize CodeQL 23 | uses: github/codeql-action/init@v4 24 | with: 25 | languages: go 26 | 27 | - name: Perform CodeQL Analysis 28 | uses: github/codeql-action/analyze@v4 29 | 30 | - name: Generate CodeQL Security Report 31 | if: ${{ inputs.export-report }} 32 | uses: rsdmike/github-security-report-action@v3.0.4 33 | with: 34 | template: report 35 | token: ${{ secrets.GITHUB_TOKEN }} 36 | 37 | - name: Upload PDF report as an artifact 38 | if: ${{ inputs.export-report }} 39 | uses: actions/upload-artifact@v5 40 | with: 41 | name: codeql-report 42 | path: report.pdf 43 | -------------------------------------------------------------------------------- /pkg/path/path_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package path 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestPath(t *testing.T) { 24 | // Helper function for checking test cases 25 | TC := func(path []string, expected string) { 26 | if result := Path(path...); result != expected { 27 | t.Errorf("unexpected path: %v -> %q, expected %q", path, result, expected) 28 | } 29 | } 30 | 31 | // Run test cases 32 | TC([]string{}, "/") 33 | TC([]string{"foo"}, "/foo") 34 | 35 | SetPrefix("/prefix/mnt/") 36 | TC([]string{}, "/prefix/mnt") 37 | TC([]string{"/foo", "bar"}, "/prefix/mnt/foo/bar") 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/verify.yaml: -------------------------------------------------------------------------------- 1 | name: Verify 2 | on: 3 | push: 4 | pull_request: 5 | paths-ignore: 6 | - "**.md" 7 | 8 | permissions: 9 | contents: read 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | test-and-lint: 17 | runs-on: ubuntu-22.04 18 | steps: 19 | - uses: actions/checkout@v6 20 | 21 | - uses: actions/setup-go@v6 22 | with: 23 | go-version-file: go.mod 24 | 25 | - name: Install golangci-lint 26 | run: | 27 | curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.1.6 28 | 29 | - name: Verify 30 | run: make verify 31 | 32 | - name: Test 33 | run: make test 34 | 35 | - name: Codecov report 36 | run: bash <(curl -s https://codecov.io/bash) 37 | 38 | trivy: 39 | permissions: 40 | contents: read 41 | security-events: write 42 | uses: "./.github/workflows/common-trivy.yaml" 43 | with: 44 | upload-to-github-security-tab: true 45 | 46 | codeql: 47 | permissions: 48 | contents: read 49 | security-events: write 50 | uses: "./.github/workflows/common-codeql.yaml" 51 | -------------------------------------------------------------------------------- /pkg/path/path.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package path 18 | 19 | import "path/filepath" 20 | 21 | // RootDir is a helper for handling system directory paths 22 | type RootDir string 23 | 24 | var prefix RootDir = "/" 25 | 26 | // Path returns a full path to a file under RootDir 27 | func (d RootDir) Path(elems ...string) string { 28 | return filepath.Join(append([]string{string(d)}, elems...)...) 29 | } 30 | 31 | // SetPrefix sets the global path prefix to use for all system files. 32 | func SetPrefix(p string) { prefix = RootDir(p) } 33 | 34 | // Path returns a path to a file, prefixed with the global prefix. 35 | func Path(elems ...string) string { return prefix.Path(elems...) } 36 | -------------------------------------------------------------------------------- /pkg/blockio/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019-2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package blockio 18 | 19 | // Config contains a blockio configuration. 20 | type Config struct { 21 | // Classes define weights and throttling parameters for sets of devices. 22 | Classes map[string][]DevicesParameters `json:",omitempty"` 23 | } 24 | 25 | // DevicesParameters defines Block IO parameters for a set of devices. 26 | type DevicesParameters struct { 27 | Devices []string `json:",omitempty"` 28 | ThrottleReadBps string `json:",omitempty"` 29 | ThrottleWriteBps string `json:",omitempty"` 30 | ThrottleReadIOPS string `json:",omitempty"` 31 | ThrottleWriteIOPS string `json:",omitempty"` 32 | Weight string `json:",omitempty"` 33 | } 34 | -------------------------------------------------------------------------------- /pkg/sst/_sst_types_amd64.go: -------------------------------------------------------------------------------- 1 | //go:build amd64 2 | // +build amd64 3 | 4 | /* 5 | Copyright 2021 Intel Corporation 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This file is used for auto-generation of sst_types_amd64.go 21 | package sst 22 | 23 | // #include 24 | // #include 25 | // 26 | import "C" 27 | 28 | const ( 29 | ISST_IF_GET_PHY_ID = C.ISST_IF_GET_PHY_ID 30 | ISST_IF_IO_CMD = C.ISST_IF_IO_CMD 31 | ISST_IF_MBOX_COMMAND = C.ISST_IF_MBOX_COMMAND 32 | ) 33 | 34 | type isstIfCPUMaps C.struct_isst_if_cpu_maps 35 | type isstIfCPUMap C.struct_isst_if_cpu_map 36 | 37 | type isstIfIoReg C.struct_isst_if_io_reg 38 | type isstIfIoRegs C.struct_isst_if_io_regs 39 | 40 | type isstIfMboxCmd C.struct_isst_if_mbox_cmd 41 | type isstIfMboxCmds C.struct_isst_if_mbox_cmds 42 | -------------------------------------------------------------------------------- /pkg/utils/sort.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Intel Corporation. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "sort" 19 | ) 20 | 21 | // SortUint64s sorts a slice of uint64 in increasing order. 22 | func SortUint64s(a []uint64) { 23 | sort.Sort(Uint64Slice(a)) 24 | } 25 | 26 | // Uint64Slice implmenents sort.Interface for a slice of uint64. 27 | type Uint64Slice []uint64 28 | 29 | // Len returns the length of an UintSlice 30 | func (s Uint64Slice) Len() int { return len(s) } 31 | 32 | // Less returns true if element at 'i' is less than the element at 'j' 33 | func (s Uint64Slice) Less(i, j int) bool { return s[i] < s[j] } 34 | 35 | // Swap swaps the values of two elements 36 | func (s Uint64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 37 | -------------------------------------------------------------------------------- /pkg/utils/msr.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "encoding/binary" 21 | "fmt" 22 | "os" 23 | 24 | goresctrlpath "github.com/intel/goresctrl/pkg/path" 25 | ) 26 | 27 | func ReadMSR(cpu ID, msr int64) (uint64, error) { 28 | path := goresctrlpath.Path("dev/cpu", fmt.Sprintf("%d", cpu), "msr") 29 | file, err := os.Open(path) 30 | if err != nil { 31 | return 0, err 32 | } 33 | 34 | defer file.Close() // nolint:errcheck 35 | 36 | // Whence is the point of reference for offset 37 | // 0 = Beginning of file 38 | // 1 = Current position 39 | // 2 = End of file 40 | whence := int(0) 41 | _, err = file.Seek(msr, whence) 42 | if err != nil { 43 | return 0, err 44 | } 45 | 46 | data := make([]byte, 8) 47 | 48 | _, err = file.Read(data) 49 | if err != nil { 50 | return 0, err 51 | } 52 | 53 | return binary.LittleEndian.Uint64(data), nil 54 | } 55 | -------------------------------------------------------------------------------- /pkg/sst/sst_types_priv.go: -------------------------------------------------------------------------------- 1 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 2 | // cgo -godefs -- -I/usr/src/linux -I/usr/src/linux/include -I/usr/src/linux/arch/x86/include/generated/ _sst_types_priv.go 3 | 4 | package sst 5 | 6 | const ( 7 | CONFIG_TDP = 0x7f 8 | CONFIG_TDP_GET_LEVELS_INFO = 0x0 9 | CONFIG_TDP_GET_TDP_CONTROL = 0x1 10 | CONFIG_TDP_SET_TDP_CONTROL = 0x2 11 | CONFIG_TDP_GET_TDP_INFO = 0x3 12 | CONFIG_TDP_GET_PWR_INFO = 0x4 13 | CONFIG_TDP_GET_TJMAX_INFO = 0x5 14 | CONFIG_TDP_GET_CORE_MASK = 0x6 15 | CONFIG_TDP_GET_TURBO_LIMIT_RATIOS = 0x7 16 | CONFIG_TDP_SET_LEVEL = 0x8 17 | CONFIG_TDP_GET_UNCORE_P0_P1_INFO = 0x9 18 | CONFIG_TDP_GET_P1_INFO = 0xa 19 | CONFIG_TDP_GET_MEM_FREQ = 0xb 20 | 21 | CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES = 0x10 22 | CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS = 0x11 23 | CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO = 0x12 24 | 25 | CONFIG_TDP_PBF_GET_CORE_MASK_INFO = 0x20 26 | CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO = 0x21 27 | CONFIG_TDP_PBF_GET_TJ_MAX_INFO = 0x22 28 | CONFIG_TDP_PBF_GET_TDP_INFO = 0x23 29 | 30 | CONFIG_CLOS = 0xd0 31 | CLOS_PM_QOS_CONFIG = 0x2 32 | CLOS_PQR_ASSOC = 0x0 33 | CLOS_PM_CLOS = 0x1 34 | CLOS_STATUS = 0x3 35 | 36 | MBOX_CMD_WRITE_BIT = 0x8 37 | 38 | READ_PM_CONFIG = 0x94 39 | WRITE_PM_CONFIG = 0x95 40 | PM_FEATURE = 0x3 41 | 42 | PM_QOS_INFO_OFFSET = 0x0 43 | PM_QOS_CONFIG_OFFSET = 0x4 44 | PM_CLOS_OFFSET = 0x8 45 | PQR_ASSOC_OFFSET = 0x20 46 | 47 | MSR_PM_ENABLE = 0x770 48 | ) 49 | -------------------------------------------------------------------------------- /pkg/blockio/kubernetes.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package blockio 18 | 19 | import ( 20 | "github.com/intel/goresctrl/pkg/kubernetes" 21 | ) 22 | 23 | const ( 24 | // BlockioContainerAnnotation is the CRI level container annotation for setting 25 | // the blockio class of a container 26 | BlockioContainerAnnotation = "io.kubernetes.cri.blockio-class" 27 | 28 | // BlockioPodAnnotation is a Pod annotation for setting the blockio class of 29 | // all containers of the pod 30 | BlockioPodAnnotation = "blockio.resources.beta.kubernetes.io/pod" 31 | 32 | // BlockioPodAnnotationContainerPrefix is prefix for per-container Pod annotation 33 | // for setting the blockio class of one container of the pod 34 | BlockioPodAnnotationContainerPrefix = "blockio.resources.beta.kubernetes.io/container." 35 | ) 36 | 37 | // ContainerClassFromAnnotations determines the effective blockio 38 | // class of a container from the Pod annotations and CRI level 39 | // container annotations of a container. If the class is not specified 40 | // by any annotation, returns empty class name. Returned error is 41 | // reserved (nil). 42 | func ContainerClassFromAnnotations(containerName string, containerAnnotations, podAnnotations map[string]string) (string, error) { 43 | clsName, _ := kubernetes.ContainerClassFromAnnotations( 44 | BlockioContainerAnnotation, BlockioPodAnnotation, BlockioPodAnnotationContainerPrefix, 45 | containerName, containerAnnotations, podAnnotations) 46 | return clsName, nil 47 | } 48 | -------------------------------------------------------------------------------- /pkg/kubernetes/annotations.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package kubernetes 18 | 19 | // ClassOrigin type indicates the source of container's class 20 | // information: whether it is found from CRI level container 21 | // annotations, Kubernetes' pod annotations, or it has not been found 22 | // at all. 23 | type ClassOrigin int 24 | 25 | const ( 26 | ClassOriginNotFound ClassOrigin = iota 27 | ClassOriginContainerAnnotation 28 | ClassOriginPodAnnotation 29 | ) 30 | 31 | func (c ClassOrigin) String() string { 32 | switch c { 33 | case ClassOriginNotFound: 34 | return "" 35 | case ClassOriginContainerAnnotation: 36 | return "container annotations" 37 | case ClassOriginPodAnnotation: 38 | return "pod annotations" 39 | default: 40 | return "" 41 | } 42 | } 43 | 44 | // ContainerClassFromAnnotations determines the effective class of a 45 | // container from the Pod annotations and CRI level container 46 | // annotations of a container. 47 | func ContainerClassFromAnnotations(containerAnnotation, podAnnotation, podAnnotationContainerPrefix string, containerName string, containerAnnotations, podAnnotations map[string]string) (string, ClassOrigin) { 48 | if clsName, ok := containerAnnotations[containerAnnotation]; ok { 49 | return clsName, ClassOriginContainerAnnotation 50 | } 51 | if clsName, ok := podAnnotations[podAnnotationContainerPrefix+containerName]; ok { 52 | return clsName, ClassOriginPodAnnotation 53 | } 54 | if clsName, ok := podAnnotations[podAnnotation]; ok { 55 | return clsName, ClassOriginPodAnnotation 56 | } 57 | return "", ClassOriginNotFound 58 | } 59 | -------------------------------------------------------------------------------- /pkg/blockio/oci.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019-2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package blockio 18 | 19 | import ( 20 | "fmt" 21 | 22 | oci "github.com/opencontainers/runtime-spec/specs-go" 23 | ) 24 | 25 | // OciLinuxBlockIO returns OCI LinuxBlockIO structure corresponding to the class. 26 | func OciLinuxBlockIO(class string) (*oci.LinuxBlockIO, error) { 27 | blockio, ok := classBlockIO[class] 28 | if !ok { 29 | return nil, fmt.Errorf("no OCI BlockIO parameters for class %#v", class) 30 | } 31 | ociBlockio := oci.LinuxBlockIO{} 32 | if blockio.Weight != -1 { 33 | w := uint16(blockio.Weight) 34 | ociBlockio.Weight = &w 35 | } 36 | ociBlockio.WeightDevice = ociLinuxWeightDevices(blockio.WeightDevice) 37 | ociBlockio.ThrottleReadBpsDevice = ociLinuxThrottleDevices(blockio.ThrottleReadBpsDevice) 38 | ociBlockio.ThrottleWriteBpsDevice = ociLinuxThrottleDevices(blockio.ThrottleWriteBpsDevice) 39 | ociBlockio.ThrottleReadIOPSDevice = ociLinuxThrottleDevices(blockio.ThrottleReadIOPSDevice) 40 | ociBlockio.ThrottleWriteIOPSDevice = ociLinuxThrottleDevices(blockio.ThrottleWriteIOPSDevice) 41 | return &ociBlockio, nil 42 | } 43 | 44 | func ociLinuxWeightDevices(dws DeviceWeights) []oci.LinuxWeightDevice { 45 | if len(dws) == 0 { 46 | return nil 47 | } 48 | olwds := make([]oci.LinuxWeightDevice, len(dws)) 49 | for i, wd := range dws { 50 | w := uint16(wd.Weight) 51 | olwds[i].Major = wd.Major 52 | olwds[i].Minor = wd.Minor 53 | olwds[i].Weight = &w 54 | } 55 | return olwds 56 | } 57 | 58 | func ociLinuxThrottleDevices(drs DeviceRates) []oci.LinuxThrottleDevice { 59 | if len(drs) == 0 { 60 | return nil 61 | } 62 | oltds := make([]oci.LinuxThrottleDevice, len(drs)) 63 | for i, dr := range drs { 64 | oltds[i].Major = dr.Major 65 | oltds[i].Minor = dr.Minor 66 | oltds[i].Rate = uint64(dr.Rate) 67 | } 68 | return oltds 69 | } 70 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/intel/goresctrl 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/google/go-cmp v0.7.0 7 | github.com/opencontainers/runtime-spec v1.0.2 8 | github.com/prometheus/client_golang v1.23.0 9 | github.com/stretchr/testify v1.11.1 10 | go.opentelemetry.io/otel v1.38.0 11 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 12 | go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 13 | go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 14 | go.opentelemetry.io/otel/metric v1.38.0 15 | go.opentelemetry.io/otel/sdk v1.38.0 16 | go.opentelemetry.io/otel/sdk/metric v1.38.0 17 | golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 18 | golang.org/x/sys v0.35.0 19 | k8s.io/apimachinery v0.27.4 20 | sigs.k8s.io/yaml v1.3.0 21 | ) 22 | 23 | require ( 24 | github.com/beorn7/perks v1.0.1 // indirect 25 | github.com/cenkalti/backoff/v5 v5.0.3 // indirect 26 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 27 | github.com/davecgh/go-spew v1.1.1 // indirect 28 | github.com/go-logr/logr v1.4.3 // indirect 29 | github.com/go-logr/stdr v1.2.2 // indirect 30 | github.com/gogo/protobuf v1.3.2 // indirect 31 | github.com/google/gofuzz v1.2.0 // indirect 32 | github.com/google/uuid v1.6.0 // indirect 33 | github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect 34 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect 35 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 36 | github.com/pmezard/go-difflib v1.0.0 // indirect 37 | github.com/prometheus/client_model v0.6.2 // indirect 38 | github.com/prometheus/common v0.65.0 // indirect 39 | github.com/prometheus/otlptranslator v0.0.2 // indirect 40 | github.com/prometheus/procfs v0.17.0 // indirect 41 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 42 | go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect 43 | go.opentelemetry.io/otel/trace v1.38.0 // indirect 44 | go.opentelemetry.io/proto/otlp v1.7.1 // indirect 45 | golang.org/x/net v0.43.0 // indirect 46 | golang.org/x/text v0.28.0 // indirect 47 | google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect 48 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect 49 | google.golang.org/grpc v1.75.0 // indirect 50 | google.golang.org/protobuf v1.36.8 // indirect 51 | gopkg.in/inf.v0 v0.9.1 // indirect 52 | gopkg.in/yaml.v2 v2.4.0 // indirect 53 | gopkg.in/yaml.v3 v3.0.1 // indirect 54 | ) 55 | -------------------------------------------------------------------------------- /pkg/log/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019-2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package log 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "log/slog" 23 | "strings" 24 | ) 25 | 26 | // Custom slog handler for changing the log level. 27 | type logHandler struct { 28 | slog.Leveler 29 | slog.Handler 30 | } 31 | 32 | // NewLogHandler creates a new slog handler that uses the provided log level 33 | // but otherwise clones the default slog handler. 34 | func NewLogHandler(level slog.Leveler) slog.Handler { 35 | return &logHandler{ 36 | Leveler: level, 37 | Handler: slog.Default().Handler(), 38 | } 39 | } 40 | 41 | // Enabled implements the slog.Handler interface. 42 | func (h *logHandler) Enabled(_ context.Context, level slog.Level) bool { 43 | return level >= h.Level() 44 | } 45 | 46 | // LevelFlag implement the flag.Value interface and can be used as a command 47 | // line flag for specifying the log level. 48 | type LevelFlag struct { 49 | level slog.Level 50 | } 51 | 52 | func NewLevelFlag(level slog.Level) *LevelFlag { 53 | return &LevelFlag{level: level} 54 | } 55 | 56 | // Set the log level. 57 | func (l *LevelFlag) Set(s string) error { 58 | switch strings.ToLower(s) { 59 | case "debug": 60 | l.level = slog.LevelDebug 61 | case "info": 62 | l.level = slog.LevelInfo 63 | case "warn": 64 | l.level = slog.LevelWarn 65 | case "error": 66 | l.level = slog.LevelError 67 | default: 68 | return fmt.Errorf("must be one of: debug, info, warn, error") 69 | } 70 | return nil 71 | } 72 | 73 | // String returns the string representation of the log level. 74 | func (l *LevelFlag) String() string { 75 | switch l.level { 76 | case slog.LevelDebug: 77 | return "debug" 78 | case slog.LevelInfo: 79 | return "info" 80 | case slog.LevelWarn: 81 | return "warn" 82 | case slog.LevelError: 83 | return "error" 84 | default: 85 | return fmt.Sprintf("level(%d)", l.level) 86 | } 87 | } 88 | 89 | func (l *LevelFlag) Level() slog.Level { 90 | return l.level 91 | } 92 | -------------------------------------------------------------------------------- /.github/workflows/common-trivy.yaml: -------------------------------------------------------------------------------- 1 | name: Trivy 2 | on: 3 | workflow_call: 4 | inputs: 5 | upload-to-github-security-tab: 6 | default: false 7 | required: false 8 | type: boolean 9 | export-csv: 10 | default: false 11 | required: false 12 | type: boolean 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | trivy-scan-licenses: 19 | runs-on: ubuntu-22.04 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v6 23 | 24 | - name: Run Trivy in fs mode 25 | uses: aquasecurity/trivy-action@master 26 | with: 27 | scan-type: fs 28 | scan-ref: . 29 | exit-code: 1 30 | scanners: license 31 | severity: "UNKNOWN,MEDIUM,HIGH,CRITICAL" 32 | 33 | trivy-scan-vulns: 34 | runs-on: ubuntu-22.04 35 | permissions: 36 | security-events: write 37 | steps: 38 | - name: Checkout 39 | uses: actions/checkout@v6 40 | 41 | - name: Run Trivy in fs mode 42 | continue-on-error: true 43 | uses: aquasecurity/trivy-action@master 44 | with: 45 | scan-type: fs 46 | scan-ref: . 47 | exit-code: 1 48 | list-all-pkgs: true 49 | format: json 50 | output: trivy-report.json 51 | 52 | - name: Show report in human-readable format 53 | uses: aquasecurity/trivy-action@master 54 | with: 55 | scan-type: convert 56 | vuln-type: '' 57 | severity: '' 58 | image-ref: trivy-report.json 59 | format: table 60 | 61 | - name: Convert report to sarif format 62 | if: ${{ inputs.upload-to-github-security-tab }} 63 | uses: aquasecurity/trivy-action@master 64 | with: 65 | scan-type: convert 66 | vuln-type: '' 67 | severity: '' 68 | image-ref: trivy-report.json 69 | format: sarif 70 | output: trivy-report.sarif 71 | 72 | - name: Upload sarif report to GitHub Security tab 73 | if: ${{ inputs.upload-to-github-security-tab }} 74 | uses: github/codeql-action/upload-sarif@v4 75 | with: 76 | sarif_file: trivy-report.sarif 77 | 78 | - name: Convert report to csv 79 | if: ${{ inputs.export-csv }} 80 | uses: aquasecurity/trivy-action@master 81 | with: 82 | scan-type: convert 83 | vuln-type: '' 84 | severity: '' 85 | image-ref: trivy-report.json 86 | format: template 87 | template: "@.github/workflows/trivy-csv.tpl" 88 | output: trivy-report.csv 89 | 90 | - name: Upload CSV report as an artifact 91 | if: ${{ inputs.export-csv }} 92 | uses: actions/upload-artifact@v5 93 | with: 94 | name: trivy-report 95 | path: trivy-report.csv 96 | -------------------------------------------------------------------------------- /doc/blockio.md: -------------------------------------------------------------------------------- 1 | # Block I/O 2 | 3 | ## Background 4 | 5 | The cgroup block I/O controller, 6 | [blkio](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/blkio-controller.html) 7 | in cgroup v1, 8 | [io](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#io) 9 | in cgroup v2, in Linux kernel controls I/O scheduler weights and I/O 10 | bandwidth per block device. 11 | 12 | The blockio package in goresctrl is configured with class-based block 13 | I/O controller parameters, where different parameters can be 14 | configured for each class. The package provides two separate output 15 | options: parameters of a class can be applied directly to cgroup v1 16 | directory structure, or they can be exported as 17 | [Linux BlockIO OCI spec](https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#block-io). 18 | 19 | ## API 20 | 21 | The API is described in 22 | [pkg.go.dev](https://pkg.go.dev/github.com/intel/goresctrl/pkg/blockio). 23 | 24 | ## Configuration 25 | 26 | Block I/O classes can be configured with a yaml file. Example: 27 | 28 | ``` 29 | Classes: 30 | 31 | # Define a blockio class "LowPrioThrottled". 32 | # Containers in this class will be throttled and handled as 33 | # low priority in the I/O scheduler. 34 | 35 | LowPrioThrottled: 36 | 37 | # Weight without a Devices list specifies the default 38 | # I/O scheduler weight for all devices 39 | # that are not explicitly mentioned in following items. 40 | # This will be written to cgroups(.bfq).weight. 41 | # Weights range from 10 to 1000, the default is 100. 42 | 43 | - Weight: 80 44 | 45 | # Set all parameters for all /dev/sd* and /dev/vd* block 46 | # devices. 47 | 48 | - Devices: 49 | - /dev/sd[a-z] 50 | - /dev/vd[a-z] 51 | ThrottleReadBps: 50M # max read bytes per second 52 | ThrottleWriteBps: 10M # max write bytes per second 53 | ThrottleReadIOPS: 10k # max read io operations per second 54 | ThrottleWriteIOPS: 5k # max write io operations per second 55 | Weight: 50 # I/O scheduler (cfq/bfq) weight for 56 | # these devices will be written to 57 | # cgroups(.bfq).weight_device 58 | 59 | # Set parameters particularly for SSD devices. 60 | # This configuration overrides above configurations for those 61 | # /dev/sd* and /dev/vd* devices whose disk id contains "SSD". 62 | 63 | - Devices: 64 | - /dev/disk/by-id/*SSD* 65 | ThrottleReadBps: 100M 66 | ThrottleWriteBps: 40M 67 | # Not mentioning Throttle*IOPS means no I/O operations 68 | # throttling on matching devices. 69 | Weight: 50 70 | 71 | # Define a blockio class "HighPrioFullSpeed". 72 | # There is no throttling on these containers, and 73 | # they will be prioritized by the I/O scheduler. 74 | 75 | HighPrioFullSpeed: 76 | - Weight: 400 77 | ``` 78 | -------------------------------------------------------------------------------- /pkg/sst/sysfs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sst 18 | 19 | import ( 20 | "os" 21 | "path/filepath" 22 | "strconv" 23 | "strings" 24 | 25 | goresctrlpath "github.com/intel/goresctrl/pkg/path" 26 | "github.com/intel/goresctrl/pkg/utils" 27 | ) 28 | 29 | type cpuPackageInfo struct { 30 | id int 31 | cpus []int 32 | } 33 | 34 | func (pkg *cpuPackageInfo) hasCpus(cpus utils.IDSet) bool { 35 | return utils.NewIDSetFromIntSlice(pkg.cpus...).Has(cpus.Members()...) 36 | } 37 | 38 | func getOnlineCpuPackages() (map[int]*cpuPackageInfo, error) { 39 | basePath := goresctrlpath.Path("sys/bus/cpu/devices") 40 | 41 | files, err := os.ReadDir(basePath) 42 | if err != nil { 43 | return nil, err 44 | } 45 | 46 | pkgs := make(map[int]*cpuPackageInfo) 47 | 48 | for _, file := range files { 49 | // Try to read siblings from topology 50 | raw, err := os.ReadFile(filepath.Join(basePath, file.Name(), "topology/physical_package_id")) 51 | if os.IsNotExist(err) { 52 | // Offline -> topology information does not exist 53 | continue 54 | } else if err != nil { 55 | return nil, err 56 | } 57 | 58 | cpuId, err := strconv.Atoi(file.Name()[3:]) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | pkgId, err := strconv.Atoi(strings.TrimSpace(string(raw))) 64 | if err != nil { 65 | return nil, err 66 | } 67 | 68 | if _, ok := pkgs[pkgId]; !ok { 69 | pkgs[pkgId] = &cpuPackageInfo{id: pkgId} 70 | } 71 | pkgs[pkgId].cpus = append(pkgs[pkgId].cpus, cpuId) 72 | } 73 | 74 | return pkgs, nil 75 | } 76 | 77 | func isHWPEnabled() (bool, error) { 78 | status, err := utils.ReadMSR(0, MSR_PM_ENABLE) 79 | if err != nil { 80 | return false, err 81 | } 82 | 83 | return (status & 0xff) != 0, nil 84 | } 85 | 86 | func setCPUScalingMin2CPUInfoMinFreq(cpu utils.ID) error { 87 | freq, err := utils.GetCPUFreqValue(cpu, "cpuinfo_min_freq") 88 | if err != nil { 89 | return err 90 | } 91 | 92 | return utils.SetCPUScalingMinFreq(cpu, freq) 93 | } 94 | 95 | func setCPUScalingMin2CPUInfoMaxFreq(cpu utils.ID) error { 96 | freq, err := utils.GetCPUFreqValue(cpu, "cpuinfo_max_freq") 97 | if err != nil { 98 | return err 99 | } 100 | 101 | return utils.SetCPUScalingMinFreq(cpu, freq) 102 | } 103 | -------------------------------------------------------------------------------- /pkg/sst/_sst_types_priv.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // This file is used for auto-generation of sst_types_priv.go 18 | package sst 19 | 20 | // #include "tools/power/x86/intel-speed-select/isst.h" 21 | // #include "tools/arch/x86/include/asm/msr-index.h" 22 | // 23 | import "C" 24 | 25 | const ( 26 | // TDP (perf profile) related commands 27 | CONFIG_TDP = C.CONFIG_TDP 28 | CONFIG_TDP_GET_LEVELS_INFO = C.CONFIG_TDP_GET_LEVELS_INFO 29 | CONFIG_TDP_GET_TDP_CONTROL = C.CONFIG_TDP_GET_TDP_CONTROL 30 | CONFIG_TDP_SET_TDP_CONTROL = C.CONFIG_TDP_SET_TDP_CONTROL 31 | CONFIG_TDP_GET_TDP_INFO = C.CONFIG_TDP_GET_TDP_INFO 32 | CONFIG_TDP_GET_PWR_INFO = C.CONFIG_TDP_GET_PWR_INFO 33 | CONFIG_TDP_GET_TJMAX_INFO = C.CONFIG_TDP_GET_TJMAX_INFO 34 | CONFIG_TDP_GET_CORE_MASK = C.CONFIG_TDP_GET_CORE_MASK 35 | CONFIG_TDP_GET_TURBO_LIMIT_RATIOS = C.CONFIG_TDP_GET_TURBO_LIMIT_RATIOS 36 | CONFIG_TDP_SET_LEVEL = C.CONFIG_TDP_SET_LEVEL 37 | CONFIG_TDP_GET_UNCORE_P0_P1_INFO = C.CONFIG_TDP_GET_UNCORE_P0_P1_INFO 38 | CONFIG_TDP_GET_P1_INFO = C.CONFIG_TDP_GET_P1_INFO 39 | CONFIG_TDP_GET_MEM_FREQ = C.CONFIG_TDP_GET_MEM_FREQ 40 | 41 | CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES = C.CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES 42 | CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS = C.CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS 43 | CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO = C.CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO 44 | 45 | CONFIG_TDP_PBF_GET_CORE_MASK_INFO = C.CONFIG_TDP_PBF_GET_CORE_MASK_INFO 46 | CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO = C.CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO 47 | CONFIG_TDP_PBF_GET_TJ_MAX_INFO = C.CONFIG_TDP_PBF_GET_TJ_MAX_INFO 48 | CONFIG_TDP_PBF_GET_TDP_INFO = C.CONFIG_TDP_PBF_GET_TDP_INFO 49 | 50 | // CLOS related commands 51 | CONFIG_CLOS = C.CONFIG_CLOS 52 | CLOS_PM_QOS_CONFIG = C.CLOS_PM_QOS_CONFIG 53 | CLOS_PQR_ASSOC = C.CLOS_PQR_ASSOC 54 | CLOS_PM_CLOS = C.CLOS_PM_CLOS 55 | CLOS_STATUS = C.CLOS_STATUS 56 | 57 | MBOX_CMD_WRITE_BIT = C.MBOX_CMD_WRITE_BIT 58 | 59 | // PM commands 60 | READ_PM_CONFIG = C.READ_PM_CONFIG 61 | WRITE_PM_CONFIG = C.WRITE_PM_CONFIG 62 | PM_FEATURE = C.PM_FEATURE 63 | 64 | PM_QOS_INFO_OFFSET = C.PM_QOS_INFO_OFFSET 65 | PM_QOS_CONFIG_OFFSET = C.PM_QOS_CONFIG_OFFSET 66 | PM_CLOS_OFFSET = C.PM_CLOS_OFFSET 67 | PQR_ASSOC_OFFSET = C.PQR_ASSOC_OFFSET 68 | 69 | // Hardware P state interface 70 | MSR_PM_ENABLE = C.MSR_PM_ENABLE 71 | ) 72 | -------------------------------------------------------------------------------- /pkg/rdt/kubernetes.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rdt 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/intel/goresctrl/pkg/kubernetes" 23 | ) 24 | 25 | const ( 26 | // RdtContainerAnnotation is the CRI level container annotation for setting 27 | // the RDT class (CLOS) of a container 28 | RdtContainerAnnotation = "io.kubernetes.cri.rdt-class" 29 | 30 | // RdtPodAnnotation is a Pod annotation for setting the RDT class (CLOS) of 31 | // all containers of the pod 32 | RdtPodAnnotation = "rdt.resources.beta.kubernetes.io/pod" 33 | 34 | // RdtPodAnnotationContainerPrefix is prefix for per-container Pod annotation 35 | // for setting the RDT class (CLOS) of one container of the pod 36 | RdtPodAnnotationContainerPrefix = "rdt.resources.beta.kubernetes.io/container." 37 | ) 38 | 39 | // ContainerClassFromAnnotations determines the effective RDT class of a 40 | // container from the Pod annotations and CRI level container annotations of a 41 | // container. Verifies that the class exists in goresctrl configuration and that 42 | // it is allowed to be used. 43 | func ContainerClassFromAnnotations(containerName string, containerAnnotations, podAnnotations map[string]string) (string, error) { 44 | clsName, clsOrigin := kubernetes.ContainerClassFromAnnotations( 45 | RdtContainerAnnotation, RdtPodAnnotation, RdtPodAnnotationContainerPrefix, 46 | containerName, containerAnnotations, podAnnotations) 47 | 48 | if clsOrigin != kubernetes.ClassOriginNotFound { 49 | if rdt == nil { 50 | return "", fmt.Errorf("RDT not initialized, class %q not available", clsName) 51 | } 52 | 53 | // Verify validity of class name 54 | if !IsQualifiedClassName(clsName) { 55 | return "", fmt.Errorf("unqualified RDT class name %q", clsName) 56 | } 57 | 58 | // If RDT has been initialized we check that the class exists 59 | if _, err := rdt.getClass(clsName); err != nil { 60 | return "", fmt.Errorf("RDT class not found: %w", err) 61 | } 62 | 63 | // If classes have been configured by goresctrl 64 | if clsConf, ok := rdt.conf.Classes[unaliasClassName(clsName)]; ok { 65 | // Check that the class is allowed 66 | if clsOrigin == kubernetes.ClassOriginPodAnnotation && clsConf.Kubernetes.DenyPodAnnotation { 67 | return "", fmt.Errorf("RDT class %q not allowed from Pod annotations", clsName) 68 | } else if clsOrigin == kubernetes.ClassOriginContainerAnnotation && clsConf.Kubernetes.DenyContainerAnnotation { 69 | return "", fmt.Errorf("RDT class %q not allowed from Container annotation", clsName) 70 | } 71 | } 72 | } 73 | 74 | return clsName, nil 75 | } 76 | -------------------------------------------------------------------------------- /cmd/blockio/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // This application demonstrates using the blockio API. 18 | 19 | package main 20 | 21 | import ( 22 | "encoding/json" 23 | "flag" 24 | "fmt" 25 | "log/slog" 26 | "os" 27 | 28 | "github.com/intel/goresctrl/pkg/blockio" 29 | "github.com/intel/goresctrl/pkg/log" 30 | goresctrlpath "github.com/intel/goresctrl/pkg/path" 31 | ) 32 | 33 | var examples string = `Examples: 34 | # Inspect OCI blockio structure 35 | $ blockio -config sample.cfg -class slowread | jq 36 | 37 | # Apply read throttling to a cgroup 38 | $ blockio -config sample.cfg -class slowread -cgroup user.slice/mygroup 39 | $ cat /sys/fs/cgroup/blkio/user.slice/mygroup/blkio.throttle.read_bps_device 40 | 41 | # Remove throttling from a cgroup 42 | $ blockio -config sample.cfg -class nolimit -cgroup user.slice/mygroup 43 | ` 44 | 45 | // nolint:errcheck 46 | func usage() { 47 | flag.CommandLine.SetOutput(os.Stdout) 48 | fmt.Fprintln(flag.CommandLine.Output(), "blockio - demo application for goresctrl/pkg/blockio API") 49 | fmt.Fprintln(flag.CommandLine.Output(), "Usage: blockio -config=FILE -class=NAME [-cgroup=CGROUP]") 50 | flag.PrintDefaults() 51 | fmt.Fprint(flag.CommandLine.Output(), examples) 52 | } 53 | 54 | func errorExit(format string, args ...interface{}) { 55 | fmt.Fprintln(os.Stderr, fmt.Sprintf(format, args...)) 56 | os.Exit(1) 57 | } 58 | 59 | func main() { 60 | // Parse commandline arguments 61 | flag.Usage = usage 62 | flag.Func("prefix", "set mount prefix for system directories", func(s string) error { 63 | goresctrlpath.SetPrefix(s) 64 | return nil 65 | }) 66 | optConfig := flag.String("config", "", "load class configuration from FILE") 67 | optClass := flag.String("class", "", "use configuration of the blockio class NAME") 68 | logLevel := log.NewLevelFlag(slog.LevelDebug) 69 | flag.Var(logLevel, "log-level", "Set log level (debug, info, warn, error)") 70 | flag.Parse() 71 | 72 | blockio.SetLogger(slog.New(log.NewLogHandler(logLevel))) 73 | 74 | if optConfig == nil || *optConfig == "" { 75 | errorExit("missing -config=FILE") 76 | } 77 | 78 | if optClass == nil || *optClass == "" { 79 | errorExit("missing -class=NAME") 80 | } 81 | 82 | // Read blockio class configuration. 83 | if err := blockio.SetConfigFromFile(*optConfig, true); err != nil { 84 | errorExit("%v", err) 85 | } 86 | 87 | // Print OCI spec. 88 | oci, err := blockio.OciLinuxBlockIO(*optClass) 89 | if err != nil { 90 | errorExit("%v", err) 91 | } 92 | ociBytes, err := json.Marshal(oci) 93 | if err != nil { 94 | errorExit("%v", err) 95 | } 96 | fmt.Printf("%s\n", ociBytes) 97 | } 98 | -------------------------------------------------------------------------------- /pkg/testutils/verify.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 Intel Corporation. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package testutils 16 | 17 | import ( 18 | "reflect" 19 | "strings" 20 | "testing" 21 | ) 22 | 23 | // VerifyDeepEqual checks that two values (including structures) are equal, or else it fails the test. 24 | func VerifyDeepEqual(t *testing.T, valueName string, expectedValue interface{}, seenValue interface{}) bool { 25 | if reflect.DeepEqual(expectedValue, seenValue) { 26 | return true 27 | } 28 | t.Errorf("expected %s value %+v, got %+v", valueName, expectedValue, seenValue) 29 | return false 30 | } 31 | 32 | // VerifyError checks a (multi)error has expected properties, or else it fails the test. 33 | func VerifyError(t *testing.T, err error, expectedCount int, expectedSubstrings []string) bool { 34 | if expectedCount > 0 { 35 | if err == nil { 36 | t.Errorf("error expected, got nil") 37 | return false 38 | } 39 | if merr, ok := err.(interface{ Unwrap() []error }); !ok { 40 | if expectedCount > 1 { 41 | t.Errorf("expected %d errors, but got %#v instead of multierror", expectedCount, err) 42 | return false 43 | } 44 | // If exactly one error is expected, then err 45 | // is allowed to be any error, not just a 46 | // multierror. 47 | } else if errs := merr.Unwrap(); len(errs) != expectedCount { 48 | t.Errorf("expected %d errors, but got %d: %v", expectedCount, len(errs), merr) 49 | return false 50 | } 51 | } else if expectedCount == 0 { 52 | if err != nil { 53 | t.Errorf("expected 0 errors, but got: %v", err) 54 | return false 55 | } 56 | } 57 | for _, substring := range expectedSubstrings { 58 | if !strings.Contains(err.Error(), substring) { 59 | t.Errorf("expected error with substring %#v, got \"%v\"", substring, err) 60 | } 61 | } 62 | return true 63 | } 64 | 65 | func VerifyNoError(t *testing.T, err error) bool { 66 | if err != nil { 67 | t.Errorf("expected no error, got %v", err) 68 | return false 69 | } 70 | return true 71 | } 72 | 73 | func VerifyStrings(t *testing.T, expected string, got string) bool { 74 | if expected != got { 75 | t.Errorf("Strings differ: expected %q, got %q", expected, got) 76 | return false 77 | } 78 | return true 79 | } 80 | 81 | func VerifyStringSlices(t *testing.T, expected []string, got []string) bool { 82 | if len(expected) != len(got) { 83 | t.Errorf("Expected string slice of length %d, got %d", len(expected), len(got)) 84 | return false 85 | } 86 | for i, es := range expected { 87 | if es != got[i] { 88 | t.Errorf("Slices differ: expected[%d]=%q, got[%d]=%q", i, es, i, got[i]) 89 | return false 90 | } 91 | } 92 | return true 93 | } 94 | -------------------------------------------------------------------------------- /pkg/sst/fuzz_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sst 18 | 19 | import ( 20 | "flag" 21 | "testing" 22 | "time" 23 | 24 | "github.com/google/go-cmp/cmp" 25 | "golang.org/x/exp/maps" 26 | ) 27 | 28 | var enable = flag.Bool("sst.system-fuzz", false, "Enable SST fuzz tests that manipulate the system state (caution: requires root, manipulates configuration of the target system)") 29 | 30 | // FuzzClosSetup is a fuzz test for the ClosSetup function. Caution needs to be 31 | // taken when this test is run. The test needs to be run as root on an 32 | // SST-enabled system. Moreover the test manipulates the actual SST 33 | // configuration of the target system so a dedicated non-production system 34 | // should be used. Test cannot be parallelized (as it depends on the system 35 | // state). Because of these precautions the test needs to be explicitly 36 | // enabled with "-sst.system-fuzz" flag. 37 | // 38 | // An example how to run the test: 39 | // 40 | // # go test -parallel=1 -fuzz=FuzzClosSetup ./pkg/sst/... -sst.system-fuzz 41 | func FuzzClosSetup(f *testing.F) { 42 | if !*enable { 43 | f.Skipf("skipping as sst.fuzz is not enabled") 44 | } 45 | 46 | pkgs, err := GetPackageInfo() 47 | if err != nil { 48 | f.Errorf("unable to get SST package info: %v", err) 49 | } 50 | pkgIDs := maps.Keys(pkgs) 51 | 52 | f.Add(pkgIDs[0], 0, 53 | 0, 0, 0, 0, 0) 54 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 55 | 2, 5, 100, 200, 150) 56 | f.Add(pkgIDs[len(pkgIDs)-1], 3, 57 | 15, 15, 255, 255, 255) 58 | // Failure test cases 59 | f.Add(pkgIDs[len(pkgIDs)-1], 4, 60 | 2, 5, 100, 200, 150) 61 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 62 | 20, 5, 100, 200, 150) 63 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 64 | 2, 20, 100, 200, 150) 65 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 66 | 2, 10, 200, 100, 150) 67 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 68 | 2, 10, 100, 300, 150) 69 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 70 | -1, -1, -1, -1, -1) 71 | f.Add(pkgIDs[len(pkgIDs)-1], 1, 72 | 16, 16, 256, 256, 256) 73 | f.Fuzz(func(t *testing.T, pkg, clos, epp, pp, minf, maxf, desiredf int) { 74 | expectedInfo := &SstClosInfo{ 75 | EPP: epp, 76 | ProportionalPriority: pp, 77 | MinFreq: minf, 78 | MaxFreq: maxf, 79 | DesiredFreq: desiredf, 80 | } 81 | err := ClosSetup(pkgs[pkg], clos, expectedInfo) 82 | if err != nil { 83 | return 84 | } 85 | time.Sleep(100 * time.Millisecond) 86 | info, err := getSinglePackageInfo(pkgs[pkg].pkg) 87 | if err != nil { 88 | t.Errorf("failed to get package info: %v", err) 89 | } 90 | if !cmp.Equal(info.ClosInfo[clos], *expectedInfo) { 91 | t.Errorf("CLOS not configured correctly, expected %v, got %v", expectedInfo, info.ClosInfo[clos]) 92 | } 93 | }) 94 | } 95 | -------------------------------------------------------------------------------- /pkg/rdt/bitmask.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rdt 18 | 19 | import ( 20 | "fmt" 21 | "math/bits" 22 | "strconv" 23 | "strings" 24 | ) 25 | 26 | // bitmask represents a generic 64 bit wide bitmask 27 | type bitmask uint64 28 | 29 | // MarshalJSON implements the Marshaler interface of "encoding/json" 30 | func (b bitmask) MarshalJSON() ([]byte, error) { 31 | return []byte(fmt.Sprintf("\"%#x\"", b)), nil 32 | } 33 | 34 | // listStr prints the bitmask in human-readable format, similar to e.g. the 35 | // cpuset format of the Linux kernel 36 | func (b bitmask) listStr() string { 37 | str := "" 38 | sep := "" 39 | 40 | shift := int(0) 41 | lsbOne := b.lsbOne() 42 | 43 | // Process "ranges of ones" 44 | for lsbOne != -1 { 45 | b >>= uint(lsbOne) 46 | 47 | // Get range lenght from the position of the first zero 48 | numOnes := b.lsbZero() 49 | 50 | if numOnes == 1 { 51 | str += sep + strconv.Itoa(lsbOne+shift) 52 | } else { 53 | str += sep + strconv.Itoa(lsbOne+shift) + "-" + strconv.Itoa(lsbOne+numOnes-1+shift) 54 | } 55 | 56 | // Shift away the bits that have been processed 57 | b >>= uint(numOnes) 58 | shift += lsbOne + numOnes 59 | 60 | // Get next bit that is set (if any) 61 | lsbOne = b.lsbOne() 62 | 63 | sep = "," 64 | } 65 | 66 | return str 67 | } 68 | 69 | // listStrToBitmask parses a string containing a human-readable list of bit 70 | // numbers into a bitmask 71 | func listStrToBitmask(str string) (bitmask, error) { 72 | b := bitmask(0) 73 | 74 | // Empty bitmask 75 | if len(str) == 0 { 76 | return b, nil 77 | } 78 | 79 | ranges := strings.Split(str, ",") 80 | for _, ran := range ranges { 81 | split := strings.SplitN(ran, "-", 2) 82 | 83 | bitNum, err := strconv.ParseUint(split[0], 10, 6) 84 | if err != nil { 85 | return b, fmt.Errorf("invalid bitmask %q: %v", str, err) 86 | } 87 | 88 | if len(split) == 1 { 89 | b |= 1 << bitNum 90 | } else { 91 | endNum, err := strconv.ParseUint(split[1], 10, 6) 92 | if err != nil { 93 | return b, fmt.Errorf("invalid bitmask %q: %v", str, err) 94 | } 95 | if endNum <= bitNum { 96 | return b, fmt.Errorf("invalid range %q in bitmask %q", ran, str) 97 | } 98 | b |= (1<<(endNum-bitNum+1) - 1) << bitNum 99 | } 100 | } 101 | return b, nil 102 | } 103 | 104 | func (b bitmask) lsbOne() int { 105 | if b == 0 { 106 | return -1 107 | } 108 | return bits.TrailingZeros64(uint64(b)) 109 | } 110 | 111 | func (b bitmask) msbOne() int { 112 | // Returns -1 for b == 0 113 | return 63 - bits.LeadingZeros64(uint64(b)) 114 | } 115 | 116 | func (b bitmask) lsbZero() int { 117 | return bits.TrailingZeros64(^uint64(b)) 118 | } 119 | -------------------------------------------------------------------------------- /pkg/cstates/sysfs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cstates 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "strconv" 23 | "strings" 24 | 25 | goresctrlpath "github.com/intel/goresctrl/pkg/path" 26 | "github.com/intel/goresctrl/pkg/utils" 27 | ) 28 | 29 | type sysfsIface interface { 30 | // PossibleCpus returns a string representing possible CPUs, e.g. "0-3". 31 | PossibleCpus() (string, error) 32 | // CpuidleStates returns a slice of cpuidle state numbers for the given CPU ID. 33 | // Numbers correspond to cpuidle/state directories in sysfs. 34 | CpuidleStates(cpuID utils.ID) ([]int, error) 35 | // CpuidleStateAttrRead reads the value of the given attribute for the specified CPU ID and cpuidle state number. 36 | CpuidleStateAttrRead(cpu utils.ID, state int, attribute string) (string, error) 37 | // CpuidleStateAttrWrite writes the given value to the specified attribute for the given CPU ID and cpuidle state number. 38 | CpuidleStateAttrWrite(cpu utils.ID, state int, attribute string, value string) error 39 | } 40 | 41 | type sysfs struct{} 42 | 43 | func NewSysfs() sysfsIface { 44 | return &sysfs{} 45 | } 46 | 47 | func (fs *sysfs) PossibleCpus() (string, error) { 48 | return fs.readString(goresctrlpath.Path("sys/devices/system/cpu/possible")) 49 | } 50 | 51 | func (fs *sysfs) CpuidleStates(cpu utils.ID) ([]int, error) { 52 | cpuidlePath := "sys/devices/system/cpu/cpu" + strconv.Itoa(cpu) + "/cpuidle" 53 | states := []int{} 54 | 55 | dirEntries, err := os.ReadDir(goresctrlpath.Path(cpuidlePath)) 56 | if err != nil { 57 | return states, err 58 | } 59 | 60 | for _, entry := range dirEntries { 61 | if entry.IsDir() && strings.HasPrefix(entry.Name(), "state") { 62 | state, err := strconv.Atoi(strings.TrimPrefix(entry.Name(), "state")) 63 | if err != nil { 64 | return states, fmt.Errorf("failed to parse cpuidle state dir name %q: %w", entry.Name(), err) 65 | } 66 | states = append(states, state) 67 | } 68 | } 69 | return states, nil 70 | } 71 | 72 | func (fs *sysfs) CpuidleStateAttrRead(cpu utils.ID, state int, attr string) (string, error) { 73 | return fs.readString(fs.cstateAttrPath(cpu, state, attr)) 74 | } 75 | 76 | func (fs *sysfs) CpuidleStateAttrWrite(cpu utils.ID, state int, attr string, value string) error { 77 | return fs.writeString(fs.cstateAttrPath(cpu, state, attr), value) 78 | } 79 | 80 | func (fs *sysfs) cstateAttrPath(cpu utils.ID, state int, attr string) string { 81 | return "sys/devices/system/cpu/cpu" + strconv.Itoa(cpu) + "/cpuidle/state" + strconv.Itoa(state) + "/" + attr 82 | } 83 | 84 | func (fs *sysfs) readString(path string) (string, error) { 85 | data, err := os.ReadFile(goresctrlpath.Path(path)) 86 | return strings.TrimSpace(string(data)), err 87 | } 88 | 89 | func (fs *sysfs) writeString(path string, data string) error { 90 | return os.WriteFile(goresctrlpath.Path(path), []byte(data), 0644) 91 | } 92 | -------------------------------------------------------------------------------- /pkg/blockio/cgroups.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020-2021 Intel Corporation. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package blockio 16 | 17 | // BlockIOParameters contains cgroups blockio controller parameters. 18 | // 19 | // Effects of Weight and Rate values in SetBlkioParameters(): 20 | // Value | Effect 21 | // -------+------------------------------------------------------------------- 22 | // 23 | // -1 | Do not write to cgroups, value is missing. 24 | // 0 | Write to cgroups, will clear the setting as specified in cgroups blkio interface. 25 | // other | Write to cgroups, sets the value. 26 | type BlockIOParameters struct { 27 | Weight int64 28 | WeightDevice DeviceWeights 29 | ThrottleReadBpsDevice DeviceRates 30 | ThrottleWriteBpsDevice DeviceRates 31 | ThrottleReadIOPSDevice DeviceRates 32 | ThrottleWriteIOPSDevice DeviceRates 33 | } 34 | 35 | // DeviceWeight contains values for 36 | // - blkio.[io-scheduler].weight 37 | type DeviceWeight struct { 38 | Major int64 39 | Minor int64 40 | Weight int64 41 | } 42 | 43 | // DeviceRate contains values for 44 | // - blkio.throttle.read_bps_device 45 | // - blkio.throttle.write_bps_device 46 | // - blkio.throttle.read_iops_device 47 | // - blkio.throttle.write_iops_device 48 | type DeviceRate struct { 49 | Major int64 50 | Minor int64 51 | Rate int64 52 | } 53 | 54 | // DeviceWeights contains weights for devices. 55 | type DeviceWeights []DeviceWeight 56 | 57 | // DeviceRates contains throttling rates for devices. 58 | type DeviceRates []DeviceRate 59 | 60 | // NewBlockIOParameters creates new BlockIOParameters instance. 61 | func NewBlockIOParameters() BlockIOParameters { 62 | return BlockIOParameters{ 63 | Weight: -1, 64 | } 65 | } 66 | 67 | // DeviceParameters interface provides functions common to DeviceWeights and DeviceRates. 68 | type DeviceParameters interface { 69 | Append(maj, min, val int64) 70 | Update(maj, min, val int64) 71 | } 72 | 73 | // Append appends (major, minor, value) to DeviceWeights slice. 74 | func (w *DeviceWeights) Append(maj, min, val int64) { 75 | *w = append(*w, DeviceWeight{Major: maj, Minor: min, Weight: val}) 76 | } 77 | 78 | // Append appends (major, minor, value) to DeviceRates slice. 79 | func (r *DeviceRates) Append(maj, min, val int64) { 80 | *r = append(*r, DeviceRate{Major: maj, Minor: min, Rate: val}) 81 | } 82 | 83 | // Update updates device weight in DeviceWeights slice, or appends it if not found. 84 | func (w *DeviceWeights) Update(maj, min, val int64) { 85 | for index, devWeight := range *w { 86 | if devWeight.Major == maj && devWeight.Minor == min { 87 | (*w)[index].Weight = val 88 | return 89 | } 90 | } 91 | w.Append(maj, min, val) 92 | } 93 | 94 | // Update updates device rate in DeviceRates slice, or appends it if not found. 95 | func (r *DeviceRates) Update(maj, min, val int64) { 96 | for index, devRate := range *r { 97 | if devRate.Major == maj && devRate.Minor == min { 98 | (*r)[index].Rate = val 99 | return 100 | } 101 | } 102 | r.Append(maj, min, val) 103 | } 104 | -------------------------------------------------------------------------------- /pkg/rdt/kubernetes_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rdt 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestContainerClassFromAnnotations(t *testing.T) { 26 | containerName := "test-container" 27 | containerAnnotations := map[string]string{} 28 | podAnnotations := map[string]string{} 29 | 30 | // Helper function for checking test cases 31 | tc := func(expectError bool, expectedClsName string) { 32 | cls, err := ContainerClassFromAnnotations(containerName, containerAnnotations, podAnnotations) 33 | if !expectError && err != nil { 34 | t.Errorf("unexpected error: %v", err) 35 | } else if expectError && err == nil { 36 | t.Errorf("unexpected success setting RDT class to %q", cls) 37 | } else if cls != expectedClsName { 38 | t.Errorf("invalid rdt class, expecting %q, got %q", expectedClsName, cls) 39 | } 40 | } 41 | 42 | // 43 | // 1. Test container annotation 44 | // 45 | 46 | // Should succeed when rdt is uninitialized but annotations are empty 47 | rdt = nil 48 | tc(false, "") 49 | 50 | // Should fail when rdt is uninitialized but annotations point to a class 51 | containerAnnotations = map[string]string{RdtContainerAnnotation: "class-1"} 52 | podAnnotations = map[string]string{ 53 | RdtPodAnnotationContainerPrefix + containerName: "class-2", 54 | RdtPodAnnotation: "class-3"} 55 | tc(true, "") 56 | 57 | // Mock configured rdt which enables the functionality 58 | mockFs, err := newMockResctrlFs(t, "resctrl.l2", "") 59 | require.NoError(t, err, "failed to set up mock resctrl fs") 60 | defer mockFs.delete() 61 | 62 | require.NoError(t, Initialize(""), "rdt initialization failed") 63 | 64 | // Should fail with an empty set of classes 65 | tc(true, "") 66 | 67 | // Should succeed when the class exists but no configuration has been set ("discovery mode") 68 | require.NoError(t, mockFs.createCtrlGroup("class-1")) 69 | require.NoError(t, mockFs.createCtrlGroup("class-2")) 70 | require.NoError(t, mockFs.createCtrlGroup("class-3")) 71 | tc(false, "class-1") 72 | 73 | // Should succeed with default class config 74 | rdt.conf.Classes = classSet{"class-1": &classConfig{}, "class-2": &classConfig{}, "class-3": &classConfig{}} 75 | tc(false, "class-1") 76 | 77 | // Should fail when container annotation has been denied in class ocnfig 78 | rdt.conf.Classes["class-1"].Kubernetes.DenyContainerAnnotation = true 79 | tc(true, "") 80 | 81 | // Test invalid class name 82 | containerAnnotations[RdtContainerAnnotation] = "foo/bar" 83 | tc(true, "") 84 | 85 | // 86 | // 2. Test per-container Pod annotation 87 | // 88 | delete(containerAnnotations, RdtContainerAnnotation) 89 | tc(false, "class-2") 90 | 91 | // Should fail when pod annotations for the class are denied 92 | rdt.conf.Classes["class-2"].Kubernetes.DenyPodAnnotation = true 93 | tc(true, "") 94 | 95 | // 96 | // 3. Test pod-wide Pod annotation 97 | // 98 | delete(podAnnotations, RdtPodAnnotationContainerPrefix+containerName) 99 | tc(false, "class-3") 100 | 101 | // Should fail when pod annotations for the class are denied 102 | rdt.conf.Classes["class-3"].Kubernetes.DenyPodAnnotation = true 103 | tc(true, "") 104 | 105 | // 106 | // Test empty annotations 107 | // 108 | delete(podAnnotations, RdtPodAnnotation) 109 | tc(false, "") 110 | } 111 | -------------------------------------------------------------------------------- /pkg/kubernetes/annotations_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package kubernetes 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | // TestContainerClassFromAnnotations: unit test for ContainerClassFromAnnotations. 24 | func TestContainerClassFromAnnotations(t *testing.T) { 25 | aContainerAnnotation := "io.kubernetes.cri.a-class" 26 | aPodAnnotation := "a.resources.beta.kubernetes.io/pod" 27 | aPodAnnotationContainerPrefix := "a.resources.beta.kubernetes.io/container." 28 | bContainerAnnotation := "io.kubernetes.cri.b-class" 29 | bPodAnnotation := "b.resources.beta.kubernetes.io/pod" 30 | bPodAnnotationContainerPrefix := "b.resources.beta.kubernetes.io/container." 31 | allContainerAnnotations := map[string]string{ 32 | aContainerAnnotation: "a-container-class", 33 | bContainerAnnotation: "b-container-class", 34 | } 35 | allPodAnnotations := map[string]string{ 36 | aPodAnnotation: "a-pod-class", 37 | aPodAnnotationContainerPrefix + "special-container": "a-pod-container-class", 38 | bPodAnnotation: "b-pod-class", 39 | bPodAnnotationContainerPrefix + "special-container": "b-pod-container-class", 40 | } 41 | tcases := []struct { 42 | name string // the name of the test case 43 | // inputs 44 | lookForCA string // container annotation to look for 45 | lookForPA string // pod annotation to look for 46 | lookForPAC string // pod annotation container prefix to look for 47 | cName string // container name 48 | cAnns map[string]string // container annotations 49 | pAnns map[string]string // pod annotations 50 | // outputs 51 | expectedClass string 52 | expectedOrigin ClassOrigin 53 | }{ 54 | { 55 | name: "all empty", 56 | expectedOrigin: ClassOriginNotFound, 57 | }, 58 | { 59 | name: "container annotation overrides all pod annotations", 60 | lookForCA: aContainerAnnotation, 61 | lookForPA: aPodAnnotation, 62 | lookForPAC: aPodAnnotationContainerPrefix, 63 | cName: "special-container", 64 | cAnns: allContainerAnnotations, 65 | pAnns: allPodAnnotations, 66 | expectedClass: "a-container-class", 67 | expectedOrigin: ClassOriginContainerAnnotation, 68 | }, 69 | { 70 | name: "container prefix overrides default pod annotation", 71 | lookForCA: "not.existing.container.annotation", 72 | lookForPA: bPodAnnotation, 73 | lookForPAC: bPodAnnotationContainerPrefix, 74 | cName: "special-container", 75 | cAnns: allContainerAnnotations, 76 | pAnns: allPodAnnotations, 77 | expectedClass: "b-pod-container-class", 78 | expectedOrigin: ClassOriginPodAnnotation, 79 | }, 80 | { 81 | name: "default pod annotation", 82 | lookForCA: "not.existing.container.annotation", 83 | lookForPA: bPodAnnotation, 84 | lookForPAC: bPodAnnotationContainerPrefix, 85 | cName: "ordinary-container", 86 | cAnns: allContainerAnnotations, 87 | pAnns: allPodAnnotations, 88 | expectedClass: "b-pod-class", 89 | expectedOrigin: ClassOriginPodAnnotation, 90 | }, 91 | } 92 | for _, tc := range tcases { 93 | t.Run(tc.name, func(t *testing.T) { 94 | observedClass, observedOrigin := ContainerClassFromAnnotations( 95 | tc.lookForCA, tc.lookForPA, tc.lookForPAC, 96 | tc.cName, tc.cAnns, tc.pAnns) 97 | if observedClass != tc.expectedClass { 98 | t.Errorf("expected class %q, observed %q", tc.expectedClass, observedClass) 99 | } 100 | if observedOrigin != tc.expectedOrigin { 101 | t.Errorf("expected origin %q, observed %q", tc.expectedOrigin, observedOrigin) 102 | } 103 | }) 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /pkg/rdt/prometheus.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rdt 18 | 19 | import ( 20 | "fmt" 21 | "sync" 22 | 23 | "github.com/prometheus/client_golang/prometheus" 24 | ) 25 | 26 | var customLabels []string = []string{} 27 | 28 | // collector implements prometheus.Collector interface 29 | type collector struct { 30 | descriptors map[string]*prometheus.Desc 31 | } 32 | 33 | // NewCollector creates new Prometheus collector of RDT metrics 34 | func NewCollector() prometheus.Collector { 35 | c := &collector{descriptors: make(map[string]*prometheus.Desc)} 36 | return c 37 | } 38 | 39 | // RegisterCustomPrometheusLabels registers monitor group annotations to be 40 | // exported as Prometheus metrics labels 41 | func RegisterCustomPrometheusLabels(names ...string) { 42 | Names: 43 | for _, n := range names { 44 | for _, c := range customLabels { 45 | if n == c { 46 | break Names 47 | } 48 | } 49 | customLabels = append(customLabels, n) 50 | } 51 | } 52 | 53 | // Describe method of the prometheus.Collector interface 54 | func (c *collector) Describe(ch chan<- *prometheus.Desc) { 55 | for resource, features := range GetMonFeatures() { 56 | switch resource { 57 | case MonResourceL3: 58 | for _, f := range features { 59 | ch <- c.describeL3(f) 60 | } 61 | } 62 | } 63 | } 64 | 65 | // Collect method of the prometheus.Collector interface 66 | func (c collector) Collect(ch chan<- prometheus.Metric) { 67 | var wg sync.WaitGroup 68 | 69 | for _, cls := range GetClasses() { 70 | c.collectGroupMetrics(ch, cls) 71 | for _, monGrp := range cls.GetMonGroups() { 72 | wg.Add(1) 73 | g := monGrp 74 | go func() { 75 | defer wg.Done() 76 | c.collectMonGroupMetrics(ch, g) 77 | }() 78 | } 79 | } 80 | wg.Wait() 81 | } 82 | 83 | func (c *collector) describeL3(feature string) *prometheus.Desc { 84 | d, ok := c.descriptors[feature] 85 | if !ok { 86 | name := "l3_" + feature 87 | help := "L3 " + feature 88 | 89 | switch feature { 90 | case "llc_occupancy": 91 | help = "L3 (LLC) occupancy" 92 | case "mbm_local_bytes": 93 | help = "bytes transferred to/from local memory through LLC" 94 | case "mbm_total_bytes": 95 | help = "total bytes transferred to/from memory through LLC" 96 | } 97 | labels := append([]string{"rdt_class", "rdt_mon_group", "cache_id"}, customLabels...) 98 | d = prometheus.NewDesc(name, help, labels, nil) 99 | c.descriptors[feature] = d 100 | } 101 | return d 102 | } 103 | 104 | func (c *collector) collectMonGroupMetrics(ch chan<- prometheus.Metric, mg MonGroup) { 105 | annotations := mg.GetAnnotations() 106 | customLabelValues := make([]string, len(customLabels)) 107 | for i, name := range customLabels { 108 | customLabelValues[i] = annotations[name] 109 | } 110 | 111 | c.collectGroupMetrics(ch, mg, customLabelValues...) 112 | } 113 | 114 | func (c *collector) collectGroupMetrics(ch chan<- prometheus.Metric, g ResctrlGroup, customLabels ...string) { 115 | allData := g.GetMonData() 116 | 117 | cgName, mgName := "", "" 118 | if mg, ok := g.(MonGroup); ok { 119 | cgName = mg.Parent().Name() 120 | mgName = mg.Name() 121 | } else { 122 | cgName = g.Name() 123 | } 124 | 125 | for cacheID, data := range allData.L3 { 126 | labels := append([]string{cgName, mgName, fmt.Sprint(cacheID)}, customLabels...) 127 | for feature, value := range data { 128 | ch <- prometheus.MustNewConstMetric( 129 | c.describeL3(feature), 130 | promValueTypeL3(feature), 131 | float64(value), 132 | labels..., 133 | ) 134 | } 135 | } 136 | } 137 | 138 | // promValueTypeL3 returns Prometheus value type for given L3 metric. 139 | func promValueTypeL3(feature string) prometheus.ValueType { 140 | switch feature { 141 | case "llc_occupancy": 142 | return prometheus.GaugeValue 143 | case "mbm_local_bytes", "mbm_total_bytes": 144 | return prometheus.CounterValue 145 | default: 146 | return prometheus.GaugeValue 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /pkg/sst/sst_if.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sst 18 | 19 | //go:generate ./gen_sst_types.sh 20 | 21 | import ( 22 | "fmt" 23 | "log/slog" 24 | "math" 25 | "os" 26 | "syscall" 27 | "unsafe" 28 | 29 | "github.com/intel/goresctrl/pkg/utils" 30 | ) 31 | 32 | // cpuMap holds the logical to punit cpu mapping table 33 | var cpuMap = make(map[utils.ID]utils.ID) 34 | 35 | // punitCPU returns the PUNIT CPU id corresponding a given Linux logical CPU 36 | func punitCPU(cpu utils.ID) (utils.ID, error) { 37 | if id, ok := cpuMap[cpu]; ok { 38 | return id, nil 39 | } 40 | 41 | id, err := getCPUMapping(cpu) 42 | if err == nil { 43 | cpuMap[cpu] = id 44 | } 45 | return id, err 46 | } 47 | 48 | // isstIoctl is a helper for executing ioctls on the linux isst_if device driver 49 | func isstIoctl(ioctl uintptr, req uintptr) error { 50 | devPath := isstDevPath() 51 | f, err := os.Open(devPath) 52 | if err != nil { 53 | return fmt.Errorf("failed to open isst device %q: %v", devPath, err) 54 | } 55 | defer f.Close() // nolint:errcheck 56 | 57 | if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), ioctl, req); errno != 0 { 58 | return errno 59 | } 60 | 61 | return nil 62 | } 63 | 64 | // getCPUMapping gets mapping of Linux logical CPU numbers to (package-specific) 65 | // PUNIT CPU number for one cpu. This is needed because the PUNIT CPU/core 66 | // numbering differs from the Linux kernel numbering (exposed via sysfs) which 67 | // is based on APIC. 68 | func getCPUMapping(cpu utils.ID) (utils.ID, error) { 69 | if cpu < 0 || cpu > math.MaxUint32 { 70 | return utils.Unknown, fmt.Errorf("invalid CPU number %d", cpu) 71 | } 72 | 73 | req := isstIfCPUMaps{ 74 | Cmd_count: 1, 75 | Cpu_map: [1]isstIfCPUMap{ 76 | {Logical_cpu: uint32(cpu)}, 77 | }, 78 | } 79 | 80 | if err := isstIoctl(ISST_IF_GET_PHY_ID, uintptr(unsafe.Pointer(&req))); err != nil { 81 | return -1, fmt.Errorf("failed to get CPU mapping for cpu %d: %v", cpu, err) 82 | } 83 | 84 | return utils.ID(req.Cpu_map[0].Physical_cpu), nil 85 | } 86 | 87 | // sendMboxCmd sends one mailbox command to PUNIT 88 | func sendMboxCmd(cpu utils.ID, cmd uint16, subCmd uint16, parameter uint32, reqData uint32) (uint32, error) { 89 | if cpu < 0 || cpu > math.MaxUint32 { 90 | return 0, fmt.Errorf("invalid CPU number %d", cpu) 91 | } 92 | 93 | req := isstIfMboxCmds{ 94 | Cmd_count: 1, 95 | Mbox_cmd: [1]isstIfMboxCmd{ 96 | { 97 | Logical_cpu: uint32(cpu), 98 | Command: cmd, 99 | Sub_command: subCmd, 100 | Parameter: parameter, 101 | Req_data: reqData, 102 | }, 103 | }, 104 | } 105 | 106 | sstlog.Debug("MBOX SEND", "cpu", cpu, "cmd", cmd, "subCmd", subCmd, slogHex("data", reqData)) 107 | if err := isstIoctl(ISST_IF_MBOX_COMMAND, uintptr(unsafe.Pointer(&req))); err != nil { 108 | return 0, fmt.Errorf("mbox command failed with %v", err) 109 | } 110 | sstlog.Debug("MBOX RECV", slogHex("data", req.Mbox_cmd[0].Resp_data)) 111 | 112 | return req.Mbox_cmd[0].Resp_data, nil 113 | } 114 | 115 | // sendMMIOCmd sends one MMIO command to PUNIT 116 | func sendMMIOCmd(cpu utils.ID, reg uint32, value uint32, doWrite bool) (uint32, error) { 117 | if cpu < 0 || cpu > math.MaxUint32 { 118 | return 0, fmt.Errorf("invalid CPU number %d", cpu) 119 | } 120 | 121 | var ReadWrite uint32 122 | 123 | if doWrite { 124 | ReadWrite = 1 125 | } 126 | 127 | req := isstIfIoRegs{ 128 | Req_count: 1, 129 | Io_reg: [1]isstIfIoReg{ 130 | { 131 | Logical_cpu: uint32(cpu), 132 | Reg: reg, 133 | Value: value, 134 | Read_write: ReadWrite, 135 | }, 136 | }, 137 | } 138 | sstlog.Debug("MMIO SEND", "cpu", cpu, "reg", reg, slogHex("data", value), "write", doWrite) 139 | if err := isstIoctl(ISST_IF_IO_CMD, uintptr(unsafe.Pointer(&req))); err != nil { 140 | return 0, fmt.Errorf("MMIO command failed with %v", err) 141 | } 142 | sstlog.Debug("MMIO RECV", slogHex("data", req.Io_reg[0].Value)) 143 | 144 | return req.Io_reg[0].Value, nil 145 | } 146 | 147 | func slogHex(key string, val uint32) slog.Attr { 148 | return slog.String(key, fmt.Sprintf("%#02x", val)) 149 | } 150 | -------------------------------------------------------------------------------- /pkg/rdt/otel.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rdt 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "strings" 23 | "sync" 24 | 25 | "go.opentelemetry.io/otel/attribute" 26 | "go.opentelemetry.io/otel/metric" 27 | ) 28 | 29 | func RegisterOpenTelemetryInstruments(meter metric.Meter) error { 30 | for resource, features := range GetMonFeatures() { 31 | switch resource { 32 | case MonResourceL3: 33 | for _, f := range features { 34 | if err := registerInstrument(meter, f); err != nil { 35 | return err 36 | } 37 | } 38 | } 39 | } 40 | 41 | return nil 42 | } 43 | 44 | func registerInstrument(meter metric.Meter, feature string) error { 45 | instr, err := createInstrument(meter, feature) 46 | if err != nil { 47 | return err 48 | } 49 | 50 | _, err = meter.RegisterCallback( 51 | func(ctx context.Context, o metric.Observer) error { 52 | select { 53 | case <-ctx.Done(): 54 | return fmt.Errorf("rdt metric collection cancelled: %w", ctx.Err()) 55 | default: 56 | observeInstrument(o, instr, feature) 57 | } 58 | return nil 59 | }, 60 | instr, 61 | ) 62 | if err != nil { 63 | return err 64 | } 65 | 66 | return nil 67 | } 68 | 69 | func createInstrument(meter metric.Meter, feature string) (metric.Int64Observable, error) { 70 | switch feature { 71 | case "llc_occupancy": 72 | name := "l3.llc.occupancy" 73 | help := "L3 (LLC) occupancy" 74 | return meter.Int64ObservableGauge( 75 | name, 76 | metric.WithDescription(help), 77 | ) 78 | 79 | case "mbm_local_bytes": 80 | name := "l3.mbm.local" 81 | help := "bytes transferred to/from local memory through LLC" 82 | unit := "bytes" 83 | return meter.Int64ObservableCounter( 84 | name, 85 | metric.WithDescription(help), 86 | metric.WithUnit(unit), 87 | ) 88 | 89 | case "mbm_total_bytes": 90 | name := "l3.mbm.total" 91 | help := "total bytes transferred to/from memory through LLC" 92 | unit := "bytes" 93 | return meter.Int64ObservableCounter( 94 | name, 95 | metric.WithDescription(help), 96 | metric.WithUnit(unit), 97 | ) 98 | } 99 | 100 | // an unknown feature, counter for bytes, gauge otherwise 101 | name := "" 102 | help := "" 103 | unit := "" 104 | if strings.HasSuffix(feature, "_bytes") { 105 | name = strings.TrimSuffix(feature, "_bytes") 106 | unit = "bytes" 107 | } 108 | name = "l3." + strings.ReplaceAll(name, "_", ".") 109 | help = "L3 " + feature 110 | 111 | if unit == "bytes" { 112 | return meter.Int64ObservableUpDownCounter( 113 | name, 114 | metric.WithDescription(help), 115 | metric.WithUnit(unit), 116 | ) 117 | } 118 | 119 | return meter.Int64ObservableGauge( 120 | name, 121 | metric.WithDescription(help), 122 | metric.WithUnit(unit), 123 | ) 124 | } 125 | 126 | func observeInstrument(o metric.Observer, m metric.Int64Observable, feature string) { 127 | var wg sync.WaitGroup 128 | 129 | for _, cls := range GetClasses() { 130 | observeGroup(o, m, feature, cls) 131 | for _, monGrp := range cls.GetMonGroups() { 132 | wg.Add(1) 133 | go func(mg MonGroup) { 134 | defer wg.Done() 135 | observeGroup(o, m, feature, mg, getMonGroupAttributes(mg)...) 136 | }(monGrp) 137 | } 138 | } 139 | 140 | wg.Wait() 141 | } 142 | 143 | func observeGroup(o metric.Observer, m metric.Int64Observable, feature string, g ResctrlGroup, customAttributes ...attribute.KeyValue) { 144 | var ( 145 | allData = g.GetMonData() 146 | cgName string 147 | mgName string 148 | ) 149 | 150 | if mg, ok := g.(MonGroup); ok { 151 | cgName = mg.Parent().Name() 152 | mgName = mg.Name() 153 | } else { 154 | cgName = g.Name() 155 | } 156 | 157 | attributes := attribute.NewSet( 158 | attribute.String("rdt.class", cgName), 159 | attribute.String("rdt.mon.group", mgName), 160 | ) 161 | 162 | for cacheID, data := range allData.L3 { 163 | if value, ok := data[feature]; ok { 164 | o.ObserveInt64( 165 | m, 166 | int64(value), 167 | metric.WithAttributeSet(attributes), 168 | metric.WithAttributes( 169 | append( 170 | []attribute.KeyValue{ 171 | attribute.String("cache.id", fmt.Sprint(cacheID)), 172 | }, 173 | customAttributes..., 174 | )..., 175 | ), 176 | ) 177 | } 178 | } 179 | } 180 | 181 | func getMonGroupAttributes(mg MonGroup) []attribute.KeyValue { 182 | var ( 183 | annotations = mg.GetAnnotations() 184 | attributes = []attribute.KeyValue{} 185 | ) 186 | 187 | for _, name := range customLabels { 188 | if value, ok := annotations[name]; ok { 189 | attributes = append(attributes, attribute.String(name, value)) 190 | } 191 | } 192 | 193 | return attributes 194 | } 195 | -------------------------------------------------------------------------------- /pkg/utils/sysfs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "strconv" 23 | "strings" 24 | 25 | goresctrlpath "github.com/intel/goresctrl/pkg/path" 26 | ) 27 | 28 | const ( 29 | SysfsUncoreBasepath = "sys/devices/system/cpu/intel_uncore_frequency" 30 | SysfsCpuBasepath = "sys/devices/system/cpu" 31 | ) 32 | 33 | func setCPUFreqValue(cpu ID, setting string, value int) error { 34 | return writeFileInt(cpuFreqPath(cpu, setting), value) 35 | } 36 | 37 | func SetCPUScalingGovernor(cpu ID, governor string) error { 38 | return writeFileStr(cpuFreqPath(cpu, "scaling_governor"), governor) 39 | } 40 | 41 | // GetCPUFreqValue returns information of the currently used CPU frequency 42 | func GetCPUFreqValue(cpu ID, setting string) (int, error) { 43 | raw, err := os.ReadFile(cpuFreqPath(cpu, setting)) 44 | if err != nil { 45 | return 0, err 46 | } 47 | 48 | value, err := strconv.Atoi(strings.TrimSpace(string(raw))) 49 | if err != nil { 50 | return 0, err 51 | } 52 | 53 | return value, nil 54 | } 55 | 56 | func cpuFreqPath(cpu ID, setting string) string { 57 | return goresctrlpath.Path(SysfsCpuBasepath, fmt.Sprintf("cpu%d", cpu), "cpufreq", setting) 58 | } 59 | 60 | // SetCPUScalingMinFreq sets the scaling_min_freq value of a given CPU 61 | func SetCPUScalingMinFreq(cpu ID, freq int) error { 62 | return setCPUFreqValue(cpu, "scaling_min_freq", freq) 63 | } 64 | 65 | // SetCPUScalingMaxFreq sets the scaling_max_freq value of a given CPU 66 | func SetCPUScalingMaxFreq(cpu ID, freq int) error { 67 | return setCPUFreqValue(cpu, "scaling_max_freq", freq) 68 | } 69 | 70 | // SetScalingGovernorForCPUs sets the scaling_governor of a given set of CPUs 71 | func SetScalingGovernorForCPUs(cpus []ID, governor string) error { 72 | for _, cpu := range cpus { 73 | if err := SetCPUScalingGovernor(cpu, governor); err != nil { 74 | return err 75 | } 76 | } 77 | 78 | return nil 79 | } 80 | 81 | // SetCPUsScalingMinFreq sets the scaling_min_freq value of a given set of CPUs 82 | func SetCPUsScalingMinFreq(cpus []ID, freq int) error { 83 | for _, cpu := range cpus { 84 | if err := SetCPUScalingMinFreq(cpu, freq); err != nil { 85 | return err 86 | } 87 | } 88 | 89 | return nil 90 | } 91 | 92 | // SetCPUsScalingMaxFreq sets the scaling_max_freq value of a given set of CPUs 93 | func SetCPUsScalingMaxFreq(cpus []ID, freq int) error { 94 | for _, cpu := range cpus { 95 | if err := SetCPUScalingMaxFreq(cpu, freq); err != nil { 96 | return err 97 | } 98 | } 99 | 100 | return nil 101 | } 102 | 103 | // UncoreFreqAvailable returns true if the uncore frequency control functions are available. 104 | func UncoreFreqAvailable() bool { 105 | _, err := os.Stat(goresctrlpath.Path(SysfsUncoreBasepath)) 106 | return err == nil 107 | } 108 | 109 | // SetUncoreMinFreq sets the minimum uncore frequency of a CPU die. Frequency is specified in kHz. 110 | func SetUncoreMinFreq(pkg, die ID, freqKhz int) error { 111 | return setUncoreFreqValue(pkg, die, "min_freq_khz", freqKhz) 112 | } 113 | 114 | // SetUncoreMaxFreq sets the maximum uncore frequency of a CPU die. Frequency is specified in kHz. 115 | func SetUncoreMaxFreq(pkg, die ID, freqKhz int) error { 116 | return setUncoreFreqValue(pkg, die, "max_freq_khz", freqKhz) 117 | } 118 | 119 | func uncoreFreqPath(pkg, die ID, attribute string) string { 120 | return goresctrlpath.Path(SysfsUncoreBasepath, fmt.Sprintf("package_%02d_die_%02d", pkg, die), attribute) 121 | } 122 | 123 | func getUncoreFreqValue(pkg, die ID, attribute string) (int, error) { 124 | return readFileInt(uncoreFreqPath(pkg, die, attribute)) 125 | } 126 | 127 | func setUncoreFreqValue(pkg, die ID, attribute string, value int) error { 128 | // Bounds checking 129 | if hwMinFreq, err := getUncoreFreqValue(pkg, die, "initial_min_freq_khz"); err != nil { 130 | return err 131 | } else if value < hwMinFreq { 132 | value = hwMinFreq 133 | } 134 | if hwMaxFreq, err := getUncoreFreqValue(pkg, die, "initial_max_freq_khz"); err != nil { 135 | return err 136 | } else if value > hwMaxFreq { 137 | value = hwMaxFreq 138 | } 139 | 140 | return writeFileInt(uncoreFreqPath(pkg, die, attribute), value) 141 | } 142 | 143 | func writeFileInt(path string, value int) error { 144 | return os.WriteFile(path, []byte(strconv.Itoa(value)), 0644) 145 | } 146 | 147 | func writeFileStr(path string, value string) error { 148 | return os.WriteFile(path, []byte(value), 0644) 149 | } 150 | 151 | func readFileInt(path string) (int, error) { 152 | data, err := os.ReadFile(path) 153 | if err != nil { 154 | return 0, err 155 | } 156 | i, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 32) 157 | return int(i), err 158 | } 159 | -------------------------------------------------------------------------------- /pkg/cstates/filter.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cstates 18 | 19 | import "github.com/intel/goresctrl/pkg/utils" 20 | 21 | type FilterInputOpt func(*FilterInput) 22 | 23 | // Filter defines the interface for filtering cstate data. 24 | type Filter interface { 25 | // Match returns true if the given arguments match the filter criteria. 26 | Match(*FilterInput) bool 27 | } 28 | 29 | // FilterInput holds the input values for evaluating the filter. All fields are 30 | // optional. Nil values indicate "not defined" and should be ignored in filter 31 | // evaluation. 32 | type FilterInput struct { 33 | CPU *utils.ID 34 | CstateName *string 35 | Attribute *AttrID 36 | AttributeValue *string 37 | } 38 | 39 | // BasicFilter implements a simple filter based on CPU IDs, cstate names and attributes. 40 | type BasicFilter struct { 41 | cpus map[utils.ID]bool 42 | cstateNames map[string]bool 43 | attributes map[AttrID]bool 44 | attributeValues map[AttrID]map[string]bool 45 | } 46 | 47 | func NewBasicFilter() *BasicFilter { 48 | return &BasicFilter{} 49 | } 50 | 51 | // SetCPUs sets the CPU IDs accepted by the filter. 52 | func (f *BasicFilter) SetCPUs(cpus ...utils.ID) *BasicFilter { 53 | f.cpus = make(map[utils.ID]bool, len(cpus)) 54 | for _, cpu := range cpus { 55 | f.cpus[cpu] = true 56 | } 57 | return f 58 | } 59 | 60 | // SetCstateNames sets the cstate names accepted by the filter. 61 | func (f *BasicFilter) SetCstateNames(names ...string) *BasicFilter { 62 | f.cstateNames = make(map[string]bool, len(names)) 63 | for _, name := range names { 64 | f.cstateNames[name] = true 65 | } 66 | return f 67 | } 68 | 69 | // SetAttributes sets the attribute IDs accepted by the filter. 70 | func (f *BasicFilter) SetAttributes(attrs ...AttrID) *BasicFilter { 71 | f.attributes = make(map[AttrID]bool, len(attrs)) 72 | for _, attr := range attrs { 73 | f.attributes[attr] = true 74 | } 75 | return f 76 | } 77 | 78 | // SetAttributeValues sets the values of a given attribute accepted by the filter. 79 | // This does not imply that the attribute itself is accepted or other 80 | // attributes would be rejected; use SetAttributes for filtering attribute IDs. 81 | func (f *BasicFilter) SetAttributeValues(attr AttrID, values ...string) *BasicFilter { 82 | if f.attributeValues == nil { 83 | f.attributeValues = make(map[AttrID]map[string]bool) 84 | } 85 | f.attributeValues[attr] = make(map[string]bool, len(values)) 86 | for _, value := range values { 87 | f.attributeValues[attr][value] = true 88 | } 89 | return f 90 | } 91 | 92 | // Match evaluates the filter against the provided input arguments. Implements a logical AND of all filter criteria. 93 | func (f *BasicFilter) Match(args *FilterInput) bool { 94 | return f.evaluateCPU(args.CPU) && f.evaluateCstateName(args.CstateName) && f.evaluateAttribute(args.Attribute) && f.evaluateAttributeValue(args.Attribute, args.AttributeValue) 95 | } 96 | 97 | func (f *BasicFilter) evaluateCPU(cpu *utils.ID) bool { 98 | return cpu == nil || f.cpus == nil || f.cpus[*cpu] 99 | } 100 | 101 | func (f *BasicFilter) evaluateCstateName(name *string) bool { 102 | return name == nil || f.cstateNames == nil || f.cstateNames[*name] 103 | } 104 | 105 | func (f *BasicFilter) evaluateAttribute(attr *AttrID) bool { 106 | return attr == nil || f.attributes == nil || f.attributes[*attr] 107 | } 108 | 109 | func (f *BasicFilter) evaluateAttributeValue(attr *AttrID, value *string) bool { 110 | return attr == nil || value == nil || f.attributeValues == nil || f.attributeValues[*attr] == nil || f.attributeValues[*attr][*value] 111 | } 112 | 113 | // NewFilterInput creates a new FilterInput instance. 114 | func NewFilterInput(opts ...FilterInputOpt) *FilterInput { 115 | return &FilterInput{} 116 | } 117 | 118 | // SetCPU sets the CPU ID in the FilterInput. 119 | func (f *FilterInput) SetCPU(cpu utils.ID) *FilterInput { 120 | f.CPU = &cpu 121 | return f 122 | } 123 | 124 | // SetCstateName sets the cstate name in the FilterInput. 125 | func (f *FilterInput) SetCstateName(name string) *FilterInput { 126 | f.CstateName = &name 127 | return f 128 | } 129 | 130 | // SetAttribute sets the attribute ID in the FilterInput. It clears any 131 | // existing AttributeValue causing the filter to match any value for the 132 | // attribute. 133 | func (f *FilterInput) SetAttribute(attr AttrID) *FilterInput { 134 | f.Attribute = &attr 135 | f.AttributeValue = nil 136 | return f 137 | } 138 | 139 | // SetAttributeValue sets the attribute ID and value in the FilterInput. 140 | func (f *FilterInput) SetAttributeValue(attr AttrID, value string) *FilterInput { 141 | f.Attribute = &attr 142 | f.AttributeValue = &value 143 | return f 144 | } 145 | -------------------------------------------------------------------------------- /pkg/cstates/filter_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cstates 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestBasicFilter(t *testing.T) { 26 | tests := []struct { 27 | name string 28 | filter Filter 29 | input *FilterInput 30 | expectedResult bool 31 | }{ 32 | { 33 | name: "empty filter, empty input", 34 | filter: NewBasicFilter(), 35 | input: NewFilterInput(), 36 | expectedResult: true, 37 | }, 38 | { 39 | name: "empty filter, non-empty input", 40 | filter: NewBasicFilter().SetCPUs(1).SetCstateNames("C2").SetAttributes(AttrDisable).SetAttributeValues(AttrDisable, "true"), 41 | input: NewFilterInput(), 42 | expectedResult: true, 43 | }, 44 | { 45 | name: "matching CPU", 46 | filter: NewBasicFilter().SetCPUs(0, 1, 2, 3), 47 | input: NewFilterInput().SetCPU(1), 48 | expectedResult: true, 49 | }, 50 | { 51 | name: "non-matching CPU", 52 | filter: NewBasicFilter().SetCPUs(0, 1, 2, 3), 53 | input: NewFilterInput().SetCPU(4), 54 | expectedResult: false, 55 | }, 56 | { 57 | name: "empty CPU set", 58 | filter: NewBasicFilter().SetCPUs(), 59 | input: NewFilterInput().SetCPU(0), 60 | expectedResult: false, 61 | }, 62 | { 63 | name: "matching C-state name", 64 | filter: NewBasicFilter().SetCstateNames("C2", "C3"), 65 | input: NewFilterInput().SetCstateName("C3"), 66 | expectedResult: true, 67 | }, 68 | { 69 | name: "non-matching C-state name", 70 | filter: NewBasicFilter().SetCstateNames("C2", "C3"), 71 | input: NewFilterInput().SetCstateName("C6"), 72 | expectedResult: false, 73 | }, 74 | { 75 | name: "empty set of C-state names", 76 | filter: NewBasicFilter().SetCstateNames(), 77 | input: NewFilterInput().SetCstateName("C2"), 78 | expectedResult: false, 79 | }, 80 | { 81 | name: "matching attribute", 82 | filter: NewBasicFilter().SetAttributes(AttrDisable, AttrLatency), 83 | input: NewFilterInput().SetAttribute(AttrLatency), 84 | expectedResult: true, 85 | }, 86 | { 87 | name: "non-matching attribute", 88 | filter: NewBasicFilter().SetAttributes(AttrDisable, AttrLatency), 89 | input: NewFilterInput().SetAttribute(AttrBelow), 90 | expectedResult: false, 91 | }, 92 | { 93 | name: "empty set of attributes", 94 | filter: NewBasicFilter().SetAttributes(), 95 | input: NewFilterInput().SetAttribute(AttrDisable), 96 | expectedResult: false, 97 | }, 98 | { 99 | name: "matching attribute value", 100 | filter: NewBasicFilter().SetAttributeValues(AttrAbove, "100", "200"), 101 | input: NewFilterInput().SetAttributeValue(AttrAbove, "200"), 102 | expectedResult: true, 103 | }, 104 | { 105 | name: "non-matching attribute value", 106 | filter: NewBasicFilter().SetAttributeValues(AttrAbove, "100", "200"), 107 | input: NewFilterInput().SetAttributeValue(AttrAbove, "300"), 108 | expectedResult: false, 109 | }, 110 | { 111 | name: "empty set of attribute values", 112 | filter: NewBasicFilter().SetAttributeValues(AttrBelow), 113 | input: NewFilterInput().SetAttributeValue(AttrBelow, "50"), 114 | expectedResult: false, 115 | }, 116 | { 117 | name: "empty filter sets, empty input", 118 | filter: NewBasicFilter().SetCPUs().SetCstateNames().SetAttributes().SetAttributeValues(AttrDisable), 119 | input: NewFilterInput(), 120 | expectedResult: true, 121 | }, 122 | { 123 | name: "multiple criteria all match", 124 | filter: NewBasicFilter().SetCPUs(0, 1).SetCstateNames("C2", "C6").SetAttributes(AttrDisable).SetAttributeValues(AttrDisable, "true"), 125 | input: NewFilterInput().SetCPU(1).SetCstateName("C2").SetAttributeValue(AttrDisable, "true"), 126 | expectedResult: true, 127 | }, 128 | { 129 | name: "multiple criteria one does not match", 130 | filter: NewBasicFilter().SetCPUs(0, 1).SetCstateNames("C2", "C6").SetAttributes(AttrBelow).SetAttributeValues(AttrDisable, "true"), 131 | input: NewFilterInput().SetCPU(1).SetCstateName("C2").SetAttributeValue(AttrDisable, "true"), 132 | expectedResult: false, 133 | }, 134 | } 135 | 136 | for _, tt := range tests { 137 | t.Run(tt.name, func(t *testing.T) { 138 | result := tt.filter.Match(tt.input) 139 | assert.Equal(t, tt.expectedResult, result) 140 | }) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /pkg/blockio/oci_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2021 Intel Corporation. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package blockio 16 | 17 | import ( 18 | "testing" 19 | 20 | oci "github.com/opencontainers/runtime-spec/specs-go" 21 | 22 | "github.com/intel/goresctrl/pkg/testutils" 23 | ) 24 | 25 | // TestOciLinuxBlockIO: unit tests for OciLinuxBlockIO(). 26 | func TestOciLinuxBlockIO(t *testing.T) { 27 | tcases := []struct { 28 | name string 29 | class string 30 | blockIOClasses map[string]BlockIOParameters 31 | expectedBlockIO *oci.LinuxBlockIO 32 | // It would be great to define expected 33 | // oci.LinuxBlockIO with a single literal. But that 34 | // is impossible because Major and Minor fields are 35 | // inside non-exported oci.linuxBlockIODevice 36 | // struct. Therefore here are expected triplets of 37 | // major/minor/(weight|rate). 38 | expectedWeight uint16 39 | expectedWeightDevices [][3]uint16 40 | expectedThrottleReadBpsDevices [][3]uint64 41 | expectedThrottleWriteBpsDevices [][3]uint64 42 | expectedThrottleReadIOPSDevices [][3]uint64 43 | expectedThrottleWriteIOPSDevices [][3]uint64 44 | expectedErrorSubstrings []string 45 | }{ 46 | { 47 | name: "unknown class", 48 | class: "foobar", 49 | blockIOClasses: nil, 50 | expectedErrorSubstrings: []string{"foobar"}, 51 | }, 52 | { 53 | name: "all fields", 54 | class: "allfields", 55 | blockIOClasses: map[string]BlockIOParameters{ 56 | "allfields": BlockIOParameters{ 57 | Weight: 10, 58 | WeightDevice: DeviceWeights{ 59 | {Major: 20, Minor: 21, Weight: 22}, 60 | {Major: 23, Minor: 24, Weight: 25}, 61 | }, 62 | ThrottleReadBpsDevice: DeviceRates{ 63 | {Major: 30, Minor: 31, Rate: 32}, 64 | {Major: 33, Minor: 34, Rate: 35}, 65 | }, 66 | ThrottleWriteBpsDevice: DeviceRates{ 67 | {Major: 40, Minor: 41, Rate: 42}, 68 | {Major: 43, Minor: 44, Rate: 45}, 69 | }, 70 | ThrottleReadIOPSDevice: DeviceRates{ 71 | {Major: 50, Minor: 51, Rate: 52}, 72 | {Major: 53, Minor: 54, Rate: 55}, 73 | }, 74 | ThrottleWriteIOPSDevice: DeviceRates{ 75 | {Major: 60, Minor: 61, Rate: 62}, 76 | {Major: 63, Minor: 64, Rate: 65}, 77 | }, 78 | }, 79 | }, 80 | expectedWeight: 10, 81 | expectedWeightDevices: [][3]uint16{{20, 21, 22}, {23, 24, 25}}, 82 | expectedThrottleReadBpsDevices: [][3]uint64{{30, 31, 32}, {33, 34, 35}}, 83 | expectedThrottleWriteBpsDevices: [][3]uint64{{40, 41, 42}, {43, 44, 45}}, 84 | expectedThrottleReadIOPSDevices: [][3]uint64{{50, 51, 52}, {53, 54, 55}}, 85 | expectedThrottleWriteIOPSDevices: [][3]uint64{{60, 61, 62}, {63, 64, 65}}, 86 | expectedBlockIO: &oci.LinuxBlockIO{}, 87 | }, 88 | } 89 | for _, tc := range tcases { 90 | t.Run(tc.name, func(t *testing.T) { 91 | classBlockIO = tc.blockIOClasses 92 | gotBlockIO, gotError := OciLinuxBlockIO(tc.class) 93 | expectedErrorCount := 0 94 | if len(tc.expectedErrorSubstrings) > 0 { 95 | expectedErrorCount = 1 96 | } 97 | testutils.VerifyError(t, gotError, expectedErrorCount, tc.expectedErrorSubstrings) 98 | if tc.expectedBlockIO != nil { 99 | tc.expectedBlockIO.Weight = &tc.expectedWeight 100 | for _, wd := range tc.expectedWeightDevices { 101 | tc.expectedBlockIO.WeightDevice = append(tc.expectedBlockIO.WeightDevice, linuxWeightDevice(wd)) 102 | } 103 | for _, rd := range tc.expectedThrottleReadBpsDevices { 104 | tc.expectedBlockIO.ThrottleReadBpsDevice = append(tc.expectedBlockIO.ThrottleReadBpsDevice, linuxThrottleDevice(rd)) 105 | } 106 | for _, rd := range tc.expectedThrottleWriteBpsDevices { 107 | tc.expectedBlockIO.ThrottleWriteBpsDevice = append(tc.expectedBlockIO.ThrottleWriteBpsDevice, linuxThrottleDevice(rd)) 108 | } 109 | for _, rd := range tc.expectedThrottleReadIOPSDevices { 110 | tc.expectedBlockIO.ThrottleReadIOPSDevice = append(tc.expectedBlockIO.ThrottleReadIOPSDevice, linuxThrottleDevice(rd)) 111 | } 112 | for _, rd := range tc.expectedThrottleWriteIOPSDevices { 113 | tc.expectedBlockIO.ThrottleWriteIOPSDevice = append(tc.expectedBlockIO.ThrottleWriteIOPSDevice, linuxThrottleDevice(rd)) 114 | } 115 | } 116 | testutils.VerifyDeepEqual(t, "OCI BlockIO", tc.expectedBlockIO, gotBlockIO) 117 | }) 118 | } 119 | } 120 | 121 | func linuxWeightDevice(triplet [3]uint16) oci.LinuxWeightDevice { 122 | wd := oci.LinuxWeightDevice{} 123 | wd.Major = int64(triplet[0]) 124 | wd.Minor = int64(triplet[1]) 125 | wd.Weight = &triplet[2] 126 | return wd 127 | } 128 | 129 | func linuxThrottleDevice(triplet [3]uint64) oci.LinuxThrottleDevice { 130 | rd := oci.LinuxThrottleDevice{} 131 | rd.Major = int64(triplet[0]) 132 | rd.Minor = int64(triplet[1]) 133 | rd.Rate = triplet[2] 134 | return rd 135 | } 136 | -------------------------------------------------------------------------------- /pkg/utils/idset.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019-2021 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "encoding/json" 21 | "fmt" 22 | "sort" 23 | "strconv" 24 | "strings" 25 | ) 26 | 27 | const ( 28 | // Unknown represents an unknown id. 29 | Unknown ID = -1 30 | // maxID sets an upper bound for the size of id sets 31 | // generated from listset strings, e.g. "0-16777215". 32 | maxID ID = (1 << 24) - 1 33 | ) 34 | 35 | // ID is nn integer id, used to identify packages, CPUs, nodes, etc. 36 | type ID = int 37 | 38 | // IDSet is an unordered set of integer ids. 39 | type IDSet map[ID]struct{} 40 | 41 | // NewIDSet creates a new unordered set of (integer) ids. 42 | func NewIDSet(ids ...ID) IDSet { 43 | s := make(map[ID]struct{}) 44 | 45 | for _, id := range ids { 46 | s[id] = struct{}{} 47 | } 48 | 49 | return s 50 | } 51 | 52 | // NewIDSetFromIntSlice creates a new unordered set from an integer slice. 53 | func NewIDSetFromIntSlice(ids ...int) IDSet { 54 | s := make(map[ID]struct{}) 55 | 56 | for _, id := range ids { 57 | s[ID(id)] = struct{}{} 58 | } 59 | 60 | return s 61 | } 62 | 63 | // NewIDSetFromString creates new unordered set from string in listset syntax "0,61-63,2". 64 | func NewIDSetFromString(listSet string) (IDSet, error) { 65 | s := NewIDSet() 66 | minValue := 0 67 | maxValue := maxID 68 | 69 | parts := strings.Split(listSet, ",") 70 | for _, part := range parts { 71 | switch { 72 | case part == "": 73 | continue 74 | case strings.Contains(part, "-"): 75 | rangeParts := strings.Split(part, "-") 76 | if len(rangeParts) != 2 { 77 | return nil, fmt.Errorf("invalid range: %s", part) 78 | } 79 | start, err := strconv.Atoi(rangeParts[0]) 80 | if err != nil { 81 | return nil, err 82 | } 83 | end, err := strconv.Atoi(rangeParts[1]) 84 | if err != nil { 85 | return nil, err 86 | } 87 | if start > end { 88 | return nil, fmt.Errorf("invalid range %s: start > end", part) 89 | } 90 | if start < minValue || end > maxValue { 91 | return nil, fmt.Errorf("invalid range %s: out of range %d-%d", part, minValue, maxValue) 92 | } 93 | for i := start; i <= end; i++ { 94 | s.Add(ID(i)) 95 | } 96 | default: 97 | num, err := strconv.Atoi(part) 98 | if err != nil { 99 | return nil, err 100 | } 101 | if num < minValue || num > maxValue { 102 | return nil, fmt.Errorf("invalid value %d: out of range %d-%d", num, minValue, maxValue) 103 | } 104 | s.Add(ID(num)) 105 | } 106 | } 107 | 108 | return s, nil 109 | } 110 | 111 | // Clone returns a copy of this IdSet. 112 | func (s IDSet) Clone() IDSet { 113 | return NewIDSet(s.Members()...) 114 | } 115 | 116 | // Add adds the given ids into the set. 117 | func (s IDSet) Add(ids ...ID) { 118 | for _, id := range ids { 119 | s[id] = struct{}{} 120 | } 121 | } 122 | 123 | // Del deletes the given ids from the set. 124 | func (s IDSet) Del(ids ...ID) { 125 | if s != nil { 126 | for _, id := range ids { 127 | delete(s, id) 128 | } 129 | } 130 | } 131 | 132 | // Size returns the number of ids in the set. 133 | func (s IDSet) Size() int { 134 | return len(s) 135 | } 136 | 137 | // Has tests if all the ids are present in the set. 138 | func (s IDSet) Has(ids ...ID) bool { 139 | if s == nil { 140 | return false 141 | } 142 | 143 | for _, id := range ids { 144 | _, ok := s[id] 145 | if !ok { 146 | return false 147 | } 148 | } 149 | 150 | return true 151 | } 152 | 153 | // Members returns all ids in the set as a randomly ordered slice. 154 | func (s IDSet) Members() []ID { 155 | if s == nil { 156 | return []ID{} 157 | } 158 | ids := make([]ID, len(s)) 159 | idx := 0 160 | for id := range s { 161 | ids[idx] = id 162 | idx++ 163 | } 164 | return ids 165 | } 166 | 167 | // SortedMembers returns all ids in the set as a sorted slice. 168 | func (s IDSet) SortedMembers() []ID { 169 | ids := s.Members() 170 | sort.Slice(ids, func(i, j int) bool { 171 | return ids[i] < ids[j] 172 | }) 173 | return ids 174 | } 175 | 176 | // String returns the set as a string. 177 | func (s IDSet) String() string { 178 | return s.StringWithSeparator(",") 179 | } 180 | 181 | // StringWithSeparator returns the set as a string, separated with the given separator. 182 | func (s IDSet) StringWithSeparator(args ...string) string { 183 | if len(s) == 0 { 184 | return "" 185 | } 186 | 187 | var sep string 188 | 189 | if len(args) == 1 { 190 | sep = args[0] 191 | } else { 192 | sep = "," 193 | } 194 | 195 | str := "" 196 | t := "" 197 | for _, id := range s.SortedMembers() { 198 | str = str + t + strconv.Itoa(int(id)) 199 | t = sep 200 | } 201 | 202 | return str 203 | } 204 | 205 | // MarshalJSON is the JSON marshaller for IDSet. 206 | func (s IDSet) MarshalJSON() ([]byte, error) { 207 | return json.Marshal(s.String()) 208 | } 209 | 210 | // UnmarshalJSON is the JSON unmarshaller for IDSet. 211 | func (s *IDSet) UnmarshalJSON(data []byte) error { 212 | str := "" 213 | if err := json.Unmarshal(data, &str); err != nil { 214 | return fmt.Errorf("invalid IDSet entry '%s': %v", string(data), err) 215 | } 216 | 217 | *s = NewIDSet() 218 | if str == "" { 219 | return nil 220 | } 221 | 222 | for _, idstr := range strings.Split(str, ",") { 223 | id, err := strconv.ParseInt(idstr, 10, 0) 224 | if err != nil { 225 | return fmt.Errorf("invalid IDSet entry '%s': %v", idstr, err) 226 | } 227 | s.Add(ID(id)) 228 | } 229 | 230 | return nil 231 | } 232 | -------------------------------------------------------------------------------- /pkg/cstates/cstates_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Intel Corporation 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cstates 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/require" 25 | 26 | "github.com/intel/goresctrl/pkg/utils" 27 | ) 28 | 29 | // mockFS implements sysfsIface for testing, allowing to override 30 | // individual methods on-the-fly. 31 | type mockFS struct { 32 | fPossibleCpus func() (string, error) 33 | fCpuidleStates func(cpu utils.ID) ([]int, error) 34 | fCpuidleStateAttrRead func(cpu utils.ID, state int, attr string) (string, error) 35 | fCpuidleStateAttrWrite func(cpu utils.ID, state int, attr string, value string) error 36 | } 37 | 38 | func (fs *mockFS) PossibleCpus() (string, error) { 39 | return fs.fPossibleCpus() 40 | } 41 | 42 | func (fs *mockFS) CpuidleStates(cpu utils.ID) ([]int, error) { 43 | return fs.fCpuidleStates(cpu) 44 | } 45 | 46 | func (fs *mockFS) CpuidleStateAttrRead(cpu utils.ID, state int, attr string) (string, error) { 47 | return fs.fCpuidleStateAttrRead(cpu, state, attr) 48 | } 49 | 50 | func (fs *mockFS) CpuidleStateAttrWrite(cpu utils.ID, state int, attr string, value string) error { 51 | return fs.fCpuidleStateAttrWrite(cpu, state, attr, value) 52 | } 53 | 54 | func TestNewCstatesFromSysfs(t *testing.T) { 55 | // Make sure the platform supports cpuidle and disabling a C-state. 56 | if _, err := os.Stat("/sys/devices/system/cpu/cpu0/cpuidle/state1/disable"); os.IsNotExist(err) { 57 | t.Skip("/sys/devices/system/cpu/cpu0/cpuidle/state1/disable does not exist") 58 | } 59 | possibleCpus, err := NewSysfs().PossibleCpus() 60 | require.NoError(t, err, "Failed to get possible CPUs from sysfs") 61 | require.NotEqual(t, possibleCpus, "") 62 | 63 | cpus, err := utils.NewIDSetFromString(possibleCpus) 64 | require.NoError(t, err, "Failed to parse possible CPUs %q", possibleCpus) 65 | 66 | cpuCount := cpus.Size() 67 | 68 | // Read the disable attribute from all C-states of all CPUs. 69 | cs, err := NewCstatesFromSysfs(NewBasicFilter().SetAttributes(AttrDisable)) 70 | require.NoError(t, err, "NewCstatesFromSysfs failed") 71 | 72 | // Compare read CPUs to the number of possible CPUs. 73 | require.Equal(t, cs.CPUs().Size(), cpuCount, "Expected %d CPUs, got %d", cpuCount, cs.CPUs().Size()) 74 | } 75 | 76 | func TestCstatesWithMockFS(t *testing.T) { 77 | // This test runs in environments without access to cpuidle in 78 | // sysfs (like in virtual machines). 79 | cs := NewCstates() 80 | fs := &mockFS{ 81 | fPossibleCpus: func() (string, error) { 82 | return "0-7", nil 83 | }, 84 | fCpuidleStates: func(cpu utils.ID) ([]int, error) { 85 | return []int{0, 1, 2, 3, 4}, nil 86 | }, 87 | fCpuidleStateAttrRead: func(cpu utils.ID, state int, attr string) (string, error) { 88 | // Fail if any other file will be read than filtered ones 89 | if cpu < 2 || cpu > 5 { 90 | t.Fatalf("Unexpected CPU ID %d", cpu) 91 | } 92 | if attr != "name" && (state != 1 && state != 2 && state != 4) { 93 | t.Fatalf("Unexpected read on cpu%d state%d attr %q", cpu, state, attr) 94 | } 95 | switch attr { 96 | case "name": 97 | return fmt.Sprintf("C%d", state), nil 98 | case "disable": 99 | if cpu == 3 && state > 0 { 100 | return "1", nil 101 | } 102 | return "0", nil 103 | case "time": 104 | return fmt.Sprintf("100%d%d", cpu, state), nil 105 | default: 106 | t.Fatalf("Unexpected read of attribute %q", attr) 107 | } 108 | return "", nil 109 | }, 110 | fCpuidleStateAttrWrite: func(cpu utils.ID, state int, attr string, value string) error { 111 | t.Fatalf("Unexpected write of attribute %q", attr) 112 | return nil 113 | }, 114 | } 115 | cs.fs = fs 116 | err := cs.Read(NewBasicFilter().SetCPUs(2, 3, 4, 5).SetCstateNames("C1", "C2", "C4").SetAttributes(AttrDisable, AttrTime)) 117 | require.NoError(t, err, "Failed to populate C-states from sysfs") 118 | 119 | // Whatever happens next, nothing must be read from sysfs anymore. 120 | fs.fPossibleCpus = func() (string, error) { 121 | t.Fatalf("Unexpected read of possible CPUs while reads prohibited") 122 | return "", nil 123 | } 124 | fs.fCpuidleStates = func(cpu utils.ID) ([]int, error) { 125 | t.Fatalf("Unexpected read of cpuidle states while reads prohibited") 126 | return nil, nil 127 | } 128 | fs.fCpuidleStateAttrRead = func(cpu utils.ID, state int, attr string) (string, error) { 129 | t.Fatalf("Unexpected read on cpu%d state%d attr %q while reads prohibited", cpu, state, attr) 130 | return "", nil 131 | } 132 | 133 | // Compare read CPUs to the number of possible CPUs. 134 | require.Equal(t, cs.CPUs().SortedMembers(), []utils.ID{2, 3, 4, 5}) 135 | 136 | require.Equal(t, cs.Names(), []string{"C1", "C2", "C4"}) 137 | 138 | require.Equal(t, cs.Attrs(), []AttrID{AttrDisable, AttrTime}) 139 | 140 | cpu2c1time := cs.GetAttr(2, "C1", AttrTime) 141 | require.NotNil(t, cpu2c1time, "CPU2 C1 time must not be nil") 142 | require.Equal(t, *cpu2c1time, "10021", "Unexpected CPU2 C1 time") 143 | 144 | cpu5c4time := cs.GetAttr(5, "C4", AttrTime) 145 | require.NotNil(t, cpu5c4time, "CPU5 C4 time must not be nil") 146 | require.Equal(t, *cpu5c4time, "10054") 147 | 148 | // Find which CPUs have C2, C3 (not even present) or C4 disabled. 149 | c2Disabled := cs.Copy(NewBasicFilter().SetCstateNames("C2", "C3", "C4").SetAttributes(AttrDisable).SetAttributeValues(AttrDisable, "1")) 150 | require.Equal(t, c2Disabled.CPUs().Members(), []utils.ID{3}, "CPU3, and only it, must have C2 disabled") 151 | 152 | // Enable C2 on CPU3. 153 | cpu3C2disable := "x" 154 | csFiltered := cs.Copy(NewBasicFilter().SetCPUs(3).SetCstateNames("C2")) 155 | // Override the fs write function to capture expected write, fail on all other writes. 156 | fs.fCpuidleStateAttrWrite = func(cpu utils.ID, state int, attr string, value string) error { 157 | if cpu == 3 && state == 2 && attr == "disable" { 158 | cpu3C2disable = value 159 | return nil 160 | } 161 | t.Fatalf("Unexpected write: cpu%d state%d attr: %q value: %q", cpu, state, attr, value) 162 | return nil 163 | } 164 | csFiltered.SetAttrs(AttrDisable, "0") 165 | require.NoError(t, csFiltered.Apply(), "Apply() failed") 166 | 167 | require.Equal(t, cpu3C2disable, "0", "Apply() was expected to write '0' to cpu3 state2 disable") 168 | 169 | csFiltered.SetAttrs(AttrDisable, "1") 170 | require.Equal(t, cpu3C2disable, "0", "Expected to keep '0' in cpu3 state2 disable until next Apply()") 171 | 172 | require.NoError(t, csFiltered.Apply(), "2nd Apply() failed") 173 | 174 | require.Equal(t, cpu3C2disable, "1", "2nd Apply() was expected to write '1' to cpu3 state2 disable") 175 | 176 | // Test that after clearing "disable" attributes Apply() will not write anything. 177 | // Force fail on every write. 178 | fs.fCpuidleStateAttrWrite = func(cpu utils.ID, state int, attr string, value string) error { 179 | t.Fatalf("Unexpected write: cpu%d state%d attr: %q value: %q", cpu, state, attr, value) 180 | return nil 181 | } 182 | csFiltered.ClearAttrs(AttrDisable) 183 | require.NoError(t, csFiltered.Apply(), "3rd Apply() failed") 184 | 185 | // Output the C-states with String(). 186 | csStr := cs.String() 187 | t.Logf("cs=%s", csStr) 188 | require.Contains(t, csStr, "time=10021", "Expected to find time=10021 in C-states String()") 189 | 190 | csFilteredStr := csFiltered.String() 191 | t.Logf("csFiltered=%s", csFilteredStr) 192 | require.Contains(t, csFilteredStr, "time=10032", "Expected to find time=10032 in filtered C-states String()") 193 | require.NotContains(t, csFilteredStr, "time=10021", "Expected to not find time=10021 in filtered C-states String()") 194 | require.NotContains(t, csFilteredStr, "disable=", "Expected to not find cleared attribute disable in filtered C-states String()") 195 | } 196 | --------------------------------------------------------------------------------