Add per packet profiling.

Per packet profiling uses tick based accounting. It has 2 outputs, a summary
and a csv file that contains per packet stats.

Stats per packet include:
 1) total ticks spent
 2) ticks spent per individual thread module
 3) "threading overhead" which is simply calculated by subtracting (2) of (1).

A number of changes were made to integrate the new code in a clean way:
a number of generic enums are now placed in tm-threads-common.h so we can
include them from any part of the engine.

Code depends on --enable-profiling just like the rule profiling code.

New yaml parameters:

profiling:
  # packet profiling
  packets:

    # Profiling can be disabled here, but it will still have a
    # performance impact if compiled in.
    enabled: yes
    filename: packet_stats.log
    append: yes

    # per packet csv output
    csv:

      # Output can be disabled here, but it will still have a
      # performance impact if compiled in.
      enabled: no
      filename: packet_stats.csv

Example output of summary stats:

IP ver   Proto   cnt        min      max          avg
------   -----   ------     ------   ----------   -------
 IPv4       6     19436      11448      5404365     32993
 IPv4     256         4      11511        49968     30575

Per Thread module stats:

Thread Module              IP ver   Proto   cnt        min      max          avg
------------------------   ------   -----   ------     ------   ----------   -------
TMM_DECODEPCAPFILE          IPv4       6     19434       1242        47889      1770
TMM_DETECT                  IPv4       6     19436       1107       137241      1504
TMM_ALERTFASTLOG            IPv4       6     19436         90         1323       155
TMM_ALERTUNIFIED2ALERT      IPv4       6     19436        108         1359       138
TMM_ALERTDEBUGLOG           IPv4       6     19436         90         1134       154
TMM_LOGHTTPLOG              IPv4       6     19436        414      5392089      7944
TMM_STREAMTCP               IPv4       6     19434        828      1299159     19438

The proto 256 is a counter for handling of pseudo/tunnel packets.

Example output of csv:

pcap_cnt,ipver,ipproto,total,TMM_DECODENFQ,TMM_VERDICTNFQ,TMM_RECEIVENFQ,TMM_RECEIVEPCAP,TMM_RECEIVEPCAPFILE,TMM_DECODEPCAP,TMM_DECODEPCAPFILE,TMM_RECEIVEPFRING,TMM_DECODEPFRING,TMM_DETECT,TMM_ALERTFASTLOG,TMM_ALERTFASTLOG4,TMM_ALERTFASTLOG6,TMM_ALERTUNIFIEDLOG,TMM_ALERTUNIFIEDALERT,TMM_ALERTUNIFIED2ALERT,TMM_ALERTPRELUDE,TMM_ALERTDEBUGLOG,TMM_ALERTSYSLOG,TMM_LOGDROPLOG,TMM_ALERTSYSLOG4,TMM_ALERTSYSLOG6,TMM_RESPONDREJECT,TMM_LOGHTTPLOG,TMM_LOGHTTPLOG4,TMM_LOGHTTPLOG6,TMM_PCAPLOG,TMM_STREAMTCP,TMM_DECODEIPFW,TMM_VERDICTIPFW,TMM_RECEIVEIPFW,TMM_RECEIVEERFFILE,TMM_DECODEERFFILE,TMM_RECEIVEERFDAG,TMM_DECODEERFDAG,threading
1,4,6,172008,0,0,0,0,0,0,47889,0,0,48582,1323,0,0,0,0,1359,0,1134,0,0,0,0,0,8028,0,0,0,49356,0,0,0,0,0,0,0,14337

First line of the file contains labels.

2 example gnuplot scripts added to plot the data.
remotes/origin/master-1.1.x
Victor Julien 14 years ago
parent 1bd1a62526
commit 820b0ded82

@ -0,0 +1,31 @@
#!/bin/bash
#
#
if [ "$1" = "" ]; then
echo "call with location of csv file."
exit 1;
fi
DRAW="dots"
gnuplot << EOF
set datafile separator ","
set terminal png size 1024,768
set output "$1.png"
set title "$1 ticks"
set key autotitle columnhead
set yrange [:]
set xrange [:]
set logscale y
plot "$1" using :4 with $DRAW, \
"" using :11 with $DRAW, \
"" using :14 with $DRAW, \
"" using :15 with $DRAW, \
"" using :20 with $DRAW, \
"" using :28 with $DRAW, \
"" using :32 with $DRAW, \
"" using :40 with $DRAW
EOF
RESULT=$?
if [ "$RESULT" = "0" ]; then
echo "PNG $1.png written"
fi

@ -0,0 +1,31 @@
#!/bin/bash
#
#
if [ "$1" = "" ]; then
echo "call with location of csv file."
exit 1;
fi
DRAW="lines"
gnuplot << EOF
set datafile separator ","
set terminal png size 1024,768
set output "$1.png"
set title "$1 ticks"
set key autotitle columnhead
set yrange [:]
set xrange [:]
set logscale y
plot "$1" using :4 with $DRAW, \
"" using :11 with $DRAW, \
"" using :14 with $DRAW, \
"" using :15 with $DRAW, \
"" using :20 with $DRAW, \
"" using :28 with $DRAW, \
"" using :32 with $DRAW, \
"" using :40 with $DRAW
EOF
RESULT=$?
if [ "$RESULT" = "0" ]; then
echo "PNG $1.png written"
fi

@ -207,7 +207,7 @@ util-vector.h \
tm-modules.c tm-modules.h \
tm-queues.c tm-queues.h \
tm-queuehandlers.c tm-queuehandlers.h \
tm-threads.c tm-threads.h \
tm-threads.c tm-threads.h tm-threads-common.h \
tmqh-simple.c tmqh-simple.h \
tmqh-nfq.c tmqh-nfq.h \
tmqh-packetpool.c tmqh-packetpool.h \

