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