On Tue, Mar 18, 2025 at 6:08 AM Aleksandr Smirnov <alekssmirnov@k2.cloud> wrote:
>
> Delay initial flow upload to OVS until all monitored updates received.
> This is a kind of replacement of the wait-before-clear parameter.
> Instead of waiting a certain amount of time we will wait
> until the final monitored update comes from SB DB.
> An event we watch in the controller's main loop is current condition
> sequence number compared vs expected condition sequence number.
> If they are not equal we still have to receive updates in response
> to recent monitor condition change request. This check makes sense
> only in code that lies after update_sb_monitors() function call.
>
> Note, this update will only work if wait-before-clear == 0,
> i.e. you can still rely on wait-before-clear behavior.
>
> Signed-off-by: Aleksandr Smirnov <alekssmirnov@k2.cloud>

Hi Aleksandr,

Sorry for the delay in reviewing this.  I was a little concerned about
this patch series initially
when I saw the patch commit message.  After reviewing this patch,  my
concerns are cleared
and I think it's a smart approach.

I tested it locally with a pretty big sized OVN SB DB.  ovn-controller
installs around 400k openflow rules.
Without this patch,  ovn-controller takes around 10 seconds to add
back all the flows when it is restarted.
With this patch,  I don't see any delay.  The existing flows are
cleared and added back without any delay.

I'd definitely like to get opinions from other maintainers too if they
have any concerns.

@Han Zhou   As you added the option - ovn-ofctrl-wait-before-clear
option can you please take a look at it ?

From my side

Acked-by: Numan Siddque <num...@ovn.org>

Numan



