diff mbox series

[ovs-dev] ofctrl: Track the OvS flow update time

Message ID 20231205091007.75576-1-amusil@redhat.com
State Changes Requested
Headers show
Series [ovs-dev] ofctrl: Track the OvS flow update time | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes success github build: passed

Commit Message

Ales Musil Dec. 5, 2023, 9:10 a.m. UTC
Add unixctl command called "ofctrl/flow-install-time"
that returns the last time it took OvS to process
and install all flows. The initial time is taken right
before controller queues the updates to rconn.
The end is marked when we receive barrier reply with
corresponding xid.

Reported-at: https://issues.redhat.com/browse/FDP-134
Signed-off-by: Ales Musil <amusil@redhat.com>
---
 controller/ofctrl.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

Comments

Dumitru Ceara Dec. 5, 2023, 10:32 a.m. UTC | #1
On 12/5/23 10:10, Ales Musil wrote:
> Add unixctl command called "ofctrl/flow-install-time"
> that returns the last time it took OvS to process
> and install all flows. The initial time is taken right
> before controller queues the updates to rconn.
> The end is marked when we receive barrier reply with
> corresponding xid.
> 
> Reported-at: https://issues.redhat.com/browse/FDP-134
> Signed-off-by: Ales Musil <amusil@redhat.com>
> ---
>  controller/ofctrl.c | 31 +++++++++++++++++++++++++++++--
>  1 file changed, 29 insertions(+), 2 deletions(-)

Hi Ales,

Thanks for the patch!

This is supposed to be a rather "stable" command as the CMS wants to
rely on this to gather relevant load statistics.  We should make sure we
document its behavior in ovn-controller.8.xml and mention it in the NEWS
file.

> 
> diff --git a/controller/ofctrl.c b/controller/ofctrl.c
> index 7aac0128b..4f8b80012 100644
> --- a/controller/ofctrl.c
> +++ b/controller/ofctrl.c
> @@ -51,6 +51,7 @@
>  #include "openvswitch/rconn.h"
>  #include "socket-util.h"
>  #include "timeval.h"
> +#include "unixctl.h"
>  #include "util.h"
>  #include "vswitch-idl.h"
>  
> @@ -323,6 +324,7 @@ struct ofctrl_flow_update {
>      struct ovs_list list_node;  /* In 'flow_updates'. */
>      ovs_be32 xid;               /* OpenFlow transaction ID for barrier. */
>      uint64_t req_cfg;           /* Requested sequence number. */
> +    long long start_msec;       /* Timestamp when the update started. */
>  };
>  
>  static struct ofctrl_flow_update *
> @@ -402,6 +404,10 @@ static enum mf_field_id mff_ovn_geneve;
>   * (e.g. after OVS restart). */
>  static bool ofctrl_initial_clear;
>  
> +/* The time in ms it took for the last flow installation to be processed
> + * by OvS. */
> +static long long last_flow_install_time_ms = 0;
> +
>  static ovs_be32 queue_msg(struct ofpbuf *);
>  
>  static struct ofpbuf *encode_flow_mod(struct ofputil_flow_mod *);
> @@ -413,6 +419,8 @@ static struct ofpbuf *encode_meter_mod(const struct ofputil_meter_mod *);
>  static void ovn_installed_flow_table_clear(void);
>  static void ovn_installed_flow_table_destroy(void);
>  
> +static void flow_install_time_report(struct unixctl_conn *conn, int argc,
> +                                     const char *argv[], void *param);
>  
>  static void ofctrl_recv(const struct ofp_header *, enum ofptype);
>  
> @@ -429,6 +437,8 @@ ofctrl_init(struct ovn_extend_table *group_table,
>      groups = group_table;
>      meters = meter_table;
>      shash_init(&meter_bands);
> +    unixctl_command_register("ofctrl/flow-install-time", "", 0, 0,
> +                             flow_install_time_report, NULL);
>  }
>  
>  /* S_NEW, for a new connection.
> @@ -732,6 +742,9 @@ recv_S_UPDATE_FLOWS(const struct ofp_header *oh, enum ofptype type,
>              if (fup->req_cfg >= cur_cfg) {
>                  cur_cfg = fup->req_cfg;
>              }
> +
> +            last_flow_install_time_ms = time_msec() - fup->start_msec;

Nit: very unlikely but this can underflow.

Nit2: too many empty lines IMO.  I'd just move this line immediately
before the "if (fup->req_cfg >= cur_cfg) {".

> +
>              mem_stats.oflow_update_usage -= ofctrl_flow_update_size(fup);
>              ovs_list_remove(&fup->list_node);
>              free(fup);
> @@ -2900,6 +2913,7 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table,
>          const struct ofp_header *oh = barrier->data;
>          ovs_be32 xid_ = oh->xid;
>          ovs_list_push_back(&msgs, &barrier->list_node);
> +        long long flow_update_start = time_msec();
>  
>          /* Queue the messages. */
>          struct ofpbuf *msg;
> @@ -2945,9 +2959,13 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table,
>  
>          /* Add a flow update. */
>          fup = xmalloc(sizeof *fup);
> +        *fup = (struct ofctrl_flow_update) {
> +            .xid = xid_,
> +            .req_cfg = req_cfg,
> +            .start_msec = flow_update_start,
> +        };
> +
>          ovs_list_push_back(&flow_updates, &fup->list_node);
> -        fup->xid = xid_;
> -        fup->req_cfg = req_cfg;
>          mem_stats.oflow_update_usage += ofctrl_flow_update_size(fup);
>      done:;
>      } else if (!ovs_list_is_empty(&flow_updates)) {
> @@ -3090,3 +3108,12 @@ ofctrl_get_memory_usage(struct simap *usage)
>                     ROUND_UP(rconn_packet_counter_n_bytes(tx_counter), 1024)
>                     / 1024);
>  }
> +
> +static void
> +flow_install_time_report(struct unixctl_conn *conn, int argc OVS_UNUSED,
> +                         const char *argv[] OVS_UNUSED, void *param OVS_UNUSED)
> +{
> +    char *msg = xasprintf("%lld ms", last_flow_install_time_ms);
> +    unixctl_command_reply(conn, msg);
> +    free(msg);
> +}

