25#ifndef SURICATA_UTIL_PROFILE_H
26#define SURICATA_UTIL_PROFILE_H
46#define KEYWORD_PROFILING_SET_LIST(ctx, list) { \
47 (ctx)->keyword_perf_list = (list); \
50#define KEYWORD_PROFILING_START \
51 uint64_t profile_keyword_start_ = 0; \
52 uint64_t profile_keyword_end_ = 0; \
53 if (profiling_keyword_enabled) { \
54 if (profiling_keyword_entered > 0) { \
55 SCLogError("Re-entered profiling, exiting."); \
58 profiling_keyword_entered++; \
59 profile_keyword_start_ = UtilCpuGetTicks(); \
64#define KEYWORD_PROFILING_END(ctx, type, m) \
65 if (profiling_keyword_enabled && profiling_keyword_entered) { \
66 profile_keyword_end_ = UtilCpuGetTicks(); \
67 SCProfilingKeywordUpdateCounter((ctx),(type),(profile_keyword_end_ - profile_keyword_start_),(m)); \
68 profiling_keyword_entered--; \
73#define PACKET_PROFILING_START(p) \
74 if (profiling_packets_enabled) { \
75 (p)->profile = SCProfilePacketStart(); \
76 if ((p)->profile != NULL) \
77 (p)->profile->ticks_start = UtilCpuGetTicks(); \
80#define PACKET_PROFILING_RESTART(p) \
81 if (profiling_packets_enabled) { \
82 if ((p)->profile != NULL) \
83 (p)->profile->ticks_start = UtilCpuGetTicks(); \
86#define PACKET_PROFILING_END(p) \
87 if (profiling_packets_enabled && (p)->profile != NULL) { \
88 (p)->profile->ticks_end = UtilCpuGetTicks(); \
89 SCProfilingAddPacket((p)); \
93#define PACKET_PROFILING_RESET_LOCKS do { \
95 mutex_lock_wait_ticks = 0; \
96 mutex_lock_contention = 0; \
98 spin_lock_wait_ticks = 0; \
99 spin_lock_contention = 0; \
101 rww_lock_wait_ticks = 0; \
102 rww_lock_contention = 0; \
104 rwr_lock_wait_ticks = 0; \
105 rwr_lock_contention = 0; \
110#define PACKET_PROFILING_COPY_LOCKS(p, id) do { \
111 (p)->profile->tmm[(id)].mutex_lock_cnt = mutex_lock_cnt; \
112 (p)->profile->tmm[(id)].mutex_lock_wait_ticks = mutex_lock_wait_ticks; \
113 (p)->profile->tmm[(id)].mutex_lock_contention = mutex_lock_contention; \
114 (p)->profile->tmm[(id)].spin_lock_cnt = spin_lock_cnt; \
115 (p)->profile->tmm[(id)].spin_lock_wait_ticks = spin_lock_wait_ticks; \
116 (p)->profile->tmm[(id)].spin_lock_contention = spin_lock_contention; \
117 (p)->profile->tmm[(id)].rww_lock_cnt = rww_lock_cnt; \
118 (p)->profile->tmm[(id)].rww_lock_wait_ticks = rww_lock_wait_ticks; \
119 (p)->profile->tmm[(id)].rww_lock_contention = rww_lock_contention; \
120 (p)->profile->tmm[(id)].rwr_lock_cnt = rwr_lock_cnt; \
121 (p)->profile->tmm[(id)].rwr_lock_wait_ticks = rwr_lock_wait_ticks; \
122 (p)->profile->tmm[(id)].rwr_lock_contention = rwr_lock_contention; \
124 SCProfilingAddPacketLocks((p)); \
127#define PACKET_PROFILING_RESET_LOCKS
128#define PACKET_PROFILING_COPY_LOCKS(p, id)
131#define PACKET_PROFILING_TMM_START(p, id) \
132 if (profiling_packets_enabled && (p)->profile != NULL) { \
133 if ((id) < TMM_SIZE) { \
134 (p)->profile->tmm[(id)].ticks_start = UtilCpuGetTicks();\
135 PACKET_PROFILING_RESET_LOCKS; \
139#define PACKET_PROFILING_TMM_END(p, id) \
140 if (profiling_packets_enabled && (p)->profile != NULL) { \
141 if ((id) < TMM_SIZE) { \
142 PACKET_PROFILING_COPY_LOCKS((p), (id)); \
143 (p)->profile->tmm[(id)].ticks_end = UtilCpuGetTicks(); \
147#define FLOWWORKER_PROFILING_START(p, id) \
148 if (profiling_packets_enabled && (p)->profile != NULL) { \
149 if ((id) < PROFILE_FLOWWORKER_SIZE) { \
150 (p)->profile->flowworker[(id)].ticks_start = UtilCpuGetTicks();\
154#define FLOWWORKER_PROFILING_END(p, id) \
155 if (profiling_packets_enabled && (p)->profile != NULL) { \
156 if ((id) < PROFILE_FLOWWORKER_SIZE) { \
157 (p)->profile->flowworker[(id)].ticks_end = UtilCpuGetTicks(); \
161#define PACKET_PROFILING_RESET(p) \
162 if (profiling_packets_enabled && (p)->profile != NULL) { \
163 SCFree((p)->profile); \
164 (p)->profile = NULL; \
167#define PACKET_PROFILING_APP_START(dp, id) \
168 if (profiling_packets_enabled) { \
169 (dp)->ticks_start = UtilCpuGetTicks(); \
170 (dp)->alproto = (id); \
173#define PACKET_PROFILING_APP_END(dp) \
174 if (profiling_packets_enabled) { \
175 (dp)->ticks_end = UtilCpuGetTicks(); \
176 if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \
177 (dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \
181#define PACKET_PROFILING_APP_PD_START(dp) \
182 if (profiling_packets_enabled) { \
183 (dp)->proto_detect_ticks_start = UtilCpuGetTicks(); \
186#define PACKET_PROFILING_APP_PD_END(dp) \
187 if (profiling_packets_enabled) { \
188 (dp)->proto_detect_ticks_end = UtilCpuGetTicks(); \
189 if ((dp)->proto_detect_ticks_start != 0 && (dp)->proto_detect_ticks_start < ((dp)->proto_detect_ticks_end)) { \
190 (dp)->proto_detect_ticks_spent = \
191 ((dp)->proto_detect_ticks_end - (dp)->proto_detect_ticks_start); \
195#define PACKET_PROFILING_APP_RESET(dp) \
196 if (profiling_packets_enabled) { \
197 (dp)->ticks_start = 0; \
198 (dp)->ticks_end = 0; \
199 (dp)->ticks_spent = 0; \
201 (dp)->proto_detect_ticks_start = 0; \
202 (dp)->proto_detect_ticks_end = 0; \
203 (dp)->proto_detect_ticks_spent = 0; \
206#define PACKET_PROFILING_APP_STORE(dp, p) \
207 if (profiling_packets_enabled && (p)->profile != NULL) { \
208 if ((dp)->alproto < g_alproto_max) { \
209 (p)->profile->app[(dp)->alproto].ticks_spent += (dp)->ticks_spent; \
210 (p)->profile->proto_detect += (dp)->proto_detect_ticks_spent; \
214#define PACKET_PROFILING_DETECT_START(p, id) \
215 if (profiling_packets_enabled && (p)->profile != NULL) { \
216 if ((id) < PROF_DETECT_SIZE) { \
217 (p)->profile->detect[(id)].ticks_start = UtilCpuGetTicks(); \
221#define PACKET_PROFILING_DETECT_END(p, id) \
222 if (profiling_packets_enabled && (p)->profile != NULL) { \
223 if ((id) < PROF_DETECT_SIZE) { \
224 (p)->profile->detect[(id)].ticks_end = UtilCpuGetTicks();\
225 if ((p)->profile->detect[(id)].ticks_start != 0 && \
226 (p)->profile->detect[(id)].ticks_start < (p)->profile->detect[(id)].ticks_end) { \
227 (p)->profile->detect[(id)].ticks_spent += \
228 ((p)->profile->detect[(id)].ticks_end - (p)->profile->detect[(id)].ticks_start); \
233#define PACKET_PROFILING_LOGGER_START(p, id) \
234 if (profiling_packets_enabled && (p)->profile != NULL) { \
235 if ((id) < LOGGER_SIZE) { \
236 (p)->profile->logger[(id)].ticks_start = UtilCpuGetTicks(); \
240#define PACKET_PROFILING_LOGGER_END(p, id) \
241 if (profiling_packets_enabled && (p)->profile != NULL) { \
242 if ((id) < LOGGER_SIZE) { \
243 (p)->profile->logger[(id)].ticks_end = UtilCpuGetTicks();\
244 if ((p)->profile->logger[(id)].ticks_start != 0 && \
245 (p)->profile->logger[(id)].ticks_start < (p)->profile->logger[(id)].ticks_end) { \
246 (p)->profile->logger[(id)].ticks_spent += \
247 ((p)->profile->logger[(id)].ticks_end - (p)->profile->logger[(id)].ticks_start); \
252#define SGH_PROFILING_RECORD(det_ctx, sgh) \
253 if (profiling_sghs_enabled) { \
254 SCProfilingSghUpdateCounter((det_ctx), (sgh)); \
260#define PREFILTER_PROFILING_START(det_ctx) \
261 (det_ctx)->prefilter_bytes = 0; \
262 (det_ctx)->prefilter_bytes_called = 0; \
263 uint64_t profile_prefilter_start_ = 0; \
264 uint64_t profile_prefilter_end_ = 0; \
265 if (profiling_prefilter_enabled) { \
266 if (profiling_prefilter_entered > 0) { \
267 SCLogError("Re-entered profiling, exiting."); \
270 profiling_prefilter_entered++; \
271 profile_prefilter_start_ = UtilCpuGetTicks(); \
276#define PREFILTER_PROFILING_END(ctx, profile_id) \
277 if (profiling_prefilter_enabled && profiling_prefilter_entered) { \
278 profile_prefilter_end_ = UtilCpuGetTicks(); \
279 if (profile_prefilter_end_ > profile_prefilter_start_) \
280 SCProfilingPrefilterUpdateCounter((ctx), (profile_id), \
281 (profile_prefilter_end_ - profile_prefilter_start_), (ctx)->prefilter_bytes, \
282 (ctx)->prefilter_bytes_called); \
283 profiling_prefilter_entered--; \
286#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes) \
287 (det_ctx)->prefilter_bytes += (bytes); \
288 (det_ctx)->prefilter_bytes_called++
302 uint64_t bytes, uint64_t bytes_called);
320#define KEYWORD_PROFILING_SET_LIST(a,b)
321#define KEYWORD_PROFILING_START
322#define KEYWORD_PROFILING_END(a,b,c)
324#define PACKET_PROFILING_START(p)
325#define PACKET_PROFILING_RESTART(p)
326#define PACKET_PROFILING_END(p)
328#define PACKET_PROFILING_TMM_START(p, id)
329#define PACKET_PROFILING_TMM_END(p, id)
331#define PACKET_PROFILING_RESET(p)
333#define PACKET_PROFILING_APP_START(dp, id)
334#define PACKET_PROFILING_APP_END(d)
335#define PACKET_PROFILING_APP_RESET(dp)
336#define PACKET_PROFILING_APP_STORE(dp, p)
338#define PACKET_PROFILING_APP_PD_START(dp)
339#define PACKET_PROFILING_APP_PD_END(dp)
341#define PACKET_PROFILING_DETECT_START(p, id)
342#define PACKET_PROFILING_DETECT_END(p, id)
344#define PACKET_PROFILING_LOGGER_START(p, id)
345#define PACKET_PROFILING_LOGGER_END(p, id)
347#define SGH_PROFILING_RECORD(det_ctx, sgh)
349#define FLOWWORKER_PROFILING_START(p, id)
350#define FLOWWORKER_PROFILING_END(p, id)
352#define PREFILTER_PROFILING_START(ctx)
353#define PREFILTER_PROFILING_END(ctx, profile_id)
354#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)
369typedef struct SCProfileData_ {
376 uint64_t ticks_match;
377 uint64_t ticks_no_match;
380typedef struct SCProfileDetectCtx_ {
384 pthread_mutex_t data_m;
387void SCProfilingRulesGlobalInit(
void);
388void SCProfilingRuleDestroyCtx(
struct SCProfileDetectCtx_ *);
399#define RULE_PROFILING_START(p) \
400 uint64_t profile_rule_start_ = 0; \
401 uint64_t profile_rule_end_ = 0; \
402 if (profiling_rules_enabled && SCProfileRuleStart((p))) { \
403 if (profiling_rules_entered > 0) { \
404 FatalError("Re-entered profiling, exiting."); \
406 profiling_rules_entered++; \
407 profile_rule_start_ = UtilCpuGetTicks(); \
410#define RULE_PROFILING_END(ctx, r, m, p) \
411 if (profiling_rules_enabled && profiling_rules_entered) { \
412 profile_rule_end_ = UtilCpuGetTicks(); \
413 SCProfilingRuleUpdateCounter( \
414 ctx, r->profiling_id, profile_rule_end_ - profile_rule_start_, m); \
415 profiling_rules_entered--; \
416 BUG_ON(profiling_rules_entered < 0); \
421#define RULE_PROFILING_START(p)
422#define RULE_PROFILING_END(a, b, c, p)
main detection engine ctx
Container for matching data for a signature group.
void SCProfileRuleStartCollection(void)
void SCProfileRuleStopCollection(void)
int SCProfileRuleStart(Packet *p)
thread_local int profiling_rules_entered
void SCProfilingKeywordsGlobalInit(void)
void SCProfilingDestroy(void)
Free resources used by profiling.
int profiling_sghs_enabled
void SCProfilingSghUpdateCounter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh)
Update a rule counter.
void SCProfilingSghInitCounters(DetectEngineCtx *)
Register the keyword profiling counters.
void SCProfilingInit(void)
Initialize profiling.
void SCProfilingAddPacket(Packet *)
void SCProfilingKeywordDestroyCtx(DetectEngineCtx *)
PktProfiling * SCProfilePacketStart(void)
void SCProfilingPrefilterUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, uint64_t bytes, uint64_t bytes_called)
Update a rule counter.
void SCProfilingRegisterTests(void)
void SCProfilingSghDestroyCtx(DetectEngineCtx *)
int profiling_prefilter_enabled
void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match)
Update a rule counter.
thread_local int profiling_keyword_entered
void SCProfilingPrefilterInitCounters(DetectEngineCtx *)
Register the prefilter profiling counters.
int profiling_packets_enabled
void SCProfilingDump(void)
int profiling_keyword_enabled
void SCProfilingSghsGlobalInit(void)
thread_local int profiling_prefilter_entered
int profiling_rules_enabled
void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *)
void SCProfilingSghThreadSetup(struct SCProfileSghDetectCtx_ *, DetectEngineThreadCtx *)
void SCProfilingPrefilterThreadCleanup(DetectEngineThreadCtx *)
void SCProfilingKeywordInitCounters(DetectEngineCtx *)
Register the keyword profiling counters.
void SCProfilingPrintPacketProfile(Packet *)
void SCProfilingPrefilterDestroyCtx(DetectEngineCtx *)
void SCProfilingPrefilterGlobalInit(void)
void SCProfilingSghThreadCleanup(DetectEngineThreadCtx *)
void SCProfilingPrefilterThreadSetup(struct SCProfilePrefilterDetectCtx_ *, DetectEngineThreadCtx *)
void SCProfilingKeywordThreadSetup(struct SCProfileKeywordDetectCtx_ *, DetectEngineThreadCtx *)