On 14 May 2022, at 10:40, Peng He wrote:

> rcu_barrier will block the current thread until all the postponed
> rcu job has been finished. it's like the OVS's version of
> the kernel rcu_barrier()
>
> Signed-off-by: Peng He <hepeng.0...@bytedance.com>
> Co-authored-by: Eelco Chaudron <echau...@redhat.com>
> ---
>  lib/ovs-rcu.c | 38 ++++++++++++++++++++++++++++++++++++++
>  lib/ovs-rcu.h | 15 +++++++++++++++
>  2 files changed, 53 insertions(+)
>
> diff --git a/lib/ovs-rcu.c b/lib/ovs-rcu.c
> index 1866bd308..9fed53449 100644
> --- a/lib/ovs-rcu.c
> +++ b/lib/ovs-rcu.c
> @@ -444,3 +444,41 @@ ovsrcu_init_module(void)
>          ovsthread_once_done(&once);
>      }
>  }
> +
> +static void
> +ovsrcu_barrier_func(void *seq_)
> +{
> +    struct seq *seq = (struct seq *) seq_;
> +    seq_change(seq);
> +}
> +
> +
> +/* Similar to the kernel rcu_barrier, ovsrcu_barrier waits for all 
> outstanding
> + * RCU callbacks to complete. However, unlike the kernel rcu_barrier, which
> + * might retrun immediately if no outstanding RCU callbacks are pending,
> + * this API will at least wait for a grace period.
> + *
> + * Another issue the caller might need to know it's that the barrier is just
> + * for "one shot", i.e. if inside some RCU callbacks, another RCU callback is

Guess it should be one-shot.

> + * registered, this API only guarantee the first round of RCU callbacks have

Missing s, i.e. should be “guarantees”

> + * been executed.
> + */
> +void
> +ovsrcu_barrier(void)
> +{
> +    struct seq *seq = seq_create();
> +    /* First let all threads flush their cbsets */

Missing dot here at the end of the comment.

> +    ovsrcu_synchronize();
> +
> +    /* Then register a new cbset, ensure this cbset
> +     * is at the tail of the global list. */
> +    uint64_t seqno = seq_read(seq);
> +    ovsrcu_postpone__(ovsrcu_barrier_func, (void *) seq);
> +
> +    do {
> +        seq_wait(seq, seqno);
> +        poll_block();
> +    } while (seqno == seq_read(seq));
> +
> +    seq_destroy(seq);
> +}
> diff --git a/lib/ovs-rcu.h b/lib/ovs-rcu.h
> index ecc4c9201..7bdfa540b 100644
> --- a/lib/ovs-rcu.h
> +++ b/lib/ovs-rcu.h
> @@ -155,6 +155,19 @@
>   *         port_delete(id);
>   *     }
>   *
> + * Use ovsrcu_barrier() to wait for all the outstanding RCU callbacks to
> + * finish. This is useful when you have to destroy some resoures however
> + * these resoures are referenced in the outstanding RCU callbacks.

Two times resoures instead of resources.

> + *
> + * void rcu_cb(void *A) {
> + *     Use_A_do_something(A);
> + * }
> + *
> + * void destroy_A() {
> + *     ovsrcu_postpone(rcu_cb, A); // will use A later
> + *     ovsrcu_barrier(); // wait for rcu_cb done
> + *     do_destroy_A(); // free A
> + * }
>   */
>
>  #include "compiler.h"
> @@ -310,4 +323,6 @@ void ovsrcu_synchronize(void);
>
>  void ovsrcu_exit(void);
>
> +void ovsrcu_barrier(void);
> +
>  #endif /* ovs-rcu.h */
> -- 
> 2.25.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to