Thanks,
Dumitru
Ales Musil Dec. 5, 2023, 11:18 a.m. UTC | #2
On Tue, Dec 5, 2023 at 11:32 AM Dumitru Ceara <dceara@redhat.com> wrote:

> On 12/5/23 10:10, Ales Musil wrote:
> > Add unixctl command called "ofctrl/flow-install-time"
> > that returns the last time it took OvS to process
> > and install all flows. The initial time is taken right
> > before controller queues the updates to rconn.
> > The end is marked when we receive barrier reply with
> > corresponding xid.
> >
> > Reported-at: https://issues.redhat.com/browse/FDP-134
> > Signed-off-by: Ales Musil <amusil@redhat.com>
> > ---
> >  controller/ofctrl.c | 31 +++++++++++++++++++++++++++++--
> >  1 file changed, 29 insertions(+), 2 deletions(-)
>
> Hi Ales,
>
> Thanks for the patch!
>

Hi Dumitru,

thank you for the review.


>
> This is supposed to be a rather "stable" command as the CMS wants to
> rely on this to gather relevant load statistics.  We should make sure we
> document its behavior in ovn-controller.8.xml and mention it in the NEWS
> file.
>

You are right, it should definitely be documented.


>
> >
> > diff --git a/controller/ofctrl.c b/controller/ofctrl.c
> > index 7aac0128b..4f8b80012 100644
> > --- a/controller/ofctrl.c
> > +++ b/controller/ofctrl.c
> > @@ -51,6 +51,7 @@
> >  #include "openvswitch/rconn.h"
> >  #include "socket-util.h"
> >  #include "timeval.h"
> > +#include "unixctl.h"
> >  #include "util.h"
> >  #include "vswitch-idl.h"
> >
> > @@ -323,6 +324,7 @@ struct ofctrl_flow_update {
> >      struct ovs_list list_node;  /* In 'flow_updates'. */
> >      ovs_be32 xid;               /* OpenFlow transaction ID for barrier.
> */
> >      uint64_t req_cfg;           /* Requested sequence number. */
> > +    long long start_msec;       /* Timestamp when the update started. */
> >  };
> >
> >  static struct ofctrl_flow_update *
> > @@ -402,6 +404,10 @@ static enum mf_field_id mff_ovn_geneve;
> >   * (e.g. after OVS restart). */
> >  static bool ofctrl_initial_clear;
> >
> > +/* The time in ms it took for the last flow installation to be processed
> > + * by OvS. */
> > +static long long last_flow_install_time_ms = 0;
> > +
> >  static ovs_be32 queue_msg(struct ofpbuf *);
> >
> >  static struct ofpbuf *encode_flow_mod(struct ofputil_flow_mod *);
> > @@ -413,6 +419,8 @@ static struct ofpbuf *encode_meter_mod(const struct
> ofputil_meter_mod *);
> >  static void ovn_installed_flow_table_clear(void);
> >  static void ovn_installed_flow_table_destroy(void);
> >
> > +static void flow_install_time_report(struct unixctl_conn *conn, int
> argc,
> > +                                     const char *argv[], void *param);
> >
> >  static void ofctrl_recv(const struct ofp_header *, enum ofptype);
> >
> > @@ -429,6 +437,8 @@ ofctrl_init(struct ovn_extend_table *group_table,
> >      groups = group_table;
> >      meters = meter_table;
> >      shash_init(&meter_bands);
> > +    unixctl_command_register("ofctrl/flow-install-time", "", 0, 0,
> > +                             flow_install_time_report, NULL);
> >  }
> >
> >  /* S_NEW, for a new connection.
> > @@ -732,6 +742,9 @@ recv_S_UPDATE_FLOWS(const struct ofp_header *oh,
> enum ofptype type,
> >              if (fup->req_cfg >= cur_cfg) {
> >                  cur_cfg = fup->req_cfg;
> >              }
> > +
> > +            last_flow_install_time_ms = time_msec() - fup->start_msec;
>
> Nit: very unlikely but this can underflow.
>

As discussed offline this very unlikely is closer to almost impossible.


>
> Nit2: too many empty lines IMO.  I'd just move this line immediately
> before the "if (fup->req_cfg >= cur_cfg) {".
>

Done in v2.


>
> > +
> >              mem_stats.oflow_update_usage -=
> ofctrl_flow_update_size(fup);
> >              ovs_list_remove(&fup->list_node);
> >              free(fup);
> > @@ -2900,6 +2913,7 @@ ofctrl_put(struct ovn_desired_flow_table
> *lflow_table,
> >          const struct ofp_header *oh = barrier->data;
> >          ovs_be32 xid_ = oh->xid;
> >          ovs_list_push_back(&msgs, &barrier->list_node);
> > +        long long flow_update_start = time_msec();
> >
> >          /* Queue the messages. */
> >          struct ofpbuf *msg;
> > @@ -2945,9 +2959,13 @@ ofctrl_put(struct ovn_desired_flow_table
> *lflow_table,
> >
> >          /* Add a flow update. */
> >          fup = xmalloc(sizeof *fup);
> > +        *fup = (struct ofctrl_flow_update) {
> > +            .xid = xid_,
> > +            .req_cfg = req_cfg,
> > +            .start_msec = flow_update_start,
> > +        };
> > +
> >          ovs_list_push_back(&flow_updates, &fup->list_node);
> > -        fup->xid = xid_;
> > -        fup->req_cfg = req_cfg;
> >          mem_stats.oflow_update_usage += ofctrl_flow_update_size(fup);
> >      done:;
> >      } else if (!ovs_list_is_empty(&flow_updates)) {
> > @@ -3090,3 +3108,12 @@ ofctrl_get_memory_usage(struct simap *usage)
> >                     ROUND_UP(rconn_packet_counter_n_bytes(tx_counter),
> 1024)
> >                     / 1024);
> >  }
> > +
> > +static void
> > +flow_install_time_report(struct unixctl_conn *conn, int argc OVS_UNUSED,
> > +                         const char *argv[] OVS_UNUSED, void *param
> OVS_UNUSED)
> > +{
> > +    char *msg = xasprintf("%lld ms", last_flow_install_time_ms);
> > +    unixctl_command_reply(conn, msg);
> > +    free(msg);
> > +}
>
> Thanks,
> Dumitru
>
>
> Thanks,
Ales
diff mbox series

Patch

diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index 7aac0128b..4f8b80012 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -51,6 +51,7 @@ 
 #include "openvswitch/rconn.h"
 #include "socket-util.h"
 #include "timeval.h"
+#include "unixctl.h"
 #include "util.h"
 #include "vswitch-idl.h"
 
@@ -323,6 +324,7 @@  struct ofctrl_flow_update {
     struct ovs_list list_node;  /* In 'flow_updates'. */
     ovs_be32 xid;               /* OpenFlow transaction ID for barrier. */
     uint64_t req_cfg;           /* Requested sequence number. */
+    long long start_msec;       /* Timestamp when the update started. */
 };
 
 static struct ofctrl_flow_update *
@@ -402,6 +404,10 @@  static enum mf_field_id mff_ovn_geneve;
  * (e.g. after OVS restart). */
 static bool ofctrl_initial_clear;
 
+/* The time in ms it took for the last flow installation to be processed
+ * by OvS. */
+static long long last_flow_install_time_ms = 0;
+
 static ovs_be32 queue_msg(struct ofpbuf *);
 
 static struct ofpbuf *encode_flow_mod(struct ofputil_flow_mod *);
@@ -413,6 +419,8 @@  static struct ofpbuf *encode_meter_mod(const struct ofputil_meter_mod *);
 static void ovn_installed_flow_table_clear(void);
 static void ovn_installed_flow_table_destroy(void);
 
