Correct various issues in scan, and set core affinity properly.
This commit is contained in:
parent
ba87550b65
commit
f6494a82b2
@ -5,4 +5,4 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
raw-cpuid = "11.0.2"
|
raw-cpuid = "11.0.2"
|
||||||
nix = "0.29.0"
|
nix = { version = "0.29.0", features = ["sched"] }
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
use cache_slice::msr;
|
use cache_slice::msr;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut args = env::args().into_iter();
|
let mut args = env::args().into_iter();
|
||||||
args.next();
|
args.next();
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match arg.parse::<u32>() {
|
match arg.parse::<u64>() {
|
||||||
Ok(msr) => {
|
Ok(msr) => {
|
||||||
match msr::read_msr_on_cpu(msr, 0) {
|
match msr::read_msr_on_cpu(msr, 0) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
println!("MSR {}: {:x}", msr, result);
|
println!("MSR {}: {:x}", msr, result);
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Error, failed to read MSR {}: {}", msr, e);
|
eprintln!("Error, failed to read MSR {}: {}", msr, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Error: {}", e);
|
eprintln!("Error: {}", e);
|
||||||
eprintln!("{} is not a valid MSR number", arg);
|
eprintln!("{} is not a valid MSR number", arg);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use cache_slice::monitor_address;
|
use cache_slice::monitor_address;
|
||||||
use cache_slice::utils::core_per_package;
|
use cache_slice::utils::core_per_package;
|
||||||
use nix::sched::{sched_getaffinity, CpuSet};
|
use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
|
||||||
|
use nix::unistd::Pid;
|
||||||
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
@ -8,10 +9,23 @@ pub fn main() {
|
|||||||
println!("Found {} cores", nb_cores);
|
println!("Found {} cores", nb_cores);
|
||||||
|
|
||||||
let target = vec![0x0123456789abcdefu64, 64];
|
let target = vec![0x0123456789abcdefu64, 64];
|
||||||
for core in 0..CpuSet::count() {
|
|
||||||
|
let old = sched_getaffinity(Pid::from_raw(0)).unwrap();
|
||||||
|
let mut core_set = Vec::new();
|
||||||
|
for i in 0..CpuSet::count() {
|
||||||
|
if old.is_set(i).unwrap() {
|
||||||
|
core_set.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for core in core_set {
|
||||||
|
let mut cpu_set = CpuSet::new();
|
||||||
|
cpu_set.set(core).unwrap();
|
||||||
|
sched_setaffinity(Pid::this(), &cpu_set).unwrap();
|
||||||
for addr in target.iter() {
|
for addr in target.iter() {
|
||||||
let res = unsafe { monitor_address(addr as *const u64 as *const u8, core as u8, nb_cores) };
|
let res = unsafe { monitor_address(addr as *const u64 as *const u8, core as u8, nb_cores) }.unwrap();
|
||||||
let slice = res.iter().enumerate().max_by_key(|(i, val)| { val });
|
let slice = res.iter().enumerate().max_by_key(|(_i, val)| { **val });
|
||||||
match slice {
|
match slice {
|
||||||
Some((slice, _)) => {
|
Some((slice, _)) => {
|
||||||
println!("({:2}) Slice for addr {:x}: {}", core, addr as *const u64 as usize, slice)
|
println!("({:2}) Slice for addr {:x}: {}", core, addr as *const u64 as usize, slice)
|
||||||
@ -22,8 +36,8 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for addr in target.iter() {
|
for addr in target.iter() {
|
||||||
let res = unsafe { monitor_address(addr as *const u64 as *const u8, 0, nb_cores) };
|
let res = unsafe { monitor_address(addr as *const u64 as *const u8, 0, nb_cores) }.unwrap();
|
||||||
let slice = res.iter().enumerate().max_by_key(|(i, val)| { val });
|
let slice = res.iter().enumerate().max_by_key(|(_i, val)| { **val });
|
||||||
match slice {
|
match slice {
|
||||||
Some((slice, _)) => {
|
Some((slice, _)) => {
|
||||||
println!("({:2}) Slice for addr {:x}: {}", 0, addr as *const u64 as usize, slice)
|
println!("({:2}) Slice for addr {:x}: {}", 0, addr as *const u64 as usize, slice)
|
||||||
@ -33,5 +47,6 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sched_setaffinity(Pid::this(), &old).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use std::arch::x86_64::_mm_clflush;
|
use std::arch::x86_64::_mm_clflush;
|
||||||
use crate::arch::CpuClass::{IntelCore, IntelXeon, IntelXeonSP};
|
use crate::arch::CpuClass::{IntelCore, IntelXeon, IntelXeonSP};
|
||||||
use crate::arch::get_performance_counters_xeon;
|
use crate::arch::{get_performance_counters_core, get_performance_counters_xeon};
|
||||||
use crate::Error::UnsupportedCPU;
|
use crate::Error::UnsupportedCPU;
|
||||||
use crate::msr::{read_msr_on_cpu, write_msr_on_cpu};
|
use crate::msr::{read_msr_on_cpu, write_msr_on_cpu};
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ pub mod msr;
|
|||||||
pub mod utils;
|
pub mod utils;
|
||||||
mod arch;
|
mod arch;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
UnsupportedCPU,
|
UnsupportedCPU,
|
||||||
InvalidParameter,
|
InvalidParameter,
|
||||||
@ -30,7 +31,7 @@ unsafe fn poke(addr: *const u8) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn monitor_xeon(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<u32>, Error> {
|
unsafe fn monitor_xeon(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<u64>, Error> {
|
||||||
let performance_counters = if let Some(p) = get_performance_counters_xeon() {
|
let performance_counters = if let Some(p) = get_performance_counters_xeon() {
|
||||||
p
|
p
|
||||||
} else {
|
} else {
|
||||||
@ -75,24 +76,38 @@ unsafe fn monitor_xeon(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read counters
|
// Read counters
|
||||||
let mut result = Vec::new();
|
let mut results = Vec::new();
|
||||||
for i in 0..max_cbox {
|
for i in 0..max_cbox {
|
||||||
let result = read_msr_on_cpu(performance_counters.msr_pmon_ctr0[i], cpu)?;
|
let result = read_msr_on_cpu(performance_counters.msr_pmon_ctr0[i], cpu)?;
|
||||||
result.push(result)
|
results.push(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn monitor_core(addr: *const u8, cpu: u8, max_core: u8) -> Result<Vec<u32>, Error> {
|
fn monitor_core(addr: *const u8, cpu: u8, max_cbox: usize) -> Result<Vec<u64>, Error> {
|
||||||
// Note, we need to add the workaround for one missing perf counter here.
|
// Note, we need to add the workaround for one missing perf counter here.
|
||||||
|
let performance_counters = if let Some(p) = get_performance_counters_core() {
|
||||||
|
p
|
||||||
|
} else {
|
||||||
|
return Err(UnsupportedCPU);
|
||||||
|
};
|
||||||
|
|
||||||
|
let workaround = if (performance_counters.max_slice as usize) + 1 == max_cbox {
|
||||||
|
true
|
||||||
|
} else if (performance_counters.max_slice as usize) >= max_cbox {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
return Err(Error::InvalidParameter);
|
||||||
|
};
|
||||||
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn monitor_address(addr: *const u8, cpu: u8, max_cbox: u16) -> Result<Vec<u32>, Error> {
|
pub unsafe fn monitor_address(addr: *const u8, cpu: u8, max_cbox: u16) -> Result<Vec<u64>, Error> {
|
||||||
match arch::determine_cpu_class() {
|
match arch::determine_cpu_class() {
|
||||||
Some(IntelCore) => {
|
Some(IntelCore) => {
|
||||||
unimplemented!()
|
unsafe { monitor_core(addr, cpu, max_cbox as usize) }
|
||||||
}
|
}
|
||||||
Some(IntelXeon) => {
|
Some(IntelXeon) => {
|
||||||
unsafe { monitor_xeon(addr, cpu, max_cbox as usize) }
|
unsafe { monitor_xeon(addr, cpu, max_cbox as usize) }
|
||||||
|
Loading…
Reference in New Issue
Block a user