]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Add more suricata.yaml configuration options for mPIPE.
authorKen Steele <ken@tilera.com>
Fri, 22 Nov 2013 20:53:12 +0000 (15:53 -0500)
committerVictor Julien <victor@inliniac.net>
Wed, 11 Dec 2013 10:51:11 +0000 (11:51 +0100)
Add two new mPIPE load-balancing configuration options in suricata.yaml.
1) "sticky" which keep sending flows to one CPU, but if that queue is full,
don't drop the packet, move the flow to the least loaded queue.
2) Round-robin, which always picks the least full input queue for each
packet.

Allow configuring the number of packets in the input queue (iqueue) in
suricata.yaml.

For the mPipe.buckets configuration, which must be a power of 2, round
up to the next power of two, rather than report an error.

Added mpipe.min-buckets, which defaults to 256, so if the requested number
of buckets can't be allocated, Suricata will keep dividing by 2 until either
it succeeds in allocating buckets, or reaches the minimum number of buckets
and fails.

src/source-mpipe.c
suricata.yaml.in

index 7276c2997172c62418481ca1195f0afb3be2b4a5..231f4d0bb1b6557a85655e77d769740d189c7853 100644 (file)
@@ -637,6 +637,7 @@ static TmEcode ReceiveMpipeCreateBuckets(int ring, int num_workers,
 {
     SCEnter();
     int result;
+    int min_buckets = 256;
 
     /* Allocate a NotifGroup. */
     int group = gxio_mpipe_alloc_notif_groups(context, 1, 0, 0);
@@ -646,19 +647,42 @@ static TmEcode ReceiveMpipeCreateBuckets(int ring, int num_workers,
     if (ConfGetInt("mpipe.buckets", &value) == 1) {
         /* range check */
         if ((value >= 1) && (value <= 4096)) {
-            *num_buckets = (int) value;
+            /* Must be a power of 2, so round up to next power of 2. */
+            int ceiling_log2 = 64 - __builtin_clz((int64_t)value - 1);
+            *num_buckets = 1 << (ceiling_log2);
         } else {
-            SCLogError(SC_ERR_INVALID_ARGUMENT, "Illegal mpipe.buckets value.");
+            SCLogError(SC_ERR_INVALID_ARGUMENT,
+                       "Illegal mpipe.buckets value (%ld). must be between 1 and 4096.", value);
+        }
+    }
+    if (ConfGetInt("mpipe.min-buckets", &value) == 1) {
+        /* range check */
+        if ((value >= 1) && (value <= 4096)) {
+            /* Must be a power of 2, so round up to next power of 2. */
+            int ceiling_log2 = 64 - __builtin_clz((int64_t)value - 1);
+            min_buckets = 1 << (ceiling_log2);
+        } else {
+          SCLogError(SC_ERR_INVALID_ARGUMENT,
+                     "Illegal min-mpipe.buckets value (%ld). must be between 1 and 4096.", value);
         }
     }
 
-    /* Allocate buckets. */
-    *first_bucket = gxio_mpipe_alloc_buckets(context, *num_buckets, 0, 0);
-    if (*first_bucket == GXIO_MPIPE_ERR_NO_BUCKET) {
+    /* Allocate buckets. Keep trying half the number of requested buckets until min-bucket is reached. */
+    while (1) {
+      *first_bucket = gxio_mpipe_alloc_buckets(context, *num_buckets, 0, 0);
+      if (*first_bucket != GXIO_MPIPE_ERR_NO_BUCKET)
+        break;
+      /* Failed to allocate the requested number of buckets. Keep
+       * trying less buckets until min-buckets is reached.
+       */
+      if (*num_buckets <= min_buckets) {
         SCLogError(SC_ERR_INVALID_ARGUMENT,
-                   "Could not allocate mpipe buckets. "
-                   "Try a smaller mpipe.buckets value in suricata.yaml");
+                   "Could not allocate (%d) mpipe buckets. "
+                   "Try a smaller mpipe.buckets value in suricata.yaml", *num_buckets);
         SCReturnInt(TM_ECODE_FAILED);
+      }
+      /* Cut the number of requested buckets in half and try again. */
+      *num_buckets /= 2;
     }
 
     /* Init group and buckets, preserving packet order among flows. */
@@ -668,17 +692,26 @@ static TmEcode ReceiveMpipeCreateBuckets(int ring, int num_workers,
         if (balance) {
             if (strcmp(balance, "static") == 0) {
                 mode = GXIO_MPIPE_BUCKET_STATIC_FLOW_AFFINITY;
-                SCLogInfo("Using \"static\" flow affinity.");
+                SCLogInfo("Using \"static\" flow affinity load balancing with %d buckets.", *num_buckets);
             } else if (strcmp(balance, "dynamic") == 0) {
                 mode = GXIO_MPIPE_BUCKET_DYNAMIC_FLOW_AFFINITY;
-                SCLogInfo("Using \"dynamic\" flow affinity.");
+                SCLogInfo("Using \"dynamic\" flow affinity load balancing with %d buckets.", *num_buckets);
+            } else if (strcmp(balance, "sticky") == 0) {
+                mode = GXIO_MPIPE_BUCKET_STICKY_FLOW_LOCALITY;
+                SCLogInfo("Using \"sticky\" load balancing with %d buckets.", *num_buckets);
+            } else if (strcmp(balance, "round-robin") == 0) {
+                mode = GXIO_MPIPE_BUCKET_ROUND_ROBIN;
             } else {
                 SCLogWarning(SC_ERR_INVALID_ARGUMENT, 
-                             "Illegal load balancing mode %s using \"static\"",
-                             balance);
+                             "Illegal load balancing mode \"%s\"", balance);
+                balance = "static";
             }
         }
+    } else {
+      balance = "static";
     }
+    SCLogInfo("Using \"%s\" load balancing with %d buckets.", balance, *num_buckets);
+
     result = gxio_mpipe_init_notif_group_and_buckets(context, group,
                                                      ring, num_workers,
                                                      *first_bucket, 
@@ -716,8 +749,17 @@ static int ReceiveMpipeRegisterRules(int bucket, int num_buckets)
  */
 static int MpipeReceiveOpenIqueue(int rank)
 {
-    /* Init the NotifRings. */
-    const size_t notif_ring_entries = 2048;
+    /* Initialize the NotifRings. */
+    size_t notif_ring_entries = 2048;
+    intmax_t value = 0;
+    if (ConfGetInt("mpipe.iqueue-packets", &value) == 1) {
+        /* range check */
+        if (value == 128 || value == 512 || value == 2048 || value == (64 * 1024)) {
+            notif_ring_entries = value;
+        } else {
+            SCLogError(SC_ERR_INVALID_ARGUMENT, "Illegal mpipe.iqueue_packets value. must be 128, 512, 2048 or 65536.");
+        }
+    }
 
     size_t notif_ring_size = notif_ring_entries * sizeof(gxio_mpipe_idesc_t);
 
index 26dbb2a284489cdb348532d8746e5c060f1f9863..d18ceb77b6472e18480c126083d40a3ff3876b0e 100644 (file)
@@ -721,9 +721,12 @@ logging:
 # Tilera mpipe configuration. for use on Tilera TILE-Gx.
 mpipe:
 
-  # Load balancing mode "static" or "dynamic".
+  # Load balancing modes: "static", "dynamic", "sticky", or "round-robin".
   load-balance: dynamic
 
+  # Number of Packets in each ingress packet queue. Must be 128, 512, 2028 or 65536
+  iqueue-packets: 2048
+
   # List of interfaces we will listen on.
   inputs:
   - interface: xgbe2