Skip to content

Commit d71e415

Browse files
authored
Merge pull request #2435 from yaakov-stein/ystein/scx_chaos_seperate_kprobe_delays
scx_chaos: separate kprobe delays
2 parents a7d5538 + ffcfc6b commit d71e415

File tree

4 files changed

+51
-13
lines changed

4 files changed

+51
-13
lines changed

scheds/rust/scx_chaos/src/bpf/intf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ enum chaos_trait_kind {
3030
CHAOS_TRAIT_RANDOM_DELAYS,
3131
CHAOS_TRAIT_CPU_FREQ,
3232
CHAOS_TRAIT_DEGRADATION,
33+
CHAOS_TRAIT_KPROBE_RANDOM_DELAYS,
3334
CHAOS_TRAIT_MAX,
3435
};
3536

@@ -49,6 +50,7 @@ enum chaos_stat_idx {
4950
CHAOS_STAT_TRAIT_DEGRADATION,
5051
CHAOS_STAT_CHAOS_EXCLUDED,
5152
CHAOS_STAT_CHAOS_SKIPPED,
53+
CHAOS_STAT_KPROBE_RANDOM_DELAYS,
5254
CHAOS_STAT_TIMER_KICKS,
5355
CHAOS_NR_STATS,
5456
};

scheds/rust/scx_chaos/src/bpf/main.bpf.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ const volatile u32 degradation_freq_frac32 = 1;
5151
const volatile u64 degradation_frac7 = 0;
5252

5353
const volatile u32 kprobe_delays_freq_frac32 = 1;
54+
const volatile u64 kprobe_delays_min_ns = 1;
55+
const volatile u64 kprobe_delays_max_ns = 2;
5456

5557
#define MIN(x, y) ((x) < (y) ? (x) : (y))
5658
#define MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -251,17 +253,16 @@ static __always_inline s32 calculate_chaos_match(struct task_struct *p)
251253
}
252254

