Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions scheds/rust/scx_layered/examples/cgrp_contains.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[
{
"name": "match one container",
"matches": [
[
{ "CgroupContains": "nope" }
]
],
"kind": {
"Grouped": {
"cpus_range_frac": [0.25, 0.5],
"util_range": [0.4, 0.85],
"growth_algo": "RandomTopo",
"disallow_preempt_after_us": 0,
"protected": true
}
}
},
{
"name": "match other containers",
"matches": [
[{ "CgroupContains": "docker" }]
],
"kind": {
"Grouped": {
"cpus_range_frac": [0.5, 0.5],
"util_range": [0.4, 0.85],
"growth_algo": "RandomTopo",
"protected": true
}
}
},
{
"name": "third",
"matches": [
[{ "PcommPrefix": "stress-ng" }]
],
"kind": {
"Grouped": {
"cpus_range": [5, 5],
"util_range": [0.4, 0.85],
"growth_algo": "RandomTopo",
"protected": true
}
}
},
{
"name": "fourth",
"matches": [
[]
],
"kind": {
"Open": {
"growth_algo": "RandomTopo"
}
}
}
]
2 changes: 2 additions & 0 deletions scheds/rust/scx_layered/src/bpf/intf.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ enum layer_match_kind {
MATCH_USED_GPU_PID,
MATCH_AVG_RUNTIME,
MATCH_CGROUP_SUFFIX,
MATCH_CGROUP_CONTAINS,

NR_LAYER_MATCH_KINDS,
};
Expand All @@ -261,6 +262,7 @@ struct layer_match {
int kind;
char cgroup_prefix[MAX_PATH];
char cgroup_suffix[MAX_PATH];
char cgroup_substr[MAX_PATH];
char comm_prefix[MAX_COMM];
char pcomm_prefix[MAX_COMM];
int nice;
Expand Down
18 changes: 12 additions & 6 deletions scheds/rust/scx_layered/src/bpf/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2148,21 +2148,24 @@ static __noinline bool match_one(struct layer_match *match,

switch (match->kind) {
case MATCH_CGROUP_PREFIX: {
return match_prefix_suffix(match->cgroup_prefix, cgrp_path, false);
return match_str(match->cgroup_prefix, cgrp_path, STR_PREFIX);
}
case MATCH_CGROUP_SUFFIX: {
return match_prefix_suffix(match->cgroup_suffix, cgrp_path, true);
return match_str(match->cgroup_suffix, cgrp_path, STR_SUFFIX);
}
case MATCH_CGROUP_CONTAINS: {
return match_str(match->cgroup_substr, cgrp_path, STR_SUBSTR);
}
case MATCH_COMM_PREFIX: {
char comm[MAX_COMM];
__builtin_memcpy(comm, p->comm, MAX_COMM);
return match_prefix_suffix(match->comm_prefix, comm, false);
return match_str(match->comm_prefix, comm, STR_PREFIX);
}
case MATCH_PCOMM_PREFIX: {
char pcomm[MAX_COMM];

__builtin_memcpy(pcomm, p->group_leader->comm, MAX_COMM);
return match_prefix_suffix(match->pcomm_prefix, pcomm, false);
return match_str(match->pcomm_prefix, pcomm, STR_PREFIX);
}
case MATCH_NICE_ABOVE:
return prio_to_nice((s32)p->static_prio) > match->nice;
Expand Down Expand Up @@ -2228,8 +2231,8 @@ static __noinline bool match_one(struct layer_match *match,
if (!taskc->join_layer[0])
return false;

return match_prefix_suffix(match->comm_prefix, taskc->join_layer,
false);
return match_str(match->comm_prefix, taskc->join_layer,
STR_PREFIX);
}
case MATCH_IS_GROUP_LEADER: {
// There is nuance to this around exec(2)s and group leader swaps.
Expand Down Expand Up @@ -3436,6 +3439,9 @@ static s32 init_layer(int layer_id)
case MATCH_CGROUP_SUFFIX:
dbg("%s CGROUP_SUFFIX \"%s\"", header, match->cgroup_suffix);
break;
case MATCH_CGROUP_CONTAINS:
dbg("%s CGROUP_CONTAINS \"%s\"", header, match->cgroup_substr);
break;
default:
scx_bpf_error("%s Invalid kind", header);
return -EINVAL;
Expand Down
69 changes: 69 additions & 0 deletions scheds/rust/scx_layered/src/bpf/util.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,72 @@ bool __noinline match_prefix_suffix(const char *prefix, const char *str, bool ma
}
return false;
}

// Copied from above for verifier.
bool __noinline match_substr(const char *prefix, const char *str)
{
u32 zero = 0;
int str_len, match_str_len, x, y;

if (!prefix || !str) {
scx_bpf_error("invalid args: %s %s",
prefix, str);
return false;
}

char *match_buf = bpf_map_lookup_elem(&match_bufs, &zero);
char *str_buf = bpf_map_lookup_elem(&str_bufs, &zero);
if (!match_buf || !str_buf) {
scx_bpf_error("failed to look up buf");
return false;
}

match_str_len = bpf_probe_read_kernel_str(match_buf, MAX_PATH, prefix);
if (match_str_len < 0) {
scx_bpf_error("failed to read prefix");
return false;
}

str_len = bpf_probe_read_kernel_str(str_buf, MAX_PATH, str);
if (str_len < 0) {
scx_bpf_error("failed to read str");
return false;
}

if (match_str_len > str_len)
return false;

bpf_for(x, 0, MAX_PATH) {
if (str_len - x < y)
break;

bpf_for(y, 0, MAX_PATH) {
if (match_buf[clamp_pathind(y)] == '\0')
return true;
if (str_buf[clamp_pathind(x+y)] != match_buf[clamp_pathind(y)])
break;
}
}
return false;
}

bool __noinline match_str(const char *prefix, const char *str, enum MatchType match_type)
{

switch (match_type) {
case STR_PREFIX:
return match_prefix_suffix(prefix, str, false);
break;
case STR_SUFFIX:
return match_prefix_suffix(prefix, str, true);
break;
case STR_SUBSTR:
return match_substr(prefix, str);
break;
default:
scx_bpf_error("match_str w/o match type specified");
return false;
}

return false;
}
8 changes: 7 additions & 1 deletion scheds/rust/scx_layered/src/bpf/util.bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ extern const volatile u32 debug;
#define dbg(fmt, args...) do { if (debug) bpf_printk(fmt, ##args); } while (0)
#define trace(fmt, args...) do { if (debug > 1) bpf_printk(fmt, ##args); } while (0)

bool match_prefix_suffix(const char *prefix, const char *str, bool match_suffix);
enum MatchType {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

STR_PREFIX = 0,
STR_SUFFIX = 1,
STR_SUBSTR = 2
};

bool match_str(const char *prefix, const char *str, enum MatchType match_type);
char *format_cgrp_path(struct cgroup *cgrp);

#endif /* __LAYERED_UTIL_H */
1 change: 1 addition & 0 deletions scheds/rust/scx_layered/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub enum LayerPlacement {
pub enum LayerMatch {
CgroupPrefix(String),
CgroupSuffix(String),
CgroupContains(String),
CommPrefix(String),
CommPrefixExclude(String),
PcommPrefix(String),
Expand Down
14 changes: 14 additions & 0 deletions scheds/rust/scx_layered/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,10 @@ impl<'a> Scheduler<'a> {
mt.kind = bpf_intf::layer_match_kind_MATCH_CGROUP_SUFFIX as i32;
copy_into_cstr(&mut mt.cgroup_suffix, suffix.as_str());
}
LayerMatch::CgroupContains(substr) => {
mt.kind = bpf_intf::layer_match_kind_MATCH_CGROUP_CONTAINS as i32;
copy_into_cstr(&mut mt.cgroup_substr, substr.as_str());
}
LayerMatch::CommPrefix(prefix) => {
mt.kind = bpf_intf::layer_match_kind_MATCH_COMM_PREFIX as i32;
copy_into_cstr(&mut mt.comm_prefix, prefix.as_str());
Expand Down Expand Up @@ -2822,6 +2826,16 @@ fn verify_layer_specs(specs: &[LayerSpec]) -> Result<()> {
bail!("Spec {:?} has too long a cgroup prefix", spec.name);
}
}
LayerMatch::CgroupSuffix(suffix) => {
if suffix.len() > MAX_PATH {
bail!("Spec {:?} has too long a cgroup suffix", spec.name);
}
}
LayerMatch::CgroupContains(substr) => {
if substr.len() > MAX_PATH {
bail!("Spec {:?} has too long a cgroup substr", spec.name);
}
}
LayerMatch::CommPrefix(prefix) => {
if prefix.len() > MAX_COMM {
bail!("Spec {:?} has too long a comm prefix", spec.name);
Expand Down