profiling: introduce per keyword profiling

Initial version of per keyword profiling. Prints stats about
how ofter a keyword was checked and what the costs were.
pull/613/head
Victor Julien 12 years ago
parent 210eede033
commit 97bfcac444

@ -319,6 +319,7 @@ util-privs.c util-privs.h \
util-profiling.c util-profiling.h \ util-profiling.c util-profiling.h \
util-profiling-locks.c util-profiling-locks.h \ util-profiling-locks.c util-profiling-locks.h \
util-profiling-rules.c \ util-profiling-rules.c \
util-profiling-keywords.c \
util-proto-name.c util-proto-name.h \ util-proto-name.c util-proto-name.h \
util-radix-tree.c util-radix-tree.h \ util-radix-tree.c util-radix-tree.h \
util-random.c util-random.h \ util-random.c util-random.h \

@ -52,6 +52,7 @@
#include "util-unittest.h" #include "util-unittest.h"
#include "util-unittest-helper.h" #include "util-unittest-helper.h"
#include "util-profiling.h"
/** /**
* \brief Run the actual payload match functions * \brief Run the actual payload match functions
@ -100,15 +101,18 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
uint8_t inspection_mode, void *data) uint8_t inspection_mode, void *data)
{ {
SCEnter(); SCEnter();
KEYWORD_PROFILING_START;
det_ctx->inspection_recursion_counter++; det_ctx->inspection_recursion_counter++;
if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) {
det_ctx->discontinue_matching = 1; det_ctx->discontinue_matching = 1;
KEYWORD_PROFILING_END(det_ctx, sm->type, 0);
SCReturnInt(0); SCReturnInt(0);
} }
if (sm == NULL || buffer_len == 0) { if (sm == NULL || buffer_len == 0) {
KEYWORD_PROFILING_END(det_ctx, sm->type, 0);
SCReturnInt(0); SCReturnInt(0);
} }
@ -316,6 +320,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
} }
SCLogDebug("content %"PRIu32, cd->id); SCLogDebug("content %"PRIu32, cd->id);
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
/* see if the next buffer keywords match. If not, we will /* see if the next buffer keywords match. If not, we will
* search for another occurence of this content and see * search for another occurence of this content and see
@ -387,6 +392,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
SCLogDebug("no relative match coming up, so this is a match"); SCLogDebug("no relative match coming up, so this is a match");
goto match; goto match;
} }
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
/* save it, in case we need to do a pcre match once again */ /* save it, in case we need to do a pcre match once again */
prev_offset = det_ctx->pcre_match_start_offset; prev_offset = det_ctx->pcre_match_start_offset;
@ -546,15 +552,18 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
} }
no_match: no_match:
KEYWORD_PROFILING_END(det_ctx, sm->type, 0);
SCReturnInt(0); SCReturnInt(0);
match: match:
/* this sigmatch matched, inspect the next one. If it was the last, /* this sigmatch matched, inspect the next one. If it was the last,
* the buffer portion of the signature matched. */ * the buffer portion of the signature matched. */
if (sm->next != NULL) { if (sm->next != NULL) {
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, sm->next, f, buffer, buffer_len, stream_start_offset, inspection_mode, data); int r = DetectEngineContentInspection(de_ctx, det_ctx, s, sm->next, f, buffer, buffer_len, stream_start_offset, inspection_mode, data);
SCReturnInt(r); SCReturnInt(r);
} else { } else {
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
SCReturnInt(1); SCReturnInt(1);
} }
} }

