suricata
util-profiling.h
Go to the documentation of this file.
1 /* Copyright (C) 2007-2012 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Endace Technology Limited.
22  * \author Victor Julien <victor@inliniac.net>
23  */
24 
25 #ifndef __UTIL_PROFILE_H__
26 #define __UTIL_PROFILE_H__
27 
28 #ifdef PROFILING
29 
30 #include "detect.h"
31 #include "util-cpu.h"
32 #include "util-profiling-locks.h"
33 
34 extern int profiling_rules_enabled;
35 extern int profiling_packets_enabled;
36 extern int profiling_sghs_enabled;
37 extern thread_local int profiling_rules_entered;
38 
42 
43 #define RULE_PROFILING_START(p) \
44  uint64_t profile_rule_start_ = 0; \
45  uint64_t profile_rule_end_ = 0; \
46  if (profiling_rules_enabled && SCProfileRuleStart((p))) { \
47  if (profiling_rules_entered > 0) { \
48  SCLogError("Re-entered profiling, exiting."); \
49  exit(1); \
50  } \
51  profiling_rules_entered++; \
52  profile_rule_start_ = UtilCpuGetTicks(); \
53  }
54 
55 #define RULE_PROFILING_END(ctx, r, m, p) \
56  if (profiling_rules_enabled && ((p)->flags & PKT_PROFILE)) { \
57  profile_rule_end_ = UtilCpuGetTicks(); \
58  SCProfilingRuleUpdateCounter(ctx, r->profiling_id, \
59  profile_rule_end_ - profile_rule_start_, m); \
60  profiling_rules_entered--; \
61  }
62 
63 extern int profiling_keyword_enabled;
64 extern thread_local int profiling_keyword_entered;
65 
66 #define KEYWORD_PROFILING_SET_LIST(ctx, list) { \
67  (ctx)->keyword_perf_list = (list); \
68 }
69 
70 #define KEYWORD_PROFILING_START \
71  uint64_t profile_keyword_start_ = 0; \
72  uint64_t profile_keyword_end_ = 0; \
73  if (profiling_keyword_enabled) { \
74  if (profiling_keyword_entered > 0) { \
75  SCLogError("Re-entered profiling, exiting."); \
76  abort(); \
77  } \
78  profiling_keyword_entered++; \
79  profile_keyword_start_ = UtilCpuGetTicks(); \
80  }
81 
82 /* we allow this macro to be called if profiling_keyword_entered == 0,
83  * so that we don't have to refactor some of the detection code. */
84 #define KEYWORD_PROFILING_END(ctx, type, m) \
85  if (profiling_keyword_enabled && profiling_keyword_entered) { \
86  profile_keyword_end_ = UtilCpuGetTicks(); \
87  SCProfilingKeywordUpdateCounter((ctx),(type),(profile_keyword_end_ - profile_keyword_start_),(m)); \
88  profiling_keyword_entered--; \
89  }
90 
92 
93 #define PACKET_PROFILING_START(p) \
94  if (profiling_packets_enabled) { \
95  (p)->profile = SCProfilePacketStart(); \
96  if ((p)->profile != NULL) \
97  (p)->profile->ticks_start = UtilCpuGetTicks(); \
98  }
99 
100 #define PACKET_PROFILING_RESTART(p) \
101  if (profiling_packets_enabled) { \
102  if ((p)->profile != NULL) \
103  (p)->profile->ticks_start = UtilCpuGetTicks(); \
104  }
105 
106 #define PACKET_PROFILING_END(p) \
107  if (profiling_packets_enabled && (p)->profile != NULL) { \
108  (p)->profile->ticks_end = UtilCpuGetTicks(); \
109  SCProfilingAddPacket((p)); \
110  }
111 
112 #ifdef PROFILE_LOCKING
113 #define PACKET_PROFILING_RESET_LOCKS do { \
114  mutex_lock_cnt = 0; \
115  mutex_lock_wait_ticks = 0; \
116  mutex_lock_contention = 0; \
117  spin_lock_cnt = 0; \
118  spin_lock_wait_ticks = 0; \
119  spin_lock_contention = 0; \
120  rww_lock_cnt = 0; \
121  rww_lock_wait_ticks = 0; \
122  rww_lock_contention = 0; \
123  rwr_lock_cnt = 0; \
124  rwr_lock_wait_ticks = 0; \
125  rwr_lock_contention = 0; \
126  locks_idx = 0; \
127  record_locks = 1;\
128  } while (0)
129 
130 #define PACKET_PROFILING_COPY_LOCKS(p, id) do { \
131  (p)->profile->tmm[(id)].mutex_lock_cnt = mutex_lock_cnt; \
132  (p)->profile->tmm[(id)].mutex_lock_wait_ticks = mutex_lock_wait_ticks; \
133  (p)->profile->tmm[(id)].mutex_lock_contention = mutex_lock_contention; \
134  (p)->profile->tmm[(id)].spin_lock_cnt = spin_lock_cnt; \
135  (p)->profile->tmm[(id)].spin_lock_wait_ticks = spin_lock_wait_ticks; \
136  (p)->profile->tmm[(id)].spin_lock_contention = spin_lock_contention; \
137  (p)->profile->tmm[(id)].rww_lock_cnt = rww_lock_cnt; \
138  (p)->profile->tmm[(id)].rww_lock_wait_ticks = rww_lock_wait_ticks; \
139  (p)->profile->tmm[(id)].rww_lock_contention = rww_lock_contention; \
140  (p)->profile->tmm[(id)].rwr_lock_cnt = rwr_lock_cnt; \
141  (p)->profile->tmm[(id)].rwr_lock_wait_ticks = rwr_lock_wait_ticks; \
142  (p)->profile->tmm[(id)].rwr_lock_contention = rwr_lock_contention; \
143  record_locks = 0; \
144  SCProfilingAddPacketLocks((p)); \
145  } while(0)
146 #else
147 #define PACKET_PROFILING_RESET_LOCKS
148 #define PACKET_PROFILING_COPY_LOCKS(p, id)
149 #endif
150 
151 #define PACKET_PROFILING_TMM_START(p, id) \
152  if (profiling_packets_enabled && (p)->profile != NULL) { \
153  if ((id) < TMM_SIZE) { \
154  (p)->profile->tmm[(id)].ticks_start = UtilCpuGetTicks();\
155  PACKET_PROFILING_RESET_LOCKS; \
156  } \
157  }
158 
159 #define PACKET_PROFILING_TMM_END(p, id) \
160  if (profiling_packets_enabled && (p)->profile != NULL) { \
161  if ((id) < TMM_SIZE) { \
162  PACKET_PROFILING_COPY_LOCKS((p), (id)); \
163  (p)->profile->tmm[(id)].ticks_end = UtilCpuGetTicks(); \
164  } \
165  }
166 
167 #define FLOWWORKER_PROFILING_START(p, id) \
168  if (profiling_packets_enabled && (p)->profile != NULL) { \
169  if ((id) < PROFILE_FLOWWORKER_SIZE) { \
170  (p)->profile->flowworker[(id)].ticks_start = UtilCpuGetTicks();\
171  } \
172  }
173 
174 #define FLOWWORKER_PROFILING_END(p, id) \
175  if (profiling_packets_enabled && (p)->profile != NULL) { \
176  if ((id) < PROFILE_FLOWWORKER_SIZE) { \
177  (p)->profile->flowworker[(id)].ticks_end = UtilCpuGetTicks(); \
178  } \
179  }
180 
181 #define PACKET_PROFILING_RESET(p) \
182  if (profiling_packets_enabled && (p)->profile != NULL) { \
183  SCFree((p)->profile); \
184  (p)->profile = NULL; \
185  }
186 
187 #define PACKET_PROFILING_APP_START(dp, id) \
188  if (profiling_packets_enabled) { \
189  (dp)->ticks_start = UtilCpuGetTicks(); \
190  (dp)->alproto = (id); \
191  }
192 
193 #define PACKET_PROFILING_APP_END(dp, id) \
194  if (profiling_packets_enabled) { \
195  BUG_ON((id) != (dp)->alproto); \
196  (dp)->ticks_end = UtilCpuGetTicks(); \
197  if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \
198  (dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \
199  } \
200  }
201 
202 #define PACKET_PROFILING_APP_PD_START(dp) \
203  if (profiling_packets_enabled) { \
204  (dp)->proto_detect_ticks_start = UtilCpuGetTicks(); \
205  }
206 
207 #define PACKET_PROFILING_APP_PD_END(dp) \
208  if (profiling_packets_enabled) { \
209  (dp)->proto_detect_ticks_end = UtilCpuGetTicks(); \
210  if ((dp)->proto_detect_ticks_start != 0 && (dp)->proto_detect_ticks_start < ((dp)->proto_detect_ticks_end)) { \
211  (dp)->proto_detect_ticks_spent = \
212  ((dp)->proto_detect_ticks_end - (dp)->proto_detect_ticks_start); \
213  } \
214  }
215 
216 #define PACKET_PROFILING_APP_RESET(dp) \
217  if (profiling_packets_enabled) { \
218  (dp)->ticks_start = 0; \
219  (dp)->ticks_end = 0; \
220  (dp)->ticks_spent = 0; \
221  (dp)->alproto = 0; \
222  (dp)->proto_detect_ticks_start = 0; \
223  (dp)->proto_detect_ticks_end = 0; \
224  (dp)->proto_detect_ticks_spent = 0; \
225  }
226 
227 #define PACKET_PROFILING_APP_STORE(dp, p) \
228  if (profiling_packets_enabled && (p)->profile != NULL) { \
229  if ((dp)->alproto < ALPROTO_MAX) { \
230  (p)->profile->app[(dp)->alproto].ticks_spent += (dp)->ticks_spent; \
231  (p)->profile->proto_detect += (dp)->proto_detect_ticks_spent; \
232  } \
233  }
234 
235 #define PACKET_PROFILING_DETECT_START(p, id) \
236  if (profiling_packets_enabled && (p)->profile != NULL) { \
237  if ((id) < PROF_DETECT_SIZE) { \
238  (p)->profile->detect[(id)].ticks_start = UtilCpuGetTicks(); \
239  } \
240  }
241 
242 #define PACKET_PROFILING_DETECT_END(p, id) \
243  if (profiling_packets_enabled && (p)->profile != NULL) { \
244  if ((id) < PROF_DETECT_SIZE) { \
245  (p)->profile->detect[(id)].ticks_end = UtilCpuGetTicks();\
246  if ((p)->profile->detect[(id)].ticks_start != 0 && \
247  (p)->profile->detect[(id)].ticks_start < (p)->profile->detect[(id)].ticks_end) { \
248  (p)->profile->detect[(id)].ticks_spent += \
249  ((p)->profile->detect[(id)].ticks_end - (p)->profile->detect[(id)].ticks_start); \
250  } \
251  } \
252  }
253 
254 #define PACKET_PROFILING_LOGGER_START(p, id) \
255  if (profiling_packets_enabled && (p)->profile != NULL) { \
256  if ((id) < LOGGER_SIZE) { \
257  (p)->profile->logger[(id)].ticks_start = UtilCpuGetTicks(); \
258  } \
259  }
260 
261 #define PACKET_PROFILING_LOGGER_END(p, id) \
262  if (profiling_packets_enabled && (p)->profile != NULL) { \
263  if ((id) < LOGGER_SIZE) { \
264  (p)->profile->logger[(id)].ticks_end = UtilCpuGetTicks();\
265  if ((p)->profile->logger[(id)].ticks_start != 0 && \
266  (p)->profile->logger[(id)].ticks_start < (p)->profile->logger[(id)].ticks_end) { \
267  (p)->profile->logger[(id)].ticks_spent += \
268  ((p)->profile->logger[(id)].ticks_end - (p)->profile->logger[(id)].ticks_start); \
269  } \
270  } \
271  }
272 
273 #define SGH_PROFILING_RECORD(det_ctx, sgh) \
274  if (profiling_sghs_enabled) { \
275  SCProfilingSghUpdateCounter((det_ctx), (sgh)); \
276  }
277 
278 extern int profiling_prefilter_enabled;
279 extern thread_local int profiling_prefilter_entered;
280 
281 #define PREFILTER_PROFILING_START(det_ctx) \
282  (det_ctx)->prefilter_bytes = 0; \
283  (det_ctx)->prefilter_bytes_called = 0; \
284  uint64_t profile_prefilter_start_ = 0; \
285  uint64_t profile_prefilter_end_ = 0; \
286  if (profiling_prefilter_enabled) { \
287  if (profiling_prefilter_entered > 0) { \
288  SCLogError("Re-entered profiling, exiting."); \
289  abort(); \
290  } \
291  profiling_prefilter_entered++; \
292  profile_prefilter_start_ = UtilCpuGetTicks(); \
293  }
294 
295 /* we allow this macro to be called if profiling_prefilter_entered == 0,
296  * so that we don't have to refactor some of the detection code. */
297 #define PREFILTER_PROFILING_END(ctx, profile_id) \
298  if (profiling_prefilter_enabled && profiling_prefilter_entered) { \
299  profile_prefilter_end_ = UtilCpuGetTicks(); \
300  if (profile_prefilter_end_ > profile_prefilter_start_) \
301  SCProfilingPrefilterUpdateCounter((ctx), (profile_id), \
302  (profile_prefilter_end_ - profile_prefilter_start_), (ctx)->prefilter_bytes, \
303  (ctx)->prefilter_bytes_called); \
304  profiling_prefilter_entered--; \
305  }
306 
307 #define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes) \
308  (det_ctx)->prefilter_bytes += (bytes); \
309  (det_ctx)->prefilter_bytes_called++
310 
311 struct SCProfileDetectCtx_;
312 void SCProfilingRulesGlobalInit(void);
315 void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int);
318 
320 void SCProfilingKeywordDestroyCtx(DetectEngineCtx *);//struct SCProfileKeywordDetectCtx_ *);
322 void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match);
325 
330 void SCProfilingPrefilterUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks,
331  uint64_t bytes, uint64_t bytes_called);
334 
335 void SCProfilingSghsGlobalInit(void);
341 
342 void SCProfilingInit(void);
343 void SCProfilingDestroy(void);
344 void SCProfilingRegisterTests(void);
345 void SCProfilingDump(void);
346 
347 #else
348 
349 #define RULE_PROFILING_START(p)
350 #define RULE_PROFILING_END(a,b,c,p)
351 
352 #define KEYWORD_PROFILING_SET_LIST(a,b)
353 #define KEYWORD_PROFILING_START
354 #define KEYWORD_PROFILING_END(a,b,c)
355 
356 #define PACKET_PROFILING_START(p)
357 #define PACKET_PROFILING_RESTART(p)
358 #define PACKET_PROFILING_END(p)
359 
360 #define PACKET_PROFILING_TMM_START(p, id)
361 #define PACKET_PROFILING_TMM_END(p, id)
362 
363 #define PACKET_PROFILING_RESET(p)
364 
365 #define PACKET_PROFILING_APP_START(dp, id)
366 #define PACKET_PROFILING_APP_END(dp, id)
367 #define PACKET_PROFILING_APP_RESET(dp)
368 #define PACKET_PROFILING_APP_STORE(dp, p)
369 
370 #define PACKET_PROFILING_APP_PD_START(dp)
371 #define PACKET_PROFILING_APP_PD_END(dp)
372 
373 #define PACKET_PROFILING_DETECT_START(p, id)
374 #define PACKET_PROFILING_DETECT_END(p, id)
375 
376 #define PACKET_PROFILING_LOGGER_START(p, id)
377 #define PACKET_PROFILING_LOGGER_END(p, id)
378 
379 #define SGH_PROFILING_RECORD(det_ctx, sgh)
380 
381 #define FLOWWORKER_PROFILING_START(p, id)
382 #define FLOWWORKER_PROFILING_END(p, id)
383 
384 #define PREFILTER_PROFILING_START(ctx)
385 #define PREFILTER_PROFILING_END(ctx, profile_id)
386 #define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)
387 
388 #endif /* PROFILING */
389 
390 #endif /* ! __UTIL_PROFILE_H__ */
SCProfilingRuleUpdateCounter
void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int)
Update a rule counter.
Definition: util-profiling-rules.c:549
profiling_rules_entered
thread_local int profiling_rules_entered
Definition: util-profiling.c:112
SCProfilingSghDestroyCtx
void SCProfilingSghDestroyCtx(DetectEngineCtx *)
Definition: util-profiling-rulegroups.c:301
SCProfilingRegisterTests
void SCProfilingRegisterTests(void)
Definition: util-profiling.c:1394
SCProfilingInit
void SCProfilingInit(void)
Initialize profiling.
Definition: util-profiling.c:135
PktProfiling_
Per pkt stats storage.
Definition: decode.h:376
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1395
SCProfileSghDetectCtx_
Definition: util-profiling-rulegroups.c:51
SCProfilingPrefilterGlobalInit
void SCProfilingPrefilterGlobalInit(void)
Definition: util-profiling-prefilter.c:60
profiling_prefilter_entered
thread_local int profiling_prefilter_entered
Definition: util-profiling-prefilter.c:56
SCProfilingRulesGlobalInit
void SCProfilingRulesGlobalInit(void)
Definition: util-profiling-rules.c:108
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
SCProfilePrefilterDetectCtx_
Definition: util-profiling-prefilter.c:47
SCProfilePacketStart
PktProfiling * SCProfilePacketStart(void)
Definition: util-profiling.c:1188
SCProfilingPrefilterThreadCleanup
void SCProfilingPrefilterThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-prefilter.c:281
SCProfilingKeywordUpdateCounter
void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match)
Update a rule counter.
Definition: util-profiling-keywords.c:213
SCProfileRuleStart
int SCProfileRuleStart(Packet *p)
Definition: util-profiling.c:1198
profiling_packets_enabled
int profiling_packets_enabled
Definition: util-profiling.c:96
SCProfilingDump
void SCProfilingDump(void)
Definition: util-profiling.c:289
SCProfilingKeywordThreadSetup
void SCProfilingKeywordThreadSetup(struct SCProfileKeywordDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-keywords.c:282
DetectEngineThreadCtx_
Definition: detect.h:1025
util-cpu.h
SCProfilingKeywordInitCounters
void SCProfilingKeywordInitCounters(DetectEngineCtx *)
Register the keyword profiling counters.
Definition: util-profiling-keywords.c:366
SCProfileKeywordDetectCtx_
Definition: util-profiling-keywords.c:48
SCProfilingPrintPacketProfile
void SCProfilingPrintPacketProfile(Packet *)
Definition: util-profiling.c:770
detect.h
SCProfilingRuleDestroyCtx
void SCProfilingRuleDestroyCtx(struct SCProfileDetectCtx_ *)
Definition: util-profiling-rules.c:579
profiling_keyword_entered
thread_local int profiling_keyword_entered
Definition: util-profiling-keywords.c:56
SCProfilingRuleThreadCleanup
void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-rules.c:621
SCProfilingPrefilterUpdateCounter
void SCProfilingPrefilterUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, uint64_t bytes, uint64_t bytes_called)
Update a rule counter.
Definition: util-profiling-prefilter.c:191
profiling_keyword_enabled
int profiling_keyword_enabled
Definition: util-profiling-keywords.c:55
SCProfilingPrefilterInitCounters
void SCProfilingPrefilterInitCounters(DetectEngineCtx *)
Register the prefilter profiling counters.
Definition: util-profiling-prefilter.c:300
Packet_
Definition: decode.h:428
SCProfilingAddPacket
void SCProfilingAddPacket(Packet *)
Definition: util-profiling.c:1098
SCProfilingKeywordThreadCleanup
void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-keywords.c:339
SCProfilingSghUpdateCounter
void SCProfilingSghUpdateCounter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh)
Update a rule counter.
Definition: util-profiling-rulegroups.c:258
SCProfilingSghsGlobalInit
void SCProfilingSghsGlobalInit(void)
Definition: util-profiling-rulegroups.c:63
profiling_sghs_enabled
int profiling_sghs_enabled
Definition: util-profiling-rulegroups.c:58
SCProfilingDestroy
void SCProfilingDestroy(void)
Free resources used by profiling.
Definition: util-profiling.c:263
SCProfilingKeywordDestroyCtx
void SCProfilingKeywordDestroyCtx(DetectEngineCtx *)
Definition: util-profiling-keywords.c:266
SCProfilingPrefilterDestroyCtx
void SCProfilingPrefilterDestroyCtx(DetectEngineCtx *)
Definition: util-profiling-prefilter.c:235
SCProfilingSghInitCounters
void SCProfilingSghInitCounters(DetectEngineCtx *)
Register the keyword profiling counters.
Definition: util-profiling-rulegroups.c:366
SCProfileDetectCtx_
Definition: util-profiling-rules.c:49
SCProfilingSghThreadSetup
void SCProfilingSghThreadSetup(struct SCProfileSghDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-rulegroups.c:310
SCProfilingSghThreadCleanup
void SCProfilingSghThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-rulegroups.c:347
SCProfilingKeywordsGlobalInit
void SCProfilingKeywordsGlobalInit(void)
Definition: util-profiling-keywords.c:60
profiling_rules_enabled
int profiling_rules_enabled
Definition: util-profiling-rules.c:75
SCProfilingRuleInitCounters
void SCProfilingRuleInitCounters(DetectEngineCtx *)
Register the rule profiling counters.
Definition: util-profiling-rules.c:641
util-profiling-locks.h
SCProfilingPrefilterThreadSetup
void SCProfilingPrefilterThreadSetup(struct SCProfilePrefilterDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-prefilter.c:244
profiling_prefilter_enabled
int profiling_prefilter_enabled
Definition: util-profiling-prefilter.c:55
SCProfilingRuleThreadSetup
void SCProfilingRuleThreadSetup(struct SCProfileDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-rules.c:590