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 
31 extern int profiling_rules_enabled;
32 extern int profiling_packets_enabled;
33 extern int profiling_sghs_enabled;
34 extern thread_local int profiling_rules_entered;
35 
39 
40 #define RULE_PROFILING_START(p) \
41  uint64_t profile_rule_start_ = 0; \
42  uint64_t profile_rule_end_ = 0; \
43  if (profiling_rules_enabled && SCProfileRuleStart((p))) { \
44  if (profiling_rules_entered > 0) { \
45  SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \
46  exit(1); \
47  } \
48  profiling_rules_entered++; \
49  profile_rule_start_ = UtilCpuGetTicks(); \
50  }
51 
52 #define RULE_PROFILING_END(ctx, r, m, p) \
53  if (profiling_rules_enabled && ((p)->flags & PKT_PROFILE)) { \
54  profile_rule_end_ = UtilCpuGetTicks(); \
55  SCProfilingRuleUpdateCounter(ctx, r->profiling_id, \
56  profile_rule_end_ - profile_rule_start_, m); \
57  profiling_rules_entered--; \
58  }
59 
60 extern int profiling_keyword_enabled;
61 extern thread_local int profiling_keyword_entered;
62 
63 #define KEYWORD_PROFILING_SET_LIST(ctx, list) { \
64  (ctx)->keyword_perf_list = (list); \
65 }
66 
67 #define KEYWORD_PROFILING_START \
68  uint64_t profile_keyword_start_ = 0; \
69  uint64_t profile_keyword_end_ = 0; \
70  if (profiling_keyword_enabled) { \
71  if (profiling_keyword_entered > 0) { \
72  SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \
73  abort(); \
74  } \
75  profiling_keyword_entered++; \
76  profile_keyword_start_ = UtilCpuGetTicks(); \
77  }
78 
79 /* we allow this macro to be called if profiling_keyword_entered == 0,
80  * so that we don't have to refactor some of the detection code. */
81 #define KEYWORD_PROFILING_END(ctx, type, m) \
82  if (profiling_keyword_enabled && profiling_keyword_entered) { \
83  profile_keyword_end_ = UtilCpuGetTicks(); \
84  SCProfilingKeywordUpdateCounter((ctx),(type),(profile_keyword_end_ - profile_keyword_start_),(m)); \
85  profiling_keyword_entered--; \
86  }
87 
89 
90 #define PACKET_PROFILING_START(p) \
91  if (profiling_packets_enabled) { \
92  (p)->profile = SCProfilePacketStart(); \
93  if ((p)->profile != NULL) \
94  (p)->profile->ticks_start = UtilCpuGetTicks(); \
95  }
96 
97 #define PACKET_PROFILING_RESTART(p) \
98  if (profiling_packets_enabled) { \
99  if ((p)->profile != NULL) \
100  (p)->profile->ticks_start = UtilCpuGetTicks(); \
101  }
102 
103 #define PACKET_PROFILING_END(p) \
104  if (profiling_packets_enabled && (p)->profile != NULL) { \
105  (p)->profile->ticks_end = UtilCpuGetTicks(); \
106  SCProfilingAddPacket((p)); \
107  }
108 
109 #ifdef PROFILE_LOCKING
110 #define PACKET_PROFILING_RESET_LOCKS do { \
111  mutex_lock_cnt = 0; \
112  mutex_lock_wait_ticks = 0; \
113  mutex_lock_contention = 0; \
114  spin_lock_cnt = 0; \
115  spin_lock_wait_ticks = 0; \
116  spin_lock_contention = 0; \
117  rww_lock_cnt = 0; \
118  rww_lock_wait_ticks = 0; \
119  rww_lock_contention = 0; \
120  rwr_lock_cnt = 0; \
121  rwr_lock_wait_ticks = 0; \
122  rwr_lock_contention = 0; \
123  locks_idx = 0; \
124  record_locks = 1;\
125  } while (0)
126 
127 #define PACKET_PROFILING_COPY_LOCKS(p, id) do { \
128  (p)->profile->tmm[(id)].mutex_lock_cnt = mutex_lock_cnt; \
129  (p)->profile->tmm[(id)].mutex_lock_wait_ticks = mutex_lock_wait_ticks; \
130  (p)->profile->tmm[(id)].mutex_lock_contention = mutex_lock_contention; \
131  (p)->profile->tmm[(id)].spin_lock_cnt = spin_lock_cnt; \
132  (p)->profile->tmm[(id)].spin_lock_wait_ticks = spin_lock_wait_ticks; \
133  (p)->profile->tmm[(id)].spin_lock_contention = spin_lock_contention; \
134  (p)->profile->tmm[(id)].rww_lock_cnt = rww_lock_cnt; \
135  (p)->profile->tmm[(id)].rww_lock_wait_ticks = rww_lock_wait_ticks; \
136  (p)->profile->tmm[(id)].rww_lock_contention = rww_lock_contention; \
137  (p)->profile->tmm[(id)].rwr_lock_cnt = rwr_lock_cnt; \
138  (p)->profile->tmm[(id)].rwr_lock_wait_ticks = rwr_lock_wait_ticks; \
139  (p)->profile->tmm[(id)].rwr_lock_contention = rwr_lock_contention; \
140  record_locks = 0; \
141  SCProfilingAddPacketLocks((p)); \
142  } while(0)
143 #else
144 #define PACKET_PROFILING_RESET_LOCKS
145 #define PACKET_PROFILING_COPY_LOCKS(p, id)
146 #endif
147 
148 #define PACKET_PROFILING_TMM_START(p, id) \
149  if (profiling_packets_enabled && (p)->profile != NULL) { \
150  if ((id) < TMM_SIZE) { \
151  (p)->profile->tmm[(id)].ticks_start = UtilCpuGetTicks();\
152  PACKET_PROFILING_RESET_LOCKS; \
153  } \
154  }
155 
156 #define PACKET_PROFILING_TMM_END(p, id) \
157  if (profiling_packets_enabled && (p)->profile != NULL) { \
158  if ((id) < TMM_SIZE) { \
159  PACKET_PROFILING_COPY_LOCKS((p), (id)); \
160  (p)->profile->tmm[(id)].ticks_end = UtilCpuGetTicks(); \
161  } \
162  }
163 
164 #define FLOWWORKER_PROFILING_START(p, id) \
165  if (profiling_packets_enabled && (p)->profile != NULL) { \
166  if ((id) < PROFILE_FLOWWORKER_SIZE) { \
167  (p)->profile->flowworker[(id)].ticks_start = UtilCpuGetTicks();\
168  } \
169  }
170 
171 #define FLOWWORKER_PROFILING_END(p, id) \
172  if (profiling_packets_enabled && (p)->profile != NULL) { \
173  if ((id) < PROFILE_FLOWWORKER_SIZE) { \
174  (p)->profile->flowworker[(id)].ticks_end = UtilCpuGetTicks(); \
175  } \
176  }
177 
178 #define PACKET_PROFILING_RESET(p) \
179  if (profiling_packets_enabled && (p)->profile != NULL) { \
180  SCFree((p)->profile); \
181  (p)->profile = NULL; \
182  }
183 
184 #define PACKET_PROFILING_APP_START(dp, id) \
185  if (profiling_packets_enabled) { \
186  (dp)->ticks_start = UtilCpuGetTicks(); \
187  (dp)->alproto = (id); \
188  }
189 
190 #define PACKET_PROFILING_APP_END(dp, id) \
191  if (profiling_packets_enabled) { \
192  BUG_ON((id) != (dp)->alproto); \
193  (dp)->ticks_end = UtilCpuGetTicks(); \
194  if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \
195  (dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \
196  } \
197  }
198 
199 #define PACKET_PROFILING_APP_PD_START(dp) \
200  if (profiling_packets_enabled) { \
201  (dp)->proto_detect_ticks_start = UtilCpuGetTicks(); \
202  }
203 
204 #define PACKET_PROFILING_APP_PD_END(dp) \
205  if (profiling_packets_enabled) { \
206  (dp)->proto_detect_ticks_end = UtilCpuGetTicks(); \
207  if ((dp)->proto_detect_ticks_start != 0 && (dp)->proto_detect_ticks_start < ((dp)->proto_detect_ticks_end)) { \
208  (dp)->proto_detect_ticks_spent = \
209  ((dp)->proto_detect_ticks_end - (dp)->proto_detect_ticks_start); \
210  } \
211  }
212 
213 #define PACKET_PROFILING_APP_RESET(dp) \
214  if (profiling_packets_enabled) { \
215  (dp)->ticks_start = 0; \
216  (dp)->ticks_end = 0; \
217  (dp)->ticks_spent = 0; \
218  (dp)->alproto = 0; \
219  (dp)->proto_detect_ticks_start = 0; \
220  (dp)->proto_detect_ticks_end = 0; \
221  (dp)->proto_detect_ticks_spent = 0; \
222  }
223 
224 #define PACKET_PROFILING_APP_STORE(dp, p) \
225  if (profiling_packets_enabled && (p)->profile != NULL) { \
226  if ((dp)->alproto < ALPROTO_MAX) { \
227  (p)->profile->app[(dp)->alproto].ticks_spent += (dp)->ticks_spent; \
228  (p)->profile->proto_detect += (dp)->proto_detect_ticks_spent; \
229  } \
230  }
231 
232 #define PACKET_PROFILING_DETECT_START(p, id) \
233  if (profiling_packets_enabled && (p)->profile != NULL) { \
234  if ((id) < PROF_DETECT_SIZE) { \
235  (p)->profile->detect[(id)].ticks_start = UtilCpuGetTicks(); \
236  } \
237  }
238 
239 #define PACKET_PROFILING_DETECT_END(p, id) \
240  if (profiling_packets_enabled && (p)->profile != NULL) { \
241  if ((id) < PROF_DETECT_SIZE) { \
242  (p)->profile->detect[(id)].ticks_end = UtilCpuGetTicks();\
243  if ((p)->profile->detect[(id)].ticks_start != 0 && \
244  (p)->profile->detect[(id)].ticks_start < (p)->profile->detect[(id)].ticks_end) { \
245  (p)->profile->detect[(id)].ticks_spent += \
246  ((p)->profile->detect[(id)].ticks_end - (p)->profile->detect[(id)].ticks_start); \
247  } \
248  } \
249  }
250 
251 #define PACKET_PROFILING_LOGGER_START(p, id) \
252  if (profiling_packets_enabled && (p)->profile != NULL) { \
253  if ((id) < LOGGER_SIZE) { \
254  (p)->profile->logger[(id)].ticks_start = UtilCpuGetTicks(); \
255  } \
256  }
257 
258 #define PACKET_PROFILING_LOGGER_END(p, id) \
259  if (profiling_packets_enabled && (p)->profile != NULL) { \
260  if ((id) < LOGGER_SIZE) { \
261  (p)->profile->logger[(id)].ticks_end = UtilCpuGetTicks();\
262  if ((p)->profile->logger[(id)].ticks_start != 0 && \
263  (p)->profile->logger[(id)].ticks_start < (p)->profile->logger[(id)].ticks_end) { \
264  (p)->profile->logger[(id)].ticks_spent += \
265  ((p)->profile->logger[(id)].ticks_end - (p)->profile->logger[(id)].ticks_start); \
266  } \
267  } \
268  }
269 
270 #define SGH_PROFILING_RECORD(det_ctx, sgh) \
271  if (profiling_sghs_enabled) { \
272  SCProfilingSghUpdateCounter((det_ctx), (sgh)); \
273  }
274 
275 extern int profiling_prefilter_enabled;
276 extern thread_local int profiling_prefilter_entered;
277 
278 #define PREFILTER_PROFILING_START(det_ctx) \
279  (det_ctx)->prefilter_bytes = 0; \
280  (det_ctx)->prefilter_bytes_called = 0; \
281  uint64_t profile_prefilter_start_ = 0; \
282  uint64_t profile_prefilter_end_ = 0; \
283  if (profiling_prefilter_enabled) { \
284  if (profiling_prefilter_entered > 0) { \
285  SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \
286  abort(); \
287  } \
288  profiling_prefilter_entered++; \
289  profile_prefilter_start_ = UtilCpuGetTicks(); \
290  }
291 
292 /* we allow this macro to be called if profiling_prefilter_entered == 0,
293  * so that we don't have to refactor some of the detection code. */
294 #define PREFILTER_PROFILING_END(ctx, profile_id) \
295  if (profiling_prefilter_enabled && profiling_prefilter_entered) { \
296  profile_prefilter_end_ = UtilCpuGetTicks(); \
297  if (profile_prefilter_end_ > profile_prefilter_start_) \
298  SCProfilingPrefilterUpdateCounter((ctx), (profile_id), \
299  (profile_prefilter_end_ - profile_prefilter_start_), (ctx)->prefilter_bytes, \
300  (ctx)->prefilter_bytes_called); \
301  profiling_prefilter_entered--; \
302  }
303 
304 #define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes) \
305  (det_ctx)->prefilter_bytes += (bytes); \
306  (det_ctx)->prefilter_bytes_called++
307 
308 void SCProfilingRulesGlobalInit(void);
311 void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int);
314 
316 void SCProfilingKeywordDestroyCtx(DetectEngineCtx *);//struct SCProfileKeywordDetectCtx_ *);
318 void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match);
321 
326 void SCProfilingPrefilterUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks,
327  uint64_t bytes, uint64_t bytes_called);
330 
331 void SCProfilingSghsGlobalInit(void);
337 
338 void SCProfilingInit(void);
339 void SCProfilingDestroy(void);
340 void SCProfilingRegisterTests(void);
341 void SCProfilingDump(void);
342 
343 #else
344 
345 #define RULE_PROFILING_START(p)
346 #define RULE_PROFILING_END(a,b,c,p)
347 
348 #define KEYWORD_PROFILING_SET_LIST(a,b)
349 #define KEYWORD_PROFILING_START
350 #define KEYWORD_PROFILING_END(a,b,c)
351 
352 #define PACKET_PROFILING_START(p)
353 #define PACKET_PROFILING_RESTART(p)
354 #define PACKET_PROFILING_END(p)
355 
356 #define PACKET_PROFILING_TMM_START(p, id)
357 #define PACKET_PROFILING_TMM_END(p, id)
358 
359 #define PACKET_PROFILING_RESET(p)
360 
361 #define PACKET_PROFILING_APP_START(dp, id)
362 #define PACKET_PROFILING_APP_END(dp, id)
363 #define PACKET_PROFILING_APP_RESET(dp)
364 #define PACKET_PROFILING_APP_STORE(dp, p)
365 
366 #define PACKET_PROFILING_APP_PD_START(dp)
367 #define PACKET_PROFILING_APP_PD_END(dp)
368 
369 #define PACKET_PROFILING_DETECT_START(p, id)
370 #define PACKET_PROFILING_DETECT_END(p, id)
371 
372 #define PACKET_PROFILING_LOGGER_START(p, id)
373 #define PACKET_PROFILING_LOGGER_END(p, id)
374 
375 #define SGH_PROFILING_RECORD(det_ctx, sgh)
376 
377 #define FLOWWORKER_PROFILING_START(p, id)
378 #define FLOWWORKER_PROFILING_END(p, id)
379 
380 #define PREFILTER_PROFILING_START(ctx)
381 #define PREFILTER_PROFILING_END(ctx, profile_id)
382 #define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)
383 
384 #endif /* PROFILING */
385 
386 #endif /* ! __UTIL_PROFILE_H__ */
SCProfilingRuleUpdateCounter
void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int)
Update a rule counter.
Definition: util-profiling-rules.c:558
profiling_rules_entered
thread_local int profiling_rules_entered
Definition: util-profiling.c:117
SCProfilingSghDestroyCtx
void SCProfilingSghDestroyCtx(DetectEngineCtx *)
Definition: util-profiling-rulegroups.c:311
SCProfilingRegisterTests
void SCProfilingRegisterTests(void)
Definition: util-profiling.c:1422
SCProfilingInit
void SCProfilingInit(void)
Initialize profiling.
Definition: util-profiling.c:140
PktProfiling_
Per pkt stats storage.
Definition: decode.h:384
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1403
SCProfileSghDetectCtx_
Definition: util-profiling-rulegroups.c:60
SCProfilingPrefilterGlobalInit
void SCProfilingPrefilterGlobalInit(void)
Definition: util-profiling-prefilter.c:69
profiling_prefilter_entered
thread_local int profiling_prefilter_entered
Definition: util-profiling-prefilter.c:65
SCProfilingRulesGlobalInit
void SCProfilingRulesGlobalInit(void)
Definition: util-profiling-rules.c:115
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
SCProfilePrefilterDetectCtx_
Definition: util-profiling-prefilter.c:56
SCProfilePacketStart
PktProfiling * SCProfilePacketStart(void)
Definition: util-profiling.c:1194
SCProfilingPrefilterThreadCleanup
void SCProfilingPrefilterThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-prefilter.c:292
SCProfilingKeywordUpdateCounter
void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match)
Update a rule counter.
Definition: util-profiling-keywords.c:224
SCProfileRuleStart
int SCProfileRuleStart(Packet *p)
Definition: util-profiling.c:1204
profiling_packets_enabled
int profiling_packets_enabled
Definition: util-profiling.c:101
SCProfilingDump
void SCProfilingDump(void)
Definition: util-profiling.c:294
SCProfilingKeywordThreadSetup
void SCProfilingKeywordThreadSetup(struct SCProfileKeywordDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-keywords.c:294
DetectEngineThreadCtx_
Definition: detect.h:1034
SCProfilingKeywordInitCounters
void SCProfilingKeywordInitCounters(DetectEngineCtx *)
Register the keyword profiling counters.
Definition: util-profiling-keywords.c:378
SCProfileKeywordDetectCtx_
Definition: util-profiling-keywords.c:58
SCProfilingPrintPacketProfile
void SCProfilingPrintPacketProfile(Packet *)
Definition: util-profiling.c:776
SCProfilingRuleDestroyCtx
void SCProfilingRuleDestroyCtx(struct SCProfileDetectCtx_ *)
Definition: util-profiling-rules.c:589
profiling_keyword_entered
thread_local int profiling_keyword_entered
Definition: util-profiling-keywords.c:66
SCProfilingRuleThreadCleanup
void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-rules.c:631
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:201
profiling_keyword_enabled
int profiling_keyword_enabled
Definition: util-profiling-keywords.c:65
SCProfilingPrefilterInitCounters
void SCProfilingPrefilterInitCounters(DetectEngineCtx *)
Register the prefilter profiling counters.
Definition: util-profiling-prefilter.c:311
Packet_
Definition: decode.h:434
SCProfilingAddPacket
void SCProfilingAddPacket(Packet *)
Definition: util-profiling.c:1104
SCProfilingKeywordThreadCleanup
void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-keywords.c:351
SCProfilingSghUpdateCounter
void SCProfilingSghUpdateCounter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh)
Update a rule counter.
Definition: util-profiling-rulegroups.c:268
SCProfilingSghsGlobalInit
void SCProfilingSghsGlobalInit(void)
Definition: util-profiling-rulegroups.c:72
profiling_sghs_enabled
int profiling_sghs_enabled
Definition: util-profiling-rulegroups.c:67
SCProfilingDestroy
void SCProfilingDestroy(void)
Free resources used by profiling.
Definition: util-profiling.c:268
SCProfilingKeywordDestroyCtx
void SCProfilingKeywordDestroyCtx(DetectEngineCtx *)
Definition: util-profiling-keywords.c:278
SCProfilingPrefilterDestroyCtx
void SCProfilingPrefilterDestroyCtx(DetectEngineCtx *)
Definition: util-profiling-prefilter.c:246
SCProfilingSghInitCounters
void SCProfilingSghInitCounters(DetectEngineCtx *)
Register the keyword profiling counters.
Definition: util-profiling-rulegroups.c:376
SCProfileDetectCtx_
Definition: util-profiling-rules.c:56
SCProfilingSghThreadSetup
void SCProfilingSghThreadSetup(struct SCProfileSghDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-rulegroups.c:320
SCProfilingSghThreadCleanup
void SCProfilingSghThreadCleanup(DetectEngineThreadCtx *)
Definition: util-profiling-rulegroups.c:357
SCProfilingKeywordsGlobalInit
void SCProfilingKeywordsGlobalInit(void)
Definition: util-profiling-keywords.c:70
profiling_rules_enabled
int profiling_rules_enabled
Definition: util-profiling-rules.c:82
SCProfilingRuleInitCounters
void SCProfilingRuleInitCounters(DetectEngineCtx *)
Register the rule profiling counters.
Definition: util-profiling-rules.c:651
SCProfilingPrefilterThreadSetup
void SCProfilingPrefilterThreadSetup(struct SCProfilePrefilterDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-prefilter.c:255
profiling_prefilter_enabled
int profiling_prefilter_enabled
Definition: util-profiling-prefilter.c:64
SCProfilingRuleThreadSetup
void SCProfilingRuleThreadSetup(struct SCProfileDetectCtx_ *, DetectEngineThreadCtx *)
Definition: util-profiling-rules.c:600