| 1 | #pragma once |
| 2 | #include <console/crash.h> |
| 3 | #include <nightmare/nightmare.h> |
| 4 | #include <nightmare/perturb.h> |
| 5 | #include <stdatomic.h> |
| 6 | #include <sync/completion.h> |
| 7 | #include <thread/queue.h> |
| 8 | #include <time/timer.h> |
| 9 | #include <watchdog.h> |
| 10 | |
| 11 | #define nightmare_panic(fmt, ...) \ |
| 12 | do { \ |
| 13 | char _nm_msg[CRASH_MSG_MAX]; \ |
| 14 | snprintf(_nm_msg, sizeof(_nm_msg), fmt, ##__VA_ARGS__); \ |
| 15 | crash_full(&(struct crash_context) { \ |
| 16 | .source = CRASH_SOURCE_NIGHTMARE, \ |
| 17 | .formats = CRASH_FMT_DEFAULT, \ |
| 18 | .file = __FILE__, \ |
| 19 | .line = __LINE__, \ |
| 20 | .func = __func__, \ |
| 21 | .msg = _nm_msg, \ |
| 22 | }); \ |
| 23 | } while (0) |
| 24 | |
| 25 | enum nightmare_on_stall : uint8_t { |
| 26 | NIGHTMARE_ON_STALL_REPORT = 0, |
| 27 | NIGHTMARE_ON_STALL_CRASH, |
| 28 | }; |
| 29 | |
| 30 | enum nightmare_liveness_phase : uint8_t { |
| 31 | NM_LIVE_OFF = 0, |
| 32 | NM_LIVE_ARMED, |
| 33 | NM_LIVE_PENDING, |
| 34 | NM_LIVE_REPORTED, |
| 35 | }; |
| 36 | |
| 37 | struct nightmare_liveness_state { |
| 38 | struct watchdog_callback callback; |
| 39 | _Atomic enum nightmare_liveness_phase phase; |
| 40 | |
| 41 | /* coordinator callback owns while armed */ |
| 42 | uint64_t last_progress; |
| 43 | time_ms_t last_change_ms; |
| 44 | |
| 45 | time_ms_t threshold_ms; |
| 46 | bool was_quiesced; |
| 47 | |
| 48 | struct nightmare_stall_evidence pending; |
| 49 | enum nightmare_on_stall policy; |
| 50 | cpu_id_t coordinator_cpu; |
| 51 | bool registered; |
| 52 | }; |
| 53 | |
| 54 | struct nightmare_cmdline_config { |
| 55 | const char *selector; |
| 56 | fx32_32_t intensity; |
| 57 | uint64_t seed; |
| 58 | bool seed_present; |
| 59 | enum nightmare_seed_mode seed_mode; |
| 60 | time_ms_t duration_ms; |
| 61 | time_ms_t drain_grace_ms; |
| 62 | time_ms_t stat_interval_ms; |
| 63 | time_ms_t stall_threshold_ms; |
| 64 | enum nightmare_on_stall on_stall; |
| 65 | uint64_t boot_index; |
| 66 | const char *campaign_id; |
| 67 | struct cmdline_list perturb; |
| 68 | bool perturb_present; |
| 69 | }; |
| 70 | |
| 71 | #define NIGHTMARE_MAX_PERTURBERS 8 |
| 72 | |
| 73 | struct nightmare_runtime { |
| 74 | struct nightmare_ctx ctx; |
| 75 | atomic_bool active; |
| 76 | _Atomic enum nightmare_stop stop; |
| 77 | atomic_bool quiesce_requested; |
| 78 | atomic_size_t parked_count; |
| 79 | atomic_size_t finding_count; |
| 80 | atomic_bool terminal; |
| 81 | atomic_bool perturb_verdict_ready; |
| 82 | struct nightmare_verdict perturb_verdict; |
| 83 | char perturb_reason[64]; |
| 84 | char perturb_msg[256]; |
| 85 | size_t total_worker_count; |
| 86 | size_t perturber_count; |
| 87 | const struct nightmare_perturb_desc *perturbers[NIGHTMARE_MAX_PERTURBERS]; |
| 88 | struct nightmare_worker *workers; |
| 89 | struct thread *heartbeat; |
| 90 | struct completion start; |
| 91 | struct timer soft_timer; |
| 92 | struct timer hard_timer; |
| 93 | time_ms_t started_ms; |
| 94 | time_ms_t stat_interval_ms; |
| 95 | const char *campaign_id; |
| 96 | uint64_t boot_index; |
| 97 | char caps[256]; |
| 98 | }; |
| 99 | |
| 100 | extern struct nightmare_runtime nightmare_runtime; |
| 101 | extern struct nightmare_liveness_state nightmare_liveness; |
| 102 | |
| 103 | void nightmare_publish_stop(enum nightmare_stop reason); |
| 104 | void nightmare_cmdline_get(struct nightmare_cmdline_config *config); |
| 105 | void nightmare_thread_main(void *arg); |
| 106 | void nightmare_heartbeat_main(void *arg); |
| 107 | void nightmare_publish_perturb_verdict(struct nightmare_verdict verdict); |
| 108 | bool nightmare_load_perturb_verdict(struct nightmare_verdict *out); |
| 109 | enum nightmare_result |
| 110 | nightmare_result_with_findings(enum nightmare_result result, size_t findings); |
| 111 | struct nightmare_verdict |
| 112 | nightmare_verdict_for_stop(struct nightmare_verdict verdict, |
| 113 | enum nightmare_stop stop); |
| 114 | const char *nightmare_result_string(enum nightmare_result result); |
| 115 | const char *nightmare_skip_string(enum nightmare_skip_reason reason); |
| 116 | const char *nightmare_seed_policy_string(enum nightmare_seed_policy policy); |
| 117 | const char *nightmare_seed_mode_string(enum nightmare_seed_mode mode); |
| 118 | bool nightmare_liveness_eval(struct nightmare_liveness_state *state, |
| 119 | uint64_t current_progress, time_ms_t now_ms, |
| 120 | bool quiesce_requested, bool run_active, |
| 121 | enum nightmare_stop stop, cpu_id_t observer_cpu); |
| 122 | bool nightmare_liveness_start(time_ms_t threshold_ms, |
| 123 | enum nightmare_on_stall policy); |
| 124 | void nightmare_liveness_stop(void); |
| 125 | void nightmare_liveness_poll(void); |
| 126 | |