The 05/11/2021 11:38, Roi Dayan wrote:
> From: Jianbo Liu <[email protected]>
>
> There is a race condidtion between purger and handler. Handler may
> create new ukey and install it while executing 'ovs-appctl
> revalidator/purge' command. However, before handler calls
> transition_ukey() in handle_upcalls(), purger may get this ukey from
> umap, then evict and delete it. This will trigger ovs_abort in
> transition_ukey() for handler because it is trying to set state to
> EVICTED or OPERATIONAL, but ukey is already in DELETED state.
> To fix this issue, purger must not delete ukey in VISIBLE state.
Friendly ping for review ...
Thanks!
Jianbo
>
> Fixes: 98bb4286970d ("tests: Add command to purge revalidators of flows.")
> Signed-off-by: Jianbo Liu <[email protected]>
> Reviewed-by: Roi Dayan <[email protected]>
> ---
> ofproto/ofproto-dpif-upcall.c | 25 ++++++++++++++++---------
> 1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
> index ccf97266c0b9..3add505ff652 100644
> --- a/ofproto/ofproto-dpif-upcall.c
> +++ b/ofproto/ofproto-dpif-upcall.c
> @@ -327,6 +327,12 @@ struct ukey_op {
> struct dpif_op dop; /* Flow operation. */
> };
>
> +enum sweep_type {
> + PURGE_NONE,
> + PURGE_SOFT,
> + PURGE_HARD,
> +};
> +
> static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> static struct ovs_list all_udpifs = OVS_LIST_INITIALIZER(&all_udpifs);
>
> @@ -345,7 +351,7 @@ static unsigned long udpif_get_n_flows(struct udpif *);
> static void revalidate(struct revalidator *);
> static void revalidator_pause(struct revalidator *);
> static void revalidator_sweep(struct revalidator *);
> -static void revalidator_purge(struct revalidator *);
> +static void revalidator_purge(struct revalidator *, enum sweep_type);
> static void upcall_unixctl_show(struct unixctl_conn *conn, int argc,
> const char *argv[], void *aux);
> static void upcall_unixctl_disable_megaflows(struct unixctl_conn *, int argc,
> @@ -541,7 +547,7 @@ udpif_stop_threads(struct udpif *udpif, bool delete_flows)
>
> if (delete_flows) {
> for (i = 0; i < udpif->n_revalidators; i++) {
> - revalidator_purge(&udpif->revalidators[i]);
> + revalidator_purge(&udpif->revalidators[i], PURGE_HARD);
> }
> }
>
> @@ -2772,7 +2778,8 @@ revalidator_pause(struct revalidator *revalidator)
> }
>
> static void
> -revalidator_sweep__(struct revalidator *revalidator, bool purge)
> +revalidator_sweep__(struct revalidator *revalidator,
> + enum sweep_type sweep_type)
> {
> struct udpif *udpif;
> uint64_t dump_seq, reval_seq;
> @@ -2803,13 +2810,13 @@ revalidator_sweep__(struct revalidator *revalidator,
> bool purge)
> }
> ukey_state = ukey->state;
> if (ukey_state == UKEY_OPERATIONAL
> - || (ukey_state == UKEY_VISIBLE && purge)) {
> + || (ukey_state == UKEY_VISIBLE && sweep_type == PURGE_HARD))
> {
> struct recirc_refs recircs = RECIRC_REFS_EMPTY_INITIALIZER;
> bool seq_mismatch = (ukey->dump_seq != dump_seq
> && ukey->reval_seq != reval_seq);
> enum reval_result result;
>
> - if (purge) {
> + if (sweep_type > PURGE_NONE) {
> result = UKEY_DELETE;
> } else if (!seq_mismatch) {
> result = UKEY_KEEP;
> @@ -2856,13 +2863,13 @@ revalidator_sweep__(struct revalidator *revalidator,
> bool purge)
> static void
> revalidator_sweep(struct revalidator *revalidator)
> {
> - revalidator_sweep__(revalidator, false);
> + revalidator_sweep__(revalidator, PURGE_NONE);
> }
>
> static void
> -revalidator_purge(struct revalidator *revalidator)
> +revalidator_purge(struct revalidator *revalidator, enum sweep_type
> sweep_type)
> {
> - revalidator_sweep__(revalidator, true);
> + revalidator_sweep__(revalidator, sweep_type);
> }
>
> /* In reaction to dpif purge, purges all 'ukey's with same 'pmd_id'. */
> @@ -3056,7 +3063,7 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int
> argc OVS_UNUSED,
> int n;
>
> for (n = 0; n < udpif->n_revalidators; n++) {
> - revalidator_purge(&udpif->revalidators[n]);
> + revalidator_purge(&udpif->revalidators[n], PURGE_SOFT);
> }
> }
> unixctl_command_reply(conn, "");
> --
> 2.8.0
>
--
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev