Skip to content

Commit e8d4260

Browse files
author
Changwoo Min
committed
scx_lavd: Use cpu_capacity from Topology.
Instead of guessing CPU capacity using a CPU's max frequency, rely on cpu_capacity information from Topology, which is best guessed from various sysfs sources. Signed-off-by: Changwoo Min <[email protected]>
1 parent a957ee1 commit e8d4260

File tree

2 files changed

+19
-41
lines changed

2 files changed

+19
-41
lines changed

scheds/rust/scx_lavd/src/bpf/power.bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ static u16 get_cputurbo_cap(void)
535535
int nr_turbo = 0, cpu;
536536

537537
/*
538-
* Find the maximum CPU frequency
538+
* Find the maximum CPU capacity
539539
*/
540540
for (cpu = 0; cpu < nr_cpu_ids && cpu < LAVD_CPU_ID_MAX; cpu++) {
541541
if (__cpu_capacity_hint[cpu] > turbo_cap) {
@@ -545,7 +545,7 @@ static u16 get_cputurbo_cap(void)
545545
}
546546

547547
/*
548-
* If all CPU's frequencies are the same, ignore the turbo.
548+
* If all CPU's capacities are the same, ignore the turbo.
549549
*/
550550
if (nr_turbo <= 1)
551551
turbo_cap = 0;

scheds/rust/scx_lavd/src/main.rs

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ use libbpf_rs::ProgramInput;
4646
use libc::c_char;
4747
use log::debug;
4848
use log::info;
49-
use log::warn;
5049
use plain::Plain;
5150
use scx_stats::prelude::*;
5251
use scx_utils::autopower::{fetch_power_profile, PowerProfile};
@@ -231,7 +230,6 @@ impl introspec {
231230
struct CpuFlatId {
232231
node_id: usize,
233232
llc_pos: usize,
234-
max_freq: usize,
235233
core_pos: usize,
236234
cpu_pos: usize,
237235
cpu_id: usize,
@@ -282,12 +280,12 @@ impl fmt::Display for FlatTopology {
282280
impl FlatTopology {
283281
/// Build a flat-structured topology
284282
pub fn new() -> Result<FlatTopology> {
285-
let (cpu_fids_performance, avg_freq) = Self::build_cpu_fids(false, false).unwrap();
283+
let (cpu_fids_performance, avg_cap) = Self::build_cpu_fids(false, false).unwrap();
286284
let (cpu_fids_powersave, _) = Self::build_cpu_fids(true, true).unwrap();
287285

288286
// Note that building compute domain is not dependent to CPU orer
289287
// so it is okay to use any cpu_fids_*.
290-
let cpdom_map = Self::build_cpdom(&cpu_fids_performance, avg_freq).unwrap();
288+
let cpdom_map = Self::build_cpdom(&cpu_fids_performance, avg_cap).unwrap();
291289

292290
Ok(FlatTopology {
293291
cpu_fids_performance,
@@ -317,50 +315,30 @@ impl FlatTopology {
317315
debug!("{:#?}", topo);
318316

319317
// Build a vector of cpu flat ids.
320-
let mut base_freq = 0;
321-
let mut avg_freq = 0;
318+
let mut avg_cap = 0;
322319
for (&node_id, node) in topo.nodes.iter() {
323320
for (llc_pos, (_llc_id, llc)) in node.llcs.iter().enumerate() {
324321
for (core_pos, (core_id, core)) in llc.cores.iter().enumerate() {
325322
for (cpu_pos, (cpu_id, cpu)) in core.cpus.iter().enumerate() {
326323
let cpu_fid = CpuFlatId {
327324
node_id,
328325
llc_pos,
329-
max_freq: cpu.max_freq,
330326
core_pos,
331327
cpu_pos,
332328
cpu_id: *cpu_id,
333329
core_id: *core_id,
334330
l2_id: cpu.l2_id,
335331
l3_id: cpu.l3_id,
336332
sharing_lvl: 0,
337-
cpu_cap: 0,
333+
cpu_cap: cpu.cpu_capacity,
338334
};
339335
cpu_fids.push(RefCell::new(cpu_fid));
340-
if base_freq < cpu.max_freq {
341-
base_freq = cpu.max_freq;
342-
}
343-
avg_freq += cpu.max_freq;
336+
avg_cap += cpu.cpu_capacity;
344337
}
345338
}
346339
}
347340
}
348-
avg_freq /= cpu_fids.len() as usize;
349-
350-
// Initialize cpu capacity
351-
if base_freq > 0 {
352-
for cpu_fid in cpu_fids.iter_mut() {
353-
let mut cpu_fid = cpu_fid.borrow_mut();
354-
cpu_fid.cpu_cap = ((cpu_fid.max_freq * 1024) / base_freq) as usize;
355-
}
356-
} else {
357-
// Unfortunately, the frequency information in sysfs seems not
358-
// always correct in some distributions.
359-
for cpu_fid in cpu_fids.iter_mut() {
360-
cpu_fid.borrow_mut().cpu_cap = 1024 as usize;
361-
}
362-
warn!("System does not provide proper CPU frequency information.");
363-
}
341+
avg_cap /= cpu_fids.len() as usize;
364342

365343
// Initialize cpu's hardware resource sharing level
366344
for (a_id, cpu_fid_a) in cpu_fids.iter().enumerate() {
@@ -394,62 +372,62 @@ impl FlatTopology {
394372
// Sort the cpu_fids
395373
match (prefer_smt_core, prefer_little_core) {
396374
(true, false) => {
397-
// Sort the cpu_fids by node, llc, ^max_freq, ^sharing_lvl, core, and cpu order
375+
// Sort the cpu_fids by node, llc, ^cpu_cap, ^sharing_lvl, core, and cpu order
398376
cpu_fids.sort_by(|a, b| {
399377
a.node_id
400378
.cmp(&b.node_id)
401379
.then_with(|| a.llc_pos.cmp(&b.llc_pos))
402-
.then_with(|| b.max_freq.cmp(&a.max_freq))
380+
.then_with(|| b.cpu_cap.cmp(&a.cpu_cap))
403381
.then_with(|| b.sharing_lvl.cmp(&a.sharing_lvl))
404382
.then_with(|| a.core_pos.cmp(&b.core_pos))
405383
.then_with(|| a.cpu_pos.cmp(&b.cpu_pos))
406384
});
407385
}
408386
(true, true) => {
409-
// Sort the cpu_fids by node, llc, max_freq, ^sharing_lvl, core, and cpu order
387+
// Sort the cpu_fids by node, llc, cpu_cap, ^sharing_lvl, core, and cpu order
410388
cpu_fids.sort_by(|a, b| {
411389
a.node_id
412390
.cmp(&b.node_id)
413391
.then_with(|| a.llc_pos.cmp(&b.llc_pos))
414-
.then_with(|| a.max_freq.cmp(&b.max_freq))
392+
.then_with(|| a.cpu_cap.cmp(&b.cpu_cap))
415393
.then_with(|| b.sharing_lvl.cmp(&a.sharing_lvl))
416394
.then_with(|| a.core_pos.cmp(&b.core_pos))
417395
.then_with(|| a.cpu_pos.cmp(&b.cpu_pos))
418396
});
419397
}
420398
(false, false) => {
421-
// Sort the cpu_fids by cpu, node, llc, ^max_freq, sharing_lvl, and core order
399+
// Sort the cpu_fids by cpu, node, llc, ^cpu_cap, sharing_lvl, and core order
422400
cpu_fids.sort_by(|a, b| {
423401
a.cpu_pos
424402
.cmp(&b.cpu_pos)
425403
.then_with(|| a.node_id.cmp(&b.node_id))
426404
.then_with(|| a.llc_pos.cmp(&b.llc_pos))
427-
.then_with(|| b.max_freq.cmp(&a.max_freq))
405+
.then_with(|| b.cpu_cap.cmp(&a.cpu_cap))
428406
.then_with(|| a.sharing_lvl.cmp(&b.sharing_lvl))
429407
.then_with(|| a.core_pos.cmp(&b.core_pos))
430408
});
431409
}
432410
(false, true) => {
433-
// Sort the cpu_fids by cpu, node, llc, max_freq, sharing_lvl, and core order
411+
// Sort the cpu_fids by cpu, node, llc, cpu_cap, sharing_lvl, and core order
434412
cpu_fids.sort_by(|a, b| {
435413
a.cpu_pos
436414
.cmp(&b.cpu_pos)
437415
.then_with(|| a.node_id.cmp(&b.node_id))
438416
.then_with(|| a.llc_pos.cmp(&b.llc_pos))
439-
.then_with(|| a.max_freq.cmp(&b.max_freq))
417+
.then_with(|| a.cpu_cap.cmp(&b.cpu_cap))
440418
.then_with(|| a.sharing_lvl.cmp(&b.sharing_lvl))
441419
.then_with(|| a.core_pos.cmp(&b.core_pos))
442420
});
443421
}
444422
}
445423

446-
Some((cpu_fids, avg_freq))
424+
Some((cpu_fids, avg_cap))
447425
}
448426

449427
/// Build a list of compute domains
450428
fn build_cpdom(
451429
cpu_fids: &Vec<CpuFlatId>,
452-
avg_freq: usize,
430+
avg_cap: usize,
453431
) -> Option<BTreeMap<ComputeDomainKey, ComputeDomainValue>> {
454432
// Creat a compute domain map
455433
let mut cpdom_id = 0;
@@ -458,7 +436,7 @@ impl FlatTopology {
458436
let key = ComputeDomainKey {
459437
node_id: cpu_fid.node_id,
460438
llc_pos: cpu_fid.llc_pos,
461-
is_big: cpu_fid.max_freq >= avg_freq,
439+
is_big: cpu_fid.cpu_cap >= avg_cap,
462440
};
463441
let mut value;
464442
match cpdom_map.get(&key) {

0 commit comments

Comments
 (0)