Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scx_layered: Add user and group layers #447

Merged
merged 2 commits into from
Jul 24, 2024
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
4 changes: 4 additions & 0 deletions scheds/rust/scx_layered/src/bpf/intf.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ enum layer_match_kind {
MATCH_NICE_ABOVE,
MATCH_NICE_BELOW,
MATCH_NICE_EQUALS,
MATCH_USER_ID_EQUALS,
MATCH_GROUP_ID_EQUALS,

NR_LAYER_MATCH_KINDS,
};
Expand All @@ -117,6 +119,8 @@ struct layer_match {
char comm_prefix[MAX_COMM];
char pcomm_prefix[MAX_COMM];
int nice;
u32 user_id;
u32 group_id;
};

struct layer_match_ands {
Expand Down
25 changes: 24 additions & 1 deletion scheds/rust/scx_layered/src/bpf/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,9 @@ void BPF_STRUCT_OPS(layered_dispatch, s32 cpu, struct task_struct *prev)

static bool match_one(struct layer_match *match, struct task_struct *p, const char *cgrp_path)
{
bool result = false;
struct cred *cred;

switch (match->kind) {
case MATCH_CGROUP_PREFIX: {
return match_prefix(match->cgroup_prefix, cgrp_path, MAX_PATH);
Expand All @@ -921,9 +924,23 @@ static bool match_one(struct layer_match *match, struct task_struct *p, const ch
return prio_to_nice((s32)p->static_prio) < match->nice;
case MATCH_NICE_EQUALS:
return prio_to_nice((s32)p->static_prio) == match->nice;
case MATCH_USER_ID_EQUALS:
bpf_rcu_read_lock();
cred = p->real_cred;
if (cred)
result = cred->euid.val == match->user_id;
bpf_rcu_read_unlock();
return result;
case MATCH_GROUP_ID_EQUALS:
bpf_rcu_read_lock();
cred = p->real_cred;
if (cred)
result = cred->egid.val == match->group_id;
bpf_rcu_read_unlock();
return result;
default:
scx_bpf_error("invalid match kind %d", match->kind);
return false;
return result;
}
}

Expand Down Expand Up @@ -1495,6 +1512,12 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(layered_init)
case MATCH_NICE_EQUALS:
dbg("%s NICE_EQUALS %d", header, match->nice);
break;
case MATCH_USER_ID_EQUALS:
dbg("%s USER_ID %u", header, match->user_id);
break;
case MATCH_GROUP_ID_EQUALS:
dbg("%s GROUP_ID %u", header, match->group_id);
break;
default:
scx_bpf_error("%s Invalid kind", header);
return -EINVAL;
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 @@ -125,6 +125,10 @@ lazy_static::lazy_static! {
/// - NiceEquals: Matches if the task's nice value is exactly equal to
/// the pattern.
///
/// - UIDEquals: Matches if the task's effective user id matches the pattern.
///
/// - GIDEquals: Matches if the task's effective group id matches the pattern.
///
/// While there are complexity limitations as the matches are performed in
/// BPF, it is straightforward to add more types of matches.
///
Expand Down Expand Up @@ -340,6 +344,8 @@ enum LayerMatch {
NiceAbove(i32),
NiceBelow(i32),
NiceEquals(i32),
UIDEquals(u32),
GIDEquals(u32),
}

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -1289,6 +1295,14 @@ impl<'a, 'b> Scheduler<'a, 'b> {
mt.kind = bpf_intf::layer_match_kind_MATCH_NICE_EQUALS as i32;
mt.nice = *nice;
}
LayerMatch::UIDEquals(user_id) => {
mt.kind = bpf_intf::layer_match_kind_MATCH_USER_ID_EQUALS as i32;
mt.user_id = *user_id;
}
LayerMatch::GIDEquals(group_id) => {
mt.kind = bpf_intf::layer_match_kind_MATCH_GROUP_ID_EQUALS as i32;
mt.group_id = *group_id;
}
}
}
layer.matches[or_i].nr_match_ands = or.len() as i32;
Expand Down