diff mbox series

[ovs-dev,v3,ovn,2/3] OVN: add meter support to trigger_event action

Message ID 1436763c62d2f038431b863ef9e162cb56309393.1566222622.git.lorenzo.bianconi@redhat.com
State Superseded
Headers show
Series add rate limiting support for controller_events | expand

Commit Message

Lorenzo Bianconi Aug. 19, 2019, 2:37 p.m. UTC
Introduce meter support to trigger_event action in order to not
overload pinctrl thread under heavy load

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 include/ovn/actions.h |  1 +
 lib/actions.c         | 43 +++++++++++++++++++++++++++++++++++++------
 2 files changed, 38 insertions(+), 6 deletions(-)

Comments

Numan Siddique Aug. 21, 2019, 8:20 p.m. UTC | #1
On Mon, Aug 19, 2019 at 8:09 PM Lorenzo Bianconi <
lorenzo.bianconi@redhat.com> wrote:

> Introduce meter support to trigger_event action in order to not
> overload pinctrl thread under heavy load
>
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
>

Hi Lorenzo,

Can you please add a test for the meter option in the "action parsing" test
case in ovn.at.
I think this also requires updating the  documentation for the
'trigger_event' action in ovn-sb.xml.

Thanks
Numan

---
>  include/ovn/actions.h |  1 +
>  lib/actions.c         | 43 +++++++++++++++++++++++++++++++++++++------
>  2 files changed, 38 insertions(+), 6 deletions(-)
>
> diff --git a/include/ovn/actions.h b/include/ovn/actions.h
> index 0ca06537c..145f27f25 100644
> --- a/include/ovn/actions.h
> +++ b/include/ovn/actions.h
> @@ -327,6 +327,7 @@ struct ovnact_controller_event {
>      int event_type;   /* controller event type */
>      struct ovnact_gen_option *options;
>      size_t n_options;
> +    char *meter;
>  };
>
>  /* OVNACT_BIND_VPORT. */
> diff --git a/lib/actions.c b/lib/actions.c
> index 08c589ab3..6a5907e1b 100644
> --- a/lib/actions.c
> +++ b/lib/actions.c
> @@ -1273,6 +1273,9 @@ format_TRIGGER_EVENT(const struct
> ovnact_controller_event *event,
>  {
>      ds_put_format(s, "trigger_event(event = \"%s\"",
>                    event_to_string(event->event_type));
> +    if (event->meter) {
> +        ds_put_format(s, ", meter = \"%s\"", event->meter);
> +    }
>      for (const struct ovnact_gen_option *o = event->options;
>           o < &event->options[event->n_options]; o++) {
>          ds_put_cstr(s, ", ");
> @@ -1420,10 +1423,21 @@ encode_TRIGGER_EVENT(const struct
> ovnact_controller_event *event,
>                       const struct ovnact_encode_params *ep OVS_UNUSED,
>                       struct ofpbuf *ofpacts)
>  {
> +    uint32_t meter_id = NX_CTLR_NO_METER;
>      size_t oc_offset;
>
> +    if (event->meter) {
> +        meter_id = ovn_extend_table_assign_id(ep->meter_table,
> event->meter,
> +                                              ep->lflow_uuid);
> +        if (meter_id == EXT_TABLE_ID_INVALID) {
> +            VLOG_WARN("Unable to assign id for trigger meter: %s",
> +                      event->meter);
> +            return;
> +        }
> +    }
> +
>      oc_offset = encode_start_controller_op(ACTION_OPCODE_EVENT, false,
> -                                           NX_CTLR_NO_METER, ofpacts);
> +                                           meter_id, ofpacts);
>      ovs_be32 ofs = htonl(event->event_type);
>      ofpbuf_put(ofpacts, &ofs, sizeof ofs);
>
> @@ -1738,11 +1752,27 @@ parse_trigger_event(struct action_context *ctx,
>                                       sizeof *event->options);
>          }
>
> -        struct ovnact_gen_option *o = &event->options[event->n_options++];
> -        memset(o, 0, sizeof *o);
> -        parse_gen_opt(ctx, o,
> -
> &ctx->pp->controller_event_opts->event_opts[event_type],
> -                      event_to_string(event_type));
> +        if (lexer_match_id(ctx->lexer, "meter")) {
> +            if (!lexer_force_match(ctx->lexer, LEX_T_EQUALS)) {
> +                return;
> +            }
> +            /* If multiple meters are given, use the most recent. */
> +            if (ctx->lexer->token.type == LEX_T_STRING &&
> +                strlen(ctx->lexer->token.s)) {
> +                free(event->meter);
> +                event->meter = xstrdup(ctx->lexer->token.s);
> +            } else if (ctx->lexer->token.type != LEX_T_STRING) {
> +                lexer_syntax_error(ctx->lexer, "expecting string");
> +                return;
> +            }
> +            lexer_get(ctx->lexer);
> +        } else {
> +            struct ovnact_gen_option *o =
> &event->options[event->n_options++];
> +            memset(o, 0, sizeof *o);
> +            parse_gen_opt(ctx, o,
> +
> &ctx->pp->controller_event_opts->event_opts[event_type],
> +                    event_to_string(event_type));
> +            }
>          if (ctx->lexer->error) {
>              return;
>          }
> @@ -1763,6 +1793,7 @@ static void
>  ovnact_controller_event_free(struct ovnact_controller_event *event)
>  {
>      free_gen_options(event->options, event->n_options);
> +    free(event->meter);
>  }
>
>  static void
> --
> 2.21.0
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
diff mbox series

Patch

diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 0ca06537c..145f27f25 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -327,6 +327,7 @@  struct ovnact_controller_event {
     int event_type;   /* controller event type */
     struct ovnact_gen_option *options;
     size_t n_options;
+    char *meter;
 };
 
 /* OVNACT_BIND_VPORT. */
diff --git a/lib/actions.c b/lib/actions.c
index 08c589ab3..6a5907e1b 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -1273,6 +1273,9 @@  format_TRIGGER_EVENT(const struct ovnact_controller_event *event,
 {
     ds_put_format(s, "trigger_event(event = \"%s\"",
                   event_to_string(event->event_type));
+    if (event->meter) {
+        ds_put_format(s, ", meter = \"%s\"", event->meter);
+    }
     for (const struct ovnact_gen_option *o = event->options;
          o < &event->options[event->n_options]; o++) {
         ds_put_cstr(s, ", ");
@@ -1420,10 +1423,21 @@  encode_TRIGGER_EVENT(const struct ovnact_controller_event *event,
                      const struct ovnact_encode_params *ep OVS_UNUSED,
                      struct ofpbuf *ofpacts)
 {
+    uint32_t meter_id = NX_CTLR_NO_METER;
     size_t oc_offset;
 
+    if (event->meter) {
+        meter_id = ovn_extend_table_assign_id(ep->meter_table, event->meter,
+                                              ep->lflow_uuid);
+        if (meter_id == EXT_TABLE_ID_INVALID) {
+            VLOG_WARN("Unable to assign id for trigger meter: %s",
+                      event->meter);
+            return;
+        }
+    }
+
     oc_offset = encode_start_controller_op(ACTION_OPCODE_EVENT, false,
-                                           NX_CTLR_NO_METER, ofpacts);
+                                           meter_id, ofpacts);
     ovs_be32 ofs = htonl(event->event_type);
     ofpbuf_put(ofpacts, &ofs, sizeof ofs);
 
@@ -1738,11 +1752,27 @@  parse_trigger_event(struct action_context *ctx,
                                      sizeof *event->options);
         }
 
-        struct ovnact_gen_option *o = &event->options[event->n_options++];
-        memset(o, 0, sizeof *o);
-        parse_gen_opt(ctx, o,
-                      &ctx->pp->controller_event_opts->event_opts[event_type],
-                      event_to_string(event_type));
+        if (lexer_match_id(ctx->lexer, "meter")) {
+            if (!lexer_force_match(ctx->lexer, LEX_T_EQUALS)) {
+                return;
+            }
+            /* If multiple meters are given, use the most recent. */
+            if (ctx->lexer->token.type == LEX_T_STRING &&
+                strlen(ctx->lexer->token.s)) {
+                free(event->meter);
+                event->meter = xstrdup(ctx->lexer->token.s);
+            } else if (ctx->lexer->token.type != LEX_T_STRING) {
+                lexer_syntax_error(ctx->lexer, "expecting string");
+                return;
+            }
+            lexer_get(ctx->lexer);
+        } else {
+            struct ovnact_gen_option *o = &event->options[event->n_options++];
+            memset(o, 0, sizeof *o);
+            parse_gen_opt(ctx, o,
+                    &ctx->pp->controller_event_opts->event_opts[event_type],
+                    event_to_string(event_type));
+            }
         if (ctx->lexer->error) {
             return;
         }
@@ -1763,6 +1793,7 @@  static void
 ovnact_controller_event_free(struct ovnact_controller_event *event)
 {
     free_gen_options(event->options, event->n_options);
+    free(event->meter);
 }
 
 static void