> ---
>  controller/ofctrl.c         | 29 ++++++++++++++++-
>  controller/ofctrl.h         |  3 +-
>  controller/ovn-controller.c |  4 ++-
>  tests/ovn-controller.at     | 62 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 95 insertions(+), 3 deletions(-)
>
> diff --git a/controller/ofctrl.c b/controller/ofctrl.c
> index 4a3d35b97..304b9bbc8 100644
> --- a/controller/ofctrl.c
> +++ b/controller/ofctrl.c
> @@ -349,6 +349,9 @@ static uint64_t cur_cfg;
>  /* Current state. */
>  static enum ofctrl_state state;
>
> +/* Release wait before clear stage. */
> +static bool wait_before_clear_proceed = false;
> +
>  /* The time (ms) to stay in the state S_WAIT_BEFORE_CLEAR. Read from
>   * external_ids: ovn-ofctrl-wait-before-clear. */
>  static unsigned int wait_before_clear_time = 0;
> @@ -446,6 +449,7 @@ run_S_NEW(void)
>      struct ofpbuf *buf = ofpraw_alloc(OFPRAW_NXT_TLV_TABLE_REQUEST,
>                                        rconn_get_version(swconn), 0);
>      xid = queue_msg(buf);
> +    wait_before_clear_proceed = false;
>      state = S_TLV_TABLE_REQUESTED;
>  }
>
> @@ -638,6 +642,14 @@ error:
>  static void
>  run_S_WAIT_BEFORE_CLEAR(void)
>  {
> +    if (wait_before_clear_time == 0) {
> +        if (wait_before_clear_proceed) {
> +            state = S_CLEAR_FLOWS;
> +        }
> +
> +        return;
> +    }
> +
>      if (!wait_before_clear_time ||
>          (wait_before_clear_expire &&
>           time_msec() >= wait_before_clear_expire)) {
> @@ -2695,11 +2707,26 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table,
>             uint64_t req_cfg,
>             bool lflows_changed,
>             bool pflows_changed,
> -           struct tracked_acl_ids *tracked_acl_ids)
> +           struct tracked_acl_ids *tracked_acl_ids,
> +           bool monitor_cond_complete)
>  {
>      static bool skipped_last_time = false;
>      static uint64_t old_req_cfg = 0;
>      bool need_put = false;
> +
> +    if (state == S_WAIT_BEFORE_CLEAR) {
> +        /* If no more monitored condition changes expected
> +           Release wait before clear stage and skip
> +           over poll wait. */
> +        if (monitor_cond_complete) {
> +            wait_before_clear_proceed = true;
> +            poll_immediate_wake();
> +        }
> +
> +        skipped_last_time = true;
> +        return;
> +    }
> +
>      if (lflows_changed || pflows_changed || skipped_last_time ||
>          ofctrl_initial_clear) {
>          need_put = true;
> diff --git a/controller/ofctrl.h b/controller/ofctrl.h
> index d1ee69cb0..76e2fbece 100644
> --- a/controller/ofctrl.h
> +++ b/controller/ofctrl.h
> @@ -68,7 +68,8 @@ void ofctrl_put(struct ovn_desired_flow_table *lflow_table,
>                  uint64_t nb_cfg,
>                  bool lflow_changed,
>                  bool pflow_changed,
> -                struct tracked_acl_ids *tracked_acl_ids);
> +                struct tracked_acl_ids *tracked_acl_ids,
> +                bool monitor_cond_complete);
>  bool ofctrl_has_backlog(void);
>  void ofctrl_wait(void);
>  void ofctrl_destroy(void);
> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> index bc8acddf1..2623fc758 100644
> --- a/controller/ovn-controller.c
> +++ b/controller/ovn-controller.c
> @@ -6384,7 +6384,9 @@ main(int argc, char *argv[])
>                                     ofctrl_seqno_get_req_cfg(),
>                                     engine_node_changed(&en_lflow_output),
>                                     engine_node_changed(&en_pflow_output),
> -                                   tracked_acl_ids);
> +                                   tracked_acl_ids,
> +                                   ovnsb_cond_seqno
> +                                   == ovnsb_expected_cond_seqno);
>                          stopwatch_stop(OFCTRL_PUT_STOPWATCH_NAME, 
> time_msec());
>                      }
>                      stopwatch_start(OFCTRL_SEQNO_RUN_STOPWATCH_NAME,
> diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
> index efb0a1741..812616711 100644
> --- a/tests/ovn-controller.at
> +++ b/tests/ovn-controller.at
> @@ -2463,6 +2463,68 @@ AT_CHECK([ovs-ofctl dump-flows br-int | grep group 
> -c], [0], [3
>  OVN_CLEANUP([hv1])
>  AT_CLEANUP
>
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([ovn-controller - ofctrl delay until all monitored updates come])
> +
> +# Prepare testing configuration
> +ovn_start
> +
> +net_add n1
> +sim_add hv1
> +as hv1
> +check ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +check ovs-vsctl -- add-port br-int hv1-vif1 -- \
> +    set interface hv1-vif1 external-ids:iface-id=ls1-lp1
> +
> +check ovn-nbctl ls-add ls1
> +
> +check ovn-nbctl lsp-add ls1 ls1-lp1 \
> +-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.1.2.3"
> +
> +check ovn-nbctl lb-add lb1 1.1.1.1 10.1.2.3 \
> +-- ls-lb-add ls1 lb1
> +
> +check ovn-nbctl lb-add lb2 2.2.2.2 10.1.2.4 \
> +-- ls-lb-add ls1 lb2
> +
> +check ovn-nbctl --wait=hv sync
> +
> +# Stop ovn-controller
> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
> +
> +# Sine we test initial flow upload controller is restarted.
> +# Clear log file and start controller.
> +rm -f hv1/ovn-controller.log
> +start_daemon ovn-controller -vfile:jsonrpc:dbg -vfile:ofctrl:dbg
> +
> +# Monitor log file until flow finally uploaded to OVS
> +OVS_WAIT_UNTIL([grep -q 'Setting lport.*in OVS' hv1/ovn-controller.log])
> +
> +# Analyse log file, select records about:
> +# 1. monitor_cond changes made for SB DB (message class is 'jsonrpc')
> +# 2. 'clearing all flows' message which is issued after 'wait before
> +#    clear' stage released (message class is 'ofctrl')
> +#
> +# We expect here that all monitoring condition changes should be made before
> +# OVS flow cleared / uploaded.
> +# For now all monitoring updates comes in three iterations: initial,
> +# direct dps, indirect dps that corresponds to
> +# three messages of type 1 followed by one message of type 2
> +#
> +# For monitor-all=true one message of type 1 followed by one message of type 
> 2
> +#
> +# Then we cut off message class and take first letter
> +# (j for jsonrpc and o for ofctrl)
> +#
> +call_seq=`grep -E \
> + "(clearing all flows)|(monitor_cond.*South)" \
> + hv1/ovn-controller.log | cut -d "|" -f 3- | cut -b 1 | tr -d '\n'`
> +AT_CHECK([echo $call_seq | grep -qE "^j+o$"], [0])
> +
> +OVN_CLEANUP([hv1])
> +AT_CLEANUP
> +])
>
>  AT_SETUP([ovn-controller - check ovn-chassis-mac-mappings])
>
> --
> 2.47.0
>
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to