@ -53,6 +53,7 @@
#include "util-unittest.h" #include "util-unittest.h"
#include "util-unittest-helper.h" #include "util-unittest-helper.h"
#include "util-print.h" #include "util-print.h"
#include "util-profiling.h"
#ifdef OS_WIN32 #ifdef OS_WIN32
#include <winsock.h> #include <winsock.h>
@ -937,11 +938,13 @@ int IPOnlyMatchCompatSMs(ThreadVars *tv,
while (sm != NULL) { while (sm != NULL) {
BUG_ON(!(sigmatch_table[sm->type].flags & SIGMATCH_IPONLY_COMPAT)); BUG_ON(!(sigmatch_table[sm->type].flags & SIGMATCH_IPONLY_COMPAT));
KEYWORD_PROFILING_START;
if (sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm) > 0) { if (sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm) > 0) {
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
sm = sm->next; sm = sm->next;
continue; continue;
} }
KEYWORD_PROFILING_END(det_ctx, sm->type, 0);
return 0; return 0;
} }
@ -1079,7 +1082,9 @@ void IPOnlyMatchPacket(ThreadVars *tv,
SCLogDebug("running match functions, sm %p", sm); SCLogDebug("running match functions, sm %p", sm);
for ( ; sm != NULL; sm = sm->next) { for ( ; sm != NULL; sm = sm->next) {
KEYWORD_PROFILING_START;
(void)sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm); (void)sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
} }
} }
if (!(s->flags & SIG_FLAG_NOALERT)) { if (!(s->flags & SIG_FLAG_NOALERT)) {

@ -378,12 +378,16 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
smb_state = (SMBState *)alstate; smb_state = (SMBState *)alstate;
if (smb_state->dcerpc_present) { if (smb_state->dcerpc_present) {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm); AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
} }
} else { } else {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm); AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
} }
if (match == 0) if (match == 0)
@ -618,12 +622,16 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
smb_state = (SMBState *)alstate; smb_state = (SMBState *)alstate;
if (smb_state->dcerpc_present) { if (smb_state->dcerpc_present) {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm); AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
} }
} else { } else {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm); AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
} }
if (match == 0) if (match == 0)

@ -811,6 +811,10 @@ DetectEngineCtx *DetectEngineCtxInit(void) {
/* init iprep... ignore errors for now */ /* init iprep... ignore errors for now */
(void)SRepInit(de_ctx); (void)SRepInit(de_ctx);
#ifdef PROFILING
SCProfilingKeywordInitCounters(de_ctx);
#endif
return de_ctx; return de_ctx;
error: error:
return NULL; return NULL;
@ -836,6 +840,10 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx) {
SCProfilingRuleDestroyCtx(de_ctx->profile_ctx); SCProfilingRuleDestroyCtx(de_ctx->profile_ctx);
de_ctx->profile_ctx = NULL; de_ctx->profile_ctx = NULL;
} }
if (de_ctx->profile_keyword_ctx != NULL) {
SCProfilingKeywordDestroyCtx(de_ctx->profile_keyword_ctx);
de_ctx->profile_keyword_ctx = NULL;
}
#endif #endif
/* Normally the hashes are freed elsewhere, but /* Normally the hashes are freed elsewhere, but
@ -1204,6 +1212,7 @@ static TmEcode ThreadCtxDoInit (DetectEngineCtx *de_ctx, DetectEngineThreadCtx *
DetectEngineThreadCtxInitKeywords(de_ctx, det_ctx); DetectEngineThreadCtxInitKeywords(de_ctx, det_ctx);
#ifdef PROFILING #ifdef PROFILING
SCProfilingRuleThreadSetup(de_ctx->profile_ctx, det_ctx); SCProfilingRuleThreadSetup(de_ctx->profile_ctx, det_ctx);
SCProfilingKeywordThreadSetup(de_ctx->profile_keyword_ctx, det_ctx);
#endif #endif
SC_ATOMIC_INIT(det_ctx->so_far_used_by_detect); SC_ATOMIC_INIT(det_ctx->so_far_used_by_detect);
@ -1309,6 +1318,7 @@ TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data) {
#ifdef PROFILING #ifdef PROFILING
SCProfilingRuleThreadCleanup(det_ctx); SCProfilingRuleThreadCleanup(det_ctx);
SCProfilingKeywordThreadCleanup(det_ctx);
#endif #endif
DetectEngineIPOnlyThreadDeinit(&det_ctx->io_ctx); DetectEngineIPOnlyThreadDeinit(&det_ctx->io_ctx);

@ -613,7 +613,9 @@ int SigMatchSignaturesRunPostMatch(ThreadVars *tv,
SCLogDebug("running match functions, sm %p", sm); SCLogDebug("running match functions, sm %p", sm);
for ( ; sm != NULL; sm = sm->next) { for ( ; sm != NULL; sm = sm->next) {
KEYWORD_PROFILING_START;
(void)sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm); (void)sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
} }
} }
@ -1469,9 +1471,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SCLogDebug("running match functions, sm %p", sm); SCLogDebug("running match functions, sm %p", sm);
for ( ; sm != NULL; sm = sm->next) { for ( ; sm != NULL; sm = sm->next) {
KEYWORD_PROFILING_START;
if (sigmatch_table[sm->type].Match(th_v, det_ctx, p, s, sm) <= 0) { if (sigmatch_table[sm->type].Match(th_v, det_ctx, p, s, sm) <= 0) {
KEYWORD_PROFILING_END(det_ctx, sm->type, 0);
goto next; goto next;
} }
KEYWORD_PROFILING_END(det_ctx, sm->type, 1);
} }
} }

@ -730,6 +730,7 @@ typedef struct DetectEngineCtx_ {
#ifdef PROFILING #ifdef PROFILING
struct SCProfileDetectCtx_ *profile_ctx; struct SCProfileDetectCtx_ *profile_ctx;
struct SCProfileKeywordDetectCtx_ *profile_keyword_ctx;
#endif #endif
} DetectEngineCtx; } DetectEngineCtx;
@ -861,6 +862,7 @@ typedef struct DetectionEngineThreadCtx_ {
#ifdef PROFILING #ifdef PROFILING
struct SCProfileData_ *rule_perf_data; struct SCProfileData_ *rule_perf_data;
int rule_perf_data_size; int rule_perf_data_size;
struct SCProfileKeywordData_ *keyword_perf_data;
#endif #endif
} DetectEngineThreadCtx; } DetectEngineThreadCtx;

@ -1980,6 +1980,7 @@ int main(int argc, char **argv)
} }
#ifdef PROFILING #ifdef PROFILING
SCProfilingRulesGlobalInit(); SCProfilingRulesGlobalInit();
SCProfilingKeywordsGlobalInit();
SCProfilingInit(); SCProfilingInit();
#endif /* PROFILING */ #endif /* PROFILING */
SCReputationInitCtx(); SCReputationInitCtx();

@ -0,0 +1,292 @@
/* Copyright (C) 2007-2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Endace Technology Limited.
* \author Victor Julien <victor@inliniac.net>
*
* An API for rule profiling operations.
*/
#include "suricata-common.h"
#include "decode.h"
#include "detect.h"
#include "conf.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "util-byte.h"
#include "util-profiling.h"
#include "util-profiling-locks.h"
#ifdef PROFILING
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
/**
* Extra data for rule profiling.
*/
typedef struct SCProfileKeywordData_ {
uint64_t checks;
uint64_t matches;
uint64_t max;
uint64_t ticks_match;
uint64_t ticks_no_match;
} SCProfileKeywordData;
typedef struct SCProfileKeywordDetectCtx_ {
uint32_t id;
SCProfileKeywordData *data;
pthread_mutex_t data_m;
} SCProfileKeywordDetectCtx;
static int profiling_keywords_output_to_file = 0;
int profiling_keyword_enabled = 1;
__thread int profiling_keyword_entered = 0;
static char *profiling_file_name = "";
static const char *profiling_file_mode = "a";
void SCProfilingKeywordsGlobalInit(void) {
ConfNode *conf;
conf = ConfGetNode("profiling.keywords");
if (conf != NULL) {
if (ConfNodeChildValueIsTrue(conf, "enabled")) {
profiling_keyword_enabled = 1;
const char *filename = ConfNodeLookupChildValue(conf, "filename");
if (filename != NULL) {
char *log_dir;
log_dir = ConfigGetLogDirectory();
profiling_file_name = SCMalloc(PATH_MAX);
if (unlikely(profiling_file_name == NULL)) {
SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
exit(EXIT_FAILURE);
}
snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);
const char *v = ConfNodeLookupChildValue(conf, "append");
if (v == NULL || ConfValIsTrue(v)) {
profiling_file_mode = "a";
} else {
profiling_file_mode = "w";
}
profiling_keywords_output_to_file = 1;
}
}
}
}
void
SCProfilingKeywordDump(SCProfileKeywordDetectCtx *rules_ctx)
{
int i;
FILE *fp;
if (rules_ctx == NULL)
return;
struct timeval tval;
struct tm *tms;
if (profiling_keywords_output_to_file == 1) {
SCLogInfo("file %s mode %s", profiling_file_name, profiling_file_mode);
fp = fopen(profiling_file_name, profiling_file_mode);
if (fp == NULL) {
SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name,
strerror(errno));
return;
}
} else {
fp = stdout;
}
gettimeofday(&tval, NULL);
struct tm local_tm;
tms = SCLocalTime(tval.tv_sec, &local_tm);
fprintf(fp, " ----------------------------------------------"
"----------------------------\n");
fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- "
"%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900,
tms->tm_hour,tms->tm_min, tms->tm_sec);
fprintf(fp, " ----------------------------------------------"
"----------------------------\n");
fprintf(fp, " %-16s %-11s %-8s %-8s %-11s %-11s %-11s %-11s\n", "Keyword", "Ticks", "Checks", "Matches", "Max Ticks", "Avg", "Avg Match", "Avg No Match");
fprintf(fp, " ---------------- "
"----------- "
"-------- "
"-------- "
"----------- "
"----------- "
"----------- "
"----------- "
"\n");
for (i = 0; i < DETECT_TBLSIZE; i++) {
SCProfileKeywordData *d = &rules_ctx->data[i];
if (d == NULL || d->checks == 0)
continue;
uint64_t ticks = d->ticks_match + d->ticks_no_match;
double avgticks = 0;
double avgticks_match = 0;
double avgticks_no_match = 0;
if (ticks && d->checks) {
avgticks = (ticks / d->checks);
if (d->ticks_match && d->matches)
avgticks_match = (d->ticks_match / d->matches);
if (d->ticks_no_match && (d->checks - d->matches) != 0)
avgticks_no_match = (d->ticks_no_match / (d->checks - d->matches));
}
fprintf(fp,
" %-16s %-11"PRIu64" %-8"PRIu64" %-8"PRIu64" %-11"PRIu64" %-11.2f %-11.2f %-11.2f\n",
sigmatch_table[i].name,
ticks,
d->checks,
d->matches,
d->max,
avgticks,
avgticks_match,
avgticks_no_match);
}
fprintf(fp,"\n");
if (fp != stdout)
fclose(fp);
SCLogInfo("Done dumping keyword profiling data.");
}
/**
* \brief Update a rule counter.
*
* \param id The ID of this counter.
* \param ticks Number of CPU ticks for this rule.
* \param match Did the rule match?
*/
void
SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match)
{
if (det_ctx != NULL && det_ctx->keyword_perf_data != NULL && id < DETECT_TBLSIZE) {
SCProfileKeywordData *p = &det_ctx->keyword_perf_data[id];
p->checks++;
p->matches += match;
if (ticks > p->max)
p->max = ticks;
if (match == 1)
p->ticks_match += ticks;
else
p->ticks_no_match += ticks;
}
}
SCProfileKeywordDetectCtx *SCProfilingKeywordInitCtx(void) {
SCProfileKeywordDetectCtx *ctx = SCMalloc(sizeof(SCProfileKeywordDetectCtx));
if (ctx != NULL) {
memset(ctx, 0x00, sizeof(SCProfileKeywordDetectCtx));
if (pthread_mutex_init(&ctx->data_m, NULL) != 0) {
SCLogError(SC_ERR_MUTEX,
"Failed to initialize hash table mutex.");
exit(EXIT_FAILURE);
}
}
return ctx;
}
void SCProfilingKeywordDestroyCtx(SCProfileKeywordDetectCtx *ctx) {
SCLogInfo("ctx %p", ctx);
if (ctx != NULL) {
SCProfilingKeywordDump(ctx);
if (ctx->data != NULL)
SCFree(ctx->data);
pthread_mutex_destroy(&ctx->data_m);
SCFree(ctx);
}
}
void SCProfilingKeywordThreadSetup(SCProfileKeywordDetectCtx *ctx, DetectEngineThreadCtx *det_ctx) {
if (ctx == NULL)
return;
SCProfileKeywordData *a = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
if (a != NULL) {
memset(a, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
det_ctx->keyword_perf_data = a;
}
}
static void SCProfilingKeywordThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) {
if (de_ctx == NULL || de_ctx->profile_keyword_ctx == NULL ||
de_ctx->profile_keyword_ctx->data == NULL || det_ctx == NULL ||
det_ctx->keyword_perf_data == NULL)
return;
int i;
for (i = 0; i < DETECT_TBLSIZE; i++) {
de_ctx->profile_keyword_ctx->data[i].checks += det_ctx->keyword_perf_data[i].checks;
de_ctx->profile_keyword_ctx->data[i].matches += det_ctx->keyword_perf_data[i].matches;
de_ctx->profile_keyword_ctx->data[i].ticks_match += det_ctx->keyword_perf_data[i].ticks_match;
de_ctx->profile_keyword_ctx->data[i].ticks_no_match += det_ctx->keyword_perf_data[i].ticks_no_match;
if (det_ctx->keyword_perf_data[i].max > de_ctx->profile_keyword_ctx->data[i].max)
de_ctx->profile_keyword_ctx->data[i].max = det_ctx->keyword_perf_data[i].max;
}
}
void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *det_ctx) {
if (det_ctx == NULL || det_ctx->de_ctx == NULL || det_ctx->keyword_perf_data == NULL)
return;
pthread_mutex_lock(&det_ctx->de_ctx->profile_keyword_ctx->data_m);
SCProfilingKeywordThreadMerge(det_ctx->de_ctx, det_ctx);
pthread_mutex_unlock(&det_ctx->de_ctx->profile_keyword_ctx->data_m);
SCFree(det_ctx->keyword_perf_data);
det_ctx->keyword_perf_data = NULL;
}
/**
* \brief Register the keyword profiling counters.
*
* \param de_ctx The active DetectEngineCtx, used to get at the loaded rules.
*/
void
SCProfilingKeywordInitCounters(DetectEngineCtx *de_ctx)
{
de_ctx->profile_keyword_ctx = SCProfilingKeywordInitCtx();
BUG_ON(de_ctx->profile_keyword_ctx == NULL);
de_ctx->profile_keyword_ctx->data = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
BUG_ON(de_ctx->profile_keyword_ctx->data == NULL);
memset(de_ctx->profile_keyword_ctx->data, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE);
SCLogInfo("Registered %"PRIu32" keyword profiling counters.", DETECT_TBLSIZE);
}
#endif /* PROFILING */

