On Sun, Sep 27, 2015 at 06:10:28PM +0300, Petko Manolov wrote:
> __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 abstracting it.
>
> Signed-off-by: Petko Manolov <[email protected]>
At first glance, this looks sane.
But who is using the new list_splice_tail_init_rcu() function?
Thanx, Paul
> ---
> include/linux/rculist.h | 72
> ++++++++++++++++++++++++++++++-------------------
> 1 file changed, 44 insertions(+), 28 deletions(-)
>
> diff --git a/include/linux/rculist.h b/include/linux/rculist.h
> index 17c6b1f..4282236 100644
> --- a/include/linux/rculist.h
> +++ b/include/linux/rculist.h
> @@ -178,33 +178,13 @@ static inline void list_replace_rcu(struct list_head
> *old,
> old->prev = LIST_POISON2;
> }
>
> -/**
> - * list_splice_init_rcu - splice 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
> - * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ...
> - *
> - * @head 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.
> - */
> -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 +211,46 @@ 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.
> + * @list: the RCU-protected list to splice
> + * @head: the place in the list to splice the first list into
> + * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ...
> + *
> + * @head 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.
> + */
> +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 - same as above, but creates a queue
> + */
> +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