253255
__weak s32 enqueue_random_delay(struct task_struct *p __arg_trusted, u64 enq_flags,
254-
struct chaos_task_ctx *taskc __arg_nonnull)
256+
struct chaos_task_ctx *taskc __arg_nonnull, u64 min_ns, u64 max_ns)
255257
{
256258
u64 rand64 = ((u64)bpf_get_prandom_u32() << 32) | bpf_get_prandom_u32();
257259

258-
u64 vtime = bpf_ktime_get_ns() + random_delays_min_ns;
259-
if (random_delays_min_ns != random_delays_max_ns) {
260-
vtime += rand64 % (random_delays_max_ns - random_delays_min_ns);
260+
u64 vtime = bpf_ktime_get_ns() + min_ns;
261+
if (min_ns != max_ns) {
262+
vtime += rand64 % (max_ns - min_ns);
261263
}
262264

263265
scx_bpf_dsq_insert_vtime(p, get_cpu_delay_dsq(-1), 0, vtime, enq_flags);
264-
chaos_stat_inc(CHAOS_STAT_TRAIT_RANDOM_DELAYS);
265266

266267
return true;
267268
}
@@ -272,10 +273,22 @@ __weak s32 enqueue_chaotic(struct task_struct *p __arg_trusted, u64 enq_flags,
272273
bool out;
273274

274275
switch (taskc->next_trait) {
276+
case CHAOS_TRAIT_KPROBE_RANDOM_DELAYS:
277+
out = enqueue_random_delay(p,
278+
enq_flags,
279+
taskc,
280+
kprobe_delays_min_ns,
281+
kprobe_delays_max_ns);
282+
chaos_stat_inc(CHAOS_STAT_KPROBE_RANDOM_DELAYS);
283+
break;
275284
case CHAOS_TRAIT_RANDOM_DELAYS:
276-
out = enqueue_random_delay(p, enq_flags, taskc);
285+
out = enqueue_random_delay(p,
286+
enq_flags,
287+
taskc,
288+
random_delays_min_ns,
289+
random_delays_max_ns);
290+
chaos_stat_inc(CHAOS_STAT_TRAIT_RANDOM_DELAYS);
277291
break;
278-
279292
case CHAOS_TRAIT_NONE:
280293
chaos_stat_inc(CHAOS_STAT_CHAOS_SKIPPED);
281294
out = false;
@@ -503,7 +516,8 @@ void BPF_STRUCT_OPS(chaos_enqueue, struct task_struct *p __arg_trusted, u64 enq_
503516
if (promise.kind == P2DQ_ENQUEUE_PROMISE_FAILED)
504517
goto cleanup;
505518

506-
if (taskc->next_trait == CHAOS_TRAIT_RANDOM_DELAYS &&
519+
if ((taskc->next_trait == CHAOS_TRAIT_RANDOM_DELAYS ||
520+
taskc->next_trait == CHAOS_TRAIT_KPROBE_RANDOM_DELAYS) &&
507521
enqueue_chaotic(p, enq_flags, taskc))
508522
goto cleanup;
509523

@@ -592,7 +606,7 @@ void BPF_STRUCT_OPS(chaos_tick, struct task_struct *p)
592606
if (!(taskc = lookup_create_chaos_task_ctx(p)))
593607
return;
594608

595-
if (taskc->pending_trait == CHAOS_TRAIT_RANDOM_DELAYS)
609+
if (taskc->pending_trait == CHAOS_TRAIT_KPROBE_RANDOM_DELAYS)
596610
p->scx.slice = 0;
597611
}
598612

@@ -643,7 +657,7 @@ int generic(struct pt_regs *ctx)
643657

644658
u32 roll = bpf_get_prandom_u32();
645659
if (roll <= kprobe_delays_freq_frac32) {
646-
taskc->pending_trait = CHAOS_TRAIT_RANDOM_DELAYS;
660+
taskc->pending_trait = CHAOS_TRAIT_KPROBE_RANDOM_DELAYS;
647661
dbg("GENERIC: setting pending_trait to RANDOM_DELAYS - task[%d]", p->pid);
648662
}
649663

scheds/rust/scx_chaos/src/lib.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ pub enum RequiresPpid {
141141
pub struct KprobeRandomDelays {
142142
pub kprobes: Vec<String>,
143143
pub freq: f64,
144+
pub min_us: u64,
145+
pub max_us: u64,
144146
}
145147

146148
#[derive(Debug)]
@@ -197,6 +199,8 @@ impl Scheduler {
197199
[bpf_intf::chaos_stat_idx_CHAOS_STAT_TRAIT_DEGRADATION as usize],
198200
chaos_excluded: stats[bpf_intf::chaos_stat_idx_CHAOS_STAT_CHAOS_EXCLUDED as usize],
199201
chaos_skipped: stats[bpf_intf::chaos_stat_idx_CHAOS_STAT_CHAOS_SKIPPED as usize],
202+
kprobe_random_delays: stats
203+
[bpf_intf::chaos_stat_idx_CHAOS_STAT_KPROBE_RANDOM_DELAYS as usize],
200204
timer_kicks: stats[bpf_intf::chaos_stat_idx_CHAOS_STAT_TIMER_KICKS as usize],
201205
}
202206
}
@@ -443,6 +447,8 @@ impl Builder<'_> {
443447
if let Some(kprobe_random_delays) = &self.kprobe_random_delays {
444448
rodata.kprobe_delays_freq_frac32 =
445449
(kprobe_random_delays.freq * 2_f64.powf(32_f64)) as u32;
450+
rodata.kprobe_delays_min_ns = kprobe_random_delays.min_us * 1000;
451+
rodata.kprobe_delays_max_ns = kprobe_random_delays.max_us * 1000;
446452
}
447453

448454
// Set up the frequency array. The first element means nothing, so should be what's
@@ -608,12 +614,20 @@ pub struct PerfDegradationArgs {
608614
#[derive(Debug, Parser)]
609615
pub struct KprobeArgs {
610616
/// Introduce random delays in the scheduler whenever a provided kprobe is hit.
611-
#[clap(long, num_args = 1.., value_parser)]
617+
#[clap(long, num_args = 1.., value_parser, requires = "kprobe_random_delay_min_us")]
612618
pub kprobes_for_random_delays: Vec<String>,
613619

614-
/// Chance of kprobe random delays. Must be between 0 and 1.
620+
/// Chance of kprobe random delays. Must be between 0 and 1. [default=0.1]
615621
#[clap(long, requires = "kprobes_for_random_delays")]
616622
pub kprobe_random_delay_frequency: Option<f64>,
623+
624+
/// Minimum time to add for kprobe random delay.
625+
#[clap(long, requires = "kprobe_random_delay_max_us")]
626+
pub kprobe_random_delay_min_us: Option<u64>,
627+
628+
/// Maximum time to add for kprobe random delay.
629+
#[clap(long, requires = "kprobes_for_random_delays")]
630+
pub kprobe_random_delay_max_us: Option<u64>,
617631
}
618632

619633
/// scx_chaos: A general purpose sched_ext scheduler designed to amplify race conditions
@@ -763,9 +777,13 @@ impl<'a> Iterator for BuilderIterator<'a> {
763777
KprobeArgs {
764778
kprobes_for_random_delays,
765779
kprobe_random_delay_frequency,
780+
kprobe_random_delay_min_us: Some(min_us),
781+
kprobe_random_delay_max_us: Some(max_us),
766782
} if !kprobes_for_random_delays.is_empty() => Some(KprobeRandomDelays {
767783
kprobes: kprobes_for_random_delays.clone(),
768784
freq: kprobe_random_delay_frequency.unwrap_or(0.1),
785+
min_us: *min_us,
786+
max_us: *max_us,
769787
}),
770788
_ => None,
771789
};

scheds/rust/scx_chaos/src/stats.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,21 @@ pub struct Metrics {
2727
pub chaos_skipped: u64,
2828
#[stat(desc = "Number of timer-based CPU kicks for delayed tasks")]
2929
pub timer_kicks: u64,
30+
#[stat(desc = "Number of times a kprobe caused a random delay to be applied")]
31+
pub kprobe_random_delays: u64,
3032
}
3133

3234
impl Metrics {
3335
fn format<W: Write>(&self, w: &mut W) -> Result<()> {
3436
writeln!(
3537
w,
36-
"chaos traits: random_delays/cpu_freq/degradation {}/{}/{}\n\tchaos excluded/skipped {}/{}\n\ttimer kicks: {}",
38+
"chaos traits: random_delays/cpu_freq/degradation {}/{}/{}\n\tchaos excluded/skipped {}/{}\n\tkprobe_random_delays {}\n\ttimer kicks: {}",
3739
self.trait_random_delays,
3840
self.trait_cpu_freq,
3941
self.trait_degradation,
4042
self.chaos_excluded,
4143
self.chaos_skipped,
44+
self.kprobe_random_delays,
4245
self.timer_kicks,
4346
)?;
4447
Ok(())
@@ -51,6 +54,7 @@ impl Metrics {
5154
trait_degradation: self.trait_degradation - rhs.trait_degradation,
5255
chaos_excluded: self.chaos_excluded - rhs.chaos_excluded,
5356
chaos_skipped: self.chaos_skipped - rhs.chaos_skipped,
57+
kprobe_random_delays: self.kprobe_random_delays - rhs.kprobe_random_delays,
5458
timer_kicks: self.timer_kicks - rhs.timer_kicks,
5559
}
5660
}

0 commit comments

Comments
 (0)