Commit 648c630c authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

Merge branches 'doc.2015.12.05a', 'exp.2015.12.07a', 'fixes.2015.12.07a',...

Merge branches 'doc.2015.12.05a', 'exp.2015.12.07a', 'fixes.2015.12.07a', 'list.2015.12.04b' and 'torture.2015.12.05a' into HEAD

doc.2015.12.05a:  Documentation updates
exp.2015.12.07a:  Expedited grace-period updates
fixes.2015.12.07a:  Miscellaneous fixes
list.2015.12.04b:  Linked-list updates
torture.2015.12.05a:  Torture-test updates
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -3296,18 +3296,35 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
	rcutorture.verbose= [KNL]
			Enable additional printk() statements.

	rcupdate.rcu_cpu_stall_suppress= [KNL]
			Suppress RCU CPU stall warning messages.

	rcupdate.rcu_cpu_stall_timeout= [KNL]
			Set timeout for RCU CPU stall warning messages.

	rcupdate.rcu_expedited= [KNL]
			Use expedited grace-period primitives, for
			example, synchronize_rcu_expedited() instead
			of synchronize_rcu().  This reduces latency,
			but can increase CPU utilization, degrade
			real-time latency, and degrade energy efficiency.

	rcupdate.rcu_cpu_stall_suppress= [KNL]
			Suppress RCU CPU stall warning messages.

	rcupdate.rcu_cpu_stall_timeout= [KNL]
			Set timeout for RCU CPU stall warning messages.
			No effect on CONFIG_TINY_RCU kernels.

	rcupdate.rcu_normal= [KNL]
			Use only normal grace-period primitives,
			for example, synchronize_rcu() instead of
			synchronize_rcu_expedited().  This improves
			real-time latency, CPU utilization, and
			energy efficiency, but can expose users to
			increased grace-period latency.  This parameter
			overrides rcupdate.rcu_expedited.  No effect on
			CONFIG_TINY_RCU kernels.

	rcupdate.rcu_normal_after_boot= [KNL]
			Once boot has completed (that is, after
			rcu_end_inkernel_boot() has been invoked), use
			only normal grace-period primitives.  No effect
			on CONFIG_TINY_RCU kernels.

	rcupdate.rcu_task_stall_timeout= [KNL]
			Set timeout in jiffies for RCU task stall warning
+7 −7
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	WRITE_ONCE(list->next, list);
	list->prev = list;
}

@@ -42,7 +42,7 @@ static inline void __list_add(struct list_head *new,
	next->prev = new;
	new->next = next;
	new->prev = prev;
	prev->next = new;
	WRITE_ONCE(prev->next, new);
}
#else
extern void __list_add(struct list_head *new,
@@ -186,7 +186,7 @@ static inline int list_is_last(const struct list_head *list,
 */
static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
	return READ_ONCE(head->next) == head;
}

/**
@@ -608,7 +608,7 @@ static inline int hlist_unhashed(const struct hlist_node *h)

static inline int hlist_empty(const struct hlist_head *h)
{
	return !h->first;
	return !READ_ONCE(h->first);
}

static inline void __hlist_del(struct hlist_node *n)
@@ -642,7 +642,7 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
	n->next = first;
	if (first)
		first->pprev = &n->next;
	h->first = n;
	WRITE_ONCE(h->first, n);
	n->pprev = &h->first;
}

@@ -653,14 +653,14 @@ static inline void hlist_add_before(struct hlist_node *n,
	n->pprev = next->pprev;
	n->next = next;
	next->pprev = &n->next;
	*(n->pprev) = n;
	WRITE_ONCE(*(n->pprev), n);
}

static inline void hlist_add_behind(struct hlist_node *n,
				    struct hlist_node *prev)
{
	n->next = prev->next;
	prev->next = n;
	WRITE_ONCE(prev->next, n);
	n->pprev = &prev->next;

	if (n->next)
+1 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ static inline void hlist_bl_set_first(struct hlist_bl_head *h,

static inline int hlist_bl_empty(const struct hlist_bl_head *h)
{
	return !((unsigned long)h->first & ~LIST_BL_LOCKMASK);
	return !((unsigned long)READ_ONCE(h->first) & ~LIST_BL_LOCKMASK);
}

static inline void hlist_bl_add_head(struct hlist_bl_node *n,
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ static inline int hlist_nulls_unhashed(const struct hlist_nulls_node *h)

static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
{
	return is_a_nulls(h->first);
	return is_a_nulls(READ_ONCE(h->first));
}

static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,
+85 −20
Original line number Diff line number Diff line
@@ -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,
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);
}

/**
@@ -304,6 +333,42 @@ static inline void list_splice_init_rcu(struct list_head *list,
		&pos->member != (head); \
		pos = list_entry_rcu(pos->member.next, typeof(*pos), member))

/**
 * list_entry_lockless - get the struct for this entry
 * @ptr:        the &struct list_head pointer.
 * @type:       the type of the struct this is embedded in.
 * @member:     the name of the list_head within the struct.
 *
 * This primitive may safely run concurrently with the _rcu list-mutation
 * primitives such as list_add_rcu(), but requires some implicit RCU
 * read-side guarding.  One example is running within a special
 * exception-time environment where preemption is disabled and where
 * lockdep cannot be invoked (in which case updaters must use RCU-sched,
 * as in synchronize_sched(), call_rcu_sched(), and friends).  Another
 * example is when items are added to the list, but never deleted.
 */
#define list_entry_lockless(ptr, type, member) \
	container_of((typeof(ptr))lockless_dereference(ptr), type, member)

/**
 * list_for_each_entry_lockless - iterate over rcu list of given type
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_struct within the struct.
 *
 * This primitive may safely run concurrently with the _rcu list-mutation
 * primitives such as list_add_rcu(), but requires some implicit RCU
 * read-side guarding.  One example is running within a special
 * exception-time environment where preemption is disabled and where
 * lockdep cannot be invoked (in which case updaters must use RCU-sched,
 * as in synchronize_sched(), call_rcu_sched(), and friends).  Another
 * example is when items are added to the list, but never deleted.
 */
#define list_for_each_entry_lockless(pos, head, member) \
	for (pos = list_entry_lockless((head)->next, typeof(*pos), member); \
	     &pos->member != (head); \
	     pos = list_entry_lockless(pos->member.next, typeof(*pos), member))

/**
 * list_for_each_entry_continue_rcu - continue iteration over list of given type
 * @pos:	the type * to use as a loop cursor.
Loading