From 2c3a92a1c9ba357c448a0884ec4f482bf0414e6a Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 1 Feb 2014 15:58:58 +0100 Subject: [PATCH] profiling: conditional rule profiling Add support for conditional rule profiling. Currently only simple rate limiting is supported, but hardcoded to inspecting rules for each packet. --- src/decode.h | 1 + src/detect-engine-state.c | 8 ++++---- src/detect.c | 4 ++-- src/util-profiling.c | 17 +++++++++++++++++ src/util-profiling.h | 13 +++++++------ 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/decode.h b/src/decode.h index 4f3e1e0577..f17606086c 100644 --- a/src/decode.h +++ b/src/decode.h @@ -935,6 +935,7 @@ void AddressDebugPrint(Address *); #define PKT_IS_FRAGMENT (1<<19) /**< Packet is a fragment */ #define PKT_IS_INVALID (1<<20) +#define PKT_PROFILE (1<<21) /** \brief return 1 if the packet is a pseudo packet */ #define PKT_IS_PSEUDOPKT(p) ((p)->flags & PKT_PSEUDO_STREAM_END) diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 25f21e82e9..8d66764059 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -567,7 +567,7 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, inspect_flags = 0; match = 0; - RULE_PROFILING_START; + RULE_PROFILING_START(p); if (alproto_supports_txs) { FLOWLOCK_WRLOCK(f); @@ -576,7 +576,7 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, htp_state = (HtpState *)alstate; if (htp_state->conn == NULL) { FLOWLOCK_UNLOCK(f); - RULE_PROFILING_END(det_ctx, s, match); + RULE_PROFILING_END(det_ctx, s, match, p); goto end; } } @@ -585,7 +585,7 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id); if (inspect_tx == NULL) { FLOWLOCK_UNLOCK(f); - RULE_PROFILING_END(det_ctx, s, match); + RULE_PROFILING_END(det_ctx, s, match, p); goto end; } while (engine != NULL) { @@ -647,7 +647,7 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; } } - RULE_PROFILING_END(det_ctx, s, match); + RULE_PROFILING_END(det_ctx, s, match, p); if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) { diff --git a/src/detect.c b/src/detect.c index 454807fd56..476221539e 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1308,7 +1308,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh PACKET_PROFILING_DETECT_START(p, PROF_DETECT_RULES); /* inspect the sigs against the packet */ for (idx = 0; idx < det_ctx->match_array_cnt; idx++) { - RULE_PROFILING_START; + RULE_PROFILING_START(p); state_alert = 0; #ifdef PROFILING smatch = 0; @@ -1539,7 +1539,7 @@ next: DetectFlowvarProcessList(det_ctx, pflow); DetectReplaceFree(det_ctx->replist); det_ctx->replist = NULL; - RULE_PROFILING_END(det_ctx, s, smatch); + RULE_PROFILING_END(det_ctx, s, smatch, p); det_ctx->flags = 0; continue; diff --git a/src/util-profiling.c b/src/util-profiling.c index fdd927eca7..e4b047697e 100644 --- a/src/util-profiling.c +++ b/src/util-profiling.c @@ -854,6 +854,23 @@ PktProfiling *SCProfilePacketStart(void) { return NULL; } +/* see if we want to profile rules for this packet */ +int SCProfileRuleStart(Packet *p) { +#ifdef PROFILE_LOCKING + if (p->profile != NULL) { + p->flags |= PKT_PROFILE; + return 1; + } +#else + uint64_t sample = SC_ATOMIC_ADD(samples, 1); + if (sample % rate == 0) { + p->flags |= PKT_PROFILE; + return 1; + } +#endif + return 0; +} + #define CASE_CODE(E) case E: return #E /** diff --git a/src/util-profiling.h b/src/util-profiling.h index bfd5f57f81..763d8414ae 100644 --- a/src/util-profiling.h +++ b/src/util-profiling.h @@ -36,11 +36,12 @@ extern __thread int profiling_rules_entered; void SCProfilingPrintPacketProfile(Packet *); void SCProfilingAddPacket(Packet *); +int SCProfileRuleStart(Packet *p); -#define RULE_PROFILING_START \ +#define RULE_PROFILING_START(p) \ uint64_t profile_rule_start_ = 0; \ uint64_t profile_rule_end_ = 0; \ - if (profiling_rules_enabled) { \ + if (profiling_rules_enabled && SCProfileRuleStart((p))) { \ if (profiling_rules_entered > 0) { \ SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \ exit(1); \ @@ -49,8 +50,8 @@ void SCProfilingAddPacket(Packet *); profile_rule_start_ = UtilCpuGetTicks(); \ } -#define RULE_PROFILING_END(ctx, r, m) \ - if (profiling_rules_enabled) { \ +#define RULE_PROFILING_END(ctx, r, m, p) \ + if (profiling_rules_enabled && ((p)->flags & PKT_PROFILE)) { \ profile_rule_end_ = UtilCpuGetTicks(); \ SCProfilingRuleUpdateCounter(ctx, r->profiling_id, \ profile_rule_end_ - profile_rule_start_, m); \ @@ -250,8 +251,8 @@ void SCProfilingDump(void); #else -#define RULE_PROFILING_START -#define RULE_PROFILING_END(a,b,c) +#define RULE_PROFILING_START(p) +#define RULE_PROFILING_END(a,b,c,p) #define KEYWORD_PROFILING_SET_LIST(a,b) #define KEYWORD_PROFILING_START