Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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