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
25enum nightmare_on_stall : uint8_t {
26 NIGHTMARE_ON_STALL_REPORT = 0,
27 NIGHTMARE_ON_STALL_CRASH,
28};
29
30enum nightmare_liveness_phase : uint8_t {
31 NM_LIVE_OFF = 0,
32 NM_LIVE_ARMED,
33 NM_LIVE_PENDING,
34 NM_LIVE_REPORTED,
35};
36
37struct 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
54struct 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
73struct 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
100extern struct nightmare_runtime nightmare_runtime;
101extern struct nightmare_liveness_state nightmare_liveness;
102
103void nightmare_publish_stop(enum nightmare_stop reason);
104void nightmare_cmdline_get(struct nightmare_cmdline_config *config);
105void nightmare_thread_main(void *arg);
106void nightmare_heartbeat_main(void *arg);
107void nightmare_publish_perturb_verdict(struct nightmare_verdict verdict);
108bool nightmare_load_perturb_verdict(struct nightmare_verdict *out);
109enum nightmare_result
110nightmare_result_with_findings(enum nightmare_result result, size_t findings);
111struct nightmare_verdict
112nightmare_verdict_for_stop(struct nightmare_verdict verdict,
113 enum nightmare_stop stop);
114const char *nightmare_result_string(enum nightmare_result result);
115const char *nightmare_skip_string(enum nightmare_skip_reason reason);
116const char *nightmare_seed_policy_string(enum nightmare_seed_policy policy);
117const char *nightmare_seed_mode_string(enum nightmare_seed_mode mode);
118bool 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);
122bool nightmare_liveness_start(time_ms_t threshold_ms,
123 enum nightmare_on_stall policy);
124void nightmare_liveness_stop(void);
125void nightmare_liveness_poll(void);
126