mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
391 lines
19 KiB
C
391 lines
19 KiB
C
/* Copyright (C) 2007-2012 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>
|
|
*/
|
|
|
|
#ifndef __UTIL_PROFILE_H__
|
|
#define __UTIL_PROFILE_H__
|
|
|
|
#ifdef PROFILING
|
|
|
|
#include "detect.h"
|
|
#include "util-cpu.h"
|
|
#include "util-profiling-locks.h"
|
|
|
|
extern int profiling_rules_enabled;
|
|
extern int profiling_packets_enabled;
|
|
extern int profiling_sghs_enabled;
|
|
extern thread_local int profiling_rules_entered;
|
|
|
|
void SCProfilingPrintPacketProfile(Packet *);
|
|
void SCProfilingAddPacket(Packet *);
|
|
int SCProfileRuleStart(Packet *p);
|
|
|
|
#define RULE_PROFILING_START(p) \
|
|
uint64_t profile_rule_start_ = 0; \
|
|
uint64_t profile_rule_end_ = 0; \
|
|
if (profiling_rules_enabled && SCProfileRuleStart((p))) { \
|
|
if (profiling_rules_entered > 0) { \
|
|
SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \
|
|
exit(1); \
|
|
} \
|
|
profiling_rules_entered++; \
|
|
profile_rule_start_ = UtilCpuGetTicks(); \
|
|
}
|
|
|
|
#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); \
|
|
profiling_rules_entered--; \
|
|
}
|
|
|
|
extern int profiling_keyword_enabled;
|
|
extern thread_local int profiling_keyword_entered;
|
|
|
|
#define KEYWORD_PROFILING_SET_LIST(ctx, list) { \
|
|
(ctx)->keyword_perf_list = (list); \
|
|
}
|
|
|
|
#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--; \
|
|
}
|
|
|
|
PktProfiling *SCProfilePacketStart(void);
|
|
|
|
#define PACKET_PROFILING_START(p) \
|
|
if (profiling_packets_enabled) { \
|
|
(p)->profile = SCProfilePacketStart(); \
|
|
if ((p)->profile != NULL) \
|
|
(p)->profile->ticks_start = UtilCpuGetTicks(); \
|
|
}
|
|
|
|
#define PACKET_PROFILING_RESTART(p) \
|
|
if (profiling_packets_enabled) { \
|
|
if ((p)->profile != NULL) \
|
|
(p)->profile->ticks_start = UtilCpuGetTicks(); \
|
|
}
|
|
|
|
#define PACKET_PROFILING_END(p) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
(p)->profile->ticks_end = UtilCpuGetTicks(); \
|
|
SCProfilingAddPacket((p)); \
|
|
}
|
|
|
|
#ifdef PROFILE_LOCKING
|
|
#define PACKET_PROFILING_RESET_LOCKS do { \
|
|
mutex_lock_cnt = 0; \
|
|
mutex_lock_wait_ticks = 0; \
|
|
mutex_lock_contention = 0; \
|
|
spin_lock_cnt = 0; \
|
|
spin_lock_wait_ticks = 0; \
|
|
spin_lock_contention = 0; \
|
|
rww_lock_cnt = 0; \
|
|
rww_lock_wait_ticks = 0; \
|
|
rww_lock_contention = 0; \
|
|
rwr_lock_cnt = 0; \
|
|
rwr_lock_wait_ticks = 0; \
|
|
rwr_lock_contention = 0; \
|
|
locks_idx = 0; \
|
|
record_locks = 1;\
|
|
} while (0)
|
|
|
|
#define PACKET_PROFILING_COPY_LOCKS(p, id) do { \
|
|
(p)->profile->tmm[(id)].mutex_lock_cnt = mutex_lock_cnt; \
|
|
(p)->profile->tmm[(id)].mutex_lock_wait_ticks = mutex_lock_wait_ticks; \
|
|
(p)->profile->tmm[(id)].mutex_lock_contention = mutex_lock_contention; \
|
|
(p)->profile->tmm[(id)].spin_lock_cnt = spin_lock_cnt; \
|
|
(p)->profile->tmm[(id)].spin_lock_wait_ticks = spin_lock_wait_ticks; \
|
|
(p)->profile->tmm[(id)].spin_lock_contention = spin_lock_contention; \
|
|
(p)->profile->tmm[(id)].rww_lock_cnt = rww_lock_cnt; \
|
|
(p)->profile->tmm[(id)].rww_lock_wait_ticks = rww_lock_wait_ticks; \
|
|
(p)->profile->tmm[(id)].rww_lock_contention = rww_lock_contention; \
|
|
(p)->profile->tmm[(id)].rwr_lock_cnt = rwr_lock_cnt; \
|
|
(p)->profile->tmm[(id)].rwr_lock_wait_ticks = rwr_lock_wait_ticks; \
|
|
(p)->profile->tmm[(id)].rwr_lock_contention = rwr_lock_contention; \
|
|
record_locks = 0; \
|
|
SCProfilingAddPacketLocks((p)); \
|
|
} while(0)
|
|
#else
|
|
#define PACKET_PROFILING_RESET_LOCKS
|
|
#define PACKET_PROFILING_COPY_LOCKS(p, id)
|
|
#endif
|
|
|
|
#define PACKET_PROFILING_TMM_START(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < TMM_SIZE) { \
|
|
(p)->profile->tmm[(id)].ticks_start = UtilCpuGetTicks();\
|
|
PACKET_PROFILING_RESET_LOCKS; \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_TMM_END(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < TMM_SIZE) { \
|
|
PACKET_PROFILING_COPY_LOCKS((p), (id)); \
|
|
(p)->profile->tmm[(id)].ticks_end = UtilCpuGetTicks(); \
|
|
} \
|
|
}
|
|
|
|
#define FLOWWORKER_PROFILING_START(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < PROFILE_FLOWWORKER_SIZE) { \
|
|
(p)->profile->flowworker[(id)].ticks_start = UtilCpuGetTicks();\
|
|
} \
|
|
}
|
|
|
|
#define FLOWWORKER_PROFILING_END(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < PROFILE_FLOWWORKER_SIZE) { \
|
|
(p)->profile->flowworker[(id)].ticks_end = UtilCpuGetTicks(); \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_RESET(p) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
SCFree((p)->profile); \
|
|
(p)->profile = NULL; \
|
|
}
|
|
|
|
#define PACKET_PROFILING_APP_START(dp, id) \
|
|
if (profiling_packets_enabled) { \
|
|
(dp)->ticks_start = UtilCpuGetTicks(); \
|
|
(dp)->alproto = (id); \
|
|
}
|
|
|
|
#define PACKET_PROFILING_APP_END(dp, id) \
|
|
if (profiling_packets_enabled) { \
|
|
BUG_ON((id) != (dp)->alproto); \
|
|
(dp)->ticks_end = UtilCpuGetTicks(); \
|
|
if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \
|
|
(dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_APP_PD_START(dp) \
|
|
if (profiling_packets_enabled) { \
|
|
(dp)->proto_detect_ticks_start = UtilCpuGetTicks(); \
|
|
}
|
|
|
|
#define PACKET_PROFILING_APP_PD_END(dp) \
|
|
if (profiling_packets_enabled) { \
|
|
(dp)->proto_detect_ticks_end = UtilCpuGetTicks(); \
|
|
if ((dp)->proto_detect_ticks_start != 0 && (dp)->proto_detect_ticks_start < ((dp)->proto_detect_ticks_end)) { \
|
|
(dp)->proto_detect_ticks_spent = \
|
|
((dp)->proto_detect_ticks_end - (dp)->proto_detect_ticks_start); \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_APP_RESET(dp) \
|
|
if (profiling_packets_enabled) { \
|
|
(dp)->ticks_start = 0; \
|
|
(dp)->ticks_end = 0; \
|
|
(dp)->ticks_spent = 0; \
|
|
(dp)->alproto = 0; \
|
|
(dp)->proto_detect_ticks_start = 0; \
|
|
(dp)->proto_detect_ticks_end = 0; \
|
|
(dp)->proto_detect_ticks_spent = 0; \
|
|
}
|
|
|
|
#define PACKET_PROFILING_APP_STORE(dp, p) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((dp)->alproto < ALPROTO_MAX) { \
|
|
(p)->profile->app[(dp)->alproto].ticks_spent += (dp)->ticks_spent; \
|
|
(p)->profile->proto_detect += (dp)->proto_detect_ticks_spent; \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_DETECT_START(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < PROF_DETECT_SIZE) { \
|
|
(p)->profile->detect[(id)].ticks_start = UtilCpuGetTicks(); \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_DETECT_END(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < PROF_DETECT_SIZE) { \
|
|
(p)->profile->detect[(id)].ticks_end = UtilCpuGetTicks();\
|
|
if ((p)->profile->detect[(id)].ticks_start != 0 && \
|
|
(p)->profile->detect[(id)].ticks_start < (p)->profile->detect[(id)].ticks_end) { \
|
|
(p)->profile->detect[(id)].ticks_spent += \
|
|
((p)->profile->detect[(id)].ticks_end - (p)->profile->detect[(id)].ticks_start); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_LOGGER_START(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < LOGGER_SIZE) { \
|
|
(p)->profile->logger[(id)].ticks_start = UtilCpuGetTicks(); \
|
|
} \
|
|
}
|
|
|
|
#define PACKET_PROFILING_LOGGER_END(p, id) \
|
|
if (profiling_packets_enabled && (p)->profile != NULL) { \
|
|
if ((id) < LOGGER_SIZE) { \
|
|
(p)->profile->logger[(id)].ticks_end = UtilCpuGetTicks();\
|
|
if ((p)->profile->logger[(id)].ticks_start != 0 && \
|
|
(p)->profile->logger[(id)].ticks_start < (p)->profile->logger[(id)].ticks_end) { \
|
|
(p)->profile->logger[(id)].ticks_spent += \
|
|
((p)->profile->logger[(id)].ticks_end - (p)->profile->logger[(id)].ticks_start); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define SGH_PROFILING_RECORD(det_ctx, sgh) \
|
|
if (profiling_sghs_enabled) { \
|
|
SCProfilingSghUpdateCounter((det_ctx), (sgh)); \
|
|
}
|
|
|
|
extern int profiling_prefilter_enabled;
|
|
extern thread_local int profiling_prefilter_entered;
|
|
|
|
#define PREFILTER_PROFILING_START(det_ctx) \
|
|
(det_ctx)->prefilter_bytes = 0; \
|
|
(det_ctx)->prefilter_bytes_called = 0; \
|
|
uint64_t profile_prefilter_start_ = 0; \
|
|
uint64_t profile_prefilter_end_ = 0; \
|
|
if (profiling_prefilter_enabled) { \
|
|
if (profiling_prefilter_entered > 0) { \
|
|
SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \
|
|
abort(); \
|
|
} \
|
|
profiling_prefilter_entered++; \
|
|
profile_prefilter_start_ = UtilCpuGetTicks(); \
|
|
}
|
|
|
|
/* we allow this macro to be called if profiling_prefilter_entered == 0,
|
|
* so that we don't have to refactor some of the detection code. */
|
|
#define PREFILTER_PROFILING_END(ctx, profile_id) \
|
|
if (profiling_prefilter_enabled && profiling_prefilter_entered) { \
|
|
profile_prefilter_end_ = UtilCpuGetTicks(); \
|
|
if (profile_prefilter_end_ > profile_prefilter_start_) \
|
|
SCProfilingPrefilterUpdateCounter((ctx), (profile_id), \
|
|
(profile_prefilter_end_ - profile_prefilter_start_), (ctx)->prefilter_bytes, \
|
|
(ctx)->prefilter_bytes_called); \
|
|
profiling_prefilter_entered--; \
|
|
}
|
|
|
|
#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes) \
|
|
(det_ctx)->prefilter_bytes += (bytes); \
|
|
(det_ctx)->prefilter_bytes_called++
|
|
|
|
struct SCProfileDetectCtx_;
|
|
void SCProfilingRulesGlobalInit(void);
|
|
void SCProfilingRuleDestroyCtx(struct SCProfileDetectCtx_ *);
|
|
void SCProfilingRuleInitCounters(DetectEngineCtx *);
|
|
void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int);
|
|
void SCProfilingRuleThreadSetup(struct SCProfileDetectCtx_ *, DetectEngineThreadCtx *);
|
|
void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *);
|
|
|
|
void SCProfilingKeywordsGlobalInit(void);
|
|
void SCProfilingKeywordDestroyCtx(DetectEngineCtx *);//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 *);
|
|
|
|
struct SCProfilePrefilterDetectCtx_;
|
|
void SCProfilingPrefilterGlobalInit(void);
|
|
void SCProfilingPrefilterDestroyCtx(DetectEngineCtx *);
|
|
void SCProfilingPrefilterInitCounters(DetectEngineCtx *);
|
|
void SCProfilingPrefilterUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks,
|
|
uint64_t bytes, uint64_t bytes_called);
|
|
void SCProfilingPrefilterThreadSetup(struct SCProfilePrefilterDetectCtx_ *, DetectEngineThreadCtx *);
|
|
void SCProfilingPrefilterThreadCleanup(DetectEngineThreadCtx *);
|
|
|
|
void SCProfilingSghsGlobalInit(void);
|
|
void SCProfilingSghDestroyCtx(DetectEngineCtx *);
|
|
void SCProfilingSghInitCounters(DetectEngineCtx *);
|
|
void SCProfilingSghUpdateCounter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh);
|
|
void SCProfilingSghThreadSetup(struct SCProfileSghDetectCtx_ *, DetectEngineThreadCtx *);
|
|
void SCProfilingSghThreadCleanup(DetectEngineThreadCtx *);
|
|
|
|
void SCProfilingInit(void);
|
|
void SCProfilingDestroy(void);
|
|
void SCProfilingRegisterTests(void);
|
|
void SCProfilingDump(void);
|
|
|
|
#else
|
|
|
|
#define RULE_PROFILING_START(p)
|
|
#define RULE_PROFILING_END(a,b,c,p)
|
|
|
|
#define KEYWORD_PROFILING_SET_LIST(a,b)
|
|
#define KEYWORD_PROFILING_START
|
|
#define KEYWORD_PROFILING_END(a,b,c)
|
|
|
|
#define PACKET_PROFILING_START(p)
|
|
#define PACKET_PROFILING_RESTART(p)
|
|
#define PACKET_PROFILING_END(p)
|
|
|
|
#define PACKET_PROFILING_TMM_START(p, id)
|
|
#define PACKET_PROFILING_TMM_END(p, id)
|
|
|
|
#define PACKET_PROFILING_RESET(p)
|
|
|
|
#define PACKET_PROFILING_APP_START(dp, id)
|
|
#define PACKET_PROFILING_APP_END(dp, id)
|
|
#define PACKET_PROFILING_APP_RESET(dp)
|
|
#define PACKET_PROFILING_APP_STORE(dp, p)
|
|
|
|
#define PACKET_PROFILING_APP_PD_START(dp)
|
|
#define PACKET_PROFILING_APP_PD_END(dp)
|
|
|
|
#define PACKET_PROFILING_DETECT_START(p, id)
|
|
#define PACKET_PROFILING_DETECT_END(p, id)
|
|
|
|
#define PACKET_PROFILING_LOGGER_START(p, id)
|
|
#define PACKET_PROFILING_LOGGER_END(p, id)
|
|
|
|
#define SGH_PROFILING_RECORD(det_ctx, sgh)
|
|
|
|
#define FLOWWORKER_PROFILING_START(p, id)
|
|
#define FLOWWORKER_PROFILING_END(p, id)
|
|
|
|
#define PREFILTER_PROFILING_START(ctx)
|
|
#define PREFILTER_PROFILING_END(ctx, profile_id)
|
|
#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)
|
|
|
|
#endif /* PROFILING */
|
|
|
|
#endif /* ! __UTIL_PROFILE_H__ */
|