On Mon, Oct 12, 2015 at 06:23:51PM +0300, Petko Manolov wrote:
>  Content preview:  __list_splice_init_rcu() can be used to splice lists 
> forming
>     both stack and queue structures, depending on its arguments. It is based
>    on the initial list_splice_init_rcu() with a few minor modifications to 
> help
>     abstrancting it. [...] 
> 
>  Content analysis details:   (-1.0 points, 5.0 required)
> 
>   pts rule name              description
>  ---- ---------------------- 
> --------------------------------------------------
>  -1.0 ALL_TRUSTED            Passed through trusted hosts only via SMTP
>   0.0 TVD_RCVD_IP            Message was received from an IP address
> X-ZLA-Header: unknown; 0
> X-ZLA-DetailInfo: BA=6.00003790; NDR=6.00000001; ZLA=6.00000003; 
> ZF=6.00000009; ZB=6.00042595; ZH=6.00000000; ZP=6.00081149; ZU=6.00000002; 
> UDB=6.00264254; UTC=2015-10-12 15:24:07
> x-cbid: 15101215-0009-0000-0000-0000051B58C0
> X-IBM-ISS-SpamDetectors: Score=0.49; FLB=0; BY=0.040899; FL=0; FP=0; FZ=0;
>  HX=0; KW=0; PH=0; RB=0; SC=0.49; ST=0; TS=0; UL=0; ISC=
> X-IBM-ISS-DetailInfo:  BY=3.00004492; HX=3.00000236; KW=3.00000007;
>  PH=3.00000004; SC=3.00000118; SDB=6.00601725; UDB=6.00264254; UTC=2015-10-12
>  15:24:16
> X-TM-AS-MML: disable
> 
> __list_splice_init_rcu() can be used to splice lists forming both stack and
> queue structures, depending on its arguments.  It is based on the initial
> list_splice_init_rcu() with a few minor modifications to help abstrancting it.
> 
> Signed-off-by: Petko Manolov <[email protected]>

Much better, thank you!  Queued for testing and review.  If things go
well, it will make it into v4.5.

                                                        Thanx, Paul

> ---
>  include/linux/rculist.h | 69 
> +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 49 insertions(+), 20 deletions(-)
> 
> diff --git a/include/linux/rculist.h b/include/linux/rculist.h
> index 5ed5409..e99d834 100644
> --- a/include/linux/rculist.h
> +++ b/include/linux/rculist.h
> @@ -179,32 +179,31 @@ static inline void list_replace_rcu(struct list_head 
> *old,
>  }
> 
>  /**
> - * list_splice_init_rcu - splice an RCU-protected list into an existing list.
> + * __list_splice_init_rcu - join an RCU-protected list into an existing list.
>   * @list:    the RCU-protected list to splice
> - * @head:    the place in the list to splice the first list into
> + * @prev:    points to the last element of the existing list
> + * @next:    points to the first element of the existing list
>   * @sync:    function to sync: synchronize_rcu(), synchronize_sched(), ...
>   *
> - * @head can be RCU-read traversed concurrently with this function.
> + * The list pointed to by @prev and @next can be RCU-read traversed
> + * concurrently with this function.
>   *
>   * Note that this function blocks.
>   *
> - * Important note: the caller must take whatever action is necessary to
> - *   prevent any other updates to @head.  In principle, it is possible
> - *   to modify the list as soon as sync() begins execution.
> - *   If this sort of thing becomes necessary, an alternative version
> - *   based on call_rcu() could be created.  But only if -really-
> - *   needed -- there is no shortage of RCU API members.
> + * Important note: the caller must take whatever action is necessary to 
> prevent
> + * any other updates to the existing list.  In principle, it is possible to
> + * modify the list as soon as sync() begins execution. If this sort of thing
> + * becomes necessary, an alternative version based on call_rcu() could be
> + * created.  But only if -really- needed -- there is no shortage of RCU API
> + * members.
>   */
> -static inline void list_splice_init_rcu(struct list_head *list,
> -                                     struct list_head *head,
> -                                     void (*sync)(void))
> +static inline void __list_splice_init_rcu(struct list_head *list,
> +                                       struct list_head *prev,
> +                                       struct list_head *next,
> +                                       void (*sync)(void))
>  {
>       struct list_head *first = list->next;
>       struct list_head *last = list->prev;
> -     struct list_head *at = head->next;
> -
> -     if (list_empty(list))
> -             return;
> 
>       /*
>        * "first" and "last" tracking list, so initialize it.  RCU readers
> @@ -231,10 +230,40 @@ static inline void list_splice_init_rcu(struct 
> list_head *list,
>        * this function.
>        */
> 
> -     last->next = at;
> -     rcu_assign_pointer(list_next_rcu(head), first);
> -     first->prev = head;
> -     at->prev = last;
> +     last->next = next;
> +     rcu_assign_pointer(list_next_rcu(prev), first);
> +     first->prev = prev;
> +     next->prev = last;
> +}
> +
> +/**
> + * list_splice_init_rcu - splice an RCU-protected list into an existing list,
> + *                        designed for stacks.
> + * @list:    the RCU-protected list to splice
> + * @head:    the place in the existing list to splice the first list into
> + * @sync:    function to sync: synchronize_rcu(), synchronize_sched(), ...
> + */
> +static inline void list_splice_init_rcu(struct list_head *list,
> +                                     struct list_head *head,
> +                                     void (*sync)(void))
> +{
> +     if (!list_empty(list))
> +             __list_splice_init_rcu(list, head, head->next, sync);
> +}
> +
> +/**
> + * list_splice_tail_init_rcu - splice an RCU-protected list into an existing
> + *                             list, designed for queues.
> + * @list:    the RCU-protected list to splice
> + * @head:    the place in the existing list to splice the first list into
> + * @sync:    function to sync: synchronize_rcu(), synchronize_sched(), ...
> + */
> +static inline void list_splice_tail_init_rcu(struct list_head *list,
> +                                          struct list_head *head,
> +                                          void (*sync)(void))
> +{
> +     if (!list_empty(list))
> +             __list_splice_init_rcu(list, head->prev, head, sync);
>  }
> 
>  /**
> -- 
> 2.1.4
> 

--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to