From d1d9e97d0898a7a8897bd47751849b5fcbf57f41 Mon Sep 17 00:00:00 2001 From: Changwoo Min Date: Fri, 23 Aug 2024 23:07:56 +0900 Subject: [PATCH] scx_lavd: reduce LAVD_CPDOM_MAX_DIST to 4 The BPF verifier in the old kernel gives up to analysis the nested loop in the consume_task(). We reduce the loop less complex by reducing LAVD_CPDOM_MAX_DIST from 6 to 4 in order to make the verifier happy. Note that the theoretical maximum distance is 6 (numa > llc > core type) but there is no such hardware today, hence reducing it to 6 should be okay in next few years, when hopefully the verifier becomes smarter. Signed-off-by: Changwoo Min --- scheds/rust/scx_lavd/src/bpf/intf.h | 6 +++--- scheds/rust/scx_lavd/src/bpf/main.bpf.c | 2 +- scheds/rust/scx_lavd/src/main.rs | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/scheds/rust/scx_lavd/src/bpf/intf.h b/scheds/rust/scx_lavd/src/bpf/intf.h index 2b9533c..9a7f27c 100644 --- a/scheds/rust/scx_lavd/src/bpf/intf.h +++ b/scheds/rust/scx_lavd/src/bpf/intf.h @@ -88,8 +88,8 @@ enum consts { LAVD_CC_CPU_PIN_INTERVAL_DIV = (LAVD_CC_CPU_PIN_INTERVAL / LAVD_SYS_STAT_INTERVAL_NS), - LAVD_CPDOM_MAX_NR = 64, /* maximum number of compute domain (<= 64) */ - LAVD_CPDOM_MAX_DIST = 6, /* maximum distance from one compute domain to another */ + LAVD_CPDOM_MAX_NR = 32, /* maximum number of compute domain */ + LAVD_CPDOM_MAX_DIST = 4, /* maximum distance from one compute domain to another */ LAVD_CPDOM_STARV_NS = (5ULL * NSEC_PER_MSEC), LAVD_STATUS_STR_LEN = 5, /* {LR: Latency-critical, Regular} @@ -132,7 +132,7 @@ struct cpdom_ctx { u8 is_active; /* if this compute domain is active */ u8 nr_neighbors[LAVD_CPDOM_MAX_DIST]; /* number of neighbors per distance */ u64 neighbor_bits[LAVD_CPDOM_MAX_DIST]; /* bitmask of neighbor bitmask per distance */ - u64 cpumask[LAVD_CPU_ID_MAX/64]; /* cpumasks belongs to this compute domain */ + u64 __cpumask[LAVD_CPU_ID_MAX/64]; /* cpumasks belongs to this compute domain */ }; /* diff --git a/scheds/rust/scx_lavd/src/bpf/main.bpf.c b/scheds/rust/scx_lavd/src/bpf/main.bpf.c index 8b3b0b8..e640a67 100644 --- a/scheds/rust/scx_lavd/src/bpf/main.bpf.c +++ b/scheds/rust/scx_lavd/src/bpf/main.bpf.c @@ -2832,7 +2832,7 @@ static s32 init_per_cpu_ctx(u64 now) continue; bpf_for(i, 0, LAVD_CPU_ID_MAX/64) { - u64 cpumask = cpdomc->cpumask[i]; + u64 cpumask = cpdomc->__cpumask[i]; bpf_for(j, 0, 64) { if (cpumask & 0x1LLU << j) { cpu = (i * 64) + j; diff --git a/scheds/rust/scx_lavd/src/main.rs b/scheds/rust/scx_lavd/src/main.rs index 89dafa0..909e608 100644 --- a/scheds/rust/scx_lavd/src/main.rs +++ b/scheds/rust/scx_lavd/src/main.rs @@ -473,12 +473,21 @@ impl<'a> Scheduler<'a> { for cpu_id in v.cpu_ids.iter() { let i = cpu_id / 64; let j = cpu_id % 64; - skel.maps.bss_data.cpdom_ctxs[v.cpdom_id].cpumask[i] |= 0x01 << j; + skel.maps.bss_data.cpdom_ctxs[v.cpdom_id].__cpumask[i] |= 0x01 << j; + } + + const LAVD_CPDOM_MAX_NR: u8 = 32; + const LAVD_CPDOM_MAX_DIST: usize = 4; + if v.neighbor_map.borrow().iter().len() > LAVD_CPDOM_MAX_DIST { + panic!("The processor topology is too complex to handle in BPF."); } for (k, (_d, neighbors)) in v.neighbor_map.borrow().iter().enumerate() { - skel.maps.bss_data.cpdom_ctxs[v.cpdom_id].nr_neighbors[k] = - neighbors.borrow().len() as u8; + let nr_neighbors = neighbors.borrow().len() as u8; + if nr_neighbors > LAVD_CPDOM_MAX_NR { + panic!("The processor topology is too complex to handle in BPF."); + } + skel.maps.bss_data.cpdom_ctxs[v.cpdom_id].nr_neighbors[k] = nr_neighbors; for n in neighbors.borrow().iter() { skel.maps.bss_data.cpdom_ctxs[v.cpdom_id].neighbor_bits[k] = 0x1 << n; }