]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
profiling: fix rule profiling output sometimes missing sid,rev,gid. Bug #576.
authorVictor Julien <victor@inliniac.net>
Mon, 8 Oct 2012 10:38:47 +0000 (12:38 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 8 Oct 2012 10:38:47 +0000 (12:38 +0200)
src/util-profiling-rules.c

index 7daa685c8f68b5dca6846732270cb225fc47144e..e7b7a2e3f2b0a2d8e9985aee689a56c21f46c9e5 100644 (file)
 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif
 
-typedef struct SCProfileDetectCtx_ {
-    uint32_t size;
-    uint32_t id;
-} SCProfileDetectCtx;
-
 /**
  * Extra data for rule profiling.
  */
@@ -61,6 +56,13 @@ typedef struct SCProfileData_ {
     uint64_t ticks_no_match;
 } SCProfileData;
 
+typedef struct SCProfileDetectCtx_ {
+    uint32_t size;
+    uint32_t id;
+    SCProfileData *data;
+    pthread_mutex_t data_m;
+} SCProfileDetectCtx;
+
 /**
  * Used for generating the summary data to print.
  */
@@ -80,8 +82,6 @@ typedef struct SCProfileSummary_ {
 } SCProfileSummary;
 
 extern int profiling_output_to_file;
-static SCProfileData rules_profile_data[0xffff];
-static pthread_mutex_t rules_profile_data_m;
 int profiling_rules_enabled = 0;
 static char *profiling_file_name = "";
 static const char *profiling_file_mode = "a";
@@ -112,7 +112,6 @@ void SCProfilingRulesGlobalInit(void) {
     conf = ConfGetNode("profiling.rules");
     if (conf != NULL) {
         if (ConfNodeChildValueIsTrue(conf, "enabled")) {
-            memset(rules_profile_data, 0, sizeof(rules_profile_data));
             profiling_rules_enabled = 1;
 
             val = ConfNodeLookupChildValue(conf, "sort");
@@ -301,29 +300,29 @@ SCProfilingRuleDump(SCProfileDetectCtx *rules_ctx)
 
     memset(summary, 0, summary_size);
     for (i = 0; i < count; i++) {
-        summary[i].sid = rules_profile_data[i].sid;
-        summary[i].rev = rules_profile_data[i].rev;
-        summary[i].gid = rules_profile_data[i].gid;
+        summary[i].sid = rules_ctx->data[i].sid;
+        summary[i].rev = rules_ctx->data[i].rev;
+        summary[i].gid = rules_ctx->data[i].gid;
 
-        summary[i].ticks = rules_profile_data[i].ticks_match + rules_profile_data[i].ticks_no_match;
-        summary[i].checks = rules_profile_data[i].checks;
+        summary[i].ticks = rules_ctx->data[i].ticks_match + rules_ctx->data[i].ticks_no_match;
+        summary[i].checks = rules_ctx->data[i].checks;
 
         if (summary[i].ticks > 0) {
-            summary[i].avgticks = (long double)summary[i].ticks / (long double)rules_profile_data[i].checks;
+            summary[i].avgticks = (long double)summary[i].ticks / (long double)summary[i].checks;
         }
 
-        summary[i].matches = rules_profile_data[i].matches;
-        summary[i].max = rules_profile_data[i].max;
-        summary[i].ticks_match = rules_profile_data[i].ticks_match;
-        summary[i].ticks_no_match = rules_profile_data[i].ticks_no_match;
-        if (rules_profile_data[i].ticks_match > 0) {
-            summary[i].avgticks_match = (long double)rules_profile_data[i].ticks_match /
-                (long double)rules_profile_data[i].matches;
+        summary[i].matches = rules_ctx->data[i].matches;
+        summary[i].max = rules_ctx->data[i].max;
+        summary[i].ticks_match = rules_ctx->data[i].ticks_match;
+        summary[i].ticks_no_match = rules_ctx->data[i].ticks_no_match;
+        if (summary[i].ticks_match > 0) {
+            summary[i].avgticks_match = (long double)summary[i].ticks_match /
+                (long double)summary[i].matches;
         }
 
-        if (rules_profile_data[i].ticks_no_match > 0) {
-            summary[i].avgticks_no_match = (long double)rules_profile_data[i].ticks_no_match /
-                ((long double)rules_profile_data[i].checks - (long double)rules_profile_data[i].matches);
+        if (summary[i].ticks_no_match > 0) {
+            summary[i].avgticks_no_match = (long double)summary[i].ticks_no_match /
+                ((long double)summary[i].checks - (long double)summary[i].matches);
         }
         total_ticks += summary[i].ticks;
     }
@@ -415,7 +414,6 @@ SCProfilingRuleDump(SCProfileDetectCtx *rules_ctx)
         fclose(fp);
     SCFree(summary);
     SCLogInfo("Done dumping profiling data.");
-    memset(rules_profile_data, 0x00, sizeof(rules_profile_data));
 }
 
 /**
@@ -459,7 +457,7 @@ SCProfileDetectCtx *SCProfilingRuleInitCtx(void) {
     if (ctx != NULL) {
         memset(ctx, 0x00, sizeof(SCProfileDetectCtx));
 
-        if (pthread_mutex_init(&rules_profile_data_m, NULL) != 0) {
+        if (pthread_mutex_init(&ctx->data_m, NULL) != 0) {
             SCLogError(SC_ERR_MUTEX,
                     "Failed to initialize hash table mutex.");
             exit(EXIT_FAILURE);
@@ -472,7 +470,9 @@ SCProfileDetectCtx *SCProfilingRuleInitCtx(void) {
 void SCProfilingRuleDestroyCtx(SCProfileDetectCtx *ctx) {
     if (ctx != NULL) {
         SCProfilingRuleDump(ctx);
-        pthread_mutex_destroy(&rules_profile_data_m);
+        if (ctx->data != NULL)
+            SCFree(ctx->data);
+        pthread_mutex_destroy(&ctx->data_m);
         SCFree(ctx);
     }
 }
@@ -490,28 +490,29 @@ void SCProfilingRuleThreadSetup(SCProfileDetectCtx *ctx, DetectEngineThreadCtx *
     }
 }
 
-static void SCProfilingRuleThreadMerge(DetectEngineThreadCtx *det_ctx) {
-    if (det_ctx == NULL || det_ctx->rule_perf_data == NULL)
+static void SCProfilingRuleThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) {
+    if (de_ctx == NULL || de_ctx->profile_ctx == NULL || de_ctx->profile_ctx->data == NULL ||
+        det_ctx == NULL || det_ctx->rule_perf_data == NULL)
         return;
 
     int i;
     for (i = 0; i < det_ctx->rule_perf_data_size; i++) {
-        rules_profile_data[i].checks += det_ctx->rule_perf_data[i].checks;
-        rules_profile_data[i].matches += det_ctx->rule_perf_data[i].matches;
-        rules_profile_data[i].ticks_match += det_ctx->rule_perf_data[i].ticks_match;
-        rules_profile_data[i].ticks_no_match += det_ctx->rule_perf_data[i].ticks_no_match;
-        if (det_ctx->rule_perf_data[i].max > rules_profile_data[i].max)
-            rules_profile_data[i].max = det_ctx->rule_perf_data[i].max;
+        de_ctx->profile_ctx->data[i].checks += det_ctx->rule_perf_data[i].checks;
+        de_ctx->profile_ctx->data[i].matches += det_ctx->rule_perf_data[i].matches;
+        de_ctx->profile_ctx->data[i].ticks_match += det_ctx->rule_perf_data[i].ticks_match;
+        de_ctx->profile_ctx->data[i].ticks_no_match += det_ctx->rule_perf_data[i].ticks_no_match;
+        if (det_ctx->rule_perf_data[i].max > de_ctx->profile_ctx->data[i].max)
+            de_ctx->profile_ctx->data[i].max = det_ctx->rule_perf_data[i].max;
     }
 }
 
 void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *det_ctx) {
-    if (det_ctx == NULL || det_ctx->rule_perf_data == NULL)
+    if (det_ctx == NULL || det_ctx->de_ctx == NULL || det_ctx->rule_perf_data == NULL)
         return;
 
-    pthread_mutex_lock(&rules_profile_data_m);
-    SCProfilingRuleThreadMerge(det_ctx);
-    pthread_mutex_unlock(&rules_profile_data_m);
+    pthread_mutex_lock(&det_ctx->de_ctx->profile_ctx->data_m);
+    SCProfilingRuleThreadMerge(det_ctx->de_ctx, det_ctx);
+    pthread_mutex_unlock(&det_ctx->de_ctx->profile_ctx->data_m);
 }
 
 /**
@@ -529,12 +530,24 @@ SCProfilingRuleInitCounters(DetectEngineCtx *de_ctx)
     uint32_t count = 0;
     while (sig != NULL) {
         sig->profiling_id = SCProfilingRegisterRuleCounter(de_ctx->profile_ctx);
-        rules_profile_data[sig->profiling_id].sid = sig->id;
-        rules_profile_data[sig->profiling_id].gid = sig->gid;
-        rules_profile_data[sig->profiling_id].rev = sig->rev;
         sig = sig->next;
         count++;
     }
+
+    if (count > 0) {
+        de_ctx->profile_ctx->data = SCMalloc(sizeof(SCProfileData) * de_ctx->profile_ctx->size);
+        BUG_ON(de_ctx->profile_ctx->data == NULL);
+        memset(de_ctx->profile_ctx->data, 0x00, sizeof(SCProfileData) * de_ctx->profile_ctx->size);
+
+        sig = de_ctx->sig_list;
+        while (sig != NULL) {
+            de_ctx->profile_ctx->data[sig->profiling_id].sid = sig->id;
+            de_ctx->profile_ctx->data[sig->profiling_id].gid = sig->gid;
+            de_ctx->profile_ctx->data[sig->profiling_id].rev = sig->rev;
+            sig = sig->next;
+        }
+    }
+
     SCLogInfo("Registered %"PRIu32" rule profiling counters.", count);
 }