+static void flow_install_time_report(struct unixctl_conn *conn, int argc,
+                                     const char *argv[], void *param);
 
 static void ofctrl_recv(const struct ofp_header *, enum ofptype);
 
@@ -429,6 +437,8 @@  ofctrl_init(struct ovn_extend_table *group_table,
     groups = group_table;
     meters = meter_table;
     shash_init(&meter_bands);
+    unixctl_command_register("ofctrl/flow-install-time", "", 0, 0,
+                             flow_install_time_report, NULL);
 }
 
 /* S_NEW, for a new connection.
@@ -732,6 +742,9 @@  recv_S_UPDATE_FLOWS(const struct ofp_header *oh, enum ofptype type,
             if (fup->req_cfg >= cur_cfg) {
                 cur_cfg = fup->req_cfg;
             }
+
+            last_flow_install_time_ms = time_msec() - fup->start_msec;
+
             mem_stats.oflow_update_usage -= ofctrl_flow_update_size(fup);
             ovs_list_remove(&fup->list_node);
             free(fup);
@@ -2900,6 +2913,7 @@  ofctrl_put(struct ovn_desired_flow_table *lflow_table,
         const struct ofp_header *oh = barrier->data;
         ovs_be32 xid_ = oh->xid;
         ovs_list_push_back(&msgs, &barrier->list_node);
+        long long flow_update_start = time_msec();
 
         /* Queue the messages. */
         struct ofpbuf *msg;
@@ -2945,9 +2959,13 @@  ofctrl_put(struct ovn_desired_flow_table *lflow_table,
 
         /* Add a flow update. */
         fup = xmalloc(sizeof *fup);
+        *fup = (struct ofctrl_flow_update) {
+            .xid = xid_,
+            .req_cfg = req_cfg,
+            .start_msec = flow_update_start,
+        };
+
         ovs_list_push_back(&flow_updates, &fup->list_node);
-        fup->xid = xid_;
-        fup->req_cfg = req_cfg;
         mem_stats.oflow_update_usage += ofctrl_flow_update_size(fup);
     done:;
     } else if (!ovs_list_is_empty(&flow_updates)) {
@@ -3090,3 +3108,12 @@  ofctrl_get_memory_usage(struct simap *usage)
                    ROUND_UP(rconn_packet_counter_n_bytes(tx_counter), 1024)
                    / 1024);
 }
+
+static void
+flow_install_time_report(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                         const char *argv[] OVS_UNUSED, void *param OVS_UNUSED)
+{
+    char *msg = xasprintf("%lld ms", last_flow_install_time_ms);
+    unixctl_command_reply(conn, msg);
+    free(msg);
+}