On Tue, Dec 22, 2020 at 9:11 PM Dumitru Ceara <[email protected]> wrote:
>
> When a user flushes the IGMP Groups ("ovn-sbctl ip-multicast-flush")
> there's no guarantee that the ovn-controller main thread runs soon after
> the pinctrl thread has flushed the in-memory IGMP groups, in
> ip_mcast_snoop_flush().
>
> To avoid unnecessarily waking the main thread just clear the local
> IGMP_Group records in the main thread.
>
> This scenario is quite hard to encounter in real deployments but every
> now and then we hit it in CI.
>
> Fixes: 70ff8243040f ("OVN: Add IGMP SB definitions and ovn-controller 
> support")
> Signed-off-by: Dumitru Ceara <[email protected]>

Thanks for the fix. I applied this patch to master and back ported to
all stable branches - 20.12 to 20.03

Thanks
Numan

> ---
>  controller/pinctrl.c | 37 +++++++++++++++++++++++++++++++++++--
>  1 file changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index 7e3abf0..e957b75 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -4507,9 +4507,16 @@ ip_mcast_snoop_state_find(int64_t dp_key)
>      return NULL;
>  }
>
> +/* Updates the ip_mcast_snoop_cfg for a logical datapath specified by
> + * 'dp_key'.  Also sets 'needs_flush' to 'true' if the config change should
> + * to trigger flushing of the existing IGMP_Groups.
> + *
> + * Returns 'true' if any changes happened to the configuration.
> + */
>  static bool
>  ip_mcast_snoop_state_update(int64_t dp_key,
> -                            const struct ip_mcast_snoop_cfg *cfg)
> +                            const struct ip_mcast_snoop_cfg *cfg,
> +                            bool *needs_flush)
>      OVS_REQUIRES(pinctrl_mutex)
>  {
>      bool notify = false;
> @@ -4519,6 +4526,9 @@ ip_mcast_snoop_state_update(int64_t dp_key,
>          ms_state = ip_mcast_snoop_state_add(dp_key);
>          notify = true;
>      } else if (memcmp(cfg, &ms_state->cfg, sizeof *cfg)) {
> +        if (ms_state->cfg.seq_no != cfg->seq_no) {
> +            *needs_flush = true;
> +        }
>          notify = true;
>      }
>
> @@ -4738,6 +4748,25 @@ ip_mcast_snoop_run(void)
>      }
>  }
>
> +/* Flushes all IGMP_Groups installed by the local chassis for the logical
> + * datapath specified by 'dp_key'.
> + */
> +static void
> +ip_mcast_flush_groups(int64_t dp_key, const struct sbrec_chassis *chassis,
> +                      struct ovsdb_idl_index *sbrec_igmp_groups)
> +{
> +    const struct sbrec_igmp_group *sbrec_igmp;
> +
> +    SBREC_IGMP_GROUP_FOR_EACH_BYINDEX (sbrec_igmp, sbrec_igmp_groups) {
> +        if (!sbrec_igmp->datapath ||
> +                sbrec_igmp->datapath->tunnel_key != dp_key ||
> +                sbrec_igmp->chassis != chassis) {
> +            continue;
> +        }
> +        igmp_group_delete(sbrec_igmp);
> +    }
> +}
> +
>  /*
>   * This runs in the pinctrl main thread, so it has access to the southbound
>   * database. It reads the IP_Multicast table and updates the local multicast
> @@ -4770,11 +4799,15 @@ ip_mcast_sync(struct ovsdb_idl_txn *ovnsb_idl_txn,
>
>          int64_t dp_key = ip_mcast->datapath->tunnel_key;
>          struct ip_mcast_snoop_cfg cfg;
> +        bool flush_groups = false;
>
>          ip_mcast_snoop_cfg_load(&cfg, ip_mcast);
> -        if (ip_mcast_snoop_state_update(dp_key, &cfg)) {
> +        if (ip_mcast_snoop_state_update(dp_key, &cfg, &flush_groups)) {
>              notify = true;
>          }
> +        if (flush_groups) {
> +            ip_mcast_flush_groups(dp_key, chassis, sbrec_igmp_groups);
> +        }
>      }
>
>      /* Then delete the old entries. */
> --
> 1.8.3.1
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to