]> git.proxmox.com Git - mirror_ovs.git/commitdiff
vswitchd: Make packet-in controller queue size configurable
authorDumitru Ceara <dceara@redhat.com>
Fri, 2 Aug 2019 08:29:52 +0000 (10:29 +0200)
committerBen Pfaff <blp@ovn.org>
Mon, 23 Sep 2019 22:47:59 +0000 (15:47 -0700)
The ofconn packet-in queue for packets that can't be immediately sent
on the rconn connection was limited to 100 packets (hardcoded value).
While increasing this limit is usually not recommended as it might
create buffer bloat and increase latency, in scaled scenarios it is
useful if the administrator (or CMS) can adjust the queue size.

One such situation was noticed while performing scale testing of the
OVN IGMP functionality: triggering ~200 simultaneous IGMP reports
was causing tail drops on the packet-in queue towards ovn-controller.

This commit adds the possibility to configure the queue size for:
- management controller (br-int.mgmt): through the
  other_config:controller-queue-size column of the Bridge table. This
  value is limited to 512 as large queues definitely affect latency. If
  not present the default value of 100 is used. This is done in order to
  maintain the same default behavior as before the commit.
- other controllers: through the controller_queue_size column of the
  Controller table. This value is also limited to 512. If not present
  the code uses the Bridge:other_config:controller-queue-size
  configuration.

Acked-by: Mark Michelson <mmichels@redhat.com>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
ofproto/connmgr.c
ofproto/ofproto.h
vswitchd/bridge.c
vswitchd/vswitch.ovsschema
vswitchd/vswitch.xml

