scx_rusty: Temporary fix of duplicate active tptr

Under severe load unbalance scenario such as mixtures of CPU-insensive
workload and I/O-intensive worload, same tptr may be written into the
same dom_active_tptrs's array.

It will lead to load balancer's failure because when the tptr task
contains large enough load, it tends be to selected so warnings about
same tptr being set in "lb_data" will continue to pop up.

Use a workaround for now , which is to keep a HashSet in userspace
recording the current active tptr under a domain, and do not generate
the same task repeatedly.

Signed-off-by: I Hsin Cheng <richard120310@gmail.com>
This commit is contained in:
I Hsin Cheng 2024-11-19 21:36:12 +08:00
parent 489ce8a766
commit 72ecf3c8e3

View File

@ -133,6 +133,7 @@
use core::cmp::Ordering;
use std::cell::Cell;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::collections::VecDeque;
use std::fmt;
use std::sync::Arc;
@ -343,6 +344,7 @@ struct Domain {
queried_tasks: bool,
load: LoadEntity,
tasks: SortedVec<TaskInfo>,
active_tptr_set: HashSet<u64>,
}
impl Domain {
@ -362,6 +364,7 @@ impl Domain {
load_avg,
),
tasks: SortedVec::new(),
active_tptr_set: HashSet::new(),
}
}
@ -680,6 +683,10 @@ impl<'a, 'b> LoadBalancer<'a, 'b> {
let tptr = active_tptrs.tptrs[(idx % MAX_TPTRS) as usize];
let key = unsafe { std::mem::transmute::<u64, [u8; 8]>(tptr) };
if dom.active_tptr_set.contains(&tptr) {
continue;
}
if let Some(task_data_elem) = task_data.lookup(&key, libbpf_rs::MapFlags::ANY)? {
let task_ctx =
unsafe { &*(task_data_elem.as_slice().as_ptr() as *const bpf_intf::task_ctx) };
@ -705,6 +712,7 @@ impl<'a, 'b> LoadBalancer<'a, 'b> {
};
load *= weight;
dom.active_tptr_set.insert(tptr);
dom.tasks.insert(TaskInfo {
tptr,
load: OrderedFloat(load),