@ -57,6 +57,30 @@ void SCProfilingAddPacket(Packet *);
profiling_rules_entered--; \ profiling_rules_entered--; \
} }
extern int profiling_keyword_enabled;
extern __thread int profiling_keyword_entered;
#define KEYWORD_PROFILING_START \
uint64_t profile_keyword_start_ = 0; \
uint64_t profile_keyword_end_ = 0; \
if (profiling_keyword_enabled) { \
if (profiling_keyword_entered > 0) { \
SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \
abort(); \
} \
profiling_keyword_entered++; \
profile_keyword_start_ = UtilCpuGetTicks(); \
}
/* we allow this macro to be called if profiling_keyword_entered == 0,
* so that we don't have to refactor some of the detection code. */
#define KEYWORD_PROFILING_END(ctx, type, m) \
if (profiling_keyword_enabled && profiling_keyword_entered) { \
profile_keyword_end_ = UtilCpuGetTicks(); \
SCProfilingKeywordUpdateCounter((ctx),(type),(profile_keyword_end_ - profile_keyword_start_),(m)); \
profiling_keyword_entered--; \
}
#define PACKET_PROFILING_START(p) \ #define PACKET_PROFILING_START(p) \
if (profiling_packets_enabled) { \ if (profiling_packets_enabled) { \
(p)->profile.ticks_start = UtilCpuGetTicks(); \ (p)->profile.ticks_start = UtilCpuGetTicks(); \
@ -200,10 +224,16 @@ void SCProfilingRulesGlobalInit(void);
void SCProfilingRuleDestroyCtx(struct SCProfileDetectCtx_ *); void SCProfilingRuleDestroyCtx(struct SCProfileDetectCtx_ *);
void SCProfilingRuleInitCounters(DetectEngineCtx *); void SCProfilingRuleInitCounters(DetectEngineCtx *);
void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int); void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int);
void SCProfilingRuleThreadSetup(struct SCProfileDetectCtx_ *, DetectEngineThreadCtx *); void SCProfilingRuleThreadSetup(struct SCProfileDetectCtx_ *, DetectEngineThreadCtx *);
void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *); void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *);
void SCProfilingKeywordsGlobalInit(void);
void SCProfilingKeywordDestroyCtx(struct SCProfileKeywordDetectCtx_ *);
void SCProfilingKeywordInitCounters(DetectEngineCtx *);
void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match);
void SCProfilingKeywordThreadSetup(struct SCProfileKeywordDetectCtx_ *, DetectEngineThreadCtx *);
void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *);
void SCProfilingInit(void); void SCProfilingInit(void);
void SCProfilingDestroy(void); void SCProfilingDestroy(void);
void SCProfilingRegisterTests(void); void SCProfilingRegisterTests(void);
@ -214,6 +244,9 @@ void SCProfilingDump(void);
#define RULE_PROFILING_START #define RULE_PROFILING_START
#define RULE_PROFILING_END(a,b,c) #define RULE_PROFILING_END(a,b,c)
#define KEYWORD_PROFILING_START
#define KEYWORD_PROFILING_END(a,b,c)
#define PACKET_PROFILING_START(p) #define PACKET_PROFILING_START(p)
#define PACKET_PROFILING_END(p) #define PACKET_PROFILING_END(p)

@ -1133,6 +1133,12 @@ profiling:
# Limit the number of items printed at exit. # Limit the number of items printed at exit.
limit: 100 limit: 100
# per keyword profiling
keywords:
enabled: yes
filename: keyword_perf.log
append: yes
# packet profiling # packet profiling
packets: packets:

Loading…
Cancel
Save