index d975a532bf2d92087b3f831d091c63860e9e2543..51d656cba9605accfc59e4936203b1f507a9c760 100644 (file)
@@ -74,6 +74,7 @@ struct ofconn {
     enum ofputil_packet_in_format packet_in_format;
 
     /* OFPT_PACKET_IN related data. */
+    int packet_in_queue_size;
     struct rconn_packet_counter *packet_in_counter; /* # queued on 'rconn'. */
 #define N_SCHEDULERS 2
     struct pinsched *schedulers[N_SCHEDULERS];
@@ -1176,6 +1177,7 @@ ofconn_create(struct ofservice *ofservice, struct rconn *rconn,
     ofconn_set_protocol(ofconn, OFPUTIL_P_NONE);
     ofconn->packet_in_format = OFPUTIL_PACKET_IN_STD;
 
+    ofconn->packet_in_queue_size = settings->max_pktq_size;
     ofconn->packet_in_counter = rconn_packet_counter_create();
     ofconn->miss_send_len = (ofconn->type == OFCONN_PRIMARY
                              ? OFP_DEFAULT_MISS_SEND_LEN
@@ -1263,6 +1265,7 @@ ofconn_reconfigure(struct ofconn *ofconn, const struct ofproto_controller *c)
     rconn_set_probe_interval(ofconn->rconn, probe_interval);
 
     ofconn->band = c->band;
+    ofconn->packet_in_queue_size = c->max_pktq_size;
 
     ofconn_set_rate_limit(ofconn, c->rate_limit, c->burst_limit);
 
@@ -1676,7 +1679,8 @@ do_send_packet_ins(struct ofconn *ofconn, struct ovs_list *txq)
 
     LIST_FOR_EACH_POP (pin, list_node, txq) {
         if (rconn_send_with_limit(ofconn->rconn, pin,
-                                  ofconn->packet_in_counter, 100) == EAGAIN) {
+                                  ofconn->packet_in_counter,
+                                  ofconn->packet_in_queue_size) == EAGAIN) {
             static struct vlog_rate_limit rll = VLOG_RATE_LIMIT_INIT(5, 5);
 
             VLOG_INFO_RL(&rll, "%s: dropping packet-in due to queue overflow",
index 1977bc2b5c1c14be40db5b96f17cf8b5badfc99b..f535d2455e35273d0dd556390db5128a0b62b464 100644 (file)
@@ -234,6 +234,7 @@ struct ofproto_controller {
                                  * be negotiated for a session. */
 
     /* OpenFlow packet-in rate-limiting. */
+    int max_pktq_size;          /* Maximum number of packet-in to be queued. */
     int rate_limit;             /* Max packet-in rate in packets per second. */
     int burst_limit;            /* Limit on accumulating packet credits. */
 
index 8c390382fbef841928e6c154f8f1421d0945d075..8ed51c9618da5ac8e04254796726a997e519dac2 100644 (file)
@@ -227,6 +227,11 @@ static struct if_notifier *ifnotifier;
 static struct seq *ifaces_changed;
 static uint64_t last_ifaces_changed;
 
+/* Default/min/max packet-in queue sizes towards the controllers. */
+#define BRIDGE_CONTROLLER_PACKET_QUEUE_DEFAULT_SIZE 100
+#define BRIDGE_CONTROLLER_PACKET_QUEUE_MIN_SIZE 1
+#define BRIDGE_CONTROLLER_PACKET_QUEUE_MAX_SIZE 512
+
 static void add_del_bridges(const struct ovsrec_open_vswitch *);
 static void bridge_run__(void);
 static void bridge_create(const struct ovsrec_bridge *);
@@ -1123,6 +1128,25 @@ bridge_get_allowed_versions(struct bridge *br)
                                          br->cfg->n_protocols);
 }
 
+static int
+bridge_get_controller_queue_size(struct bridge *br,
+                                 struct ovsrec_controller *c)
+{
+    if (c && c->controller_queue_size) {
+        return *c->controller_queue_size;
+    }
+
+    int queue_size = smap_get_int(&br->cfg->other_config,
+                                  "controller-queue-size",
+                                  BRIDGE_CONTROLLER_PACKET_QUEUE_DEFAULT_SIZE);
+    if (queue_size < BRIDGE_CONTROLLER_PACKET_QUEUE_MIN_SIZE ||
+            queue_size > BRIDGE_CONTROLLER_PACKET_QUEUE_MAX_SIZE) {
+        return BRIDGE_CONTROLLER_PACKET_QUEUE_DEFAULT_SIZE;
+    }
+
+    return queue_size;
+}
+
 /* Set NetFlow configuration on 'br'. */
 static void
 bridge_configure_netflow(struct bridge *br)
@@ -3616,6 +3640,7 @@ bridge_configure_remotes(struct bridge *br,
         .band = OFPROTO_OUT_OF_BAND,
         .enable_async_msgs = true,
         .allowed_versions = bridge_get_allowed_versions(br),
+        .max_pktq_size = bridge_get_controller_queue_size(br, NULL),
     };
     shash_add_nocopy(
         &ocs, xasprintf("punix:%s/%s.mgmt", ovs_rundir(), br->name), oc);
@@ -3691,6 +3716,7 @@ bridge_configure_remotes(struct bridge *br,
             .enable_async_msgs = (!c->enable_async_messages
                                   || *c->enable_async_messages),
             .allowed_versions = bridge_get_allowed_versions(br),
+            .max_pktq_size = bridge_get_controller_queue_size(br, c),
             .rate_limit = (c->controller_rate_limit
                            ? *c->controller_rate_limit : 0),
             .burst_limit = (c->controller_burst_limit
index c0a2242ad3459aa06e14a8032c3037e27f23fe11..02be5ddeec975db8394fff724ea72d6549b5b97d 100644 (file)
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
- "version": "8.1.0",
- "cksum": "1635647160 26090",
+ "version": "8.2.0",
+ "cksum": "4076590391 26298",
  "tables": {
    "Open_vSwitch": {
      "columns": {
        "enable_async_messages": {
          "type": {"key": {"type": "boolean"},
                   "min": 0, "max": 1}},
+       "controller_queue_size": {
+         "type": {"key": {"type": "integer",
+                          "minInteger": 1,
+                          "maxInteger": 512},
+                  "min": 0, "max": 1}},
        "controller_rate_limit": {
          "type": {"key": {"type": "integer",
                           "minInteger": 100},
index 08586110db5179501bb3123cb60a6adbd84f7d94..f3538cf6c6b907b5577e38e266d54fadc56c3e56 100644 (file)
         ID, the default queue is used instead.
       </column>
 
+      <column name="other_config" key="controller-queue-size"
+              type='{"type": "integer", "minInteger": 1, "maxInteger": 512}'>
+        This sets the maximum size of the queue of packets that need to be
+        sent to the OpenFlow management controller. The value must be less
+        than 512. If not specified the queue size is limited to 100 packets
+        by default. Note: increasing the queue size might have a negative
+        impact on latency.
+      </column>
+
       <column name="protocols">
         List of OpenFlow protocols that may be used when negotiating a
         connection with a controller.  OpenFlow 1.0, 1.1, 1.2, 1.3, 1.4, and
@@ -4993,6 +5002,18 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
           table="Interface"/> table for ingress policing configuration.
         </p>
 
+      <column name="controller_queue_size">
+        <p>
+           This sets the maximum size of the queue of packets that need to be
+           sent to this OpenFlow controller. The value must be less than 512.
+           If not specified the queue size is limited to the value set for
+           the management controller in <ref table="Bridge"
+           column="other_config" key="controller-queue-size"/> if present or
+           100 packets by default. Note: increasing the queue size might
+           have a negative impact on latency.
+        </p>
+      </column>
+
         <column name="controller_rate_limit">
           <p>
             The maximum rate at which the switch will forward packets to the