@ -26,6 +26,8 @@
*/
#include "suricata-common.h"
#include "suricata.h"
#include "debug.h"
#include "detect.h"
#include "flow.h"
@ -35,7 +37,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-print.h"

@ -36,7 +36,6 @@
#include "threads.h"
#include "tm-threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "util-debug.h"
#include "util-unittest.h"

@ -21,7 +21,6 @@
* \author Victor Julien <victor@inliniac.net>
*/
#include "tm-modules.h"
#ifndef __ALERT_FASTLOG_H__
#define __ALERT_FASTLOG_H__

@ -44,7 +44,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "util-time.h"

@ -32,7 +32,6 @@
#include "threads.h"
#include "tm-threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "detect.h"
#include "detect-parse.h"

@ -37,7 +37,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "util-time.h"

@ -37,7 +37,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "util-time.h"

@ -33,7 +33,7 @@
#include "pkt-var.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "alert-unified2-alert.h"

@ -31,7 +31,6 @@
#include "debug.h"
#include "decode.h"
#include "threads.h"
#include "tm-modules.h"
#include "threadvars.h"
#include "tm-threads.h"

@ -27,7 +27,6 @@
#include "suricata.h"
#include "counters.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "conf.h"
#include "util-time.h"

@ -51,7 +51,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "cuda-packet-batcher.h"
#include "conf.h"

@ -36,6 +36,7 @@
#include "util-debug.h"
#include "util-optimize.h"
#include "util-print.h"
#include "util-profiling.h"
/* Generic validation
*

@ -29,10 +29,11 @@
#include "util-debug.h"
#include "util-mem.h"
#include "app-layer-detect-proto.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-error.h"
#include "util-print.h"
#include "tmqh-packetpool.h"
#include "util-profiling.h"
void DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
uint8_t *pkt, uint16_t len, PacketQueue *pq, uint8_t proto)
@ -80,6 +81,7 @@ Packet *PacketGetFromQueueOrAlloc(void) {
SCLogDebug("allocated a new packet...");
}
PACKET_PROFILING_START(p);
return p;
}

@ -27,6 +27,8 @@
//#define DBG_THREADS
#define COUNTERS
#include "suricata-common.h"
#include "threadvars.h"
#include "source-nfq.h"
@ -262,6 +264,24 @@ typedef struct PktVar_ {
uint16_t value_len;
} PktVar;
#ifdef PROFILING
/** \brief Per TMM stats storage */
typedef struct PktProfilingTmmData_ {
uint64_t ticks_start;
uint64_t ticks_end;
} PktProfilingTmmData;
/** \brief Per pkt stats storage */
typedef struct PktProfiling_ {
uint64_t ticks_start;
uint64_t ticks_end;
PktProfilingTmmData tmm[TMM_SIZE];
} PktProfiling;
#endif /* PROFILING */
/* forward declartion since Packet struct definition requires this */
struct PacketQueue_;
@ -412,6 +432,10 @@ typedef struct Packet_
/* the extra 1 in the 1481, is to hold the no_of_matches from the mpm run */
uint16_t mpm_offsets[CUDA_MAX_PAYLOAD_SIZE + 1];
#endif
#ifdef PROFILING
PktProfiling profile;
#endif
} Packet;
#define DEFAULT_PACKET_SIZE 1500 + ETHERNET_HEADER_LEN
@ -577,6 +601,7 @@ typedef struct DecodeThreadVars_
(p)->prev = NULL; \
(p)->root = NULL; \
PACKET_RESET_CHECKSUMS((p)); \
PACKET_PROFILING_RESET((p)); \
} while (0)
#ifndef __SC_CUDA_SUPPORT__

@ -24,7 +24,7 @@
#ifndef __DETECT_ENGINE_MPM_H__
#define __DETECT_ENGINE_MPM_H__
#include "tm-modules.h"
#include "tm-threads.h"
#include "detect-content.h"
#include "detect-uricontent.h"

@ -61,7 +61,7 @@
#include "util-debug.h"
#include "util-var-name.h"
#include "tm-modules.h"
#include "tm-threads.h"
/**
* \brief Check if a certain signature has threshold option

@ -54,7 +54,8 @@
#include "util-unittest.h"
#include "util-var-name.h"
#include "tm-modules.h"
#include "tm-threads.h"
#define DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT 3000

@ -25,7 +25,7 @@
#define __DETECT_ENGINE_H__
#include "detect.h"
#include "tm-modules.h"
#include "tm-threads.h"
/* prototypes */
DetectEngineCtx *DetectEngineCtxInit(void);

@ -137,7 +137,7 @@
#include "detect-ssl-state.h"
#include "action-globals.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "pkt-var.h"

