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

Commit 630e1e0b authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'rcu/next' of...

Merge branch 'rcu/next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu

Conflicts:
	arch/x86/kernel/ptrace.c

Pull the latest RCU tree from Paul E. McKenney:

"       The major features of this series are:

  1.	A first version of no-callbacks CPUs.  This version prohibits
  	offlining CPU 0, but only when enabled via CONFIG_RCU_NOCB_CPU=y.
  	Relaxing this constraint is in progress, but not yet ready
  	for prime time.  These commits were posted to LKML at
  	https://lkml.org/lkml/2012/10/30/724, and are at branch rcu/nocb.

  2.	Changes to SRCU that allows statically initialized srcu_struct
  	structures.  These commits were posted to LKML at
  	https://lkml.org/lkml/2012/10/30/296, and are at branch rcu/srcu.

  3.	Restructuring of RCU's debugfs output.  These commits were posted
  	to LKML at https://lkml.org/lkml/2012/10/30/341, and are at
  	branch rcu/tracing.

  4.	Additional CPU-hotplug/RCU improvements, posted to LKML at
  	https://lkml.org/lkml/2012/10/30/327, and are at branch rcu/hotplug.
  	Note that the commit eliminating __stop_machine() was judged to
  	be too-high of risk, so is deferred to 3.9.

  5.	Changes to RCU's idle interface, most notably a new module
  	parameter that redirects normal grace-period operations to
  	their expedited equivalents.  These were posted to LKML at
  	https://lkml.org/lkml/2012/10/30/739, and are at branch rcu/idle.

  6.	Additional diagnostics for RCU's CPU stall warning facility,
  	posted to LKML at https://lkml.org/lkml/2012/10/30/315, and
  	are at branch rcu/stall.  The most notable change reduces the
  	default RCU CPU stall-warning time from 60 seconds to 21 seconds,
  	so that it once again happens sooner than the softlockup timeout.

  7.	Documentation updates, which were posted to LKML at
  	https://lkml.org/lkml/2012/10/30/280, and are at branch rcu/doc.
  	A couple of late-breaking changes were posted at
  	https://lkml.org/lkml/2012/11/16/634 and
  	https://lkml.org/lkml/2012/11/16/547.

  8.	Miscellaneous fixes, which were posted to LKML at
  	https://lkml.org/lkml/2012/10/30/309, along with a late-breaking
  	change posted at Fri, 16 Nov 2012 11:26:25 -0800 with message-ID
  	<20121116192625.GA447@linux.vnet.ibm.com>, but which lkml.org
  	seems to have missed.  These are at branch rcu/fixes.

  9.	Finally, a fix for an lockdep-RCU splat was posted to LKML
  	at https://lkml.org/lkml/2012/11/7/486

.  This is at rcu/next. "

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 7e5530af 91d1aa43
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -186,7 +186,7 @@ Bibtex Entries

@article{Kung80
,author="H. T. Kung and Q. Lehman"
,title="Concurrent Maintenance of Binary Search Trees"
,title="Concurrent Manipulation of Binary Search Trees"
,Year="1980"
,Month="September"
,journal="ACM Transactions on Database Systems"
+8 −9
Original line number Diff line number Diff line
@@ -271,15 +271,14 @@ over a rather long period of time, but improvements are always welcome!
	The same cautions apply to call_rcu_bh() and call_rcu_sched().

9.	All RCU list-traversal primitives, which include
	rcu_dereference(), list_for_each_entry_rcu(),
	list_for_each_continue_rcu(), and list_for_each_safe_rcu(),
	must be either within an RCU read-side critical section or
	must be protected by appropriate update-side locks.  RCU
	read-side critical sections are delimited by rcu_read_lock()
	and rcu_read_unlock(), or by similar primitives such as
	rcu_read_lock_bh() and rcu_read_unlock_bh(), in which case
	the matching rcu_dereference() primitive must be used in order
	to keep lockdep happy, in this case, rcu_dereference_bh().
	rcu_dereference(), list_for_each_entry_rcu(), and
	list_for_each_safe_rcu(), must be either within an RCU read-side
	critical section or must be protected by appropriate update-side
	locks.	RCU read-side critical sections are delimited by
	rcu_read_lock() and rcu_read_unlock(), or by similar primitives
	such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which
	case the matching rcu_dereference() primitive must be used in
	order to keep lockdep happy, in this case, rcu_dereference_bh().

	The reason that it is permissible to use RCU list-traversal
	primitives when the update-side lock is held is that doing so
+1 −1
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows:
				audit_copy_rule(&ne->rule, &e->rule);
				ne->rule.action = newaction;
				ne->rule.file_count = newfield_count;
				list_replace_rcu(e, ne);
				list_replace_rcu(&e->list, &ne->list);
				call_rcu(&e->rcu, audit_free_rule);
				return 0;
			}
+59 −2
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ release_referenced() delete()
{					{
    ...					    write_lock(&list_lock);
    atomic_dec(&el->rc, relfunc)	    ...
    ...					    delete_element
    ...					    remove_element
}					    write_unlock(&list_lock);
 					    ...
					    if (atomic_dec_and_test(&el->rc))
@@ -52,7 +52,7 @@ release_referenced() delete()
{					{
    ...					    spin_lock(&list_lock);
    if (atomic_dec_and_test(&el->rc))       ...
        call_rcu(&el->head, el_free);       delete_element
        call_rcu(&el->head, el_free);       remove_element
    ...                                     spin_unlock(&list_lock);
} 					    ...
					    if (atomic_dec_and_test(&el->rc))
@@ -64,3 +64,60 @@ Sometimes, a reference to the element needs to be obtained in the
update (write) stream.  In such cases, atomic_inc_not_zero() might be
overkill, since we hold the update-side spinlock.  One might instead
use atomic_inc() in such cases.

It is not always convenient to deal with "FAIL" in the
search_and_reference() code path.  In such cases, the
atomic_dec_and_test() may be moved from delete() to el_free()
as follows:

1.					2.
add()					search_and_reference()
{					{
    alloc_object			    rcu_read_lock();
    ...					    search_for_element
    atomic_set(&el->rc, 1);		    atomic_inc(&el->rc);
    spin_lock(&list_lock);		    ...

    add_element				    rcu_read_unlock();
    ...					}
    spin_unlock(&list_lock);		4.
}					delete()
3.					{
release_referenced()			    spin_lock(&list_lock);
{					    ...
    ...					    remove_element
    if (atomic_dec_and_test(&el->rc))       spin_unlock(&list_lock);
        kfree(el);			    ...
    ...                                     call_rcu(&el->head, el_free);
} 					    ...
5.					}
void el_free(struct rcu_head *rhp)
{
    release_referenced();
}

The key point is that the initial reference added by add() is not removed
until after a grace period has elapsed following removal.  This means that
search_and_reference() cannot find this element, which means that the value
of el->rc cannot increase.  Thus, once it reaches zero, there are no
readers that can or ever will be able to reference the element.  The
element can therefore safely be freed.  This in turn guarantees that if
any reader finds the element, that reader may safely acquire a reference
without checking the value of the reference counter.

In cases where delete() can sleep, synchronize_rcu() can be called from
delete(), so that el_free() can be subsumed into delete as follows:

4.
delete()
{
    spin_lock(&list_lock);
    ...
    remove_element
    spin_unlock(&list_lock);
    ...
    synchronize_rcu();
    if (atomic_dec_and_test(&el->rc))
    	kfree(el);
    ...
}
Loading