@ -31,7 +31,6 @@
#include "decode.h"
#include "conf.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "runmodes.h"
@ -220,6 +219,7 @@ static int FlowPrune (FlowQueue *q, struct timeval *ts)
#endif
return 0;
}
if (SCMutexTrylock(&f->m) != 0) {
SCLogDebug("cant lock 1");
SCMutexUnlock(&q->mutex_q);

@ -33,7 +33,6 @@
#include "threads.h"
#include "tm-threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "util-debug.h"
#include "decode-ipv4.h"

@ -23,16 +23,17 @@
* Implements http logging portion of the engine.
*/
#include <htp/dslib.h>
#include "suricata-common.h"
#include "debug.h"
#include "detect.h"
#include "pkt-var.h"
#include "conf.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-threads.h"
#include "util-print.h"
#include "util-unittest.h"
@ -42,7 +43,6 @@
#include "output.h"
#include "log-httplog.h"
#include "app-layer-htp.h"
#include <htp/dslib.h>
#include "app-layer.h"
#include "util-privs.h"

@ -37,7 +37,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "log-pcap.h"

@ -26,7 +26,7 @@
#include "suricata-common.h"
#include "flow.h"
#include "conf.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-error.h"
#include "util-debug.h"
#include "output.h"

@ -25,6 +25,7 @@
#define __OUTPUT_H__
#include "suricata.h"
#include "tm-threads.h"
#define DEFAULT_LOG_MODE_APPEND "yes"

@ -43,7 +43,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "action-globals.h"
#include "respond-reject.h"
#include "respond-reject-libnet11.h"

@ -32,7 +32,7 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "action-globals.h"
#include "respond-reject.h"

@ -24,6 +24,8 @@
#ifndef __RESPOND_REJECT_H__
#define __RESPOND_REJECT_H__
#include "tm-threads.h"
#define REJECT_DIR_SRC 0
#define REJECT_DIR_DST 1

@ -28,7 +28,7 @@
#include "suricata-common.h"
#include "suricata.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-privs.h"
#include "tmqh-packetpool.h"

@ -27,7 +27,7 @@
#include "suricata-common.h"
#include "suricata.h"
#include "tm-modules.h"
#include "tm-threads.h"
#define DAG_TYPE_ETH 2

@ -30,7 +30,6 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "source-ipfw.h"
#include "util-debug.h"

@ -31,13 +31,16 @@
#include "suricata.h"
#include "decode.h"
#include "packet-queue.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-threads.h"
#include "tm-queuehandlers.h"
#include "tmqh-packetpool.h"
#include "conf.h"
#include "config.h"
#include "conf-yaml-loader.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "source-nfq.h"
#include "source-nfq-prototypes.h"
#include "action-globals.h"
@ -46,7 +49,6 @@
#include "util-error.h"
#include "util-byte.h"
#include "util-privs.h"
#include "tmqh-packetpool.h"
#ifndef NFQ
/** Handle the case where no NFQ support is compiled in.

@ -36,7 +36,6 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "source-pcap-file.h"
#include "util-time.h"
#include "util-debug.h"
@ -124,6 +123,7 @@ void PcapFileCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt) {
p->ts.tv_usec = h->ts.tv_usec;
SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec);
p->datalink = pcap_g.datalink;
p->pcap_cnt = ++pcap_g.cnt;
ptv->pkts++;
ptv->bytes += h->caplen;

@ -36,7 +36,6 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "source-pcap.h"
#include "conf.h"

@ -39,7 +39,6 @@
#include "threads.h"
#include "threadvars.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "source-pfring.h"
#include "util-debug.h"

@ -36,7 +36,7 @@
#include "flow-util.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-pool.h"
#include "util-unittest.h"

@ -36,12 +36,12 @@
#include "flow.h"
#include "flow-util.h"
#include "threads.h"
#include "conf.h"
#include "conf-yaml-loader.h"
#include "threads.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-pool.h"
#include "util-unittest.h"

@ -162,6 +162,7 @@
#include <htp/htp.h>
#include "threads.h"
#include "tm-threads-common.h"
#include "util-debug.h"
#include "util-error.h"
#include "util-mem.h"

@ -66,7 +66,6 @@
#include "tm-queuehandlers.h"
#include "tm-queues.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "tmqh-flow.h"

@ -28,7 +28,6 @@
#include "util-unittest.h"
#include "debug.h"
#include "util-debug.h"
#include "util-unittest.h"
#include "threads.h"
#ifdef UNITTESTS /* UNIT TESTS */

@ -25,7 +25,7 @@
#include "suricata-common.h"
#include "packet-queue.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-debug.h"
#include "threads.h"
@ -133,3 +133,59 @@ void TmModuleRegisterTests(void) {
#endif /* UNITTESTS */
}
#define CASE_CODE(E) case E: return #E
/**
* \brief Maps the TmmId, to its string equivalent
*
* \param id tmm id
*
* \retval string equivalent for the tmm id
*/
const char * TmModuleTmmIdToString(TmmId id)
{
switch (id) {
CASE_CODE (TMM_DECODENFQ);
CASE_CODE (TMM_VERDICTNFQ);
CASE_CODE (TMM_RECEIVENFQ);
CASE_CODE (TMM_RECEIVEPCAP);
CASE_CODE (TMM_RECEIVEPCAPFILE);
CASE_CODE (TMM_DECODEPCAP);
CASE_CODE (TMM_DECODEPCAPFILE);
CASE_CODE (TMM_RECEIVEPFRING);
CASE_CODE (TMM_DECODEPFRING);
CASE_CODE (TMM_DETECT);
CASE_CODE (TMM_ALERTFASTLOG);
CASE_CODE (TMM_ALERTFASTLOG4);
CASE_CODE (TMM_ALERTFASTLOG6);
CASE_CODE (TMM_ALERTUNIFIEDLOG);
CASE_CODE (TMM_ALERTUNIFIEDALERT);
CASE_CODE (TMM_ALERTUNIFIED2ALERT);
CASE_CODE (TMM_ALERTPRELUDE);
CASE_CODE (TMM_ALERTDEBUGLOG);
CASE_CODE (TMM_ALERTSYSLOG);
CASE_CODE (TMM_LOGDROPLOG);
CASE_CODE (TMM_ALERTSYSLOG4);
CASE_CODE (TMM_ALERTSYSLOG6);
CASE_CODE (TMM_RESPONDREJECT);
CASE_CODE (TMM_LOGHTTPLOG);
CASE_CODE (TMM_LOGHTTPLOG4);
CASE_CODE (TMM_LOGHTTPLOG6);
CASE_CODE (TMM_PCAPLOG);
CASE_CODE (TMM_STREAMTCP);
CASE_CODE (TMM_DECODEIPFW);
CASE_CODE (TMM_VERDICTIPFW);
CASE_CODE (TMM_RECEIVEIPFW);
#ifdef __SC_CUDA_SUPPORT__
CASE_CODE (TMM_CUDA_MPM_B2G);
CASE_CODE (TMM_CUDA_PACKET_BATCHER);
#endif
CASE_CODE (TMM_RECEIVEERFFILE);
CASE_CODE (TMM_DECODEERFFILE);
CASE_CODE (TMM_RECEIVEERFDAG);
CASE_CODE (TMM_DECODEERFDAG);
default:
return "UNKNOWN";
}
}

@ -24,14 +24,9 @@
#ifndef __TM_MODULES_H__
#define __TM_MODULES_H__
#include "tm-threads-common.h"
#include "threadvars.h"
/*Error codes for the thread modules*/
typedef enum {
TM_ECODE_OK = 0, /**< Thread module exits OK*/
TM_ECODE_FAILED, /**< Thread module exits due to failure*/
}TmEcode;
typedef struct TmModule_ {
char *name;
@ -51,49 +46,6 @@ typedef struct TmModule_ {
the given TmModule */
} TmModule;
enum {
TMM_DECODENFQ,
TMM_VERDICTNFQ,
TMM_RECEIVENFQ,
TMM_RECEIVEPCAP,
TMM_RECEIVEPCAPFILE,
TMM_DECODEPCAP,
TMM_DECODEPCAPFILE,
TMM_RECEIVEPFRING,
TMM_DECODEPFRING,
TMM_DETECT,
TMM_ALERTFASTLOG,
TMM_ALERTFASTLOG4,
TMM_ALERTFASTLOG6,
TMM_ALERTUNIFIEDLOG,
TMM_ALERTUNIFIEDALERT,
TMM_ALERTUNIFIED2ALERT,
TMM_ALERTPRELUDE,
TMM_ALERTDEBUGLOG,
TMM_ALERTSYSLOG,
TMM_LOGDROPLOG,
TMM_ALERTSYSLOG4,
TMM_ALERTSYSLOG6,
TMM_RESPONDREJECT,
TMM_LOGHTTPLOG,
TMM_LOGHTTPLOG4,
TMM_LOGHTTPLOG6,
TMM_PCAPLOG,
TMM_STREAMTCP,
TMM_DECODEIPFW,
TMM_VERDICTIPFW,
TMM_RECEIVEIPFW,
#ifdef __SC_CUDA_SUPPORT__
TMM_CUDA_MPM_B2G,
TMM_CUDA_PACKET_BATCHER,
#endif
TMM_RECEIVEERFFILE,
TMM_DECODEERFFILE,
TMM_RECEIVEERFDAG,
TMM_DECODEERFDAG,
TMM_SIZE,
};
TmModule tmm_modules[TMM_SIZE];
/** Global structure for Output Context */
@ -144,6 +96,7 @@ TmModule *TmModuleGetByName(char *name);
TmEcode TmModuleRegister(char *name, int (*module_func)(ThreadVars *, Packet *, void *));
void TmModuleDebugList(void);
void TmModuleRegisterTests(void);
const char * TmModuleTmmIdToString(TmmId id);
#endif /* __TM_MODULES_H__ */

@ -0,0 +1,90 @@
/* Copyright (C) 2007-2011 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 Victor Julien <victor@inliniac.net>
* \author Anoop Saldanha <poonaatsoc@gmail.com>
*/
#ifndef __TM_THREADS_COMMON_H__
#define __TM_THREADS_COMMON_H__
/** \brief Thread Model Module id's.
*
* \note anything added here should also be added to TmModuleTmmIdToString
* in tm-modules.c
*/
typedef enum {
TMM_DECODENFQ,
TMM_VERDICTNFQ,
TMM_RECEIVENFQ,
TMM_RECEIVEPCAP,
TMM_RECEIVEPCAPFILE,
TMM_DECODEPCAP,
TMM_DECODEPCAPFILE,
TMM_RECEIVEPFRING,
TMM_DECODEPFRING,
TMM_DETECT,
TMM_ALERTFASTLOG,
TMM_ALERTFASTLOG4,
TMM_ALERTFASTLOG6,
TMM_ALERTUNIFIEDLOG,
TMM_ALERTUNIFIEDALERT,
TMM_ALERTUNIFIED2ALERT,
TMM_ALERTPRELUDE,
TMM_ALERTDEBUGLOG,
TMM_ALERTSYSLOG,
TMM_LOGDROPLOG,
TMM_ALERTSYSLOG4,
TMM_ALERTSYSLOG6,
TMM_RESPONDREJECT,
TMM_LOGHTTPLOG,
TMM_LOGHTTPLOG4,
TMM_LOGHTTPLOG6,
TMM_PCAPLOG,
TMM_STREAMTCP,
TMM_DECODEIPFW,
TMM_VERDICTIPFW,
TMM_RECEIVEIPFW,
#ifdef __SC_CUDA_SUPPORT__
TMM_CUDA_MPM_B2G,
TMM_CUDA_PACKET_BATCHER,
#endif
TMM_RECEIVEERFFILE,
TMM_DECODEERFFILE,
TMM_RECEIVEERFDAG,
TMM_DECODEERFDAG,
TMM_SIZE,
} TmmId;
/*Error codes for the thread modules*/
typedef enum {
TM_ECODE_OK = 0, /**< Thread module exits OK*/
TM_ECODE_FAILED, /**< Thread module exits due to failure*/
} TmEcode;
/* ThreadVars type */
enum {
TVT_PPT,
TVT_MGMT,
TVT_MAX,
};
#endif /* __TM_THREADS_COMMON_H__ */

@ -32,7 +32,6 @@
#include "threadvars.h"
#include "tm-queues.h"
#include "tm-queuehandlers.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "tmqh-packetpool.h"
#include "threads.h"
@ -42,6 +41,7 @@
#include "util-privs.h"
#include "util-cpu.h"
#include "util-optimize.h"
#include "util-profiling.h"
#ifdef OS_FREEBSD
#include <sched.h>
@ -425,11 +425,16 @@ TmEcode TmThreadsSlotVarRun(ThreadVars *tv, Packet *p,
Packet *extra_p;
for (s = slot; s != NULL; s = s->slot_next) {
PACKET_PROFILING_TMM_START(p, s->tm_module_id);
if (unlikely(s->id == 0)) {
r = s->SlotFunc(tv, p, s->slot_data, &s->slot_pre_pq, &s->slot_post_pq);
} else {
r = s->SlotFunc(tv, p, s->slot_data, &s->slot_pre_pq, NULL);
}
PACKET_PROFILING_TMM_END(p, s->tm_module_id);
/* handle error */
if (unlikely(r == TM_ECODE_FAILED)) {
/* Encountered error. Return packets to packetpool and return */
@ -791,6 +796,19 @@ void TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, void *data)
}
}
#ifdef PROFILING
TmModule *prof_tm;
int prof_tm_id = 0;
for (prof_tm_id = 0; prof_tm_id < TMM_SIZE; prof_tm_id++) {
prof_tm = &tmm_modules[prof_tm_id];
if (prof_tm == tm) {
slot->tm_module_id = prof_tm_id;
break;
}
}
#endif
return;
}

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2011 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
@ -25,15 +25,9 @@
#ifndef __TM_THREADS_H__
#define __TM_THREADS_H__
#include "tm-threads-common.h"
#include "tm-modules.h"
/* ThreadVars type */
enum {
TVT_PPT,
TVT_MGMT,
TVT_MAX,
};
typedef struct TmSlot_ {
/* function pointers */
TmEcode (*SlotFunc)(ThreadVars *, Packet *, void *, PacketQueue *,
@ -64,6 +58,10 @@ typedef struct TmSlot_ {
/* linked list, only used when you have multiple slots(used by TmVarSlot) */
struct TmSlot_ *slot_next;
#ifdef PROFILING
int tm_module_id;
#endif
} TmSlot;
extern ThreadVars *tv_root[TVT_MAX];

@ -48,6 +48,7 @@
#include "util-ringbuffer.h"
#include "util-debug.h"
#include "util-error.h"
#include "util-profiling.h"
static RingBuffer16 *ringbuffer = NULL;
/**
@ -154,6 +155,8 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
* by the tunnel packets, and we will enqueue it
* when we handle them */
SET_TUNNEL_PKT_VERDICTED(p);
PACKET_PROFILING_END(p);
SCReturn;
}
} else {
@ -217,6 +220,8 @@ void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
p->ext_pkt = NULL;
}
PACKET_PROFILING_END(p);
SCLogDebug("getting rid of tunnel pkt... alloc'd %s (root %p)", p->flags & PKT_ALLOC ? "true" : "false", p->root);
if (p->flags & PKT_ALLOC) {
PACKET_CLEANUP(p);

@ -37,7 +37,6 @@
#include "tm-queuehandlers.h"
#include "tm-queues.h"
#include "tm-modules.h"
#include "tm-threads.h"
#include "util-unittest.h"

@ -33,7 +33,6 @@
#include "util-print.h"
#include "threadvars.h"
#include "tm-modules.h"
#include "util-error.h"
#include "util-debug.h"

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2011 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
@ -19,6 +19,7 @@
* \file
*
* \author Endace Technology Limited.
* \author Victor Julien <victor@inliniac.net>
*
* An API for profiling operations.
*
@ -26,9 +27,13 @@
*/
#include "suricata-common.h"
#include "detect.h"
#include "counters.h"
#include "conf.h"
#include "tm-threads.h"
#include "util-unittest.h"
#include "util-byte.h"
#include "util-profiling.h"
@ -61,6 +66,9 @@ static uint32_t profiling_rules_limit = UINT32_MAX;
static SCPerfContext rules_ctx;
static SCPerfCounterArray *rules_pca;
static SCMutex packet_profile_lock;
static FILE *packet_profile_csv_fp = NULL;
/**
* Extra data for rule profiling.
*/
@ -74,6 +82,19 @@ typedef struct SCProfileData_ {
} SCProfileData;
SCProfileData rules_profile_data[0xffff];
typedef struct SCProfilePacketData_ {
uint32_t min;
uint32_t max;
uint64_t tot;
uint32_t cnt;
} SCProfilePacketData;
SCProfilePacketData packet_profile_data4[257]; /**< all proto's + tunnel */
SCProfilePacketData packet_profile_data6[257]; /**< all proto's + tunnel */
/* each module, each proto */
SCProfilePacketData packet_profile_tmm_data4[TMM_SIZE][257];
SCProfilePacketData packet_profile_tmm_data6[TMM_SIZE][257];
/**
* Used for generating the summary data to print.
*/
@ -93,15 +114,24 @@ typedef struct SCProfileSummary_ {
} SCProfileSummary;
int profiling_rules_enabled = 0;
int profiling_packets_enabled = 0;
int profiling_packets_csv_enabled = 0;
int profiling_output_to_file = 0;
int profiling_packets_output_to_file = 0;
char *profiling_file_name;
char *profiling_packets_file_name;
char *profiling_csv_file_name;
const char *profiling_file_mode;
const char *profiling_packets_file_mode;
/**
* Used as a check so we don't double enter a profiling run.
*/
__thread int profiling_rules_entered = 0;
void SCProfilingDumpPacketStats(void);
/**
* \brief Initialize profiling.
*/
@ -112,80 +142,148 @@ SCProfilingInit(void)
const char *val;
conf = ConfGetNode("profiling.rules");
if (conf == NULL) {
return;
}
if (ConfNodeChildValueIsTrue(conf, "enabled")) {
memset(rules_profile_data, 0, sizeof(rules_profile_data));
memset(&rules_ctx, 0, sizeof(rules_ctx));
rules_pca = SCPerfGetAllCountersArray(NULL);
if (SCMutexInit(&rules_ctx.m, NULL) != 0) {
SCLogError(SC_ERR_MEM_ALLOC,
"Failed to initialize hash table mutex.");
exit(EXIT_FAILURE);
}
profiling_rules_enabled = 1;
val = ConfNodeLookupChildValue(conf, "sort");
if (val != NULL) {
if (strcmp(val, "ticks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_TICKS;
}
else if (strcmp(val, "avgticks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_AVG_TICKS;
}
else if (strcmp(val, "avgticks_match") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH;
}
else if (strcmp(val, "avgticks_no_match") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH;
}
else if (strcmp(val, "checks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_CHECKS;
if (conf != NULL) {
if (ConfNodeChildValueIsTrue(conf, "enabled")) {
memset(rules_profile_data, 0, sizeof(rules_profile_data));
memset(&rules_ctx, 0, sizeof(rules_ctx));
rules_pca = SCPerfGetAllCountersArray(NULL);
if (SCMutexInit(&rules_ctx.m, NULL) != 0) {
SCLogError(SC_ERR_MUTEX,
"Failed to initialize hash table mutex.");
exit(EXIT_FAILURE);
}
else if (strcmp(val, "matches") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_MATCHES;
profiling_rules_enabled = 1;
val = ConfNodeLookupChildValue(conf, "sort");
if (val != NULL) {
if (strcmp(val, "ticks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_TICKS;
}
else if (strcmp(val, "avgticks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_AVG_TICKS;
}
else if (strcmp(val, "avgticks_match") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH;
}
else if (strcmp(val, "avgticks_no_match") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH;
}
else if (strcmp(val, "checks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_CHECKS;
}
else if (strcmp(val, "matches") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_MATCHES;
}
else if (strcmp(val, "maxticks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_MAX_TICKS;
}
else {
SCLogError(SC_ERR_INVALID_ARGUMENT,
"Invalid profiling sort order: %s", val);
exit(EXIT_FAILURE);
}
}
else if (strcmp(val, "maxticks") == 0) {
profiling_rules_sort_order =
SC_PROFILING_RULES_SORT_BY_MAX_TICKS;
val = ConfNodeLookupChildValue(conf, "limit");
if (val != NULL) {
if (ByteExtractStringUint32(&profiling_rules_limit, 10,
(uint16_t)strlen(val), val) <= 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid limit: %s", val);
exit(EXIT_FAILURE);
}
}
else {
SCLogError(SC_ERR_INVALID_ARGUMENT,
"Invalid profiling sort order: %s", val);
exit(EXIT_FAILURE);
const char *filename = ConfNodeLookupChildValue(conf, "filename");
if (filename != NULL) {
char *log_dir;
if (ConfGet("default-log-dir", &log_dir) != 1)
log_dir = DEFAULT_LOG_DIR;
profiling_file_name = SCMalloc(PATH_MAX);
snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);
profiling_file_mode = ConfNodeLookupChildValue(conf, "append");
if (profiling_file_mode == NULL)
profiling_file_mode = DEFAULT_LOG_MODE_APPEND;
profiling_output_to_file = 1;
}
}
}
val = ConfNodeLookupChildValue(conf, "limit");
if (val != NULL) {
if (ByteExtractStringUint32(&profiling_rules_limit, 10,
(uint16_t)strlen(val), val) <= 0) {
SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid limit: %s", val);
conf = ConfGetNode("profiling.packets");
if (conf != NULL) {
if (ConfNodeChildValueIsTrue(conf, "enabled")) {
profiling_packets_enabled = 1;
if (SCMutexInit(&packet_profile_lock, NULL) != 0) {
SCLogError(SC_ERR_MUTEX,
"Failed to initialize packet profiling mutex.");
exit(EXIT_FAILURE);
}
}
const char *filename = ConfNodeLookupChildValue(conf, "filename");
if (filename != NULL) {
memset(&packet_profile_data4, 0, sizeof(packet_profile_data4));
memset(&packet_profile_data6, 0, sizeof(packet_profile_data6));
memset(&packet_profile_tmm_data4, 0, sizeof(packet_profile_tmm_data4));
memset(&packet_profile_tmm_data6, 0, sizeof(packet_profile_tmm_data6));
char *log_dir;
if (ConfGet("default-log-dir", &log_dir) != 1)
log_dir = DEFAULT_LOG_DIR;
const char *filename = ConfNodeLookupChildValue(conf, "filename");
if (filename != NULL) {
profiling_file_name = SCMalloc(PATH_MAX);
snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);
char *log_dir;
if (ConfGet("default-log-dir", &log_dir) != 1)
log_dir = DEFAULT_LOG_DIR;
profiling_file_mode = ConfNodeLookupChildValue(conf, "append");
if (profiling_file_mode == NULL)
profiling_file_mode = DEFAULT_LOG_MODE_APPEND;
profiling_packets_file_name = SCMalloc(PATH_MAX);
snprintf(profiling_packets_file_name, PATH_MAX, "%s/%s", log_dir, filename);
profiling_output_to_file = 1;
profiling_packets_file_mode = ConfNodeLookupChildValue(conf, "append");
if (profiling_packets_file_mode == NULL)
profiling_packets_file_mode = DEFAULT_LOG_MODE_APPEND;
profiling_packets_output_to_file = 1;
}
}
conf = ConfGetNode("profiling.packets.csv");
if (conf != NULL) {
if (ConfNodeChildValueIsTrue(conf, "enabled")) {
const char *filename = ConfNodeLookupChildValue(conf, "filename");
if (filename == NULL) {
filename = "packet_profile.csv";
}
char *log_dir;
if (ConfGet("default-log-dir", &log_dir) != 1)
log_dir = DEFAULT_LOG_DIR;
profiling_csv_file_name = SCMalloc(PATH_MAX);
if (profiling_csv_file_name == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "out of memory");
exit(EXIT_FAILURE);
}
snprintf(profiling_csv_file_name, PATH_MAX, "%s/%s", log_dir, filename);
packet_profile_csv_fp = fopen(profiling_csv_file_name, "w");
if (packet_profile_csv_fp == NULL) {
return;
}
fprintf(packet_profile_csv_fp, "pcap_cnt,ipver,ipproto,total,");
int i;
for (i = 0; i < TMM_SIZE; i++) {
fprintf(packet_profile_csv_fp, "%s,", TmModuleTmmIdToString(i));
}
fprintf(packet_profile_csv_fp, "threading\n");
profiling_packets_csv_enabled = 1;
}
}
}
}
@ -199,7 +297,23 @@ SCProfilingDestroy(void)
if (profiling_rules_enabled) {
SCPerfReleasePerfCounterS(rules_ctx.head);
SCPerfReleasePCA(rules_pca);
SCMutexDestroy(&rules_ctx.m);
}
if (profiling_packets_enabled) {
SCMutexDestroy(&packet_profile_lock);
}
if (profiling_packets_csv_enabled) {
if (packet_profile_csv_fp != NULL)
fclose(packet_profile_csv_fp);
}
if (profiling_csv_file_name != NULL)
SCFree(profiling_csv_file_name);
if (profiling_file_name != NULL)
SCFree(profiling_file_name);
}
/**
@ -285,6 +399,8 @@ SCProfilingDump(void)
uint32_t i;
FILE *fp;
SCProfilingDumpPacketStats();
struct timeval tval;
struct tm *tms;
if (profiling_output_to_file == 1) {
@ -515,6 +631,229 @@ SCProfilingUpdateRuleCounter(uint16_t id, uint64_t ticks, int match)
SCMutexUnlock(&rules_ctx.m);
}
void SCProfilingDumpPacketStats(void) {
int i;
FILE *fp;
if (profiling_packets_enabled == 0)
return;
if (profiling_packets_output_to_file == 1) {
if (strcasecmp(profiling_packets_file_mode, "yes") == 0) {
fp = fopen(profiling_packets_file_name, "a");
} else {
fp = fopen(profiling_packets_file_name, "w");
}
if (fp == NULL) {
SCLogError(SC_ERR_FOPEN, "failed to open %s: %s",
profiling_packets_file_name, strerror(errno));
return;
}
} else {
fp = stdout;
}
fprintf(fp, "\n\nPacket profile dump:\n");
fprintf(fp, "\n%-6s %-5s %-8s %-6s %-10s %-8s\n",
"IP ver", "Proto", "cnt", "min", "max", "avg");
fprintf(fp, "%-6s %-5s %-8s %-6s %-10s %-8s\n",
"------", "-----", "------", "------", "----------", "-------");
for (i = 0; i < 257; i++) {
SCProfilePacketData *pd = &packet_profile_data4[i];
if (pd->cnt == 0) {
continue;
}
fprintf(fp, " IPv4 %3d %8u %6u %10u %8"PRIu64"\n", i, pd->cnt,
pd->min, pd->max, pd->tot / pd->cnt);
}
for (i = 0; i < 257; i++) {
SCProfilePacketData *pd = &packet_profile_data6[i];
if (pd->cnt == 0) {
continue;
}
fprintf(fp, " IPv6 %3d %8u %6u %10u %8"PRIu64"\n", i, pd->cnt,
pd->min, pd->max, pd->tot / pd->cnt);
}
fprintf(fp, "\nPer Thread module stats:\n");
fprintf(fp, "\n%-24s %-6s %-5s %-8s %-6s %-10s %-8s\n",
"Thread Module", "IP ver", "Proto", "cnt", "min", "max", "avg");
fprintf(fp, "%-24s %-6s %-5s %-8s %-6s %-10s %-8s\n",
"------------------------", "------", "-----", "------", "------", "----------", "-------");
int m;
for (m = 0; m < TMM_SIZE; m++) {
int p;
for (p = 0; p < 257; p++) {
SCProfilePacketData *pd = &packet_profile_tmm_data4[m][p];
if (pd->cnt == 0) {
continue;
}
fprintf(fp, "%-24s IPv4 %3d %8u %6u %10u %8"PRIu64"\n",
TmModuleTmmIdToString(m), p, pd->cnt, pd->min, pd->max, pd->tot / pd->cnt);
}
}
for (m = 0; m < TMM_SIZE; m++) {
int p;
for (p = 0; p < 257; p++) {
SCProfilePacketData *pd = &packet_profile_tmm_data6[m][p];
if (pd->cnt == 0) {
continue;
}
fprintf(fp, "%3d IPv6 %3d %8u %6u %10u %8"PRIu64"\n",
m, p, pd->cnt, pd->min, pd->max, pd->tot / pd->cnt);
}
}
fclose(fp);
}
void SCProfilingPrintPacketProfile(Packet *p) {
if (profiling_packets_csv_enabled == 0 || p == NULL || packet_profile_csv_fp == NULL) {
return;
}
uint32_t delta = (uint32_t)(p->profile.ticks_end - p->profile.ticks_start);
fprintf(packet_profile_csv_fp, "%"PRIu64",%c,%"PRIu8",%"PRIu32",",
p->pcap_cnt, PKT_IS_IPV4(p) ? '4' : (PKT_IS_IPV6(p) ? '6' : '?'), p->proto,
delta);
int i;
uint32_t tmm_total = 0;
for (i = 0; i < TMM_SIZE; i++) {
PktProfilingTmmData *pdt = &p->profile.tmm[i];
uint32_t tmm_delta = (uint32_t)(pdt->ticks_end - pdt->ticks_start);
fprintf(packet_profile_csv_fp, "%u,", tmm_delta);
tmm_total += tmm_delta;
}
fprintf(packet_profile_csv_fp, "%u\n", delta - tmm_total);
}
void SCProfilingUpdatePacketTmmRecord(int module, uint8_t proto, PktProfilingTmmData *pdt, int ipver) {
if (pdt == NULL) {
return;
}
SCProfilePacketData *pd;
if (ipver == 4)
pd = &packet_profile_tmm_data4[module][proto];
else
pd = &packet_profile_tmm_data6[module][proto];
uint32_t delta = (uint32_t)pdt->ticks_end - pdt->ticks_start;
if (pd->min == 0 || delta < pd->min) {
pd->min = delta;
}
if (pd->max < delta) {
pd->max = delta;
}
pd->tot += (uint64_t)delta;
pd->cnt ++;
}
void SCProfilingUpdatePacketTmmRecords(Packet *p) {
int i;
for (i = 0; i < TMM_SIZE; i++) {
PktProfilingTmmData *pdt = &p->profile.tmm[i];
if (pdt->ticks_start == 0) {
continue;
}
if (PKT_IS_IPV4(p)) {
SCProfilingUpdatePacketTmmRecord(i, p->proto, pdt, 4);
} else {
SCProfilingUpdatePacketTmmRecord(i, p->proto, pdt, 6);
}
}
}
void SCProfilingAddPacket(Packet *p) {
SCMutexLock(&packet_profile_lock);
{
if (profiling_packets_csv_enabled)
SCProfilingPrintPacketProfile(p);
if (PKT_IS_IPV4(p)) {
SCProfilePacketData *pd = &packet_profile_data4[p->proto];
uint32_t delta = (uint32_t)p->profile.ticks_end - p->profile.ticks_start;
if (pd->min == 0 || delta < pd->min) {
pd->min = delta;
}
if (pd->max < delta) {
pd->max = delta;
}
pd->tot += (uint64_t)delta;
pd->cnt ++;
if (IS_TUNNEL_PKT(p)) {
pd = &packet_profile_data4[256];
if (pd->min == 0 || delta < pd->min) {
pd->min = delta;
}
if (pd->max < delta) {
pd->max = delta;
}
pd->tot += (uint64_t)delta;
pd->cnt ++;
}
SCProfilingUpdatePacketTmmRecords(p);
} else if (PKT_IS_IPV6(p)) {
SCProfilePacketData *pd = &packet_profile_data6[p->proto];
uint32_t delta = (uint32_t)p->profile.ticks_end - p->profile.ticks_start;
if (pd->min == 0 || delta < pd->min) {
pd->min = delta;
}
if (pd->max < delta) {
pd->max = delta;
}
pd->tot += (uint64_t)delta;
pd->cnt ++;
if (IS_TUNNEL_PKT(p)) {
pd = &packet_profile_data6[256];
if (pd->min == 0 || delta < pd->min) {
pd->min = delta;
}
if (pd->max < delta) {
pd->max = delta;
}
pd->tot += (uint64_t)delta;
pd->cnt ++;
}
SCProfilingUpdatePacketTmmRecords(p);
}
}
SCMutexUnlock(&packet_profile_lock);
}
#ifdef UNITTESTS
static int

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2011 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
@ -19,6 +19,7 @@
* \file
*
* \author Endace Technology Limited.
* \author Victor Julien <victor@inliniac.net>
*/
#ifndef __UTIL_PROFILE_H__
@ -29,8 +30,12 @@
#include "util-cpu.h"
extern int profiling_rules_enabled;
extern int profiling_packets_enabled;
extern __thread int profiling_rules_entered;
void SCProfilingPrintPacketProfile(Packet *);
void SCProfilingAddPacket(Packet *);
#define RULE_PROFILING_START \
uint64_t profile_rule_start_ = 0; \
uint64_t profile_rule_end_ = 0; \
@ -51,6 +56,36 @@ extern __thread int profiling_rules_entered;
profiling_rules_entered--; \
}
#define PACKET_PROFILING_START(p) \
if (profiling_packets_enabled) { \
(p)->profile.ticks_start = UtilCpuGetTicks(); \
}
#define PACKET_PROFILING_END(p) \
if (profiling_packets_enabled) { \
(p)->profile.ticks_end = UtilCpuGetTicks(); \
SCProfilingAddPacket((p)); \
}
#define PACKET_PROFILING_TMM_START(p, id) \
if (profiling_packets_enabled) { \
if ((id) < TMM_SIZE) { \
(p)->profile.tmm[(id)].ticks_start = UtilCpuGetTicks(); \
} \
}
#define PACKET_PROFILING_TMM_END(p, id) \
if (profiling_packets_enabled) { \
if ((id) < TMM_SIZE) { \
(p)->profile.tmm[(id)].ticks_end = UtilCpuGetTicks(); \
} \
}
#define PACKET_PROFILING_RESET(p) \
if (profiling_packets_enabled) { \
memset(&(p)->profile, 0x00, sizeof(PktProfiling)); \
}
void SCProfilingInit(void);
void SCProfilingDestroy(void);
void SCProfilingInitRuleCounters(DetectEngineCtx *);
@ -64,6 +99,14 @@ void SCProfilingUpdateRuleCounter(uint16_t, uint64_t, int);
#define RULE_PROFILING_START
#define RULE_PROFILING_END(r, m)
#define PACKET_PROFILING_START(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)
#endif /* PROFILING */
#endif /* ! __UTIL_PROFILE_H__ */

@ -719,17 +719,18 @@ libhtp:
personality: IIS_7_0
request_body_limit: 4096
# rule profiling settings. Only effective if Suricata has been built with the
# Profiling settings. Only effective if Suricata has been built with the
# the --enable-profiling configure flag.
#
profiling:
# rule profiling
rules:
# Profiling can be disabled here, but it will still have a
# performance impact if compiled in.
enabled: yes
filename: perf.log
filename: rule_perf.log
append: yes
# Sort options: ticks, avgticks, checks, matches, maxticks
@ -738,3 +739,20 @@ profiling:
# Limit the number of items printed at exit.
limit: 100
# packet profiling
packets:
# Profiling can be disabled here, but it will still have a
# performance impact if compiled in.
enabled: yes
filename: packet_stats.log
append: yes
# per packet csv output
csv:
# Output can be disabled here, but it will still have a
# performance impact if compiled in.
enabled: no
filename: packet_stats.csv

Loading…
Cancel
Save