Merge branch 'linus' into core/objtool, to pick up dependent commits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
1
.mailmap
@@ -102,6 +102,7 @@ Leonid I Ananiev <leonid.i.ananiev@intel.com>
|
|||||||
Linas Vepstas <linas@austin.ibm.com>
|
Linas Vepstas <linas@austin.ibm.com>
|
||||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
|
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
|
||||||
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
|
Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
|
||||||
|
Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
|
||||||
Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
|
Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
|
||||||
Mark Brown <broonie@sirena.org.uk>
|
Mark Brown <broonie@sirena.org.uk>
|
||||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
||||||
|
9
CREDITS
@@ -2113,6 +2113,10 @@ S: J. Obrechtstr 23
|
|||||||
S: NL-5216 GP 's-Hertogenbosch
|
S: NL-5216 GP 's-Hertogenbosch
|
||||||
S: The Netherlands
|
S: The Netherlands
|
||||||
|
|
||||||
|
N: Ashley Lai
|
||||||
|
E: ashleydlai@gmail.com
|
||||||
|
D: IBM VTPM driver
|
||||||
|
|
||||||
N: Savio Lam
|
N: Savio Lam
|
||||||
E: lam836@cs.cuhk.hk
|
E: lam836@cs.cuhk.hk
|
||||||
D: Author of the dialog utility, foundation
|
D: Author of the dialog utility, foundation
|
||||||
@@ -3333,6 +3337,10 @@ S: Braunschweiger Strasse 79
|
|||||||
S: 31134 Hildesheim
|
S: 31134 Hildesheim
|
||||||
S: Germany
|
S: Germany
|
||||||
|
|
||||||
|
N: Marcel Selhorst
|
||||||
|
E: tpmdd@selhorst.net
|
||||||
|
D: TPM driver
|
||||||
|
|
||||||
N: Darren Senn
|
N: Darren Senn
|
||||||
E: sinster@darkwater.com
|
E: sinster@darkwater.com
|
||||||
D: Whatever I notice needs doing (so far: itimers, /proc)
|
D: Whatever I notice needs doing (so far: itimers, /proc)
|
||||||
@@ -4128,7 +4136,6 @@ D: MD driver
|
|||||||
D: EISA/sysfs subsystem
|
D: EISA/sysfs subsystem
|
||||||
S: France
|
S: France
|
||||||
|
|
||||||
|
|
||||||
# Don't add your name here, unless you really _are_ after Marc
|
# Don't add your name here, unless you really _are_ after Marc
|
||||||
# alphabetically. Leonard used to be very proud of being the
|
# alphabetically. Leonard used to be very proud of being the
|
||||||
# last entry, and he'll get positively pissed if he can't even
|
# last entry, and he'll get positively pissed if he can't even
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# Note: This documents additional properties of any device beyond what
|
# Note: This documents additional properties of any device beyond what
|
||||||
# is documented in Documentation/sysfs-rules.txt
|
# is documented in Documentation/admin-guide/sysfs-rules.rst
|
||||||
|
|
||||||
What: /sys/devices/*/of_node
|
What: /sys/devices/*/of_node
|
||||||
Date: February 2015
|
Date: February 2015
|
||||||
|
@@ -7,17 +7,37 @@ Description:
|
|||||||
HMAC-sha1 value across the extended attributes, storing the
|
HMAC-sha1 value across the extended attributes, storing the
|
||||||
value as the extended attribute 'security.evm'.
|
value as the extended attribute 'security.evm'.
|
||||||
|
|
||||||
EVM depends on the Kernel Key Retention System to provide it
|
EVM supports two classes of security.evm. The first is
|
||||||
with a trusted/encrypted key for the HMAC-sha1 operation.
|
an HMAC-sha1 generated locally with a
|
||||||
The key is loaded onto the root's keyring using keyctl. Until
|
trusted/encrypted key stored in the Kernel Key
|
||||||
EVM receives notification that the key has been successfully
|
Retention System. The second is a digital signature
|
||||||
loaded onto the keyring (echo 1 > <securityfs>/evm), EVM
|
generated either locally or remotely using an
|
||||||
can not create or validate the 'security.evm' xattr, but
|
asymmetric key. These keys are loaded onto root's
|
||||||
returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM
|
keyring using keyctl, and EVM is then enabled by
|
||||||
should be done as early as possible. Normally this is done
|
echoing a value to <securityfs>/evm:
|
||||||
in the initramfs, which has already been measured as part
|
|
||||||
of the trusted boot. For more information on creating and
|
1: enable HMAC validation and creation
|
||||||
loading existing trusted/encrypted keys, refer to:
|
2: enable digital signature validation
|
||||||
Documentation/keys-trusted-encrypted.txt. (A sample dracut
|
3: enable HMAC and digital signature validation and HMAC
|
||||||
patch, which loads the trusted/encrypted key and enables
|
creation
|
||||||
EVM, is available from http://linux-ima.sourceforge.net/#EVM.)
|
|
||||||
|
Further writes will be blocked if HMAC support is enabled or
|
||||||
|
if bit 32 is set:
|
||||||
|
|
||||||
|
echo 0x80000002 ><securityfs>/evm
|
||||||
|
|
||||||
|
will enable digital signature validation and block
|
||||||
|
further writes to <securityfs>/evm.
|
||||||
|
|
||||||
|
Until this is done, EVM can not create or validate the
|
||||||
|
'security.evm' xattr, but returns INTEGRITY_UNKNOWN.
|
||||||
|
Loading keys and signaling EVM should be done as early
|
||||||
|
as possible. Normally this is done in the initramfs,
|
||||||
|
which has already been measured as part of the trusted
|
||||||
|
boot. For more information on creating and loading
|
||||||
|
existing trusted/encrypted keys, refer to:
|
||||||
|
|
||||||
|
Documentation/security/keys/trusted-encrypted.rst. Both dracut
|
||||||
|
(via 97masterkey and 98integrity) and systemd (via
|
||||||
|
core/ima-setup) have support for loading keys at boot
|
||||||
|
time.
|
||||||
|
4
Documentation/ABI/testing/sysfs-bus-mmc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
What: /sys/bus/mmc/devices/.../rev
|
||||||
|
Date: October 2017
|
||||||
|
Contact: Jin Qian <jinqian@android.com>
|
||||||
|
Description: Extended CSD revision number
|
@@ -187,7 +187,8 @@ Description: Processor frequency boosting control
|
|||||||
This switch controls the boost setting for the whole system.
|
This switch controls the boost setting for the whole system.
|
||||||
Boosting allows the CPU and the firmware to run at a frequency
|
Boosting allows the CPU and the firmware to run at a frequency
|
||||||
beyound it's nominal limit.
|
beyound it's nominal limit.
|
||||||
More details can be found in Documentation/cpu-freq/boost.txt
|
More details can be found in
|
||||||
|
Documentation/admin-guide/pm/cpufreq.rst
|
||||||
|
|
||||||
|
|
||||||
What: /sys/devices/system/cpu/cpu#/crash_notes
|
What: /sys/devices/system/cpu/cpu#/crash_notes
|
||||||
@@ -223,7 +224,8 @@ Description: Parameters for the Intel P-state driver
|
|||||||
no_turbo: limits the driver to selecting P states below the turbo
|
no_turbo: limits the driver to selecting P states below the turbo
|
||||||
frequency range.
|
frequency range.
|
||||||
|
|
||||||
More details can be found in Documentation/cpu-freq/intel-pstate.txt
|
More details can be found in
|
||||||
|
Documentation/admin-guide/pm/intel_pstate.rst
|
||||||
|
|
||||||
What: /sys/devices/system/cpu/cpu*/cache/index*/<set_of_attributes_mentioned_below>
|
What: /sys/devices/system/cpu/cpu*/cache/index*/<set_of_attributes_mentioned_below>
|
||||||
Date: July 2014(documented, existed before August 2008)
|
Date: July 2014(documented, existed before August 2008)
|
||||||
|
@@ -18,7 +18,8 @@ Description:
|
|||||||
Writing one of the above strings to this file causes the system
|
Writing one of the above strings to this file causes the system
|
||||||
to transition into the corresponding state, if available.
|
to transition into the corresponding state, if available.
|
||||||
|
|
||||||
See Documentation/power/states.txt for more information.
|
See Documentation/admin-guide/pm/sleep-states.rst for more
|
||||||
|
information.
|
||||||
|
|
||||||
What: /sys/power/mem_sleep
|
What: /sys/power/mem_sleep
|
||||||
Date: November 2016
|
Date: November 2016
|
||||||
@@ -35,7 +36,8 @@ Description:
|
|||||||
represented by it to be used on subsequent attempts to suspend
|
represented by it to be used on subsequent attempts to suspend
|
||||||
the system.
|
the system.
|
||||||
|
|
||||||
See Documentation/power/states.txt for more information.
|
See Documentation/admin-guide/pm/sleep-states.rst for more
|
||||||
|
information.
|
||||||
|
|
||||||
What: /sys/power/disk
|
What: /sys/power/disk
|
||||||
Date: September 2006
|
Date: September 2006
|
||||||
|
@@ -97,6 +97,9 @@ endif # HAVE_SPHINX
|
|||||||
# The following targets are independent of HAVE_SPHINX, and the rules should
|
# The following targets are independent of HAVE_SPHINX, and the rules should
|
||||||
# work or silently pass without Sphinx.
|
# work or silently pass without Sphinx.
|
||||||
|
|
||||||
|
refcheckdocs:
|
||||||
|
$(Q)cd $(srctree);scripts/documentation-file-ref-check
|
||||||
|
|
||||||
cleandocs:
|
cleandocs:
|
||||||
$(Q)rm -rf $(BUILDDIR)
|
$(Q)rm -rf $(BUILDDIR)
|
||||||
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
||||||
@@ -109,6 +112,7 @@ dochelp:
|
|||||||
@echo ' epubdocs - EPUB'
|
@echo ' epubdocs - EPUB'
|
||||||
@echo ' xmldocs - XML'
|
@echo ' xmldocs - XML'
|
||||||
@echo ' linkcheckdocs - check for broken external links (will connect to external hosts)'
|
@echo ' linkcheckdocs - check for broken external links (will connect to external hosts)'
|
||||||
|
@echo ' refcheckdocs - check for references to non-existing files under Documentation'
|
||||||
@echo ' cleandocs - clean all generated files'
|
@echo ' cleandocs - clean all generated files'
|
||||||
@echo
|
@echo
|
||||||
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
||||||
@@ -116,3 +120,5 @@ dochelp:
|
|||||||
@echo
|
@echo
|
||||||
@echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build'
|
@echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build'
|
||||||
@echo ' configuration. This is e.g. useful to build with nit-picking config.'
|
@echo ' configuration. This is e.g. useful to build with nit-picking config.'
|
||||||
|
@echo
|
||||||
|
@echo ' Default location for the generated documents is Documentation/output'
|
||||||
|
@@ -527,7 +527,7 @@ grace period also drove it to completion.
|
|||||||
This straightforward approach had the disadvantage of needing to
|
This straightforward approach had the disadvantage of needing to
|
||||||
account for POSIX signals sent to user tasks,
|
account for POSIX signals sent to user tasks,
|
||||||
so more recent implemementations use the Linux kernel's
|
so more recent implemementations use the Linux kernel's
|
||||||
<a href="https://www.kernel.org/doc/Documentation/workqueue.txt">workqueues</a>.
|
<a href="https://www.kernel.org/doc/Documentation/core-api/workqueue.rst">workqueues</a>.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The requesting task still does counter snapshotting and funnel-lock
|
The requesting task still does counter snapshotting and funnel-lock
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head><title>A Diagram of TREE_RCU's Grace-Period Memory Ordering</title>
|
||||||
|
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
|
||||||
|
<p><img src="TreeRCU-gp.svg" alt="TreeRCU-gp.svg">
|
||||||
|
|
||||||
|
</body></html>
|
@@ -0,0 +1,707 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head><title>A Tour Through TREE_RCU's Grace-Period Memory Ordering</title>
|
||||||
|
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
|
||||||
|
<p>August 8, 2017</p>
|
||||||
|
<p>This article was contributed by Paul E. McKenney</p>
|
||||||
|
|
||||||
|
<h3>Introduction</h3>
|
||||||
|
|
||||||
|
<p>This document gives a rough visual overview of how Tree RCU's
|
||||||
|
grace-period memory ordering guarantee is provided.
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> <a href="#What Is Tree RCU's Grace Period Memory Ordering Guarantee?">
|
||||||
|
What Is Tree RCU's Grace Period Memory Ordering Guarantee?</a>
|
||||||
|
<li> <a href="#Tree RCU Grace Period Memory Ordering Building Blocks">
|
||||||
|
Tree RCU Grace Period Memory Ordering Building Blocks</a>
|
||||||
|
<li> <a href="#Tree RCU Grace Period Memory Ordering Components">
|
||||||
|
Tree RCU Grace Period Memory Ordering Components</a>
|
||||||
|
<li> <a href="#Putting It All Together">Putting It All Together</a>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h3><a name="What Is Tree RCU's Grace Period Memory Ordering Guarantee?">
|
||||||
|
What Is Tree RCU's Grace Period Memory Ordering Guarantee?</a></h3>
|
||||||
|
|
||||||
|
<p>RCU grace periods provide extremely strong memory-ordering guarantees
|
||||||
|
for non-idle non-offline code.
|
||||||
|
Any code that happens after the end of a given RCU grace period is guaranteed
|
||||||
|
to see the effects of all accesses prior to the beginning of that grace
|
||||||
|
period that are within RCU read-side critical sections.
|
||||||
|
Similarly, any code that happens before the beginning of a given RCU grace
|
||||||
|
period is guaranteed to see the effects of all accesses following the end
|
||||||
|
of that grace period that are within RCU read-side critical sections.
|
||||||
|
|
||||||
|
<p>This guarantee is particularly pervasive for <tt>synchronize_sched()</tt>,
|
||||||
|
for which RCU-sched read-side critical sections include any region
|
||||||
|
of code for which preemption is disabled.
|
||||||
|
Given that each individual machine instruction can be thought of as
|
||||||
|
an extremely small region of preemption-disabled code, one can think of
|
||||||
|
<tt>synchronize_sched()</tt> as <tt>smp_mb()</tt> on steroids.
|
||||||
|
|
||||||
|
<p>RCU updaters use this guarantee by splitting their updates into
|
||||||
|
two phases, one of which is executed before the grace period and
|
||||||
|
the other of which is executed after the grace period.
|
||||||
|
In the most common use case, phase one removes an element from
|
||||||
|
a linked RCU-protected data structure, and phase two frees that element.
|
||||||
|
For this to work, any readers that have witnessed state prior to the
|
||||||
|
phase-one update (in the common case, removal) must not witness state
|
||||||
|
following the phase-two update (in the common case, freeing).
|
||||||
|
|
||||||
|
<p>The RCU implementation provides this guarantee using a network
|
||||||
|
of lock-based critical sections, memory barriers, and per-CPU
|
||||||
|
processing, as is described in the following sections.
|
||||||
|
|
||||||
|
<h3><a name="Tree RCU Grace Period Memory Ordering Building Blocks">
|
||||||
|
Tree RCU Grace Period Memory Ordering Building Blocks</a></h3>
|
||||||
|
|
||||||
|
<p>The workhorse for RCU's grace-period memory ordering is the
|
||||||
|
critical section for the <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->lock</tt>.
|
||||||
|
These critical sections use helper functions for lock acquisition, including
|
||||||
|
<tt>raw_spin_lock_rcu_node()</tt>,
|
||||||
|
<tt>raw_spin_lock_irq_rcu_node()</tt>, and
|
||||||
|
<tt>raw_spin_lock_irqsave_rcu_node()</tt>.
|
||||||
|
Their lock-release counterparts are
|
||||||
|
<tt>raw_spin_unlock_rcu_node()</tt>,
|
||||||
|
<tt>raw_spin_unlock_irq_rcu_node()</tt>, and
|
||||||
|
<tt>raw_spin_unlock_irqrestore_rcu_node()</tt>,
|
||||||
|
respectively.
|
||||||
|
For completeness, a
|
||||||
|
<tt>raw_spin_trylock_rcu_node()</tt>
|
||||||
|
is also provided.
|
||||||
|
The key point is that the lock-acquisition functions, including
|
||||||
|
<tt>raw_spin_trylock_rcu_node()</tt>, all invoke
|
||||||
|
<tt>smp_mb__after_unlock_lock()</tt> immediately after successful
|
||||||
|
acquisition of the lock.
|
||||||
|
|
||||||
|
<p>Therefore, for any given <tt>rcu_node</tt> struction, any access
|
||||||
|
happening before one of the above lock-release functions will be seen
|
||||||
|
by all CPUs as happening before any access happening after a later
|
||||||
|
one of the above lock-acquisition functions.
|
||||||
|
Furthermore, any access happening before one of the
|
||||||
|
above lock-release function on any given CPU will be seen by all
|
||||||
|
CPUs as happening before any access happening after a later one
|
||||||
|
of the above lock-acquisition functions executing on that same CPU,
|
||||||
|
even if the lock-release and lock-acquisition functions are operating
|
||||||
|
on different <tt>rcu_node</tt> structures.
|
||||||
|
Tree RCU uses these two ordering guarantees to form an ordering
|
||||||
|
network among all CPUs that were in any way involved in the grace
|
||||||
|
period, including any CPUs that came online or went offline during
|
||||||
|
the grace period in question.
|
||||||
|
|
||||||
|
<p>The following litmus test exhibits the ordering effects of these
|
||||||
|
lock-acquisition and lock-release functions:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
1 int x, y, z;
|
||||||
|
2
|
||||||
|
3 void task0(void)
|
||||||
|
4 {
|
||||||
|
5 raw_spin_lock_rcu_node(rnp);
|
||||||
|
6 WRITE_ONCE(x, 1);
|
||||||
|
7 r1 = READ_ONCE(y);
|
||||||
|
8 raw_spin_unlock_rcu_node(rnp);
|
||||||
|
9 }
|
||||||
|
10
|
||||||
|
11 void task1(void)
|
||||||
|
12 {
|
||||||
|
13 raw_spin_lock_rcu_node(rnp);
|
||||||
|
14 WRITE_ONCE(y, 1);
|
||||||
|
15 r2 = READ_ONCE(z);
|
||||||
|
16 raw_spin_unlock_rcu_node(rnp);
|
||||||
|
17 }
|
||||||
|
18
|
||||||
|
19 void task2(void)
|
||||||
|
20 {
|
||||||
|
21 WRITE_ONCE(z, 1);
|
||||||
|
22 smp_mb();
|
||||||
|
23 r3 = READ_ONCE(x);
|
||||||
|
24 }
|
||||||
|
25
|
||||||
|
26 WARN_ON(r1 == 0 && r2 == 0 && r3 == 0);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>The <tt>WARN_ON()</tt> is evaluated at “the end of time”,
|
||||||
|
after all changes have propagated throughout the system.
|
||||||
|
Without the <tt>smp_mb__after_unlock_lock()</tt> provided by the
|
||||||
|
acquisition functions, this <tt>WARN_ON()</tt> could trigger, for example
|
||||||
|
on PowerPC.
|
||||||
|
The <tt>smp_mb__after_unlock_lock()</tt> invocations prevent this
|
||||||
|
<tt>WARN_ON()</tt> from triggering.
|
||||||
|
|
||||||
|
<p>This approach must be extended to include idle CPUs, which need
|
||||||
|
RCU's grace-period memory ordering guarantee to extend to any
|
||||||
|
RCU read-side critical sections preceding and following the current
|
||||||
|
idle sojourn.
|
||||||
|
This case is handled by calls to the strongly ordered
|
||||||
|
<tt>atomic_add_return()</tt> read-modify-write atomic operation that
|
||||||
|
is invoked within <tt>rcu_dynticks_eqs_enter()</tt> at idle-entry
|
||||||
|
time and within <tt>rcu_dynticks_eqs_exit()</tt> at idle-exit time.
|
||||||
|
The grace-period kthread invokes <tt>rcu_dynticks_snap()</tt> and
|
||||||
|
<tt>rcu_dynticks_in_eqs_since()</tt> (both of which invoke
|
||||||
|
an <tt>atomic_add_return()</tt> of zero) to detect idle CPUs.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
But what about CPUs that remain offline for the entire
|
||||||
|
grace period?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
Such CPUs will be offline at the beginning of the grace period,
|
||||||
|
so the grace period won't expect quiescent states from them.
|
||||||
|
Races between grace-period start and CPU-hotplug operations
|
||||||
|
are mediated by the CPU's leaf <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->lock</tt> as described above.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>The approach must be extended to handle one final case, that
|
||||||
|
of waking a task blocked in <tt>synchronize_rcu()</tt>.
|
||||||
|
This task might be affinitied to a CPU that is not yet aware that
|
||||||
|
the grace period has ended, and thus might not yet be subject to
|
||||||
|
the grace period's memory ordering.
|
||||||
|
Therefore, there is an <tt>smp_mb()</tt> after the return from
|
||||||
|
<tt>wait_for_completion()</tt> in the <tt>synchronize_rcu()</tt>
|
||||||
|
code path.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
What? Where???
|
||||||
|
I don't see any <tt>smp_mb()</tt> after the return from
|
||||||
|
<tt>wait_for_completion()</tt>!!!
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
That would be because I spotted the need for that
|
||||||
|
<tt>smp_mb()</tt> during the creation of this documentation,
|
||||||
|
and it is therefore unlikely to hit mainline before v4.14.
|
||||||
|
Kudos to Lance Roy, Will Deacon, Peter Zijlstra, and
|
||||||
|
Jonathan Cameron for asking questions that sensitized me
|
||||||
|
to the rather elaborate sequence of events that demonstrate
|
||||||
|
the need for this memory barrier.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>Tree RCU's grace--period memory-ordering guarantees rely most
|
||||||
|
heavily on the <tt>rcu_node</tt> structure's <tt>->lock</tt>
|
||||||
|
field, so much so that it is necessary to abbreviate this pattern
|
||||||
|
in the diagrams in the next section.
|
||||||
|
For example, consider the <tt>rcu_prepare_for_idle()</tt> function
|
||||||
|
shown below, which is one of several functions that enforce ordering
|
||||||
|
of newly arrived RCU callbacks against future grace periods:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
1 static void rcu_prepare_for_idle(void)
|
||||||
|
2 {
|
||||||
|
3 bool needwake;
|
||||||
|
4 struct rcu_data *rdp;
|
||||||
|
5 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
||||||
|
6 struct rcu_node *rnp;
|
||||||
|
7 struct rcu_state *rsp;
|
||||||
|
8 int tne;
|
||||||
|
9
|
||||||
|
10 if (IS_ENABLED(CONFIG_RCU_NOCB_CPU_ALL) ||
|
||||||
|
11 rcu_is_nocb_cpu(smp_processor_id()))
|
||||||
|
12 return;
|
||||||
|
13 tne = READ_ONCE(tick_nohz_active);
|
||||||
|
14 if (tne != rdtp->tick_nohz_enabled_snap) {
|
||||||
|
15 if (rcu_cpu_has_callbacks(NULL))
|
||||||
|
16 invoke_rcu_core();
|
||||||
|
17 rdtp->tick_nohz_enabled_snap = tne;
|
||||||
|
18 return;
|
||||||
|
19 }
|
||||||
|
20 if (!tne)
|
||||||
|
21 return;
|
||||||
|
22 if (rdtp->all_lazy &&
|
||||||
|
23 rdtp->nonlazy_posted != rdtp->nonlazy_posted_snap) {
|
||||||
|
24 rdtp->all_lazy = false;
|
||||||
|
25 rdtp->nonlazy_posted_snap = rdtp->nonlazy_posted;
|
||||||
|
26 invoke_rcu_core();
|
||||||
|
27 return;
|
||||||
|
28 }
|
||||||
|
29 if (rdtp->last_accelerate == jiffies)
|
||||||
|
30 return;
|
||||||
|
31 rdtp->last_accelerate = jiffies;
|
||||||
|
32 for_each_rcu_flavor(rsp) {
|
||||||
|
33 rdp = this_cpu_ptr(rsp->rda);
|
||||||
|
34 if (rcu_segcblist_pend_cbs(&rdp->cblist))
|
||||||
|
35 continue;
|
||||||
|
36 rnp = rdp->mynode;
|
||||||
|
37 raw_spin_lock_rcu_node(rnp);
|
||||||
|
38 needwake = rcu_accelerate_cbs(rsp, rnp, rdp);
|
||||||
|
39 raw_spin_unlock_rcu_node(rnp);
|
||||||
|
40 if (needwake)
|
||||||
|
41 rcu_gp_kthread_wake(rsp);
|
||||||
|
42 }
|
||||||
|
43 }
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>But the only part of <tt>rcu_prepare_for_idle()</tt> that really
|
||||||
|
matters for this discussion are lines 37–39.
|
||||||
|
We will therefore abbreviate this function as follows:
|
||||||
|
|
||||||
|
</p><p><img src="rcu_node-lock.svg" alt="rcu_node-lock.svg">
|
||||||
|
|
||||||
|
<p>The box represents the <tt>rcu_node</tt> structure's <tt>->lock</tt>
|
||||||
|
critical section, with the double line on top representing the additional
|
||||||
|
<tt>smp_mb__after_unlock_lock()</tt>.
|
||||||
|
|
||||||
|
<h3><a name="Tree RCU Grace Period Memory Ordering Components">
|
||||||
|
Tree RCU Grace Period Memory Ordering Components</a></h3>
|
||||||
|
|
||||||
|
<p>Tree RCU's grace-period memory-ordering guarantee is provided by
|
||||||
|
a number of RCU components:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> <a href="#Callback Registry">Callback Registry</a>
|
||||||
|
<li> <a href="#Grace-Period Initialization">Grace-Period Initialization</a>
|
||||||
|
<li> <a href="#Self-Reported Quiescent States">
|
||||||
|
Self-Reported Quiescent States</a>
|
||||||
|
<li> <a href="#Dynamic Tick Interface">Dynamic Tick Interface</a>
|
||||||
|
<li> <a href="#CPU-Hotplug Interface">CPU-Hotplug Interface</a>
|
||||||
|
<li> <a href="Forcing Quiescent States">Forcing Quiescent States</a>
|
||||||
|
<li> <a href="Grace-Period Cleanup">Grace-Period Cleanup</a>
|
||||||
|
<li> <a href="Callback Invocation">Callback Invocation</a>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>Each of the following section looks at the corresponding component
|
||||||
|
in detail.
|
||||||
|
|
||||||
|
<h4><a name="Callback Registry">Callback Registry</a></h4>
|
||||||
|
|
||||||
|
<p>If RCU's grace-period guarantee is to mean anything at all, any
|
||||||
|
access that happens before a given invocation of <tt>call_rcu()</tt>
|
||||||
|
must also happen before the corresponding grace period.
|
||||||
|
The implementation of this portion of RCU's grace period guarantee
|
||||||
|
is shown in the following figure:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-callback-registry.svg" alt="TreeRCU-callback-registry.svg">
|
||||||
|
|
||||||
|
<p>Because <tt>call_rcu()</tt> normally acts only on CPU-local state,
|
||||||
|
it provides no ordering guarantees, either for itself or for
|
||||||
|
phase one of the update (which again will usually be removal of
|
||||||
|
an element from an RCU-protected data structure).
|
||||||
|
It simply enqueues the <tt>rcu_head</tt> structure on a per-CPU list,
|
||||||
|
which cannot become associated with a grace period until a later
|
||||||
|
call to <tt>rcu_accelerate_cbs()</tt>, as shown in the diagram above.
|
||||||
|
|
||||||
|
<p>One set of code paths shown on the left invokes
|
||||||
|
<tt>rcu_accelerate_cbs()</tt> via
|
||||||
|
<tt>note_gp_changes()</tt>, either directly from <tt>call_rcu()</tt> (if
|
||||||
|
the current CPU is inundated with queued <tt>rcu_head</tt> structures)
|
||||||
|
or more likely from an <tt>RCU_SOFTIRQ</tt> handler.
|
||||||
|
Another code path in the middle is taken only in kernels built with
|
||||||
|
<tt>CONFIG_RCU_FAST_NO_HZ=y</tt>, which invokes
|
||||||
|
<tt>rcu_accelerate_cbs()</tt> via <tt>rcu_prepare_for_idle()</tt>.
|
||||||
|
The final code path on the right is taken only in kernels built with
|
||||||
|
<tt>CONFIG_HOTPLUG_CPU=y</tt>, which invokes
|
||||||
|
<tt>rcu_accelerate_cbs()</tt> via
|
||||||
|
<tt>rcu_advance_cbs()</tt>, <tt>rcu_migrate_callbacks</tt>,
|
||||||
|
<tt>rcutree_migrate_callbacks()</tt>, and <tt>takedown_cpu()</tt>,
|
||||||
|
which in turn is invoked on a surviving CPU after the outgoing
|
||||||
|
CPU has been completely offlined.
|
||||||
|
|
||||||
|
<p>There are a few other code paths within grace-period processing
|
||||||
|
that opportunistically invoke <tt>rcu_accelerate_cbs()</tt>.
|
||||||
|
However, either way, all of the CPU's recently queued <tt>rcu_head</tt>
|
||||||
|
structures are associated with a future grace-period number under
|
||||||
|
the protection of the CPU's lead <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->lock</tt>.
|
||||||
|
In all cases, there is full ordering against any prior critical section
|
||||||
|
for that same <tt>rcu_node</tt> structure's <tt>->lock</tt>, and
|
||||||
|
also full ordering against any of the current task's or CPU's prior critical
|
||||||
|
sections for any <tt>rcu_node</tt> structure's <tt>->lock</tt>.
|
||||||
|
|
||||||
|
<p>The next section will show how this ordering ensures that any
|
||||||
|
accesses prior to the <tt>call_rcu()</tt> (particularly including phase
|
||||||
|
one of the update)
|
||||||
|
happen before the start of the corresponding grace period.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
But what about <tt>synchronize_rcu()</tt>?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
The <tt>synchronize_rcu()</tt> passes <tt>call_rcu()</tt>
|
||||||
|
to <tt>wait_rcu_gp()</tt>, which invokes it.
|
||||||
|
So either way, it eventually comes down to <tt>call_rcu()</tt>.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4><a name="Grace-Period Initialization">Grace-Period Initialization</a></h4>
|
||||||
|
|
||||||
|
<p>Grace-period initialization is carried out by
|
||||||
|
the grace-period kernel thread, which makes several passes over the
|
||||||
|
<tt>rcu_node</tt> tree within the <tt>rcu_gp_init()</tt> function.
|
||||||
|
This means that showing the full flow of ordering through the
|
||||||
|
grace-period computation will require duplicating this tree.
|
||||||
|
If you find this confusing, please note that the state of the
|
||||||
|
<tt>rcu_node</tt> changes over time, just like Heraclitus's river.
|
||||||
|
However, to keep the <tt>rcu_node</tt> river tractable, the
|
||||||
|
grace-period kernel thread's traversals are presented in multiple
|
||||||
|
parts, starting in this section with the various phases of
|
||||||
|
grace-period initialization.
|
||||||
|
|
||||||
|
<p>The first ordering-related grace-period initialization action is to
|
||||||
|
increment the <tt>rcu_state</tt> structure's <tt>->gpnum</tt>
|
||||||
|
grace-period-number counter, as shown below:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-gp-init-1.svg" alt="TreeRCU-gp-init-1.svg" width="75%">
|
||||||
|
|
||||||
|
<p>The actual increment is carried out using <tt>smp_store_release()</tt>,
|
||||||
|
which helps reject false-positive RCU CPU stall detection.
|
||||||
|
Note that only the root <tt>rcu_node</tt> structure is touched.
|
||||||
|
|
||||||
|
<p>The first pass through the <tt>rcu_node</tt> tree updates bitmasks
|
||||||
|
based on CPUs having come online or gone offline since the start of
|
||||||
|
the previous grace period.
|
||||||
|
In the common case where the number of online CPUs for this <tt>rcu_node</tt>
|
||||||
|
structure has not transitioned to or from zero,
|
||||||
|
this pass will scan only the leaf <tt>rcu_node</tt> structures.
|
||||||
|
However, if the number of online CPUs for a given leaf <tt>rcu_node</tt>
|
||||||
|
structure has transitioned from zero,
|
||||||
|
<tt>rcu_init_new_rnp()</tt> will be invoked for the first incoming CPU.
|
||||||
|
Similarly, if the number of online CPUs for a given leaf <tt>rcu_node</tt>
|
||||||
|
structure has transitioned to zero,
|
||||||
|
<tt>rcu_cleanup_dead_rnp()</tt> will be invoked for the last outgoing CPU.
|
||||||
|
The diagram below shows the path of ordering if the leftmost
|
||||||
|
<tt>rcu_node</tt> structure onlines its first CPU and if the next
|
||||||
|
<tt>rcu_node</tt> structure has no online CPUs
|
||||||
|
(or, alternatively if the leftmost <tt>rcu_node</tt> structure offlines
|
||||||
|
its last CPU and if the next <tt>rcu_node</tt> structure has no online CPUs).
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-gp-init-2.svg" alt="TreeRCU-gp-init-1.svg" width="75%">
|
||||||
|
|
||||||
|
<p>The final <tt>rcu_gp_init()</tt> pass through the <tt>rcu_node</tt>
|
||||||
|
tree traverses breadth-first, setting each <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->gpnum</tt> field to the newly incremented value from the
|
||||||
|
<tt>rcu_state</tt> structure, as shown in the following diagram.
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-gp-init-3.svg" alt="TreeRCU-gp-init-1.svg" width="75%">
|
||||||
|
|
||||||
|
<p>This change will also cause each CPU's next call to
|
||||||
|
<tt>__note_gp_changes()</tt>
|
||||||
|
to notice that a new grace period has started, as described in the next
|
||||||
|
section.
|
||||||
|
But because the grace-period kthread started the grace period at the
|
||||||
|
root (with the increment of the <tt>rcu_state</tt> structure's
|
||||||
|
<tt>->gpnum</tt> field) before setting each leaf <tt>rcu_node</tt>
|
||||||
|
structure's <tt>->gpnum</tt> field, each CPU's observation of
|
||||||
|
the start of the grace period will happen after the actual start
|
||||||
|
of the grace period.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
But what about the CPU that started the grace period?
|
||||||
|
Why wouldn't it see the start of the grace period right when
|
||||||
|
it started that grace period?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
In some deep philosophical and overly anthromorphized
|
||||||
|
sense, yes, the CPU starting the grace period is immediately
|
||||||
|
aware of having done so.
|
||||||
|
However, if we instead assume that RCU is not self-aware,
|
||||||
|
then even the CPU starting the grace period does not really
|
||||||
|
become aware of the start of this grace period until its
|
||||||
|
first call to <tt>__note_gp_changes()</tt>.
|
||||||
|
On the other hand, this CPU potentially gets early notification
|
||||||
|
because it invokes <tt>__note_gp_changes()</tt> during its
|
||||||
|
last <tt>rcu_gp_init()</tt> pass through its leaf
|
||||||
|
<tt>rcu_node</tt> structure.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4><a name="Self-Reported Quiescent States">
|
||||||
|
Self-Reported Quiescent States</a></h4>
|
||||||
|
|
||||||
|
<p>When all entities that might block the grace period have reported
|
||||||
|
quiescent states (or as described in a later section, had quiescent
|
||||||
|
states reported on their behalf), the grace period can end.
|
||||||
|
Online non-idle CPUs report their own quiescent states, as shown
|
||||||
|
in the following diagram:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-qs.svg" alt="TreeRCU-qs.svg" width="75%">
|
||||||
|
|
||||||
|
<p>This is for the last CPU to report a quiescent state, which signals
|
||||||
|
the end of the grace period.
|
||||||
|
Earlier quiescent states would push up the <tt>rcu_node</tt> tree
|
||||||
|
only until they encountered an <tt>rcu_node</tt> structure that
|
||||||
|
is waiting for additional quiescent states.
|
||||||
|
However, ordering is nevertheless preserved because some later quiescent
|
||||||
|
state will acquire that <tt>rcu_node</tt> structure's <tt>->lock</tt>.
|
||||||
|
|
||||||
|
<p>Any number of events can lead up to a CPU invoking
|
||||||
|
<tt>note_gp_changes</tt> (or alternatively, directly invoking
|
||||||
|
<tt>__note_gp_changes()</tt>), at which point that CPU will notice
|
||||||
|
the start of a new grace period while holding its leaf
|
||||||
|
<tt>rcu_node</tt> lock.
|
||||||
|
Therefore, all execution shown in this diagram happens after the
|
||||||
|
start of the grace period.
|
||||||
|
In addition, this CPU will consider any RCU read-side critical
|
||||||
|
section that started before the invocation of <tt>__note_gp_changes()</tt>
|
||||||
|
to have started before the grace period, and thus a critical
|
||||||
|
section that the grace period must wait on.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
But a RCU read-side critical section might have started
|
||||||
|
after the beginning of the grace period
|
||||||
|
(the <tt>->gpnum++</tt> from earlier), so why should
|
||||||
|
the grace period wait on such a critical section?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
It is indeed not necessary for the grace period to wait on such
|
||||||
|
a critical section.
|
||||||
|
However, it is permissible to wait on it.
|
||||||
|
And it is furthermore important to wait on it, as this
|
||||||
|
lazy approach is far more scalable than a “big bang”
|
||||||
|
all-at-once grace-period start could possibly be.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>If the CPU does a context switch, a quiescent state will be
|
||||||
|
noted by <tt>rcu_node_context_switch()</tt> on the left.
|
||||||
|
On the other hand, if the CPU takes a scheduler-clock interrupt
|
||||||
|
while executing in usermode, a quiescent state will be noted by
|
||||||
|
<tt>rcu_check_callbacks()</tt> on the right.
|
||||||
|
Either way, the passage through a quiescent state will be noted
|
||||||
|
in a per-CPU variable.
|
||||||
|
|
||||||
|
<p>The next time an <tt>RCU_SOFTIRQ</tt> handler executes on
|
||||||
|
this CPU (for example, after the next scheduler-clock
|
||||||
|
interrupt), <tt>__rcu_process_callbacks()</tt> will invoke
|
||||||
|
<tt>rcu_check_quiescent_state()</tt>, which will notice the
|
||||||
|
recorded quiescent state, and invoke
|
||||||
|
<tt>rcu_report_qs_rdp()</tt>.
|
||||||
|
If <tt>rcu_report_qs_rdp()</tt> verifies that the quiescent state
|
||||||
|
really does apply to the current grace period, it invokes
|
||||||
|
<tt>rcu_report_rnp()</tt> which traverses up the <tt>rcu_node</tt>
|
||||||
|
tree as shown at the bottom of the diagram, clearing bits from
|
||||||
|
each <tt>rcu_node</tt> structure's <tt>->qsmask</tt> field,
|
||||||
|
and propagating up the tree when the result is zero.
|
||||||
|
|
||||||
|
<p>Note that traversal passes upwards out of a given <tt>rcu_node</tt>
|
||||||
|
structure only if the current CPU is reporting the last quiescent
|
||||||
|
state for the subtree headed by that <tt>rcu_node</tt> structure.
|
||||||
|
A key point is that if a CPU's traversal stops at a given <tt>rcu_node</tt>
|
||||||
|
structure, then there will be a later traversal by another CPU
|
||||||
|
(or perhaps the same one) that proceeds upwards
|
||||||
|
from that point, and the <tt>rcu_node</tt> <tt>->lock</tt>
|
||||||
|
guarantees that the first CPU's quiescent state happens before the
|
||||||
|
remainder of the second CPU's traversal.
|
||||||
|
Applying this line of thought repeatedly shows that all CPUs'
|
||||||
|
quiescent states happen before the last CPU traverses through
|
||||||
|
the root <tt>rcu_node</tt> structure, the “last CPU”
|
||||||
|
being the one that clears the last bit in the root <tt>rcu_node</tt>
|
||||||
|
structure's <tt>->qsmask</tt> field.
|
||||||
|
|
||||||
|
<h4><a name="Dynamic Tick Interface">Dynamic Tick Interface</a></h4>
|
||||||
|
|
||||||
|
<p>Due to energy-efficiency considerations, RCU is forbidden from
|
||||||
|
disturbing idle CPUs.
|
||||||
|
CPUs are therefore required to notify RCU when entering or leaving idle
|
||||||
|
state, which they do via fully ordered value-returning atomic operations
|
||||||
|
on a per-CPU variable.
|
||||||
|
The ordering effects are as shown below:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-dyntick.svg" alt="TreeRCU-dyntick.svg" width="50%">
|
||||||
|
|
||||||
|
<p>The RCU grace-period kernel thread samples the per-CPU idleness
|
||||||
|
variable while holding the corresponding CPU's leaf <tt>rcu_node</tt>
|
||||||
|
structure's <tt>->lock</tt>.
|
||||||
|
This means that any RCU read-side critical sections that precede the
|
||||||
|
idle period (the oval near the top of the diagram above) will happen
|
||||||
|
before the end of the current grace period.
|
||||||
|
Similarly, the beginning of the current grace period will happen before
|
||||||
|
any RCU read-side critical sections that follow the
|
||||||
|
idle period (the oval near the bottom of the diagram above).
|
||||||
|
|
||||||
|
<p>Plumbing this into the full grace-period execution is described
|
||||||
|
<a href="#Forcing Quiescent States">below</a>.
|
||||||
|
|
||||||
|
<h4><a name="CPU-Hotplug Interface">CPU-Hotplug Interface</a></h4>
|
||||||
|
|
||||||
|
<p>RCU is also forbidden from disturbing offline CPUs, which might well
|
||||||
|
be powered off and removed from the system completely.
|
||||||
|
CPUs are therefore required to notify RCU of their comings and goings
|
||||||
|
as part of the corresponding CPU hotplug operations.
|
||||||
|
The ordering effects are shown below:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-hotplug.svg" alt="TreeRCU-hotplug.svg" width="50%">
|
||||||
|
|
||||||
|
<p>Because CPU hotplug operations are much less frequent than idle transitions,
|
||||||
|
they are heavier weight, and thus acquire the CPU's leaf <tt>rcu_node</tt>
|
||||||
|
structure's <tt>->lock</tt> and update this structure's
|
||||||
|
<tt>->qsmaskinitnext</tt>.
|
||||||
|
The RCU grace-period kernel thread samples this mask to detect CPUs
|
||||||
|
having gone offline since the beginning of this grace period.
|
||||||
|
|
||||||
|
<p>Plumbing this into the full grace-period execution is described
|
||||||
|
<a href="#Forcing Quiescent States">below</a>.
|
||||||
|
|
||||||
|
<h4><a name="Forcing Quiescent States">Forcing Quiescent States</a></h4>
|
||||||
|
|
||||||
|
<p>As noted above, idle and offline CPUs cannot report their own
|
||||||
|
quiescent states, and therefore the grace-period kernel thread
|
||||||
|
must do the reporting on their behalf.
|
||||||
|
This process is called “forcing quiescent states”, it is
|
||||||
|
repeated every few jiffies, and its ordering effects are shown below:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-gp-fqs.svg" alt="TreeRCU-gp-fqs.svg" width="100%">
|
||||||
|
|
||||||
|
<p>Each pass of quiescent state forcing is guaranteed to traverse the
|
||||||
|
leaf <tt>rcu_node</tt> structures, and if there are no new quiescent
|
||||||
|
states due to recently idled and/or offlined CPUs, then only the
|
||||||
|
leaves are traversed.
|
||||||
|
However, if there is a newly offlined CPU as illustrated on the left
|
||||||
|
or a newly idled CPU as illustrated on the right, the corresponding
|
||||||
|
quiescent state will be driven up towards the root.
|
||||||
|
As with self-reported quiescent states, the upwards driving stops
|
||||||
|
once it reaches an <tt>rcu_node</tt> structure that has quiescent
|
||||||
|
states outstanding from other CPUs.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
The leftmost drive to root stopped before it reached
|
||||||
|
the root <tt>rcu_node</tt> structure, which means that
|
||||||
|
there are still CPUs subordinate to that structure on
|
||||||
|
which the current grace period is waiting.
|
||||||
|
Given that, how is it possible that the rightmost drive
|
||||||
|
to root ended the grace period?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
Good analysis!
|
||||||
|
It is in fact impossible in the absence of bugs in RCU.
|
||||||
|
But this diagram is complex enough as it is, so simplicity
|
||||||
|
overrode accuracy.
|
||||||
|
You can think of it as poetic license, or you can think of
|
||||||
|
it as misdirection that is resolved in the
|
||||||
|
<a href="#Putting It All Together">stitched-together diagram</a>.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4><a name="Grace-Period Cleanup">Grace-Period Cleanup</a></h4>
|
||||||
|
|
||||||
|
<p>Grace-period cleanup first scans the <tt>rcu_node</tt> tree
|
||||||
|
breadth-first setting all the <tt>->completed</tt> fields equal
|
||||||
|
to the number of the newly completed grace period, then it sets
|
||||||
|
the <tt>rcu_state</tt> structure's <tt>->completed</tt> field,
|
||||||
|
again to the number of the newly completed grace period.
|
||||||
|
The ordering effects are shown below:
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-gp-cleanup.svg" alt="TreeRCU-gp-cleanup.svg" width="75%">
|
||||||
|
|
||||||
|
<p>As indicated by the oval at the bottom of the diagram, once
|
||||||
|
grace-period cleanup is complete, the next grace period can begin.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
But when precisely does the grace period end?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
There is no useful single point at which the grace period
|
||||||
|
can be said to end.
|
||||||
|
The earliest reasonable candidate is as soon as the last
|
||||||
|
CPU has reported its quiescent state, but it may be some
|
||||||
|
milliseconds before RCU becomes aware of this.
|
||||||
|
The latest reasonable candidate is once the <tt>rcu_state</tt>
|
||||||
|
structure's <tt>->completed</tt> field has been updated,
|
||||||
|
but it is quite possible that some CPUs have already completed
|
||||||
|
phase two of their updates by that time.
|
||||||
|
In short, if you are going to work with RCU, you need to
|
||||||
|
learn to embrace uncertainty.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<h4><a name="Callback Invocation">Callback Invocation</a></h4>
|
||||||
|
|
||||||
|
<p>Once a given CPU's leaf <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->completed</tt> field has been updated, that CPU can begin
|
||||||
|
invoking its RCU callbacks that were waiting for this grace period
|
||||||
|
to end.
|
||||||
|
These callbacks are identified by <tt>rcu_advance_cbs()</tt>,
|
||||||
|
which is usually invoked by <tt>__note_gp_changes()</tt>.
|
||||||
|
As shown in the diagram below, this invocation can be triggered by
|
||||||
|
the scheduling-clock interrupt (<tt>rcu_check_callbacks()</tt> on
|
||||||
|
the left) or by idle entry (<tt>rcu_cleanup_after_idle()</tt> on
|
||||||
|
the right, but only for kernels build with
|
||||||
|
<tt>CONFIG_RCU_FAST_NO_HZ=y</tt>).
|
||||||
|
Either way, <tt>RCU_SOFTIRQ</tt> is raised, which results in
|
||||||
|
<tt>rcu_do_batch()</tt> invoking the callbacks, which in turn
|
||||||
|
allows those callbacks to carry out (either directly or indirectly
|
||||||
|
via wakeup) the needed phase-two processing for each update.
|
||||||
|
|
||||||
|
</p><p><img src="TreeRCU-callback-invocation.svg" alt="TreeRCU-callback-invocation.svg" width="60%">
|
||||||
|
|
||||||
|
<p>Please note that callback invocation can also be prompted by any
|
||||||
|
number of corner-case code paths, for example, when a CPU notes that
|
||||||
|
it has excessive numbers of callbacks queued.
|
||||||
|
In all cases, the CPU acquires its leaf <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->lock</tt> before invoking callbacks, which preserves the
|
||||||
|
required ordering against the newly completed grace period.
|
||||||
|
|
||||||
|
<p>However, if the callback function communicates to other CPUs,
|
||||||
|
for example, doing a wakeup, then it is that function's responsibility
|
||||||
|
to maintain ordering.
|
||||||
|
For example, if the callback function wakes up a task that runs on
|
||||||
|
some other CPU, proper ordering must in place in both the callback
|
||||||
|
function and the task being awakened.
|
||||||
|
To see why this is important, consider the top half of the
|
||||||
|
<a href="#Grace-Period Cleanup">grace-period cleanup</a> diagram.
|
||||||
|
The callback might be running on a CPU corresponding to the leftmost
|
||||||
|
leaf <tt>rcu_node</tt> structure, and awaken a task that is to run on
|
||||||
|
a CPU corresponding to the rightmost leaf <tt>rcu_node</tt> structure,
|
||||||
|
and the grace-period kernel thread might not yet have reached the
|
||||||
|
rightmost leaf.
|
||||||
|
In this case, the grace period's memory ordering might not yet have
|
||||||
|
reached that CPU, so again the callback function and the awakened
|
||||||
|
task must supply proper ordering.
|
||||||
|
|
||||||
|
<h3><a name="Putting It All Together">Putting It All Together</a></h3>
|
||||||
|
|
||||||
|
<p>A stitched-together diagram is
|
||||||
|
<a href="Tree-RCU-Diagram.html">here</a>.
|
||||||
|
|
||||||
|
<h3><a name="Legal Statement">
|
||||||
|
Legal Statement</a></h3>
|
||||||
|
|
||||||
|
<p>This work represents the view of the author and does not necessarily
|
||||||
|
represent the view of IBM.
|
||||||
|
|
||||||
|
</p><p>Linux is a registered trademark of Linus Torvalds.
|
||||||
|
|
||||||
|
</p><p>Other company, product, and service names may be trademarks or
|
||||||
|
service marks of others.
|
||||||
|
|
||||||
|
</body></html>
|
@@ -0,0 +1,486 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="592.12805"
|
||||||
|
height="469.83038"
|
||||||
|
viewBox="-44 -44 7874.1949 6244.9802"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-callback-invocation.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1144"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="1.2009216"
|
||||||
|
inkscape:cx="289.88715"
|
||||||
|
inkscape:cy="219.06265"
|
||||||
|
inkscape:window-x="713"
|
||||||
|
inkscape:window-y="28"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="g3058"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3079"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
originx="-116.00011px"
|
||||||
|
originy="-87.2081px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4"
|
||||||
|
transform="translate(-2296.0293,-2364.1166)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
|
||||||
|
d="m 6161.6776,2411.7612 0,4920.3076"
|
||||||
|
id="path3134-9-0-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
|
||||||
|
d="m 6161.6776,4672.443 -2393.6631,0.5116 0,1196.8316 2393.6631,-0.5116"
|
||||||
|
id="path3134-9-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
|
||||||
|
d="m 6161.6776,4672.443 2393.6631,0.5116 0,1196.8316 -2393.6631,-0.5116"
|
||||||
|
id="path3134-9-0-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 8100 - 5710 5790-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 9300 - 4512 7140-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1040 9300 - 1502 7140-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2240 8100 - 2702 5940-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2250 8100 - 2250 6240-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1050 9300 - 1050 7440-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 9300 - 4050 7440-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 8100 - 5250 6240-->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9300 3150 - 10860 3150-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11400 3600 - 11400 4410-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11400 5100 - 11400 5910-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9900 4650 - 10860 4650-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9600 6150 - 10860 6150-->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<rect
|
||||||
|
x="2333.5203"
|
||||||
|
y="5109.5566"
|
||||||
|
width="2844.0974"
|
||||||
|
height="360.77411"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.0005789, 60.00115781;stroke-dashoffset:0"
|
||||||
|
id="rect118-3"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="2562.135"
|
||||||
|
y="5357.9937"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_check_callbacks()</text>
|
||||||
|
<rect
|
||||||
|
x="7069.6187"
|
||||||
|
y="5087.4678"
|
||||||
|
width="2975.115"
|
||||||
|
height="382.86298"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057902, 60.00115804;stroke-dashoffset:0"
|
||||||
|
id="rect118-36"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7165.2524"
|
||||||
|
y="5333.4927"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-9-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_cleanup_after_idle()</text>
|
||||||
|
<g
|
||||||
|
id="g3058"
|
||||||
|
transform="translate(-53.192514,-2819.2063)">
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Courier"
|
||||||
|
id="text202"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="6532.0293"
|
||||||
|
x="5073.3374"
|
||||||
|
xml:space="preserve">rcu_advance_cbs()</text>
|
||||||
|
<rect
|
||||||
|
id="rect112"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="5650.2598"
|
||||||
|
x="4800.2563" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="5726.2852"
|
||||||
|
x="4800.2563" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-3-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="6961.395"
|
||||||
|
x="7220.106"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-6-5"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-3"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="6321.9248"
|
||||||
|
x="5073.3374"
|
||||||
|
xml:space="preserve">__note_gp_changes()</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3049"
|
||||||
|
transform="translate(26.596257,6090.5512)">
|
||||||
|
<path
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,1872.6808,-2726.4833)"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
id="path3084-3"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-6"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="1785.2073"
|
||||||
|
x="5717.4517"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-7"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">Phase Two</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3110-5"
|
||||||
|
y="2005.6624"
|
||||||
|
x="6119.668"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="2005.6624"
|
||||||
|
x="6119.668"
|
||||||
|
id="tspan3112-3"
|
||||||
|
sodipodi:role="line">of Update</tspan></text>
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
x="5097.8271"
|
||||||
|
y="6268.2183"
|
||||||
|
width="1994.7195"
|
||||||
|
height="664.90662"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057858, 60.00115716;stroke-dashoffset:0"
|
||||||
|
id="rect118-36-3"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5363.7886"
|
||||||
|
y="6534.1812"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-9-6-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">RCU_SOFTIRQ</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5363.7886"
|
||||||
|
y="6800.1436"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-9-6-6-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_do_batch()</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,655 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="816.04761"
|
||||||
|
height="636.55627"
|
||||||
|
viewBox="-44 -44 10851.906 8461.0989"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-callback-registry.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1144"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="1.2009216"
|
||||||
|
inkscape:cx="408.02381"
|
||||||
|
inkscape:cy="254.38856"
|
||||||
|
inkscape:window-x="713"
|
||||||
|
inkscape:window-y="28"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="g4"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3079"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
originx="5.2596966e-08px"
|
||||||
|
originy="-4.5963961e-06px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4"
|
||||||
|
transform="translate(-753.44492,-1306.6788)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
|
||||||
|
d="m 6161.6776,2411.7612 0,6117.1391"
|
||||||
|
id="path3134-9-0-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
|
||||||
|
d="m 6161.6776,3342.6302 -3856.4573,0 10.6979,5757.1962 2918.1436,-2e-4"
|
||||||
|
id="path3134-9-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
|
||||||
|
d="m 6161.6776,3342.6302 3856.4574,0 -12.188,5757.1963 -2918.1436,-3e-4"
|
||||||
|
id="path3134-9-0-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 8100 - 5710 5790-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 9300 - 4512 7140-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1040 9300 - 1502 7140-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2240 8100 - 2702 5940-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2250 8100 - 2250 6240-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1050 9300 - 1050 7440-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 9300 - 4050 7440-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 8100 - 5250 6240-->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9300 3150 - 10860 3150-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11400 3600 - 11400 4410-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11400 5100 - 11400 5910-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9900 4650 - 10860 4650-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9600 6150 - 10860 6150-->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<rect
|
||||||
|
x="4544.7305"
|
||||||
|
y="4603.417"
|
||||||
|
width="3240.0088"
|
||||||
|
height="2650.6289"
|
||||||
|
rx="0"
|
||||||
|
style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057884, 60.00115769;stroke-dashoffset:0"
|
||||||
|
id="rect118"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5073.3374"
|
||||||
|
y="6372.4521"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Courier">rcu_accelerate_cbs()</text>
|
||||||
|
<g
|
||||||
|
id="g3107"
|
||||||
|
transform="translate(2715.7065,4700.8888)">
|
||||||
|
<rect
|
||||||
|
id="rect112"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="4773.3452"
|
||||||
|
y="4825.2578"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_prepare_for_idle()</text>
|
||||||
|
<rect
|
||||||
|
x="790.93585"
|
||||||
|
y="4630.8252"
|
||||||
|
width="3240.0088"
|
||||||
|
height="2650.6289"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.0005789, 60.00115781;stroke-dashoffset:0"
|
||||||
|
id="rect118-3"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="1319.5447"
|
||||||
|
y="6639.2261"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_accelerate_cbs()</text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-7"
|
||||||
|
transform="translate(-1038.0776,4728.2971)">
|
||||||
|
<rect
|
||||||
|
id="rect112-5"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="1019.5512"
|
||||||
|
y="4852.666"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">note_gp_changes()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="1319.5447"
|
||||||
|
y="6376.6328"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-6-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_advance_cbs()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="1340.6649"
|
||||||
|
y="6111.4473"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-6-6-2"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">__note_gp_changes()</text>
|
||||||
|
<rect
|
||||||
|
x="5422.6279"
|
||||||
|
y="3041.8311"
|
||||||
|
width="1480.4871"
|
||||||
|
height="379.24637"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.0005789, 60.00115794;stroke-dashoffset:0"
|
||||||
|
id="rect118-3-9"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5607.2734"
|
||||||
|
y="3283.3892"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">call_rcu()</text>
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
id="path3084"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,1915.7286,4523.6528)" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5853.9238"
|
||||||
|
y="8902.3623"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104">Wake up</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
x="6165.7158"
|
||||||
|
y="9122.8174"
|
||||||
|
id="text3110"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3112"
|
||||||
|
x="6165.7158"
|
||||||
|
y="9122.8174">grace-period</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
x="6162.8716"
|
||||||
|
y="9364.3564"
|
||||||
|
id="text3114"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3116"
|
||||||
|
x="6162.8716"
|
||||||
|
y="9364.3564">kernel thread</tspan></text>
|
||||||
|
<rect
|
||||||
|
x="8239.8516"
|
||||||
|
y="4608.7363"
|
||||||
|
width="3240.0088"
|
||||||
|
height="2650.6289"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057902, 60.00115804;stroke-dashoffset:0"
|
||||||
|
id="rect118-36"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="8768.4678"
|
||||||
|
y="6484.1562"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-75"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_accelerate_cbs()</text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-3"
|
||||||
|
transform="translate(6410.833,4706.2127)">
|
||||||
|
<rect
|
||||||
|
id="rect112-56"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-2"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="8329.5352"
|
||||||
|
y="4830.5771"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-9"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">takedown_cpu()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="8335.4873"
|
||||||
|
y="5094.127"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-9-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcutree_migrate_callbacks()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="8335.4873"
|
||||||
|
y="5357.1006"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-9-6-0"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_migrate_callbacks()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="8768.4678"
|
||||||
|
y="6224.9038"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-6-6-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_advance_cbs()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3467.9963"
|
||||||
|
y="6987.9912"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7220.106"
|
||||||
|
y="6961.395"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="10905.331"
|
||||||
|
y="6961.395"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-3"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-5">Leaf</tspan></text>
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
id="path3084-3"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,1872.6808,-2726.4833)" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5717.4517"
|
||||||
|
y="1785.2073"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-7">Phase One</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
x="6119.668"
|
||||||
|
y="2005.6624"
|
||||||
|
id="text3110-5"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3112-3"
|
||||||
|
x="6119.668"
|
||||||
|
y="2005.6624">of Update</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 23 KiB |
700
Documentation/RCU/Design/Memory-Ordering/TreeRCU-dyntick.svg
Normal file
@@ -0,0 +1,700 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="670.61804"
|
||||||
|
height="557.16394"
|
||||||
|
viewBox="-44 -44 8917.9652 7405.8166"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-dyntick.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-1"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-7"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker4880"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4882"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-10"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-36"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-0"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-26"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-8"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-7"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-367"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-5"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-56"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-2"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3081"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3083"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3085"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3087"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3089"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3091"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3093"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3095"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3097"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3099"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-9"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-1"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3675"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-3"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1148"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="1.4142136"
|
||||||
|
inkscape:cx="381.32663"
|
||||||
|
inkscape:cy="239.67141"
|
||||||
|
inkscape:window-x="833"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5"
|
||||||
|
inkscape:snap-global="false">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3154"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
originx="-235.14935px"
|
||||||
|
originy="-709.25071px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-1-3-5"
|
||||||
|
d="m 3754.1051,47.378296 -2.828,7173.860804"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-1-3"
|
||||||
|
d="m 6681.1176,1435.1734 -2.828,1578.9586 -2861.3912,7.7159"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-1"
|
||||||
|
d="m 3748.8929,3772.1176 2904.1747,-0.8434 26.8008,1842.1825"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<g
|
||||||
|
id="g3115"
|
||||||
|
transform="translate(-2341.8794,10827.399)">
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057923, 60.00115859;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="2349.7295"
|
||||||
|
width="5308.7119"
|
||||||
|
y="-8909.5498"
|
||||||
|
x="2379.3704" />
|
||||||
|
<g
|
||||||
|
transform="translate(2576.8841,-9085.2783)"
|
||||||
|
id="g3107-7"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<rect
|
||||||
|
x="2084.55"
|
||||||
|
y="949.37109"
|
||||||
|
width="2809.1992"
|
||||||
|
height="1370.8721"
|
||||||
|
rx="0"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
id="rect112-5" />
|
||||||
|
<rect
|
||||||
|
x="2084.55"
|
||||||
|
y="1025.3964"
|
||||||
|
width="2809.1992"
|
||||||
|
height="1294.8468"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
id="rect112-3-3" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-6-6-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-7356.375"
|
||||||
|
x="4769.4536"
|
||||||
|
xml:space="preserve">->qsmask &= ~->grpmask</text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-3"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-6825.5815"
|
||||||
|
x="7082.9585"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-6"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2-7-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-8652.5312"
|
||||||
|
x="2466.7822"
|
||||||
|
xml:space="preserve">dyntick_save_progress_counter()</text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2-7-2-0"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-8368.1475"
|
||||||
|
x="2463.3262"
|
||||||
|
xml:space="preserve">rcu_implicit_dynticks_qs()</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4504"
|
||||||
|
transform="translate(2063.5184,-16111.739)">
|
||||||
|
<path
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,335.22989,12456.379)"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
id="path3084"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="16835.086"
|
||||||
|
x="4409.043"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">RCU</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3110"
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
id="tspan3112"
|
||||||
|
sodipodi:role="line">read-side</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3114"
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
id="tspan3116"
|
||||||
|
sodipodi:role="line">critical section</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3148-9-9"
|
||||||
|
transform="translate(2035.3087,6370.5796)">
|
||||||
|
<rect
|
||||||
|
x="3592.3828"
|
||||||
|
y="-4715.7246"
|
||||||
|
width="3164.783"
|
||||||
|
height="769.99048"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057963, 60.00115926;stroke-dashoffset:0"
|
||||||
|
id="rect118-3-5-1-3"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3745.7725"
|
||||||
|
y="-4418.6582"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-3-27-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_dynticks_eqs_enter()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3745.7725"
|
||||||
|
y="-4165.7954"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-3-27-0-0"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">atomic_add_return()</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3148-9-9-2"
|
||||||
|
transform="translate(2035.3089,9031.6839)">
|
||||||
|
<rect
|
||||||
|
x="3592.3828"
|
||||||
|
y="-4715.7246"
|
||||||
|
width="3164.783"
|
||||||
|
height="769.99048"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057963, 60.00115926;stroke-dashoffset:0"
|
||||||
|
id="rect118-3-5-1-3-6"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3745.7725"
|
||||||
|
y="-4418.6582"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-3-27-6-1"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_dynticks_eqs_exit()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3745.7725"
|
||||||
|
y="-4165.7954"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-3-27-0-0-8"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">atomic_add_return()</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4504-7"
|
||||||
|
transform="translate(2082.3248,-10883.562)">
|
||||||
|
<path
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,335.22989,12456.379)"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
id="path3084-9"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="16835.086"
|
||||||
|
x="4409.043"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-0"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">RCU</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3110-2"
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
id="tspan3112-3"
|
||||||
|
sodipodi:role="line">read-side</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3114-7"
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
id="tspan3116-5"
|
||||||
|
sodipodi:role="line">critical section</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 25 KiB |
1126
Documentation/RCU/Design/Memory-Ordering/TreeRCU-gp-cleanup.svg
Normal file
After Width: | Height: | Size: 42 KiB |
1309
Documentation/RCU/Design/Memory-Ordering/TreeRCU-gp-fqs.svg
Normal file
After Width: | Height: | Size: 50 KiB |
656
Documentation/RCU/Design/Memory-Ordering/TreeRCU-gp-init-1.svg
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="1039.3743"
|
||||||
|
height="677.72852"
|
||||||
|
viewBox="-44 -44 13821.733 9008.3597"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-gp-init-1.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-1"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-7"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker4880"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4882"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-10"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-36"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-7"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1144"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="0.70710678"
|
||||||
|
inkscape:cx="617.89019"
|
||||||
|
inkscape:cy="636.57143"
|
||||||
|
inkscape:window-x="697"
|
||||||
|
inkscape:window-y="28"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3059"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
originx="1.6062488e-07px"
|
||||||
|
originy="10.7285px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3"
|
||||||
|
d="m 6871.027,46.883461 0,8777.144039"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(2450.4075,-10679.115)"
|
||||||
|
id="g3188">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3305.5364"
|
||||||
|
y="13255.592"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Courier">rsp->gpnum++</text>
|
||||||
|
<g
|
||||||
|
id="g3107"
|
||||||
|
transform="translate(947.90548,11584.029)">
|
||||||
|
<rect
|
||||||
|
id="rect112"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5452.3052"
|
||||||
|
y="13844.535"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5">Root</tspan></text>
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057884, 60.00115769;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="6844.4546"
|
||||||
|
width="13658.751"
|
||||||
|
y="1371.6335"
|
||||||
|
x="37.490932" />
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="1631.0878"
|
||||||
|
x="153.26733"
|
||||||
|
xml:space="preserve">rcu_gp_init()</text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(2329.9439,-10642.748)"
|
||||||
|
id="g3147">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6"
|
||||||
|
transform="translate(3054.6101,13760.052)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(3181.0246,-10679.115)"
|
||||||
|
id="g3153">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-1642.5375,-10642.748)"
|
||||||
|
id="g3147-3"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-6"
|
||||||
|
transform="translate(3054.6101,13760.052)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-0"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-6"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-151.71726,-10679.115)"
|
||||||
|
id="g3153-2"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-6"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-1"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-8"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-9">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-3484.4587,-10679.115)"
|
||||||
|
id="g3153-20"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-2"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-3"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-7"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-5"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-92">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-6817.1998,-10679.115)"
|
||||||
|
id="g3153-28"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-9"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-7"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-1">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812908px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 5473.7572,3203.2219 -582.9982,865.094"
|
||||||
|
id="path3414"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812813px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 8282.5391,3203.4839 582.9982,865.094"
|
||||||
|
id="path3414-9"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812813px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 3523.1241,5416.3989 -582.9982,865.094"
|
||||||
|
id="path3414-8"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 10268.171,5416.6609 583,865.094"
|
||||||
|
id="path3414-9-4"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 4939.6205,5416.3989 0,846.288"
|
||||||
|
id="path3414-8-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 8816.5958,5442.9949 0,846.288"
|
||||||
|
id="path3414-8-3-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
id="g4504-3-9"
|
||||||
|
transform="translate(4866.0367,-16425.339)">
|
||||||
|
<path
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,335.22989,12456.379)"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
id="path3084-6-1"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-7-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="16888.277"
|
||||||
|
x="4344.877"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-5-7"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">End of</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3110-3-0"
|
||||||
|
y="17119.1"
|
||||||
|
x="4578.7886"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17119.1"
|
||||||
|
x="4578.7886"
|
||||||
|
id="tspan3112-5-9"
|
||||||
|
sodipodi:role="line">Last Grace</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3114-6-3"
|
||||||
|
y="17350.271"
|
||||||
|
x="4581.7886"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17350.271"
|
||||||
|
x="4581.7886"
|
||||||
|
id="tspan3116-2-6"
|
||||||
|
sodipodi:role="line">Period</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-5"
|
||||||
|
d="m 8546.5914,605.78414 -1595.7755,0"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send-36)" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 23 KiB |
656
Documentation/RCU/Design/Memory-Ordering/TreeRCU-gp-init-2.svg
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="1037.9602"
|
||||||
|
height="666.38184"
|
||||||
|
viewBox="-44 -44 13802.928 8857.5401"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-gp-init-2.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-1"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-7"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker4880"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4882"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-10"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1144"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.79710462"
|
||||||
|
inkscape:cx="564.27119"
|
||||||
|
inkscape:cy="397.32188"
|
||||||
|
inkscape:window-x="833"
|
||||||
|
inkscape:window-y="28"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccccccccccccccccccccccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3"
|
||||||
|
d="m 6861.6904,46.438525 -2.8276,1315.668775 -5343.8436,17.1194 -2.8276,6561.7446 2039.0799,17.963 -2.7042,-2144.1399 -491.6705,-0.2109 -2.7042,-1993.6887 1487.7179,-4.7279 -17.8,1812.453 2017.2374,-7.6434 4.9532,-2151.5723 -1405.5264,11.163 -10.919,-1891.1468 1739.2164,-2.7175 -13.2006,4234.2295 -1701.3595,1.3953 -8.7841,2107.7116 1702.6392,-4.8334 33.4144,-1867.7167 1312.2492,12.9229 14.608,1818.3367 2000.0063,20.4217 -12.279,-1841.4113 1304.168,1.6154 -12.279,2032.7059 -4638.6515,1.6154 19.5828,569.0378"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057884, 60.00115769;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="7653.1299"
|
||||||
|
width="13639.945"
|
||||||
|
y="555.69745"
|
||||||
|
x="37.490929" />
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="799.34259"
|
||||||
|
x="134.46091"
|
||||||
|
xml:space="preserve">rcu_gp_init()</text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(2311.1375,-10650.009)"
|
||||||
|
id="g3147">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6"
|
||||||
|
transform="translate(3054.6101,13760.052)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(3162.2182,-10686.376)"
|
||||||
|
id="g3153">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-1661.3439,-10650.009)"
|
||||||
|
id="g3147-3"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-6"
|
||||||
|
transform="translate(3054.6101,13760.052)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-0"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-6"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5398.415"
|
||||||
|
y="15310.093"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-8"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->qsmaskinit</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5398.415"
|
||||||
|
y="15545.01"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-5-8"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->qsmaskinitnext</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-170.52359,-10686.376)"
|
||||||
|
id="g3153-2"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-6"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-1"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-8"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-9">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-3503.2651,-10686.376)"
|
||||||
|
id="g3153-20"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-2"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-3"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-7"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-5"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-92">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-6836.0062,-10686.376)"
|
||||||
|
id="g3153-28"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-9"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-7"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-1">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7699.7246"
|
||||||
|
y="17734.791"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-4"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->qsmaskinit</text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812908px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 5454.9508,3195.9607 -582.9982,865.094"
|
||||||
|
id="path3414"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812813px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 8263.7327,3196.2227 582.9982,865.094"
|
||||||
|
id="path3414-9"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812813px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 3504.3177,5409.1377 -582.9982,865.094"
|
||||||
|
id="path3414-8"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 10249.365,5409.3997 583,865.094"
|
||||||
|
id="path3414-9-4"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 4920.8141,5409.1377 0,846.288"
|
||||||
|
id="path3414-8-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 8797.7894,5435.7337 0,846.288"
|
||||||
|
id="path3414-8-3-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118-1"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057923, 60.00115846;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="4418.4302"
|
||||||
|
width="4932.5845"
|
||||||
|
y="1492.2119"
|
||||||
|
x="2087.8708" />
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="1690.4336"
|
||||||
|
x="2223.3145"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:linespacing="125%">rcu_init_new_rnp()<tspan
|
||||||
|
style="font-size:192px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3307"> or</tspan></text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="1958.5066"
|
||||||
|
x="2223.3145"
|
||||||
|
xml:space="preserve">rcu_cleanup_dead_rnp()</text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2-7-6"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="2227.4531"
|
||||||
|
x="2226.1592"
|
||||||
|
xml:space="preserve"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:192px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3327">(optional)</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(2431.6011,-10686.376)"
|
||||||
|
id="g3188">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3305.5364"
|
||||||
|
y="13255.592"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Courier">->qsmaskinit</text>
|
||||||
|
<g
|
||||||
|
id="g3107"
|
||||||
|
transform="translate(947.90548,11584.029)">
|
||||||
|
<rect
|
||||||
|
id="rect112"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5452.3052"
|
||||||
|
y="13844.535"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5">Root</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3305.5364"
|
||||||
|
y="13490.509"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-5"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->qsmaskinitnext</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 24 KiB |
632
Documentation/RCU/Design/Memory-Ordering/TreeRCU-gp-init-3.svg
Normal file
@@ -0,0 +1,632 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="1039.3743"
|
||||||
|
height="594.19171"
|
||||||
|
viewBox="-44 -44 13821.733 7897.9895"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-gp-init-2.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-1"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-7"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker4880"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4882"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-10"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1144"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.70710678"
|
||||||
|
inkscape:cx="617.89019"
|
||||||
|
inkscape:cy="625.84293"
|
||||||
|
inkscape:window-x="697"
|
||||||
|
inkscape:window-y="28"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccccccccccccccccccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3"
|
||||||
|
d="m 6899.3032,45.520244 -2.8276,2480.757056 -2316.0141,-1.687 -2.8276,2179.8547 2321.1758,-0.8434 -2.7042,-1843.2376 2404.5142,-0.2109 16.1022,1993.2669 -7783.8345,-4.7279 -16.7936,2120.3946 2033.1033,-23.5344 2.0128,-1866.561 2051.9097,14.0785 2.0128,1838.2987 1280.8475,-4.728 14.608,-1830.1039 1312.2492,12.9229 14.608,1818.3367 2000.0059,20.4217 -12.279,-1841.4113 1304.168,1.6154 -12.279,2032.7059 -4638.6511,1.6154 19.5828,569.0378"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(2450.4075,-11647.329)"
|
||||||
|
id="g3188">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3305.5364"
|
||||||
|
y="13255.592"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
<g
|
||||||
|
id="g3107"
|
||||||
|
transform="translate(947.90548,11584.029)">
|
||||||
|
<rect
|
||||||
|
id="rect112"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5452.3052"
|
||||||
|
y="13844.535"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5">Root</tspan></text>
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057884, 60.00115769;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="6844.4546"
|
||||||
|
width="13658.751"
|
||||||
|
y="403.41983"
|
||||||
|
x="37.490932" />
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="662.8739"
|
||||||
|
x="153.26733"
|
||||||
|
xml:space="preserve">rcu_gp_init()</text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(2329.9439,-11610.962)"
|
||||||
|
id="g3147">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6"
|
||||||
|
transform="translate(3054.6101,13760.052)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5392.3345"
|
||||||
|
y="15407.104"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
transform="translate(3181.0246,-11647.329)"
|
||||||
|
id="g3153">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7536.4883"
|
||||||
|
y="17640.934"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-9"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-1642.5375,-11610.962)"
|
||||||
|
id="g3147-3"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-6"
|
||||||
|
transform="translate(3054.6101,13760.052)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-0"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-6"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="5378.4146"
|
||||||
|
y="15436.927"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-3"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-151.71726,-11647.329)"
|
||||||
|
id="g3153-2"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-6"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-1"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-8"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-9">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-3484.4587,-11647.329)"
|
||||||
|
id="g3153-20"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-2"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-3"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-7"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-5"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-92">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7520.1294"
|
||||||
|
y="17673.639"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-35"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-6817.1998,-11647.329)"
|
||||||
|
id="g3153-28"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-6-9-9"
|
||||||
|
transform="translate(5213.0126,16008.808)">
|
||||||
|
<rect
|
||||||
|
id="rect112-7-1-7"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-5-2-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="9717.4141"
|
||||||
|
y="18269.314"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-7-35-7-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-5-6-0-1">Leaf</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7521.4663"
|
||||||
|
y="17666.062"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-75"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812908px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 5473.7572,2235.0081 -582.9982,865.094"
|
||||||
|
id="path3414"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812813px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 8282.5391,2235.2701 582.9982,865.094"
|
||||||
|
id="path3414-9"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812813px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 3523.1241,4448.1851 -582.9982,865.094"
|
||||||
|
id="path3414-8"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 10268.171,4448.4471 583,865.094"
|
||||||
|
id="path3414-9-4"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 4939.6205,4448.1851 0,846.288"
|
||||||
|
id="path3414-8-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:13.29812717px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||||
|
d="m 8816.5958,4474.7811 0,846.288"
|
||||||
|
id="path3414-8-3-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="7370.856"
|
||||||
|
y="5997.5972"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-62"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->gpnum = rsp->gpnum</text>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 22 KiB |
5135
Documentation/RCU/Design/Memory-Ordering/TreeRCU-gp.svg
Normal file
After Width: | Height: | Size: 208 KiB |
775
Documentation/RCU/Design/Memory-Ordering/TreeRCU-hotplug.svg
Normal file
@@ -0,0 +1,775 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="613.22784"
|
||||||
|
height="707.07056"
|
||||||
|
viewBox="-44 -44 8154.7829 9398.3736"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="TreeRCU-hotplug.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutS"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutS"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4073"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.2,0.2)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="TriangleOutM"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="TriangleOutM"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4070"
|
||||||
|
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="scale(0.4,0.4)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3952"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3952-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(-0.6,-0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-6"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-2"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3940-9"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-3"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-1"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-7"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker4880"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4882"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-0"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-10"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-36"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-0"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-26"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-8"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-7"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-367"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-5"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-56"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3946-2"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3081"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3083"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3085"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3087"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3089"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3091"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3093"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3095"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker3097"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3099"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-9"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-1"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Send"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Send-3675"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3940-3"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1148"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="1.4142136"
|
||||||
|
inkscape:cx="325.41695"
|
||||||
|
inkscape:cy="364.94502"
|
||||||
|
inkscape:window-x="833"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5"
|
||||||
|
inkscape:snap-global="false">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3154"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true"
|
||||||
|
originx="65.610033px"
|
||||||
|
originy="-659.12429px" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-1-3-5"
|
||||||
|
d="m 5749.1555,47.151064 2.828,9167.338436"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-1"
|
||||||
|
d="m 5746.8844,5080.2018 -4107.7813,-0.8434 20.2152,2632.0511"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3134-9-0-3-1-3"
|
||||||
|
d="m 1629.8595,1633.6804 12.2312,2669.7294 4055.5945,7.7159"
|
||||||
|
style="fill:none;stroke:#969696;stroke-width:53.19251633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
|
||||||
|
<g
|
||||||
|
id="g3115"
|
||||||
|
transform="translate(1657.6576,12154.29)">
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057923, 60.00115859;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="2349.7295"
|
||||||
|
width="3992.2642"
|
||||||
|
y="-8909.5498"
|
||||||
|
x="2379.3704" />
|
||||||
|
<g
|
||||||
|
transform="translate(582.16224,-9085.2783)"
|
||||||
|
id="g3107-7"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<rect
|
||||||
|
x="2084.55"
|
||||||
|
y="949.37109"
|
||||||
|
width="2809.1992"
|
||||||
|
height="1370.8721"
|
||||||
|
rx="0"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
id="rect112-5" />
|
||||||
|
<rect
|
||||||
|
x="2084.55"
|
||||||
|
y="1025.3964"
|
||||||
|
width="2809.1992"
|
||||||
|
height="1294.8468"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
id="rect112-3-3" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-6-6-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-7356.375"
|
||||||
|
x="2774.7393"
|
||||||
|
xml:space="preserve">->qsmask &= ~->grpmask</text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2-7-7"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-8652.5312"
|
||||||
|
x="2466.7822"
|
||||||
|
xml:space="preserve">dyntick_save_progress_counter()</text>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-2-7-2-0"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-8368.1475"
|
||||||
|
x="2463.3262"
|
||||||
|
xml:space="preserve">rcu_implicit_dynticks_qs()</text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-3"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-6817.3472"
|
||||||
|
x="5103.9922"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-6"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4504"
|
||||||
|
transform="translate(-2953.0872,-15955.072)">
|
||||||
|
<path
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,335.22989,12456.379)"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
id="path3084"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="16835.086"
|
||||||
|
x="4409.043"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">RCU</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3110"
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
id="tspan3112"
|
||||||
|
sodipodi:role="line">read-side</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3114"
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
id="tspan3116"
|
||||||
|
sodipodi:role="line">critical section</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3148-9-9"
|
||||||
|
transform="translate(-3554.8919,7020.44)">
|
||||||
|
<rect
|
||||||
|
x="3592.3828"
|
||||||
|
y="-4981.6865"
|
||||||
|
width="3728.9751"
|
||||||
|
height="2265.0989"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057963, 60.00115926;stroke-dashoffset:0"
|
||||||
|
id="rect118-3-5-1-3"
|
||||||
|
ry="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3745.7725"
|
||||||
|
y="-4684.6201"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-3-27-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_report_dead()</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3745.7725"
|
||||||
|
y="-4431.7573"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-3-27-0-0"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_cleanup_dying_idle_cpu()</text>
|
||||||
|
<g
|
||||||
|
transform="translate(1783.3183,-5255.3491)"
|
||||||
|
id="g3107-7-5"
|
||||||
|
style="fill:none;stroke-width:0.025in">
|
||||||
|
<rect
|
||||||
|
x="2084.55"
|
||||||
|
y="949.37109"
|
||||||
|
width="2809.1992"
|
||||||
|
height="1370.8721"
|
||||||
|
rx="0"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
id="rect112-5-3" />
|
||||||
|
<rect
|
||||||
|
x="2084.55"
|
||||||
|
y="1025.3964"
|
||||||
|
width="2809.1992"
|
||||||
|
height="1294.8468"
|
||||||
|
rx="0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
id="rect112-3-3-5" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-6-6-2-6"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-3526.4448"
|
||||||
|
x="4241.8574"
|
||||||
|
xml:space="preserve">->qsmaskinitnext</text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-3-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="-2987.4167"
|
||||||
|
x="6305.1484"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-6-9"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4504-7"
|
||||||
|
transform="translate(-2934.2808,-8785.3871)">
|
||||||
|
<path
|
||||||
|
transform="matrix(13.298129,0,0,13.298129,335.22989,12456.379)"
|
||||||
|
d="m 385.2961,345.54001 c 0,21.84301 -29.51209,39.55026 -65.9171,39.55026 -36.40501,0 -65.91711,-17.70725 -65.91711,-39.55026 0,-21.84301 29.5121,-39.55026 65.91711,-39.55026 36.40501,0 65.9171,17.70725 65.9171,39.55026 z"
|
||||||
|
sodipodi:ry="39.550262"
|
||||||
|
sodipodi:rx="65.917107"
|
||||||
|
sodipodi:cy="345.54001"
|
||||||
|
sodipodi:cx="319.379"
|
||||||
|
id="path3084-9"
|
||||||
|
style="fill:#ffffa1;fill-opacity:0;stroke:#000000;stroke-width:2.25600004;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.256, 4.512;stroke-dashoffset:0"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-1-2-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="16835.086"
|
||||||
|
x="4409.043"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan3104-0"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans">RCU</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3110-2"
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17055.541"
|
||||||
|
x="4579.373"
|
||||||
|
id="tspan3112-3"
|
||||||
|
sodipodi:role="line">read-side</tspan></text>
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3114-7"
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="17297.08"
|
||||||
|
x="4584.8276"
|
||||||
|
id="tspan3116-5"
|
||||||
|
sodipodi:role="line">critical section</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3206"
|
||||||
|
transform="translate(3999.537,1706.6099)">
|
||||||
|
<rect
|
||||||
|
ry="0"
|
||||||
|
id="rect118-3-5-1-3-1"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30.00057983;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00058007, 60.00116001;stroke-dashoffset:0"
|
||||||
|
rx="0"
|
||||||
|
height="2265.0989"
|
||||||
|
width="3728.9751"
|
||||||
|
y="3382.2036"
|
||||||
|
x="-3958.3845" />
|
||||||
|
<text
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
id="text202-7-5-3-27-6-2"
|
||||||
|
font-size="192"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="normal"
|
||||||
|
y="3679.27"
|
||||||
|
x="-3804.9949"
|
||||||
|
xml:space="preserve">rcu_cpu_starting()</text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g3107-7-5-0"
|
||||||
|
transform="translate(-5767.4491,3108.5424)">
|
||||||
|
<rect
|
||||||
|
id="rect112-5-3-9"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3-3-5-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="-3308.9099"
|
||||||
|
y="4837.4453"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-6-6-2-6-6"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">->qsmaskinitnext</text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="-1245.6189"
|
||||||
|
y="5376.4731"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7-5-1-2-3-2-0"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;line-height:125%;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
style="font-size:159.57754517px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"
|
||||||
|
id="tspan3104-6-9-6">Leaf</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 28 KiB |
1095
Documentation/RCU/Design/Memory-Ordering/TreeRCU-qs.svg
Normal file
After Width: | Height: | Size: 43 KiB |
229
Documentation/RCU/Design/Memory-Ordering/rcu_node-lock.svg
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:35:03 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 2.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="303.54147"
|
||||||
|
height="211.57945"
|
||||||
|
viewBox="-44 -44 4036.5336 2812.3117"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="rcu_node-lock.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata212">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs210">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3970"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1087"
|
||||||
|
inkscape:window-height="1144"
|
||||||
|
id="namedview208"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.0495049"
|
||||||
|
inkscape:cx="311.2033"
|
||||||
|
inkscape:cy="168.10913"
|
||||||
|
inkscape:window-x="833"
|
||||||
|
inkscape:window-y="28"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="g4"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4"
|
||||||
|
transform="translate(-1905.5784,-4568.3024)">
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 8100 - 5710 5790-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 9300 - 4512 7140-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1040 9300 - 1502 7140-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2240 8100 - 2702 5940-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 2250 8100 - 2250 6240-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 1050 9300 - 1050 7440-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 4050 9300 - 4050 7440-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 8100 - 5250 6240-->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Circle -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9300 3150 - 10860 3150-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11400 3600 - 11400 4410-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<rect
|
||||||
|
x="1943.0693"
|
||||||
|
y="4603.417"
|
||||||
|
width="3873.5518"
|
||||||
|
height="2650.6289"
|
||||||
|
rx="0"
|
||||||
|
style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:30.00057884, 60.00115769;stroke-dashoffset:0"
|
||||||
|
id="rect118"
|
||||||
|
ry="0" />
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11400 5100 - 11400 5910-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9900 4650 - 10860 4650-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9600 6150 - 10860 6150-->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="3105.219"
|
||||||
|
y="6425.6445"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;font-family:Courier">rcu_accelerate_cbs()</text>
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<g
|
||||||
|
id="g3107"
|
||||||
|
transform="translate(747.5807,4700.8888)">
|
||||||
|
<rect
|
||||||
|
id="rect112"
|
||||||
|
style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1370.8721"
|
||||||
|
width="2809.1992"
|
||||||
|
y="949.37109"
|
||||||
|
x="2084.55" />
|
||||||
|
<rect
|
||||||
|
id="rect112-3"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter"
|
||||||
|
rx="0"
|
||||||
|
height="1294.8468"
|
||||||
|
width="2809.1992"
|
||||||
|
y="1025.3964"
|
||||||
|
x="2084.55" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
x="2025.5763"
|
||||||
|
y="4825.2578"
|
||||||
|
font-style="normal"
|
||||||
|
font-weight="bold"
|
||||||
|
font-size="192"
|
||||||
|
id="text202-7"
|
||||||
|
style="font-size:192px;font-style:normal;font-weight:bold;text-anchor:start;fill:#000000;stroke-width:0.025in;font-family:Courier">rcu_prepare_for_idle()</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
@@ -40,7 +40,9 @@ o Booting Linux using a console connection that is too slow to
|
|||||||
o Anything that prevents RCU's grace-period kthreads from running.
|
o Anything that prevents RCU's grace-period kthreads from running.
|
||||||
This can result in the "All QSes seen" console-log message.
|
This can result in the "All QSes seen" console-log message.
|
||||||
This message will include information on when the kthread last
|
This message will include information on when the kthread last
|
||||||
ran and how often it should be expected to run.
|
ran and how often it should be expected to run. It can also
|
||||||
|
result in the "rcu_.*kthread starved for" console-log message,
|
||||||
|
which will include additional debugging information.
|
||||||
|
|
||||||
o A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might
|
o A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might
|
||||||
happen to preempt a low-priority task in the middle of an RCU
|
happen to preempt a low-priority task in the middle of an RCU
|
||||||
@@ -60,6 +62,20 @@ o A CPU-bound real-time task in a CONFIG_PREEMPT_RT kernel that
|
|||||||
CONFIG_PREEMPT_RCU case, you might see stall-warning
|
CONFIG_PREEMPT_RCU case, you might see stall-warning
|
||||||
messages.
|
messages.
|
||||||
|
|
||||||
|
o A periodic interrupt whose handler takes longer than the time
|
||||||
|
interval between successive pairs of interrupts. This can
|
||||||
|
prevent RCU's kthreads and softirq handlers from running.
|
||||||
|
Note that certain high-overhead debugging options, for example
|
||||||
|
the function_graph tracer, can result in interrupt handler taking
|
||||||
|
considerably longer than normal, which can in turn result in
|
||||||
|
RCU CPU stall warnings.
|
||||||
|
|
||||||
|
o Testing a workload on a fast system, tuning the stall-warning
|
||||||
|
timeout down to just barely avoid RCU CPU stall warnings, and then
|
||||||
|
running the same workload with the same stall-warning timeout on a
|
||||||
|
slow system. Note that thermal throttling and on-demand governors
|
||||||
|
can cause a single system to be sometimes fast and sometimes slow!
|
||||||
|
|
||||||
o A hardware or software issue shuts off the scheduler-clock
|
o A hardware or software issue shuts off the scheduler-clock
|
||||||
interrupt on a CPU that is not in dyntick-idle mode. This
|
interrupt on a CPU that is not in dyntick-idle mode. This
|
||||||
problem really has happened, and seems to be most likely to
|
problem really has happened, and seems to be most likely to
|
||||||
@@ -155,67 +171,32 @@ Interpreting RCU's CPU Stall-Detector "Splats"
|
|||||||
For non-RCU-tasks flavors of RCU, when a CPU detects that it is stalling,
|
For non-RCU-tasks flavors of RCU, when a CPU detects that it is stalling,
|
||||||
it will print a message similar to the following:
|
it will print a message similar to the following:
|
||||||
|
|
||||||
INFO: rcu_sched_state detected stall on CPU 5 (t=2500 jiffies)
|
INFO: rcu_sched detected stalls on CPUs/tasks:
|
||||||
|
2-...: (3 GPs behind) idle=06c/0/0 softirq=1453/1455 fqs=0
|
||||||
|
16-...: (0 ticks this GP) idle=81c/0/0 softirq=764/764 fqs=0
|
||||||
|
(detected by 32, t=2603 jiffies, g=7073, c=7072, q=625)
|
||||||
|
|
||||||
This message indicates that CPU 5 detected that it was causing a stall,
|
This message indicates that CPU 32 detected that CPUs 2 and 16 were both
|
||||||
and that the stall was affecting RCU-sched. This message will normally be
|
causing stalls, and that the stall was affecting RCU-sched. This message
|
||||||
followed by a stack dump of the offending CPU. On TREE_RCU kernel builds,
|
|
||||||
RCU and RCU-sched are implemented by the same underlying mechanism,
|
|
||||||
while on PREEMPT_RCU kernel builds, RCU is instead implemented
|
|
||||||
by rcu_preempt_state.
|
|
||||||
|
|
||||||
On the other hand, if the offending CPU fails to print out a stall-warning
|
|
||||||
message quickly enough, some other CPU will print a message similar to
|
|
||||||
the following:
|
|
||||||
|
|
||||||
INFO: rcu_bh_state detected stalls on CPUs/tasks: { 3 5 } (detected by 2, 2502 jiffies)
|
|
||||||
|
|
||||||
This message indicates that CPU 2 detected that CPUs 3 and 5 were both
|
|
||||||
causing stalls, and that the stall was affecting RCU-bh. This message
|
|
||||||
will normally be followed by stack dumps for each CPU. Please note that
|
will normally be followed by stack dumps for each CPU. Please note that
|
||||||
PREEMPT_RCU builds can be stalled by tasks as well as by CPUs,
|
PREEMPT_RCU builds can be stalled by tasks as well as by CPUs, and that
|
||||||
and that the tasks will be indicated by PID, for example, "P3421".
|
the tasks will be indicated by PID, for example, "P3421". It is even
|
||||||
It is even possible for a rcu_preempt_state stall to be caused by both
|
possible for a rcu_preempt_state stall to be caused by both CPUs -and-
|
||||||
CPUs -and- tasks, in which case the offending CPUs and tasks will all
|
tasks, in which case the offending CPUs and tasks will all be called
|
||||||
be called out in the list.
|
out in the list.
|
||||||
|
|
||||||
Finally, if the grace period ends just as the stall warning starts
|
CPU 2's "(3 GPs behind)" indicates that this CPU has not interacted with
|
||||||
printing, there will be a spurious stall-warning message:
|
the RCU core for the past three grace periods. In contrast, CPU 16's "(0
|
||||||
|
ticks this GP)" indicates that this CPU has not taken any scheduling-clock
|
||||||
INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
|
interrupts during the current stalled grace period.
|
||||||
|
|
||||||
This is rare, but does happen from time to time in real life. It is also
|
|
||||||
possible for a zero-jiffy stall to be flagged in this case, depending
|
|
||||||
on how the stall warning and the grace-period initialization happen to
|
|
||||||
interact. Please note that it is not possible to entirely eliminate this
|
|
||||||
sort of false positive without resorting to things like stop_machine(),
|
|
||||||
which is overkill for this sort of problem.
|
|
||||||
|
|
||||||
Recent kernels will print a long form of the stall-warning message:
|
|
||||||
|
|
||||||
INFO: rcu_preempt detected stall on CPU
|
|
||||||
0: (63959 ticks this GP) idle=241/3fffffffffffffff/0 softirq=82/543
|
|
||||||
(t=65000 jiffies)
|
|
||||||
|
|
||||||
In kernels with CONFIG_RCU_FAST_NO_HZ, more information is printed:
|
|
||||||
|
|
||||||
INFO: rcu_preempt detected stall on CPU
|
|
||||||
0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 softirq=82/543 last_accelerate: a345/d342 nonlazy_posted: 25 .D
|
|
||||||
(t=65000 jiffies)
|
|
||||||
|
|
||||||
The "(64628 ticks this GP)" indicates that this CPU has taken more
|
|
||||||
than 64,000 scheduling-clock interrupts during the current stalled
|
|
||||||
grace period. If the CPU was not yet aware of the current grace
|
|
||||||
period (for example, if it was offline), then this part of the message
|
|
||||||
indicates how many grace periods behind the CPU is.
|
|
||||||
|
|
||||||
The "idle=" portion of the message prints the dyntick-idle state.
|
The "idle=" portion of the message prints the dyntick-idle state.
|
||||||
The hex number before the first "/" is the low-order 12 bits of the
|
The hex number before the first "/" is the low-order 12 bits of the
|
||||||
dynticks counter, which will have an even-numbered value if the CPU is
|
dynticks counter, which will have an even-numbered value if the CPU
|
||||||
in dyntick-idle mode and an odd-numbered value otherwise. The hex
|
is in dyntick-idle mode and an odd-numbered value otherwise. The hex
|
||||||
number between the two "/"s is the value of the nesting, which will
|
number between the two "/"s is the value of the nesting, which will be
|
||||||
be a small positive number if in the idle loop and a very large positive
|
a small non-negative number if in the idle loop (as shown above) and a
|
||||||
number (as shown above) otherwise.
|
very large positive number otherwise.
|
||||||
|
|
||||||
The "softirq=" portion of the message tracks the number of RCU softirq
|
The "softirq=" portion of the message tracks the number of RCU softirq
|
||||||
handlers that the stalled CPU has executed. The number before the "/"
|
handlers that the stalled CPU has executed. The number before the "/"
|
||||||
@@ -230,24 +211,72 @@ handlers are no longer able to execute on this CPU. This can happen if
|
|||||||
the stalled CPU is spinning with interrupts are disabled, or, in -rt
|
the stalled CPU is spinning with interrupts are disabled, or, in -rt
|
||||||
kernels, if a high-priority process is starving RCU's softirq handler.
|
kernels, if a high-priority process is starving RCU's softirq handler.
|
||||||
|
|
||||||
For CONFIG_RCU_FAST_NO_HZ kernels, the "last_accelerate:" prints the
|
The "fps=" shows the number of force-quiescent-state idle/offline
|
||||||
low-order 16 bits (in hex) of the jiffies counter when this CPU last
|
detection passes that the grace-period kthread has made across this
|
||||||
invoked rcu_try_advance_all_cbs() from rcu_needs_cpu() or last invoked
|
CPU since the last time that this CPU noted the beginning of a grace
|
||||||
rcu_accelerate_cbs() from rcu_prepare_for_idle(). The "nonlazy_posted:"
|
period.
|
||||||
prints the number of non-lazy callbacks posted since the last call to
|
|
||||||
rcu_needs_cpu(). Finally, an "L" indicates that there are currently
|
The "detected by" line indicates which CPU detected the stall (in this
|
||||||
no non-lazy callbacks ("." is printed otherwise, as shown above) and
|
case, CPU 32), how many jiffies have elapsed since the start of the
|
||||||
"D" indicates that dyntick-idle processing is enabled ("." is printed
|
grace period (in this case 2603), the number of the last grace period
|
||||||
otherwise, for example, if disabled via the "nohz=" kernel boot parameter).
|
to start and to complete (7073 and 7072, respectively), and an estimate
|
||||||
|
of the total number of RCU callbacks queued across all CPUs (625 in
|
||||||
|
this case).
|
||||||
|
|
||||||
|
In kernels with CONFIG_RCU_FAST_NO_HZ, more information is printed
|
||||||
|
for each CPU:
|
||||||
|
|
||||||
|
0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 softirq=82/543 last_accelerate: a345/d342 nonlazy_posted: 25 .D
|
||||||
|
|
||||||
|
The "last_accelerate:" prints the low-order 16 bits (in hex) of the
|
||||||
|
jiffies counter when this CPU last invoked rcu_try_advance_all_cbs()
|
||||||
|
from rcu_needs_cpu() or last invoked rcu_accelerate_cbs() from
|
||||||
|
rcu_prepare_for_idle(). The "nonlazy_posted:" prints the number
|
||||||
|
of non-lazy callbacks posted since the last call to rcu_needs_cpu().
|
||||||
|
Finally, an "L" indicates that there are currently no non-lazy callbacks
|
||||||
|
("." is printed otherwise, as shown above) and "D" indicates that
|
||||||
|
dyntick-idle processing is enabled ("." is printed otherwise, for example,
|
||||||
|
if disabled via the "nohz=" kernel boot parameter).
|
||||||
|
|
||||||
|
If the grace period ends just as the stall warning starts printing,
|
||||||
|
there will be a spurious stall-warning message, which will include
|
||||||
|
the following:
|
||||||
|
|
||||||
|
INFO: Stall ended before state dump start
|
||||||
|
|
||||||
|
This is rare, but does happen from time to time in real life. It is also
|
||||||
|
possible for a zero-jiffy stall to be flagged in this case, depending
|
||||||
|
on how the stall warning and the grace-period initialization happen to
|
||||||
|
interact. Please note that it is not possible to entirely eliminate this
|
||||||
|
sort of false positive without resorting to things like stop_machine(),
|
||||||
|
which is overkill for this sort of problem.
|
||||||
|
|
||||||
|
If all CPUs and tasks have passed through quiescent states, but the
|
||||||
|
grace period has nevertheless failed to end, the stall-warning splat
|
||||||
|
will include something like the following:
|
||||||
|
|
||||||
|
All QSes seen, last rcu_preempt kthread activity 23807 (4297905177-4297881370), jiffies_till_next_fqs=3, root ->qsmask 0x0
|
||||||
|
|
||||||
|
The "23807" indicates that it has been more than 23 thousand jiffies
|
||||||
|
since the grace-period kthread ran. The "jiffies_till_next_fqs"
|
||||||
|
indicates how frequently that kthread should run, giving the number
|
||||||
|
of jiffies between force-quiescent-state scans, in this case three,
|
||||||
|
which is way less than 23807. Finally, the root rcu_node structure's
|
||||||
|
->qsmask field is printed, which will normally be zero.
|
||||||
|
|
||||||
If the relevant grace-period kthread has been unable to run prior to
|
If the relevant grace-period kthread has been unable to run prior to
|
||||||
the stall warning, the following additional line is printed:
|
the stall warning, as was the case in the "All QSes seen" line above,
|
||||||
|
the following additional line is printed:
|
||||||
|
|
||||||
rcu_preempt kthread starved for 2023 jiffies!
|
kthread starved for 23807 jiffies! g7073 c7072 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
|
||||||
|
|
||||||
Starving the grace-period kthreads of CPU time can of course result in
|
Starving the grace-period kthreads of CPU time can of course result
|
||||||
RCU CPU stall warnings even when all CPUs and tasks have passed through
|
in RCU CPU stall warnings even when all CPUs and tasks have passed
|
||||||
the required quiescent states.
|
through the required quiescent states. The "g" and "c" numbers flag the
|
||||||
|
number of the last grace period started and completed, respectively,
|
||||||
|
the "f" precedes the ->gp_flags command to the grace-period kthread,
|
||||||
|
the "RCU_GP_WAIT_FQS" indicates that the kthread is waiting for a short
|
||||||
|
timeout, and the "state" precedes value of the task_struct ->state field.
|
||||||
|
|
||||||
|
|
||||||
Multiple Warnings From One Stall
|
Multiple Warnings From One Stall
|
||||||
@@ -264,13 +293,28 @@ Stall Warnings for Expedited Grace Periods
|
|||||||
If an expedited grace period detects a stall, it will place a message
|
If an expedited grace period detects a stall, it will place a message
|
||||||
like the following in dmesg:
|
like the following in dmesg:
|
||||||
|
|
||||||
INFO: rcu_sched detected expedited stalls on CPUs: { 1 2 6 } 26009 jiffies s: 1043
|
INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 7-... } 21119 jiffies s: 73 root: 0x2/.
|
||||||
|
|
||||||
This indicates that CPUs 1, 2, and 6 have failed to respond to a
|
This indicates that CPU 7 has failed to respond to a reschedule IPI.
|
||||||
reschedule IPI, that the expedited grace period has been going on for
|
The three periods (".") following the CPU number indicate that the CPU
|
||||||
26,009 jiffies, and that the expedited grace-period sequence counter is
|
is online (otherwise the first period would instead have been "O"),
|
||||||
1043. The fact that this last value is odd indicates that an expedited
|
that the CPU was online at the beginning of the expedited grace period
|
||||||
grace period is in flight.
|
(otherwise the second period would have instead been "o"), and that
|
||||||
|
the CPU has been online at least once since boot (otherwise, the third
|
||||||
|
period would instead have been "N"). The number before the "jiffies"
|
||||||
|
indicates that the expedited grace period has been going on for 21,119
|
||||||
|
jiffies. The number following the "s:" indicates that the expedited
|
||||||
|
grace-period sequence counter is 73. The fact that this last value is
|
||||||
|
odd indicates that an expedited grace period is in flight. The number
|
||||||
|
following "root:" is a bitmask that indicates which children of the root
|
||||||
|
rcu_node structure correspond to CPUs and/or tasks that are blocking the
|
||||||
|
current expedited grace period. If the tree had more than one level,
|
||||||
|
additional hex numbers would be printed for the states of the other
|
||||||
|
rcu_node structures in the tree.
|
||||||
|
|
||||||
|
As with normal grace periods, PREEMPT_RCU builds can be stalled by
|
||||||
|
tasks as well as by CPUs, and that the tasks will be indicated by PID,
|
||||||
|
for example, "P3421".
|
||||||
|
|
||||||
It is entirely possible to see stall warnings from normal and from
|
It is entirely possible to see stall warnings from normal and from
|
||||||
expedited grace periods at about the same time from the same run.
|
expedited grace periods at about the same time during the same run.
|
||||||
|
@@ -350,7 +350,7 @@ If something goes wrong
|
|||||||
help debugging the problem. The text above the dump is also
|
help debugging the problem. The text above the dump is also
|
||||||
important: it tells something about why the kernel dumped code (in
|
important: it tells something about why the kernel dumped code (in
|
||||||
the above example, it's due to a bad kernel pointer). More information
|
the above example, it's due to a bad kernel pointer). More information
|
||||||
on making sense of the dump is in Documentation/admin-guide/oops-tracing.rst
|
on making sense of the dump is in Documentation/admin-guide/bug-hunting.rst
|
||||||
|
|
||||||
- If you compiled the kernel with CONFIG_KALLSYMS you can send the dump
|
- If you compiled the kernel with CONFIG_KALLSYMS you can send the dump
|
||||||
as is, otherwise you will have to use the ``ksymoops`` program to make
|
as is, otherwise you will have to use the ``ksymoops`` program to make
|
||||||
|
@@ -240,7 +240,7 @@ In order to report it upstream, you should identify the mailing list
|
|||||||
used for the development of the affected code. This can be done by using
|
used for the development of the affected code. This can be done by using
|
||||||
the ``get_maintainer.pl`` script.
|
the ``get_maintainer.pl`` script.
|
||||||
|
|
||||||
For example, if you find a bug at the gspca's conex.c file, you can get
|
For example, if you find a bug at the gspca's sonixj.c file, you can get
|
||||||
their maintainers with::
|
their maintainers with::
|
||||||
|
|
||||||
$ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c
|
$ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c
|
||||||
@@ -257,7 +257,7 @@ Please notice that it will point to:
|
|||||||
Tejun and Bhaktipriya (in this specific case, none really envolved on the
|
Tejun and Bhaktipriya (in this specific case, none really envolved on the
|
||||||
development of this file);
|
development of this file);
|
||||||
- The driver maintainer (Hans Verkuil);
|
- The driver maintainer (Hans Verkuil);
|
||||||
- The subsystem maintainer (Mauro Carvalho Chehab)
|
- The subsystem maintainer (Mauro Carvalho Chehab);
|
||||||
- The driver and/or subsystem mailing list (linux-media@vger.kernel.org);
|
- The driver and/or subsystem mailing list (linux-media@vger.kernel.org);
|
||||||
- the Linux Kernel mailing list (linux-kernel@vger.kernel.org).
|
- the Linux Kernel mailing list (linux-kernel@vger.kernel.org).
|
||||||
|
|
||||||
@@ -274,14 +274,14 @@ Fixing the bug
|
|||||||
--------------
|
--------------
|
||||||
|
|
||||||
If you know programming, you could help us by not only reporting the bug,
|
If you know programming, you could help us by not only reporting the bug,
|
||||||
but also providing us with a solution. After all open source is about
|
but also providing us with a solution. After all, open source is about
|
||||||
sharing what you do and don't you want to be recognised for your genius?
|
sharing what you do and don't you want to be recognised for your genius?
|
||||||
|
|
||||||
If you decide to take this way, once you have worked out a fix please submit
|
If you decide to take this way, once you have worked out a fix please submit
|
||||||
it upstream.
|
it upstream.
|
||||||
|
|
||||||
Please do read
|
Please do read
|
||||||
ref:`Documentation/process/submitting-patches.rst <submittingpatches>` though
|
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` though
|
||||||
to help your code get accepted.
|
to help your code get accepted.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -314,7 +314,7 @@
|
|||||||
amijoy.map= [HW,JOY] Amiga joystick support
|
amijoy.map= [HW,JOY] Amiga joystick support
|
||||||
Map of devices attached to JOY0DAT and JOY1DAT
|
Map of devices attached to JOY0DAT and JOY1DAT
|
||||||
Format: <a>,<b>
|
Format: <a>,<b>
|
||||||
See also Documentation/input/joystick.txt
|
See also Documentation/input/joydev/joystick.rst
|
||||||
|
|
||||||
analog.map= [HW,JOY] Analog joystick and gamepad support
|
analog.map= [HW,JOY] Analog joystick and gamepad support
|
||||||
Specifies type or capabilities of an analog joystick
|
Specifies type or capabilities of an analog joystick
|
||||||
@@ -439,7 +439,7 @@
|
|||||||
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
|
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
|
||||||
bttv.radio= Most important insmod options are available as
|
bttv.radio= Most important insmod options are available as
|
||||||
kernel args too.
|
kernel args too.
|
||||||
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
|
bttv.pll= See Documentation/media/v4l-drivers/bttv.rst
|
||||||
bttv.tuner=
|
bttv.tuner=
|
||||||
|
|
||||||
bulk_remove=off [PPC] This parameter disables the use of the pSeries
|
bulk_remove=off [PPC] This parameter disables the use of the pSeries
|
||||||
@@ -641,8 +641,8 @@
|
|||||||
For now, only VisioBraille is supported.
|
For now, only VisioBraille is supported.
|
||||||
|
|
||||||
consoleblank= [KNL] The console blank (screen saver) timeout in
|
consoleblank= [KNL] The console blank (screen saver) timeout in
|
||||||
seconds. Defaults to 10*60 = 10mins. A value of 0
|
seconds. A value of 0 disables the blank timer.
|
||||||
disables the blank timer.
|
Defaults to 0.
|
||||||
|
|
||||||
coredump_filter=
|
coredump_filter=
|
||||||
[KNL] Change the default value for
|
[KNL] Change the default value for
|
||||||
@@ -709,6 +709,9 @@
|
|||||||
It will be ignored when crashkernel=X,high is not used
|
It will be ignored when crashkernel=X,high is not used
|
||||||
or memory reserved is below 4G.
|
or memory reserved is below 4G.
|
||||||
|
|
||||||
|
crossrelease_fullstack
|
||||||
|
[KNL] Allow to record full stack trace in cross-release
|
||||||
|
|
||||||
cryptomgr.notests
|
cryptomgr.notests
|
||||||
[KNL] Disable crypto self-tests
|
[KNL] Disable crypto self-tests
|
||||||
|
|
||||||
@@ -724,7 +727,7 @@
|
|||||||
db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port
|
db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port
|
||||||
(one device per port)
|
(one device per port)
|
||||||
Format: <port#>,<type>
|
Format: <port#>,<type>
|
||||||
See also Documentation/input/joystick-parport.txt
|
See also Documentation/input/devices/joystick-parport.rst
|
||||||
|
|
||||||
ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
|
ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
|
||||||
time. See
|
time. See
|
||||||
@@ -1220,7 +1223,7 @@
|
|||||||
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
||||||
support via parallel port (up to 5 devices per port)
|
support via parallel port (up to 5 devices per port)
|
||||||
Format: <port#>,<pad1>,<pad2>,<pad3>,<pad4>,<pad5>
|
Format: <port#>,<pad1>,<pad2>,<pad3>,<pad4>,<pad5>
|
||||||
See also Documentation/input/joystick-parport.txt
|
See also Documentation/input/devices/joystick-parport.rst
|
||||||
|
|
||||||
gamma= [HW,DRM]
|
gamma= [HW,DRM]
|
||||||
|
|
||||||
@@ -1713,6 +1716,13 @@
|
|||||||
irqaffinity= [SMP] Set the default irq affinity mask
|
irqaffinity= [SMP] Set the default irq affinity mask
|
||||||
The argument is a cpu list, as described above.
|
The argument is a cpu list, as described above.
|
||||||
|
|
||||||
|
irqchip.gicv2_force_probe=
|
||||||
|
[ARM, ARM64]
|
||||||
|
Format: <bool>
|
||||||
|
Force the kernel to look for the second 4kB page
|
||||||
|
of a GICv2 controller even if the memory range
|
||||||
|
exposed by the device tree is too small.
|
||||||
|
|
||||||
irqfixup [HW]
|
irqfixup [HW]
|
||||||
When an interrupt is not handled search all handlers
|
When an interrupt is not handled search all handlers
|
||||||
for it. Intended to get systems with badly broken
|
for it. Intended to get systems with badly broken
|
||||||
@@ -1727,20 +1737,33 @@
|
|||||||
isapnp= [ISAPNP]
|
isapnp= [ISAPNP]
|
||||||
Format: <RDP>,<reset>,<pci_scan>,<verbosity>
|
Format: <RDP>,<reset>,<pci_scan>,<verbosity>
|
||||||
|
|
||||||
isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler.
|
isolcpus= [KNL,SMP] Isolate a given set of CPUs from disturbance.
|
||||||
The argument is a cpu list, as described above.
|
[Deprecated - use cpusets instead]
|
||||||
|
Format: [flag-list,]<cpu-list>
|
||||||
|
|
||||||
|
Specify one or more CPUs to isolate from disturbances
|
||||||
|
specified in the flag list (default: domain):
|
||||||
|
|
||||||
|
nohz
|
||||||
|
Disable the tick when a single task runs.
|
||||||
|
domain
|
||||||
|
Isolate from the general SMP balancing and scheduling
|
||||||
|
algorithms. Note that performing domain isolation this way
|
||||||
|
is irreversible: it's not possible to bring back a CPU to
|
||||||
|
the domains once isolated through isolcpus. It's strongly
|
||||||
|
advised to use cpusets instead to disable scheduler load
|
||||||
|
balancing through the "cpuset.sched_load_balance" file.
|
||||||
|
It offers a much more flexible interface where CPUs can
|
||||||
|
move in and out of an isolated set anytime.
|
||||||
|
|
||||||
|
You can move a process onto or off an "isolated" CPU via
|
||||||
|
the CPU affinity syscalls or cpuset.
|
||||||
|
<cpu number> begins at 0 and the maximum value is
|
||||||
|
"number of CPUs in system - 1".
|
||||||
|
|
||||||
|
The format of <cpu-list> is described above.
|
||||||
|
|
||||||
This option can be used to specify one or more CPUs
|
|
||||||
to isolate from the general SMP balancing and scheduling
|
|
||||||
algorithms. You can move a process onto or off an
|
|
||||||
"isolated" CPU via the CPU affinity syscalls or cpuset.
|
|
||||||
<cpu number> begins at 0 and the maximum value is
|
|
||||||
"number of CPUs in system - 1".
|
|
||||||
|
|
||||||
This option is the preferred way to isolate CPUs. The
|
|
||||||
alternative -- manually setting the CPU mask of all
|
|
||||||
tasks in the system -- can cause problems and
|
|
||||||
suboptimal load balancer performance.
|
|
||||||
|
|
||||||
iucv= [HW,NET]
|
iucv= [HW,NET]
|
||||||
|
|
||||||
@@ -1766,7 +1789,7 @@
|
|||||||
ivrs_acpihid[00:14.5]=AMD0020:0
|
ivrs_acpihid[00:14.5]=AMD0020:0
|
||||||
|
|
||||||
js= [HW,JOY] Analog joystick
|
js= [HW,JOY] Analog joystick
|
||||||
See Documentation/input/joystick.txt.
|
See Documentation/input/joydev/joystick.rst.
|
||||||
|
|
||||||
nokaslr [KNL]
|
nokaslr [KNL]
|
||||||
When CONFIG_RANDOMIZE_BASE is set, this disables
|
When CONFIG_RANDOMIZE_BASE is set, this disables
|
||||||
@@ -2248,10 +2271,10 @@
|
|||||||
s2idle - Suspend-To-Idle
|
s2idle - Suspend-To-Idle
|
||||||
shallow - Power-On Suspend or equivalent (if supported)
|
shallow - Power-On Suspend or equivalent (if supported)
|
||||||
deep - Suspend-To-RAM or equivalent (if supported)
|
deep - Suspend-To-RAM or equivalent (if supported)
|
||||||
See Documentation/power/states.txt.
|
See Documentation/admin-guide/pm/sleep-states.rst.
|
||||||
|
|
||||||
meye.*= [HW] Set MotionEye Camera parameters
|
meye.*= [HW] Set MotionEye Camera parameters
|
||||||
See Documentation/video4linux/meye.txt.
|
See Documentation/media/v4l-drivers/meye.rst.
|
||||||
|
|
||||||
mfgpt_irq= [IA-32] Specify the IRQ to use for the
|
mfgpt_irq= [IA-32] Specify the IRQ to use for the
|
||||||
Multi-Function General Purpose Timers on AMD Geode
|
Multi-Function General Purpose Timers on AMD Geode
|
||||||
@@ -2548,6 +2571,9 @@
|
|||||||
|
|
||||||
noalign [KNL,ARM]
|
noalign [KNL,ARM]
|
||||||
|
|
||||||
|
noaltinstr [S390] Disables alternative instructions patching
|
||||||
|
(CPU alternatives feature).
|
||||||
|
|
||||||
noapic [SMP,APIC] Tells the kernel to not make use of any
|
noapic [SMP,APIC] Tells the kernel to not make use of any
|
||||||
IOAPICs that may be present in the system.
|
IOAPICs that may be present in the system.
|
||||||
|
|
||||||
@@ -3134,7 +3160,7 @@
|
|||||||
|
|
||||||
plip= [PPT,NET] Parallel port network link
|
plip= [PPT,NET] Parallel port network link
|
||||||
Format: { parport<nr> | timid | 0 }
|
Format: { parport<nr> | timid | 0 }
|
||||||
See also Documentation/parport.txt.
|
See also Documentation/admin-guide/parport.rst.
|
||||||
|
|
||||||
pmtmr= [X86] Manual setup of pmtmr I/O Port.
|
pmtmr= [X86] Manual setup of pmtmr I/O Port.
|
||||||
Override pmtimer IOPort with a hex value.
|
Override pmtimer IOPort with a hex value.
|
||||||
@@ -3539,6 +3565,9 @@
|
|||||||
rcutorture.stall_cpu_holdoff= [KNL]
|
rcutorture.stall_cpu_holdoff= [KNL]
|
||||||
Time to wait (s) after boot before inducing stall.
|
Time to wait (s) after boot before inducing stall.
|
||||||
|
|
||||||
|
rcutorture.stall_cpu_irqsoff= [KNL]
|
||||||
|
Disable interrupts while stalling if set.
|
||||||
|
|
||||||
rcutorture.stat_interval= [KNL]
|
rcutorture.stat_interval= [KNL]
|
||||||
Time (s) between statistics printk()s.
|
Time (s) between statistics printk()s.
|
||||||
|
|
||||||
@@ -3885,6 +3914,12 @@
|
|||||||
[KNL] Should the soft-lockup detector generate panics.
|
[KNL] Should the soft-lockup detector generate panics.
|
||||||
Format: <integer>
|
Format: <integer>
|
||||||
|
|
||||||
|
A nonzero value instructs the soft-lockup detector
|
||||||
|
to panic the machine when a soft-lockup occurs. This
|
||||||
|
is also controlled by CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC
|
||||||
|
which is the respective build-time switch to that
|
||||||
|
functionality.
|
||||||
|
|
||||||
softlockup_all_cpu_backtrace=
|
softlockup_all_cpu_backtrace=
|
||||||
[KNL] Should the soft-lockup detector generate
|
[KNL] Should the soft-lockup detector generate
|
||||||
backtraces on all cpus.
|
backtraces on all cpus.
|
||||||
@@ -4194,12 +4229,15 @@
|
|||||||
Used to run time disable IRQ_TIME_ACCOUNTING on any
|
Used to run time disable IRQ_TIME_ACCOUNTING on any
|
||||||
platforms where RDTSC is slow and this accounting
|
platforms where RDTSC is slow and this accounting
|
||||||
can add overhead.
|
can add overhead.
|
||||||
|
[x86] unstable: mark the TSC clocksource as unstable, this
|
||||||
|
marks the TSC unconditionally unstable at bootup and
|
||||||
|
avoids any further wobbles once the TSC watchdog notices.
|
||||||
|
|
||||||
turbografx.map[2|3]= [HW,JOY]
|
turbografx.map[2|3]= [HW,JOY]
|
||||||
TurboGraFX parallel port interface
|
TurboGraFX parallel port interface
|
||||||
Format:
|
Format:
|
||||||
<port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
|
<port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
|
||||||
See also Documentation/input/joystick-parport.txt
|
See also Documentation/input/devices/joystick-parport.rst
|
||||||
|
|
||||||
udbg-immortal [PPC] When debugging early kernel crashes that
|
udbg-immortal [PPC] When debugging early kernel crashes that
|
||||||
happen after console_init() and before a proper
|
happen after console_init() and before a proper
|
||||||
|
@@ -94,7 +94,7 @@ step-by-step instructions for how a user can trigger the bug.
|
|||||||
|
|
||||||
If the failure includes an "OOPS:", take a picture of the screen, capture
|
If the failure includes an "OOPS:", take a picture of the screen, capture
|
||||||
a netconsole trace, or type the message from your screen into the bug
|
a netconsole trace, or type the message from your screen into the bug
|
||||||
report. Please read "Documentation/admin-guide/oops-tracing.rst" before posting your
|
report. Please read "Documentation/admin-guide/bug-hunting.rst" before posting your
|
||||||
bug report. This explains what you should do with the "Oops" information
|
bug report. This explains what you should do with the "Oops" information
|
||||||
to make it useful to the recipient.
|
to make it useful to the recipient.
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ summary from [1.]>" for easy identification by the developers::
|
|||||||
[4.2.] Kernel .config file:
|
[4.2.] Kernel .config file:
|
||||||
[5.] Most recent kernel version which did not have the bug:
|
[5.] Most recent kernel version which did not have the bug:
|
||||||
[6.] Output of Oops.. message (if applicable) with symbolic information
|
[6.] Output of Oops.. message (if applicable) with symbolic information
|
||||||
resolved (see Documentation/admin-guide/oops-tracing.rst)
|
resolved (see Documentation/admin-guide/bug-hunting.rst)
|
||||||
[7.] A small shell script or example program which triggers the
|
[7.] A small shell script or example program which triggers the
|
||||||
problem (if possible)
|
problem (if possible)
|
||||||
[8.] Environment
|
[8.] Environment
|
||||||
|
@@ -70,6 +70,7 @@ stable kernels.
|
|||||||
| | | | |
|
| | | | |
|
||||||
| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
|
| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
|
||||||
| Hisilicon | Hip0{6,7} | #161010701 | N/A |
|
| Hisilicon | Hip0{6,7} | #161010701 | N/A |
|
||||||
|
| Hisilicon | Hip07 | #161600802 | HISILICON_ERRATUM_161600802 |
|
||||||
| | | | |
|
| | | | |
|
||||||
| Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
|
| Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
|
||||||
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
|
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
|
||||||
|
@@ -55,13 +55,9 @@ This driver provides the following features:
|
|||||||
(to compile support as a module which can be loaded and unloaded)
|
(to compile support as a module which can be loaded and unloaded)
|
||||||
to the options:
|
to the options:
|
||||||
|
|
||||||
Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
|
ATA/ATAPI/MFM/RLL support
|
||||||
Include IDE/ATAPI CDROM support
|
Include IDE/ATAPI CDROM support
|
||||||
|
|
||||||
and `no' to
|
|
||||||
|
|
||||||
Use old disk-only driver on primary interface
|
|
||||||
|
|
||||||
Depending on what type of IDE interface you have, you may need to
|
Depending on what type of IDE interface you have, you may need to
|
||||||
specify additional configuration options. See
|
specify additional configuration options. See
|
||||||
Documentation/ide/ide.txt.
|
Documentation/ide/ide.txt.
|
||||||
|
@@ -2,11 +2,9 @@
|
|||||||
The Linux Kernel API
|
The Linux Kernel API
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Data Types
|
|
||||||
==========
|
|
||||||
|
|
||||||
Doubly Linked Lists
|
List Management Functions
|
||||||
-------------------
|
=========================
|
||||||
|
|
||||||
.. kernel-doc:: include/linux/list.h
|
.. kernel-doc:: include/linux/list.h
|
||||||
:internal:
|
:internal:
|
||||||
@@ -55,12 +53,27 @@ The Linux kernel provides more basic utility functions.
|
|||||||
Bitmap Operations
|
Bitmap Operations
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/bitmap.c
|
||||||
|
:doc: bitmap introduction
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/bitmap.h
|
||||||
|
:doc: declare bitmap
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/bitmap.h
|
||||||
|
:doc: bitmap overview
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/bitmap.h
|
||||||
|
:doc: bitmap bitops
|
||||||
|
|
||||||
.. kernel-doc:: lib/bitmap.c
|
.. kernel-doc:: lib/bitmap.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
.. kernel-doc:: lib/bitmap.c
|
.. kernel-doc:: lib/bitmap.c
|
||||||
:internal:
|
:internal:
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/bitmap.h
|
||||||
|
:internal:
|
||||||
|
|
||||||
Command-line Parsing
|
Command-line Parsing
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -70,20 +83,26 @@ Command-line Parsing
|
|||||||
CRC Functions
|
CRC Functions
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/crc4.c
|
||||||
|
:export:
|
||||||
|
|
||||||
.. kernel-doc:: lib/crc7.c
|
.. kernel-doc:: lib/crc7.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/crc8.c
|
||||||
|
:export:
|
||||||
|
|
||||||
.. kernel-doc:: lib/crc16.c
|
.. kernel-doc:: lib/crc16.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
.. kernel-doc:: lib/crc-itu-t.c
|
|
||||||
:export:
|
|
||||||
|
|
||||||
.. kernel-doc:: lib/crc32.c
|
.. kernel-doc:: lib/crc32.c
|
||||||
|
|
||||||
.. kernel-doc:: lib/crc-ccitt.c
|
.. kernel-doc:: lib/crc-ccitt.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/crc-itu-t.c
|
||||||
|
:export:
|
||||||
|
|
||||||
idr/ida Functions
|
idr/ida Functions
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@@ -96,6 +115,30 @@ idr/ida Functions
|
|||||||
.. kernel-doc:: lib/idr.c
|
.. kernel-doc:: lib/idr.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
|
Math Functions in Linux
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Base 2 log and power Functions
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/log2.h
|
||||||
|
:internal:
|
||||||
|
|
||||||
|
Division Functions
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. kernel-doc:: include/asm-generic/div64.h
|
||||||
|
:functions: do_div
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/math64.h
|
||||||
|
:internal:
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/div64.c
|
||||||
|
:functions: div_s64_rem div64_u64_rem div64_u64 div64_s64
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/gcd.c
|
||||||
|
:export:
|
||||||
|
|
||||||
Memory Management in Linux
|
Memory Management in Linux
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@@ -209,7 +209,7 @@ err.log will now have the profiling information, while stdout will
|
|||||||
provide some progress information as Coccinelle moves forward with
|
provide some progress information as Coccinelle moves forward with
|
||||||
work.
|
work.
|
||||||
|
|
||||||
DEBUG_FILE support is only supported when using coccinelle >= 1.2.
|
DEBUG_FILE support is only supported when using coccinelle >= 1.0.2.
|
||||||
|
|
||||||
.cocciconfig support
|
.cocciconfig support
|
||||||
--------------------
|
--------------------
|
||||||
|
@@ -31,6 +31,17 @@ To build and run the tests with a single command, use::
|
|||||||
|
|
||||||
Note that some tests will require root privileges.
|
Note that some tests will require root privileges.
|
||||||
|
|
||||||
|
Build and run from user specific object directory (make O=dir)::
|
||||||
|
|
||||||
|
$ make O=/tmp/kselftest kselftest
|
||||||
|
|
||||||
|
Build and run KBUILD_OUTPUT directory (make KBUILD_OUTPUT=)::
|
||||||
|
|
||||||
|
$ make KBUILD_OUTPUT=/tmp/kselftest kselftest
|
||||||
|
|
||||||
|
The above commands run the tests and print pass/fail summary to make it
|
||||||
|
easier to understand the test results. Please find the detailed individual
|
||||||
|
test results for each test in /tmp/testname file(s).
|
||||||
|
|
||||||
Running a subset of selftests
|
Running a subset of selftests
|
||||||
=============================
|
=============================
|
||||||
@@ -46,10 +57,21 @@ You can specify multiple tests to build and run::
|
|||||||
|
|
||||||
$ make TARGETS="size timers" kselftest
|
$ make TARGETS="size timers" kselftest
|
||||||
|
|
||||||
|
Build and run from user specific object directory (make O=dir)::
|
||||||
|
|
||||||
|
$ make O=/tmp/kselftest TARGETS="size timers" kselftest
|
||||||
|
|
||||||
|
Build and run KBUILD_OUTPUT directory (make KBUILD_OUTPUT=)::
|
||||||
|
|
||||||
|
$ make KBUILD_OUTPUT=/tmp/kselftest TARGETS="size timers" kselftest
|
||||||
|
|
||||||
|
The above commands run the tests and print pass/fail summary to make it
|
||||||
|
easier to understand the test results. Please find the detailed individual
|
||||||
|
test results for each test in /tmp/testname file(s).
|
||||||
|
|
||||||
See the top-level tools/testing/selftests/Makefile for the list of all
|
See the top-level tools/testing/selftests/Makefile for the list of all
|
||||||
possible targets.
|
possible targets.
|
||||||
|
|
||||||
|
|
||||||
Running the full range hotplug selftests
|
Running the full range hotplug selftests
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
@@ -113,9 +135,17 @@ Contributing new tests (details)
|
|||||||
* Use TEST_GEN_XXX if such binaries or files are generated during
|
* Use TEST_GEN_XXX if such binaries or files are generated during
|
||||||
compiling.
|
compiling.
|
||||||
|
|
||||||
TEST_PROGS, TEST_GEN_PROGS mean it is the excutable tested by
|
TEST_PROGS, TEST_GEN_PROGS mean it is the executable tested by
|
||||||
default.
|
default.
|
||||||
|
|
||||||
|
TEST_CUSTOM_PROGS should be used by tests that require custom build
|
||||||
|
rule and prevent common build rule use.
|
||||||
|
|
||||||
|
TEST_PROGS are for test shell scripts. Please ensure shell script has
|
||||||
|
its exec bit set. Otherwise, lib.mk run_tests will generate a warning.
|
||||||
|
|
||||||
|
TEST_CUSTOM_PROGS and TEST_PROGS will be run by common run_tests.
|
||||||
|
|
||||||
TEST_PROGS_EXTENDED, TEST_GEN_PROGS_EXTENDED mean it is the
|
TEST_PROGS_EXTENDED, TEST_GEN_PROGS_EXTENDED mean it is the
|
||||||
executable which is not tested by default.
|
executable which is not tested by default.
|
||||||
TEST_FILES, TEST_GEN_FILES mean it is the file which is used by
|
TEST_FILES, TEST_GEN_FILES mean it is the file which is used by
|
||||||
|
12
Documentation/devicetree/bindings/hwmon/max1619.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Bindings for MAX1619 Temperature Sensor
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : "maxim,max1619"
|
||||||
|
- reg : I2C address, one of 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, or
|
||||||
|
0x4d, 0x4e
|
||||||
|
|
||||||
|
Example:
|
||||||
|
temp@4c {
|
||||||
|
compatible = "maxim,max1619";
|
||||||
|
reg = <0x4c>;
|
||||||
|
};
|
22
Documentation/devicetree/bindings/hwmon/max31785.txt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Bindings for the Maxim MAX31785 Intelligent Fan Controller
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
Reference:
|
||||||
|
|
||||||
|
https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
|
||||||
|
|
||||||
|
The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan
|
||||||
|
management with temperature and remote voltage sensing. Various fan control
|
||||||
|
features are provided, including PWM frequency control, temperature hysteresis,
|
||||||
|
dual tachometer measurements, and fan health monitoring.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : One of "maxim,max31785" or "maxim,max31785a"
|
||||||
|
- reg : I2C address, one of 0x52, 0x53, 0x54, 0x55.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
fans@52 {
|
||||||
|
compatible = "maxim,max31785";
|
||||||
|
reg = <0x52>;
|
||||||
|
};
|
@@ -0,0 +1,36 @@
|
|||||||
|
Amlogic meson GPIO interrupt controller
|
||||||
|
|
||||||
|
Meson SoCs contains an interrupt controller which is able to watch the SoC
|
||||||
|
pads and generate an interrupt on edge or level. The controller is essentially
|
||||||
|
a 256 pads to 8 GIC interrupt multiplexer, with a filter block to select edge
|
||||||
|
or level and polarity. It does not expose all 256 mux inputs because the
|
||||||
|
documentation shows that the upper part is not mapped to any pad. The actual
|
||||||
|
number of interrupt exposed depends on the SoC.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : must have "amlogic,meson8-gpio-intc” and either
|
||||||
|
“amlogic,meson8-gpio-intc” for meson8 SoCs (S802) or
|
||||||
|
“amlogic,meson8b-gpio-intc” for meson8b SoCs (S805) or
|
||||||
|
“amlogic,meson-gxbb-gpio-intc” for GXBB SoCs (S905) or
|
||||||
|
“amlogic,meson-gxl-gpio-intc” for GXL SoCs (S905X, S912)
|
||||||
|
- interrupt-parent : a phandle to the GIC the interrupts are routed to.
|
||||||
|
Usually this is provided at the root level of the device tree as it is
|
||||||
|
common to most of the SoC.
|
||||||
|
- reg : Specifies base physical address and size of the registers.
|
||||||
|
- interrupt-controller : Identifies the node as an interrupt controller.
|
||||||
|
- #interrupt-cells : Specifies the number of cells needed to encode an
|
||||||
|
interrupt source. The value must be 2.
|
||||||
|
- meson,channel-interrupts: Array with the 8 upstream hwirq numbers. These
|
||||||
|
are the hwirqs used on the parent interrupt controller.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
gpio_interrupt: interrupt-controller@9880 {
|
||||||
|
compatible = "amlogic,meson-gxbb-gpio-intc",
|
||||||
|
"amlogic,meson-gpio-intc";
|
||||||
|
reg = <0x0 0x9880 0x0 0x10>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
meson,channel-interrupts = <64 65 66 67 68 69 70 71>;
|
||||||
|
};
|
@@ -75,6 +75,10 @@ These nodes must have the following properties:
|
|||||||
- reg: Specifies the base physical address and size of the ITS
|
- reg: Specifies the base physical address and size of the ITS
|
||||||
registers.
|
registers.
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
- socionext,synquacer-pre-its: (u32, u32) tuple describing the untranslated
|
||||||
|
address and size of the pre-ITS window.
|
||||||
|
|
||||||
The main GIC node must contain the appropriate #address-cells,
|
The main GIC node must contain the appropriate #address-cells,
|
||||||
#size-cells and ranges properties for the reg property of all ITS
|
#size-cells and ranges properties for the reg property of all ITS
|
||||||
nodes.
|
nodes.
|
||||||
|
@@ -2,7 +2,8 @@ Broadcom Generic Level 2 Interrupt Controller
|
|||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible: should be "brcm,l2-intc"
|
- compatible: should be "brcm,l2-intc" for latched interrupt controllers
|
||||||
|
should be "brcm,bcm7271-l2-intc" for level interrupt controllers
|
||||||
- reg: specifies the base physical address and size of the registers
|
- reg: specifies the base physical address and size of the registers
|
||||||
- interrupt-controller: identifies the node as an interrupt controller
|
- interrupt-controller: identifies the node as an interrupt controller
|
||||||
- #interrupt-cells: specifies the number of cells needed to encode an
|
- #interrupt-cells: specifies the number of cells needed to encode an
|
||||||
|
@@ -0,0 +1,22 @@
|
|||||||
|
Open Multi-Processor Interrupt Controller
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : This should be "openrisc,ompic"
|
||||||
|
- reg : Specifies base physical address and size of the register space. The
|
||||||
|
size is based on the number of cores the controller has been configured
|
||||||
|
to handle, this should be set to 8 bytes per cpu core.
|
||||||
|
- interrupt-controller : Identifies the node as an interrupt controller.
|
||||||
|
- #interrupt-cells : This should be set to 0 as this will not be an irq
|
||||||
|
parent.
|
||||||
|
- interrupts : Specifies the interrupt line to which the ompic is wired.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
ompic: interrupt-controller@98000000 {
|
||||||
|
compatible = "openrisc,ompic";
|
||||||
|
reg = <0x98000000 16>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <0>;
|
||||||
|
interrupts = <1>;
|
||||||
|
};
|
@@ -13,6 +13,9 @@ Required properties:
|
|||||||
- "renesas,irqc-r8a7793" (R-Car M2-N)
|
- "renesas,irqc-r8a7793" (R-Car M2-N)
|
||||||
- "renesas,irqc-r8a7794" (R-Car E2)
|
- "renesas,irqc-r8a7794" (R-Car E2)
|
||||||
- "renesas,intc-ex-r8a7795" (R-Car H3)
|
- "renesas,intc-ex-r8a7795" (R-Car H3)
|
||||||
|
- "renesas,intc-ex-r8a7796" (R-Car M3-W)
|
||||||
|
- "renesas,intc-ex-r8a77970" (R-Car V3M)
|
||||||
|
- "renesas,intc-ex-r8a77995" (R-Car D3)
|
||||||
- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
|
- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
|
||||||
interrupts.txt in this directory
|
interrupts.txt in this directory
|
||||||
- clocks: Must contain a reference to the functional clock.
|
- clocks: Must contain a reference to the functional clock.
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
Socionext SynQuacer External Interrupt Unit (EXIU)
|
||||||
|
|
||||||
|
The Socionext Synquacer SoC has an external interrupt unit (EXIU)
|
||||||
|
that forwards a block of 32 configurable input lines to 32 adjacent
|
||||||
|
level-high type GICv3 SPIs.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : Should be "socionext,synquacer-exiu".
|
||||||
|
- reg : Specifies base physical address and size of the
|
||||||
|
control registers.
|
||||||
|
- interrupt-controller : Identifies the node as an interrupt controller.
|
||||||
|
- #interrupt-cells : Specifies the number of cells needed to encode an
|
||||||
|
interrupt source. The value must be 3.
|
||||||
|
- interrupt-parent : phandle of the GIC these interrupts are routed to.
|
||||||
|
- socionext,spi-base : The SPI number of the first SPI of the 32 adjacent
|
||||||
|
ones the EXIU forwards its interrups to.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- Only SPIs can use the EXIU as an interrupt parent.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
exiu: interrupt-controller@510c0000 {
|
||||||
|
compatible = "socionext,synquacer-exiu";
|
||||||
|
reg = <0x0 0x510c0000 0x0 0x20>;
|
||||||
|
interrupt-controller;
|
||||||
|
interrupt-parent = <&gic>;
|
||||||
|
#interrupt-cells = <3>;
|
||||||
|
socionext,spi-base = <112>;
|
||||||
|
};
|
@@ -2,7 +2,9 @@ STM32 External Interrupt Controller
|
|||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible: Should be "st,stm32-exti"
|
- compatible: Should be:
|
||||||
|
"st,stm32-exti"
|
||||||
|
"st,stm32h7-exti"
|
||||||
- reg: Specifies base physical address and size of the registers
|
- reg: Specifies base physical address and size of the registers
|
||||||
- interrupt-controller: Indentifies the node as an interrupt controller
|
- interrupt-controller: Indentifies the node as an interrupt controller
|
||||||
- #interrupt-cells: Specifies the number of cells to encode an interrupt
|
- #interrupt-cells: Specifies the number of cells to encode an interrupt
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
* Amlogic Meson6, Meson8 and Meson8b SDIO/MMC controller
|
||||||
|
|
||||||
|
The highspeed MMC host controller on Amlogic SoCs provides an interface
|
||||||
|
for MMC, SD, SDIO and SDHC types of memory cards.
|
||||||
|
|
||||||
|
Supported maximum speeds are the ones of the eMMC standard 4.41 as well
|
||||||
|
as the speed of SD standard 2.0.
|
||||||
|
|
||||||
|
The hardware provides an internal "mux" which allows up to three slots
|
||||||
|
to be controlled. Only one slot can be accessed at a time.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : must be one of
|
||||||
|
- "amlogic,meson8-sdio"
|
||||||
|
- "amlogic,meson8b-sdio"
|
||||||
|
along with the generic "amlogic,meson-mx-sdio"
|
||||||
|
- reg : mmc controller base registers
|
||||||
|
- interrupts : mmc controller interrupt
|
||||||
|
- #address-cells : must be 1
|
||||||
|
- size-cells : must be 0
|
||||||
|
- clocks : phandle to clock providers
|
||||||
|
- clock-names : must contain "core" and "clkin"
|
||||||
|
|
||||||
|
Required child nodes:
|
||||||
|
A node for each slot provided by the MMC controller is required.
|
||||||
|
NOTE: due to a driver limitation currently only one slot (= child node)
|
||||||
|
is supported!
|
||||||
|
|
||||||
|
Required properties on each child node (= slot):
|
||||||
|
- compatible : must be "mmc-slot" (see mmc.txt within this directory)
|
||||||
|
- reg : the slot (or "port") ID
|
||||||
|
|
||||||
|
Optional properties on each child node (= slot):
|
||||||
|
- bus-width : must be 1 or 4 (8-bit bus is not supported)
|
||||||
|
- for cd and all other additional generic mmc parameters
|
||||||
|
please refer to mmc.txt within this directory
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
mmc@c1108c20 {
|
||||||
|
compatible = "amlogic,meson8-sdio", "amlogic,meson-mx-sdio";
|
||||||
|
reg = <0xc1108c20 0x20>;
|
||||||
|
interrupts = <0 28 1>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
clocks = <&clkc CLKID_SDIO>, <&clkc CLKID_CLK81>;
|
||||||
|
clock-names = "core", "clkin";
|
||||||
|
|
||||||
|
slot@1 {
|
||||||
|
compatible = "mmc-slot";
|
||||||
|
reg = <1>;
|
||||||
|
|
||||||
|
bus-width = <4>;
|
||||||
|
};
|
||||||
|
};
|
@@ -53,6 +53,9 @@ Optional properties:
|
|||||||
- no-sdio: controller is limited to send sdio cmd during initialization
|
- no-sdio: controller is limited to send sdio cmd during initialization
|
||||||
- no-sd: controller is limited to send sd cmd during initialization
|
- no-sd: controller is limited to send sd cmd during initialization
|
||||||
- no-mmc: controller is limited to send mmc cmd during initialization
|
- no-mmc: controller is limited to send mmc cmd during initialization
|
||||||
|
- fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type.
|
||||||
|
The value <n> is the driver type as specified in the eMMC specification
|
||||||
|
(table 206 in spec version 5.1).
|
||||||
|
|
||||||
*NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
|
*NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
|
||||||
polarity properties, we have to fix the meaning of the "normal" and "inverted"
|
polarity properties, we have to fix the meaning of the "normal" and "inverted"
|
||||||
|
@@ -7,10 +7,18 @@ This file documents differences between the core properties in mmc.txt
|
|||||||
and the properties used by the msdc driver.
|
and the properties used by the msdc driver.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
|
- compatible: value should be either of the following.
|
||||||
|
"mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
|
||||||
|
"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
|
||||||
|
"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
|
||||||
|
"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
|
||||||
|
- reg: physical base address of the controller and length
|
||||||
- interrupts: Should contain MSDC interrupt number
|
- interrupts: Should contain MSDC interrupt number
|
||||||
- clocks: MSDC source clock, HCLK
|
- clocks: Should contain phandle for the clock feeding the MMC controller
|
||||||
- clock-names: "source", "hclk"
|
- clock-names: Should contain the following:
|
||||||
|
"source" - source clock (required)
|
||||||
|
"hclk" - HCLK which used for host (required)
|
||||||
|
"source_cg" - independent source clock gate (required for MT2712)
|
||||||
- pinctrl-names: should be "default", "state_uhs"
|
- pinctrl-names: should be "default", "state_uhs"
|
||||||
- pinctrl-0: should contain default/high speed pin ctrl
|
- pinctrl-0: should contain default/high speed pin ctrl
|
||||||
- pinctrl-1: should contain uhs mode pin ctrl
|
- pinctrl-1: should contain uhs mode pin ctrl
|
||||||
@@ -30,6 +38,10 @@ Optional properties:
|
|||||||
- mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection
|
- mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection
|
||||||
If present,HS400 command responses are sampled on rising edges.
|
If present,HS400 command responses are sampled on rising edges.
|
||||||
If not present,HS400 command responses are sampled on falling edges.
|
If not present,HS400 command responses are sampled on falling edges.
|
||||||
|
- mediatek,latch-ck: Some SoCs do not support enhance_rx, need set correct latch-ck to avoid data crc
|
||||||
|
error caused by stop clock(fifo full)
|
||||||
|
Valid range = [0:0x7]. if not present, default value is 0.
|
||||||
|
applied to compatible "mediatek,mt2701-mmc".
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
mmc0: mmc@11230000 {
|
mmc0: mmc@11230000 {
|
||||||
|
@@ -15,6 +15,8 @@ Required properties:
|
|||||||
Optional properties:
|
Optional properties:
|
||||||
- vqmmc-supply: phandle to the regulator device tree node, mentioned
|
- vqmmc-supply: phandle to the regulator device tree node, mentioned
|
||||||
as the VCCQ/VDD_IO supply in the eMMC/SD specs.
|
as the VCCQ/VDD_IO supply in the eMMC/SD specs.
|
||||||
|
- fujitsu,cmd-dat-delay-select: boolean property indicating that this host
|
||||||
|
requires the CMD_DAT_DELAY control to be enabled.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@@ -18,6 +18,8 @@ Required properties:
|
|||||||
"core" - SDC MMC clock (MCLK) (required)
|
"core" - SDC MMC clock (MCLK) (required)
|
||||||
"bus" - SDCC bus voter clock (optional)
|
"bus" - SDCC bus voter clock (optional)
|
||||||
"xo" - TCXO clock (optional)
|
"xo" - TCXO clock (optional)
|
||||||
|
"cal" - reference clock for RCLK delay calibration (optional)
|
||||||
|
"sleep" - sleep clock for RCLK delay calibration (optional)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
16
Documentation/devicetree/bindings/mmc/sdhci-omap.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
* TI OMAP SDHCI Controller
|
||||||
|
|
||||||
|
Refer to mmc.txt for standard MMC bindings.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
|
||||||
|
- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
|
||||||
|
|
||||||
|
Example:
|
||||||
|
mmc1: mmc@4809c000 {
|
||||||
|
compatible = "ti,dra7-sdhci";
|
||||||
|
reg = <0x4809c000 0x400>;
|
||||||
|
ti,hwmods = "mmc1";
|
||||||
|
bus-width = <4>;
|
||||||
|
vmmc-supply = <&vmmc>; /* phandle to regulator node */
|
||||||
|
};
|
@@ -10,7 +10,7 @@ described in mmc.txt, can be used. Additionally the following tmio_mmc-specific
|
|||||||
optional bindings can be used.
|
optional bindings can be used.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: "renesas,sdhi-shmobile" - a generic sh-mobile SDHI unit
|
- compatible: should contain one or more of the following:
|
||||||
"renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC
|
"renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC
|
||||||
"renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC
|
"renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC
|
||||||
"renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC
|
"renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC
|
||||||
@@ -26,6 +26,16 @@ Required properties:
|
|||||||
"renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
|
"renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
|
||||||
"renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
|
"renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
|
||||||
"renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
|
"renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
|
||||||
|
"renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller
|
||||||
|
"renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller
|
||||||
|
"renesas,rcar-gen2-sdhi" - a generic R-Car Gen2 or RZ/G1
|
||||||
|
SDHI controller
|
||||||
|
"renesas,rcar-gen3-sdhi" - a generic R-Car Gen3 SDHI controller
|
||||||
|
|
||||||
|
|
||||||
|
When compatible with the generic version, nodes must list
|
||||||
|
the SoC-specific version corresponding to the platform
|
||||||
|
first followed by the generic version.
|
||||||
|
|
||||||
- clocks: Most controllers only have 1 clock source per channel. However, on
|
- clocks: Most controllers only have 1 clock source per channel. However, on
|
||||||
some variations of this controller, the internal card detection
|
some variations of this controller, the internal card detection
|
||||||
@@ -43,3 +53,61 @@ Optional properties:
|
|||||||
- pinctrl-names: should be "default", "state_uhs"
|
- pinctrl-names: should be "default", "state_uhs"
|
||||||
- pinctrl-0: should contain default/high speed pin ctrl
|
- pinctrl-0: should contain default/high speed pin ctrl
|
||||||
- pinctrl-1: should contain uhs mode pin ctrl
|
- pinctrl-1: should contain uhs mode pin ctrl
|
||||||
|
|
||||||
|
Example: R8A7790 (R-Car H2) SDHI controller nodes
|
||||||
|
|
||||||
|
sdhi0: sd@ee100000 {
|
||||||
|
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
|
||||||
|
reg = <0 0xee100000 0 0x328>;
|
||||||
|
interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&cpg CPG_MOD 314>;
|
||||||
|
dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
|
||||||
|
<&dmac1 0xcd>, <&dmac1 0xce>;
|
||||||
|
dma-names = "tx", "rx", "tx", "rx";
|
||||||
|
max-frequency = <195000000>;
|
||||||
|
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||||
|
resets = <&cpg 314>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
sdhi1: sd@ee120000 {
|
||||||
|
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
|
||||||
|
reg = <0 0xee120000 0 0x328>;
|
||||||
|
interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&cpg CPG_MOD 313>;
|
||||||
|
dmas = <&dmac0 0xc9>, <&dmac0 0xca>,
|
||||||
|
<&dmac1 0xc9>, <&dmac1 0xca>;
|
||||||
|
dma-names = "tx", "rx", "tx", "rx";
|
||||||
|
max-frequency = <195000000>;
|
||||||
|
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||||
|
resets = <&cpg 313>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
sdhi2: sd@ee140000 {
|
||||||
|
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
|
||||||
|
reg = <0 0xee140000 0 0x100>;
|
||||||
|
interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&cpg CPG_MOD 312>;
|
||||||
|
dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
|
||||||
|
<&dmac1 0xc1>, <&dmac1 0xc2>;
|
||||||
|
dma-names = "tx", "rx", "tx", "rx";
|
||||||
|
max-frequency = <97500000>;
|
||||||
|
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||||
|
resets = <&cpg 312>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
sdhi3: sd@ee160000 {
|
||||||
|
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
|
||||||
|
reg = <0 0xee160000 0 0x100>;
|
||||||
|
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&cpg CPG_MOD 311>;
|
||||||
|
dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
|
||||||
|
<&dmac1 0xd3>, <&dmac1 0xd4>;
|
||||||
|
dma-names = "tx", "rx", "tx", "rx";
|
||||||
|
max-frequency = <97500000>;
|
||||||
|
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||||
|
resets = <&cpg 311>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
OpenRISC Generic SoC
|
||||||
|
====================
|
||||||
|
|
||||||
|
Boards and FPGA SoC's which support the OpenRISC standard platform. The
|
||||||
|
platform essentially follows the conventions of the OpenRISC architecture
|
||||||
|
specification, however some aspects, such as the boot protocol have been defined
|
||||||
|
by the Linux port.
|
||||||
|
|
||||||
|
Required properties
|
||||||
|
-------------------
|
||||||
|
- compatible: Must include "opencores,or1ksim"
|
||||||
|
|
||||||
|
CPU nodes:
|
||||||
|
----------
|
||||||
|
A "cpus" node is required. Required properties:
|
||||||
|
- #address-cells: Must be 1.
|
||||||
|
- #size-cells: Must be 0.
|
||||||
|
A CPU sub-node is also required for at least CPU 0. Since the topology may
|
||||||
|
be probed via CPS, it is not necessary to specify secondary CPUs. Required
|
||||||
|
properties:
|
||||||
|
- compatible: Must be "opencores,or1200-rtlsvn481".
|
||||||
|
- reg: CPU number.
|
||||||
|
- clock-frequency: The CPU clock frequency in Hz.
|
||||||
|
Example:
|
||||||
|
cpus {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
cpu@0 {
|
||||||
|
compatible = "opencores,or1200-rtlsvn481";
|
||||||
|
reg = <0>;
|
||||||
|
clock-frequency = <20000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Boot protocol
|
||||||
|
-------------
|
||||||
|
The bootloader may pass the following arguments to the kernel:
|
||||||
|
- r3: address of a flattened device-tree blob or 0x0.
|
@@ -1,8 +1,9 @@
|
|||||||
* Dialog Semiconductor DA9211/DA9212/DA9213/DA9214/DA9215 Voltage Regulator
|
* Dialog Semiconductor DA9211/DA9212/DA9213/DA9223/DA9214/DA9224/DA9215/DA9225
|
||||||
|
Voltage Regulator
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: "dlg,da9211" or "dlg,da9212" or "dlg,da9213"
|
- compatible: "dlg,da9211" or "dlg,da9212" or "dlg,da9213" or "dlg,da9223"
|
||||||
or "dlg,da9214" or "dlg,da9215"
|
or "dlg,da9214" or "dlg,da9224" or "dlg,da9215" or "dlg,da9225"
|
||||||
- reg: I2C slave address, usually 0x68.
|
- reg: I2C slave address, usually 0x68.
|
||||||
- interrupts: the interrupt outputs of the controller
|
- interrupts: the interrupt outputs of the controller
|
||||||
- regulators: A node that houses a sub-node for each regulator within the
|
- regulators: A node that houses a sub-node for each regulator within the
|
||||||
@@ -16,7 +17,6 @@ Optional properties:
|
|||||||
- Any optional property defined in regulator.txt
|
- Any optional property defined in regulator.txt
|
||||||
|
|
||||||
Example 1) DA9211
|
Example 1) DA9211
|
||||||
|
|
||||||
pmic: da9211@68 {
|
pmic: da9211@68 {
|
||||||
compatible = "dlg,da9211";
|
compatible = "dlg,da9211";
|
||||||
reg = <0x68>;
|
reg = <0x68>;
|
||||||
@@ -35,7 +35,6 @@ Example 1) DA9211
|
|||||||
};
|
};
|
||||||
|
|
||||||
Example 2) DA9212
|
Example 2) DA9212
|
||||||
|
|
||||||
pmic: da9212@68 {
|
pmic: da9212@68 {
|
||||||
compatible = "dlg,da9212";
|
compatible = "dlg,da9212";
|
||||||
reg = <0x68>;
|
reg = <0x68>;
|
||||||
@@ -79,7 +78,25 @@ Example 3) DA9213
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Example 4) DA9214
|
Example 4) DA9223
|
||||||
|
pmic: da9223@68 {
|
||||||
|
compatible = "dlg,da9223";
|
||||||
|
reg = <0x68>;
|
||||||
|
interrupts = <3 27>;
|
||||||
|
|
||||||
|
regulators {
|
||||||
|
BUCKA {
|
||||||
|
regulator-name = "VBUCKA";
|
||||||
|
regulator-min-microvolt = < 300000>;
|
||||||
|
regulator-max-microvolt = <1570000>;
|
||||||
|
regulator-min-microamp = <3000000>;
|
||||||
|
regulator-max-microamp = <6000000>;
|
||||||
|
enable-gpios = <&gpio 27 0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Example 5) DA9214
|
||||||
pmic: da9214@68 {
|
pmic: da9214@68 {
|
||||||
compatible = "dlg,da9214";
|
compatible = "dlg,da9214";
|
||||||
reg = <0x68>;
|
reg = <0x68>;
|
||||||
@@ -105,7 +122,33 @@ Example 4) DA9214
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Example 5) DA9215
|
Example 6) DA9224
|
||||||
|
pmic: da9224@68 {
|
||||||
|
compatible = "dlg,da9224";
|
||||||
|
reg = <0x68>;
|
||||||
|
interrupts = <3 27>;
|
||||||
|
|
||||||
|
regulators {
|
||||||
|
BUCKA {
|
||||||
|
regulator-name = "VBUCKA";
|
||||||
|
regulator-min-microvolt = < 300000>;
|
||||||
|
regulator-max-microvolt = <1570000>;
|
||||||
|
regulator-min-microamp = <3000000>;
|
||||||
|
regulator-max-microamp = <6000000>;
|
||||||
|
enable-gpios = <&gpio 27 0>;
|
||||||
|
};
|
||||||
|
BUCKB {
|
||||||
|
regulator-name = "VBUCKB";
|
||||||
|
regulator-min-microvolt = < 300000>;
|
||||||
|
regulator-max-microvolt = <1570000>;
|
||||||
|
regulator-min-microamp = <3000000>;
|
||||||
|
regulator-max-microamp = <6000000>;
|
||||||
|
enable-gpios = <&gpio 17 0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Example 7) DA9215
|
||||||
pmic: da9215@68 {
|
pmic: da9215@68 {
|
||||||
compatible = "dlg,da9215";
|
compatible = "dlg,da9215";
|
||||||
reg = <0x68>;
|
reg = <0x68>;
|
||||||
@@ -131,3 +174,28 @@ Example 5) DA9215
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Example 8) DA9225
|
||||||
|
pmic: da9225@68 {
|
||||||
|
compatible = "dlg,da9225";
|
||||||
|
reg = <0x68>;
|
||||||
|
interrupts = <3 27>;
|
||||||
|
|
||||||
|
regulators {
|
||||||
|
BUCKA {
|
||||||
|
regulator-name = "VBUCKA";
|
||||||
|
regulator-min-microvolt = < 300000>;
|
||||||
|
regulator-max-microvolt = <1570000>;
|
||||||
|
regulator-min-microamp = <4000000>;
|
||||||
|
regulator-max-microamp = <7000000>;
|
||||||
|
enable-gpios = <&gpio 27 0>;
|
||||||
|
};
|
||||||
|
BUCKB {
|
||||||
|
regulator-name = "VBUCKB";
|
||||||
|
regulator-min-microvolt = < 300000>;
|
||||||
|
regulator-max-microvolt = <1570000>;
|
||||||
|
regulator-min-microamp = <4000000>;
|
||||||
|
regulator-max-microamp = <7000000>;
|
||||||
|
enable-gpios = <&gpio 17 0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@@ -21,7 +21,7 @@ Each regulator is defined using the standard binding for regulators.
|
|||||||
|
|
||||||
Example 1: PFUZE100
|
Example 1: PFUZE100
|
||||||
|
|
||||||
pmic: pfuze100@08 {
|
pmic: pfuze100@8 {
|
||||||
compatible = "fsl,pfuze100";
|
compatible = "fsl,pfuze100";
|
||||||
reg = <0x08>;
|
reg = <0x08>;
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ Example 1: PFUZE100
|
|||||||
|
|
||||||
Example 2: PFUZE200
|
Example 2: PFUZE200
|
||||||
|
|
||||||
pmic: pfuze200@08 {
|
pmic: pfuze200@8 {
|
||||||
compatible = "fsl,pfuze200";
|
compatible = "fsl,pfuze200";
|
||||||
reg = <0x08>;
|
reg = <0x08>;
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ Example 2: PFUZE200
|
|||||||
|
|
||||||
Example 3: PFUZE3000
|
Example 3: PFUZE3000
|
||||||
|
|
||||||
pmic: pfuze3000@08 {
|
pmic: pfuze3000@8 {
|
||||||
compatible = "fsl,pfuze3000";
|
compatible = "fsl,pfuze3000";
|
||||||
reg = <0x08>;
|
reg = <0x08>;
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ Qualcomm SPMI Regulators
|
|||||||
"qcom,pm8916-regulators"
|
"qcom,pm8916-regulators"
|
||||||
"qcom,pm8941-regulators"
|
"qcom,pm8941-regulators"
|
||||||
"qcom,pm8994-regulators"
|
"qcom,pm8994-regulators"
|
||||||
|
"qcom,pmi8994-regulators"
|
||||||
|
|
||||||
- interrupts:
|
- interrupts:
|
||||||
Usage: optional
|
Usage: optional
|
||||||
@@ -100,6 +101,15 @@ Qualcomm SPMI Regulators
|
|||||||
Definition: Reference to regulator supplying the input pin, as
|
Definition: Reference to regulator supplying the input pin, as
|
||||||
described in the data sheet.
|
described in the data sheet.
|
||||||
|
|
||||||
|
- vdd_s1-supply:
|
||||||
|
- vdd_s2-supply:
|
||||||
|
- vdd_s3-supply:
|
||||||
|
- vdd_l1-supply:
|
||||||
|
Usage: optional (pmi8994 only)
|
||||||
|
Value type: <phandle>
|
||||||
|
Definition: Reference to regulator supplying the input pin, as
|
||||||
|
described in the data sheet.
|
||||||
|
|
||||||
|
|
||||||
The regulator node houses sub-nodes for each regulator within the device. Each
|
The regulator node houses sub-nodes for each regulator within the device. Each
|
||||||
sub-node is identified using the node's name, with valid values listed for each
|
sub-node is identified using the node's name, with valid values listed for each
|
||||||
@@ -122,6 +132,9 @@ pm8994:
|
|||||||
l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20,
|
l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20,
|
||||||
l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2
|
l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2
|
||||||
|
|
||||||
|
pmi8994:
|
||||||
|
s1, s2, s3, l1
|
||||||
|
|
||||||
The content of each sub-node is defined by the standard binding for regulators -
|
The content of each sub-node is defined by the standard binding for regulators -
|
||||||
see regulator.txt - with additional custom properties described below:
|
see regulator.txt - with additional custom properties described below:
|
||||||
|
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
Renesas MSIOF spi controller
|
Renesas MSIOF spi controller
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : "renesas,msiof-r8a7790" (R-Car H2)
|
- compatible : "renesas,msiof-r8a7743" (RZ/G1M)
|
||||||
|
"renesas,msiof-r8a7745" (RZ/G1E)
|
||||||
|
"renesas,msiof-r8a7790" (R-Car H2)
|
||||||
"renesas,msiof-r8a7791" (R-Car M2-W)
|
"renesas,msiof-r8a7791" (R-Car M2-W)
|
||||||
"renesas,msiof-r8a7792" (R-Car V2H)
|
"renesas,msiof-r8a7792" (R-Car V2H)
|
||||||
"renesas,msiof-r8a7793" (R-Car M2-N)
|
"renesas,msiof-r8a7793" (R-Car M2-N)
|
||||||
@@ -10,7 +12,7 @@ Required properties:
|
|||||||
"renesas,msiof-r8a7796" (R-Car M3-W)
|
"renesas,msiof-r8a7796" (R-Car M3-W)
|
||||||
"renesas,msiof-sh73a0" (SH-Mobile AG5)
|
"renesas,msiof-sh73a0" (SH-Mobile AG5)
|
||||||
"renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
|
"renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device)
|
||||||
"renesas,rcar-gen2-msiof" (generic R-Car Gen2 compatible device)
|
"renesas,rcar-gen2-msiof" (generic R-Car Gen2 and RZ/G1 compatible device)
|
||||||
"renesas,rcar-gen3-msiof" (generic R-Car Gen3 compatible device)
|
"renesas,rcar-gen3-msiof" (generic R-Car Gen3 compatible device)
|
||||||
"renesas,sh-msiof" (deprecated)
|
"renesas,sh-msiof" (deprecated)
|
||||||
|
|
||||||
|
@@ -24,6 +24,16 @@ Required properties:
|
|||||||
based on a specific SoC configuration.
|
based on a specific SoC configuration.
|
||||||
- interrupts: interrupt number mapped to CPU.
|
- interrupts: interrupt number mapped to CPU.
|
||||||
- clocks: spi clk phandle
|
- clocks: spi clk phandle
|
||||||
|
For 66AK2G this property should be set per binding,
|
||||||
|
Documentation/devicetree/bindings/clock/ti,sci-clk.txt
|
||||||
|
|
||||||
|
SoC-specific Required Properties:
|
||||||
|
|
||||||
|
The following are mandatory properties for Keystone 2 66AK2G SoCs only:
|
||||||
|
|
||||||
|
- power-domains: Should contain a phandle to a PM domain provider node
|
||||||
|
and an args specifier containing the SPI device id
|
||||||
|
value. This property is as per the binding,
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
- cs-gpios: gpio chip selects
|
- cs-gpios: gpio chip selects
|
||||||
|
@@ -5,11 +5,14 @@ Required properties:
|
|||||||
"renesas,rspi-<soctype>", "renesas,rspi" as fallback.
|
"renesas,rspi-<soctype>", "renesas,rspi" as fallback.
|
||||||
For Renesas Serial Peripheral Interface on RZ/A1H:
|
For Renesas Serial Peripheral Interface on RZ/A1H:
|
||||||
"renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
|
"renesas,rspi-<soctype>", "renesas,rspi-rz" as fallback.
|
||||||
For Quad Serial Peripheral Interface on R-Car Gen2:
|
For Quad Serial Peripheral Interface on R-Car Gen2 and
|
||||||
|
RZ/G1 devices:
|
||||||
"renesas,qspi-<soctype>", "renesas,qspi" as fallback.
|
"renesas,qspi-<soctype>", "renesas,qspi" as fallback.
|
||||||
Examples with soctypes are:
|
Examples with soctypes are:
|
||||||
- "renesas,rspi-sh7757" (SH)
|
- "renesas,rspi-sh7757" (SH)
|
||||||
- "renesas,rspi-r7s72100" (RZ/A1H)
|
- "renesas,rspi-r7s72100" (RZ/A1H)
|
||||||
|
- "renesas,qspi-r8a7743" (RZ/G1M)
|
||||||
|
- "renesas,qspi-r8a7745" (RZ/G1E)
|
||||||
- "renesas,qspi-r8a7790" (R-Car H2)
|
- "renesas,qspi-r8a7790" (R-Car H2)
|
||||||
- "renesas,qspi-r8a7791" (R-Car M2-W)
|
- "renesas,qspi-r8a7791" (R-Car M2-W)
|
||||||
- "renesas,qspi-r8a7792" (R-Car V2H)
|
- "renesas,qspi-r8a7792" (R-Car V2H)
|
||||||
|
58
Documentation/devicetree/bindings/spi/spi-sprd-adi.txt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
Spreadtrum ADI controller
|
||||||
|
|
||||||
|
ADI is the abbreviation of Anolog-Digital interface, which is used to access
|
||||||
|
analog chip (such as PMIC) from digital chip. ADI controller follows the SPI
|
||||||
|
framework for its hardware implementation is alike to SPI bus and its timing
|
||||||
|
is compatile to SPI timing.
|
||||||
|
|
||||||
|
ADI controller has 50 channels including 2 software read/write channels and
|
||||||
|
48 hardware channels to access analog chip. For 2 software read/write channels,
|
||||||
|
users should set ADI registers to access analog chip. For hardware channels,
|
||||||
|
we can configure them to allow other hardware components to use it independently,
|
||||||
|
which means we can just link one analog chip address to one hardware channel,
|
||||||
|
then users can access the mapped analog chip address by this hardware channel
|
||||||
|
triggered by hardware components instead of ADI software channels.
|
||||||
|
|
||||||
|
Thus we introduce one property named "sprd,hw-channels" to configure hardware
|
||||||
|
channels, the first value specifies the hardware channel id which is used to
|
||||||
|
transfer data triggered by hardware automatically, and the second value specifies
|
||||||
|
the analog chip address where user want to access by hardware components.
|
||||||
|
|
||||||
|
Since we have multi-subsystems will use unique ADI to access analog chip, when
|
||||||
|
one system is reading/writing data by ADI software channels, that should be under
|
||||||
|
one hardware spinlock protection to prevent other systems from reading/writing
|
||||||
|
data by ADI software channels at the same time, or two parallel routine of setting
|
||||||
|
ADI registers will make ADI controller registers chaos to lead incorrect results.
|
||||||
|
Then we need one hardware spinlock to synchronize between the multiple subsystems.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Should be "sprd,sc9860-adi".
|
||||||
|
- reg: Offset and length of ADI-SPI controller register space.
|
||||||
|
- hwlocks: Reference to a phandle of a hwlock provider node.
|
||||||
|
- hwlock-names: Reference to hwlock name strings defined in the same order
|
||||||
|
as the hwlocks, should be "adi".
|
||||||
|
- #address-cells: Number of cells required to define a chip select address
|
||||||
|
on the ADI-SPI bus. Should be set to 1.
|
||||||
|
- #size-cells: Size of cells required to define a chip select address size
|
||||||
|
on the ADI-SPI bus. Should be set to 0.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- sprd,hw-channels: This is an array of channel values up to 49 channels.
|
||||||
|
The first value specifies the hardware channel id which is used to
|
||||||
|
transfer data triggered by hardware automatically, and the second
|
||||||
|
value specifies the analog chip address where user want to access
|
||||||
|
by hardware components.
|
||||||
|
|
||||||
|
SPI slave nodes must be children of the SPI controller node and can contain
|
||||||
|
properties described in Documentation/devicetree/bindings/spi/spi-bus.txt.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
adi_bus: spi@40030000 {
|
||||||
|
compatible = "sprd,sc9860-adi";
|
||||||
|
reg = <0 0x40030000 0 0x10000>;
|
||||||
|
hwlocks = <&hwlock1 0>;
|
||||||
|
hwlock-names = "adi";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
sprd,hw-channels = <30 0x8c20>;
|
||||||
|
};
|
@@ -20,16 +20,16 @@ Required Properties:
|
|||||||
(CMT1 on sh73a0 and r8a7740)
|
(CMT1 on sh73a0 and r8a7740)
|
||||||
This is a fallback for the above renesas,cmt-48-* entries.
|
This is a fallback for the above renesas,cmt-48-* entries.
|
||||||
|
|
||||||
- "renesas,cmt0-r8a73a4" for the 32-bit CMT0 device included in r8a73a4.
|
- "renesas,r8a73a4-cmt0" for the 32-bit CMT0 device included in r8a73a4.
|
||||||
- "renesas,cmt1-r8a73a4" for the 48-bit CMT1 device included in r8a73a4.
|
- "renesas,r8a73a4-cmt1" for the 48-bit CMT1 device included in r8a73a4.
|
||||||
- "renesas,cmt0-r8a7790" for the 32-bit CMT0 device included in r8a7790.
|
- "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
|
||||||
- "renesas,cmt1-r8a7790" for the 48-bit CMT1 device included in r8a7790.
|
- "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790.
|
||||||
- "renesas,cmt0-r8a7791" for the 32-bit CMT0 device included in r8a7791.
|
- "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791.
|
||||||
- "renesas,cmt1-r8a7791" for the 48-bit CMT1 device included in r8a7791.
|
- "renesas,r8a7791-cmt1" for the 48-bit CMT1 device included in r8a7791.
|
||||||
- "renesas,cmt0-r8a7793" for the 32-bit CMT0 device included in r8a7793.
|
- "renesas,r8a7793-cmt0" for the 32-bit CMT0 device included in r8a7793.
|
||||||
- "renesas,cmt1-r8a7793" for the 48-bit CMT1 device included in r8a7793.
|
- "renesas,r8a7793-cmt1" for the 48-bit CMT1 device included in r8a7793.
|
||||||
- "renesas,cmt0-r8a7794" for the 32-bit CMT0 device included in r8a7794.
|
- "renesas,r8a7794-cmt0" for the 32-bit CMT0 device included in r8a7794.
|
||||||
- "renesas,cmt1-r8a7794" for the 48-bit CMT1 device included in r8a7794.
|
- "renesas,r8a7794-cmt1" for the 48-bit CMT1 device included in r8a7794.
|
||||||
|
|
||||||
- "renesas,rcar-gen2-cmt0" for 32-bit CMT0 devices included in R-Car Gen2.
|
- "renesas,rcar-gen2-cmt0" for 32-bit CMT0 devices included in R-Car Gen2.
|
||||||
- "renesas,rcar-gen2-cmt1" for 48-bit CMT1 devices included in R-Car Gen2.
|
- "renesas,rcar-gen2-cmt1" for 48-bit CMT1 devices included in R-Car Gen2.
|
||||||
@@ -46,7 +46,7 @@ Required Properties:
|
|||||||
Example: R8A7790 (R-Car H2) CMT0 and CMT1 nodes
|
Example: R8A7790 (R-Car H2) CMT0 and CMT1 nodes
|
||||||
|
|
||||||
cmt0: timer@ffca0000 {
|
cmt0: timer@ffca0000 {
|
||||||
compatible = "renesas,cmt0-r8a7790", "renesas,rcar-gen2-cmt0";
|
compatible = "renesas,r8a7790-cmt0", "renesas,rcar-gen2-cmt0";
|
||||||
reg = <0 0xffca0000 0 0x1004>;
|
reg = <0 0xffca0000 0 0x1004>;
|
||||||
interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<0 142 IRQ_TYPE_LEVEL_HIGH>;
|
<0 142 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
@@ -55,7 +55,7 @@ Example: R8A7790 (R-Car H2) CMT0 and CMT1 nodes
|
|||||||
};
|
};
|
||||||
|
|
||||||
cmt1: timer@e6130000 {
|
cmt1: timer@e6130000 {
|
||||||
compatible = "renesas,cmt1-r8a7790", "renesas,rcar-gen2-cmt1";
|
compatible = "renesas,r8a7790-cmt1", "renesas,rcar-gen2-cmt1";
|
||||||
reg = <0 0xe6130000 0 0x1004>;
|
reg = <0 0xe6130000 0 0x1004>;
|
||||||
interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<0 121 IRQ_TYPE_LEVEL_HIGH>,
|
<0 121 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
@@ -71,6 +71,7 @@ isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
|
|||||||
isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor
|
isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor
|
||||||
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
|
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
|
||||||
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
|
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
|
||||||
|
maxim,max6621 PECI-to-I2C translator for PECI-to-SMBus/I2C protocol conversion
|
||||||
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
|
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
|
||||||
mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
||||||
mcube,mc3230 mCube 3-axis 8-bit digital accelerometer
|
mcube,mc3230 mCube 3-axis 8-bit digital accelerometer
|
||||||
|
@@ -246,6 +246,7 @@ onion Onion Corporation
|
|||||||
onnn ON Semiconductor Corp.
|
onnn ON Semiconductor Corp.
|
||||||
ontat On Tat Industrial Company
|
ontat On Tat Industrial Company
|
||||||
opencores OpenCores.org
|
opencores OpenCores.org
|
||||||
|
openrisc OpenRISC.io
|
||||||
option Option NV
|
option Option NV
|
||||||
ORCL Oracle Corporation
|
ORCL Oracle Corporation
|
||||||
ortustech Ortus Technology Co., Ltd.
|
ortustech Ortus Technology Co., Ltd.
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
00-INDEX
|
|
||||||
- this file.
|
|
||||||
client.txt
|
|
||||||
-the DMA Engine API Guide.
|
|
||||||
dmatest.txt
|
|
||||||
- how to compile, configure and use the dmatest system.
|
|
||||||
provider.txt
|
|
||||||
- the DMA controller API.
|
|
@@ -1,222 +0,0 @@
|
|||||||
DMA Engine API Guide
|
|
||||||
====================
|
|
||||||
|
|
||||||
Vinod Koul <vinod dot koul at intel.com>
|
|
||||||
|
|
||||||
NOTE: For DMA Engine usage in async_tx please see:
|
|
||||||
Documentation/crypto/async-tx-api.txt
|
|
||||||
|
|
||||||
|
|
||||||
Below is a guide to device driver writers on how to use the Slave-DMA API of the
|
|
||||||
DMA Engine. This is applicable only for slave DMA usage only.
|
|
||||||
|
|
||||||
The slave DMA usage consists of following steps:
|
|
||||||
1. Allocate a DMA slave channel
|
|
||||||
2. Set slave and controller specific parameters
|
|
||||||
3. Get a descriptor for transaction
|
|
||||||
4. Submit the transaction
|
|
||||||
5. Issue pending requests and wait for callback notification
|
|
||||||
|
|
||||||
1. Allocate a DMA slave channel
|
|
||||||
|
|
||||||
Channel allocation is slightly different in the slave DMA context,
|
|
||||||
client drivers typically need a channel from a particular DMA
|
|
||||||
controller only and even in some cases a specific channel is desired.
|
|
||||||
To request a channel dma_request_chan() API is used.
|
|
||||||
|
|
||||||
Interface:
|
|
||||||
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
|
|
||||||
|
|
||||||
Which will find and return the 'name' DMA channel associated with the 'dev'
|
|
||||||
device. The association is done via DT, ACPI or board file based
|
|
||||||
dma_slave_map matching table.
|
|
||||||
|
|
||||||
A channel allocated via this interface is exclusive to the caller,
|
|
||||||
until dma_release_channel() is called.
|
|
||||||
|
|
||||||
2. Set slave and controller specific parameters
|
|
||||||
|
|
||||||
Next step is always to pass some specific information to the DMA
|
|
||||||
driver. Most of the generic information which a slave DMA can use
|
|
||||||
is in struct dma_slave_config. This allows the clients to specify
|
|
||||||
DMA direction, DMA addresses, bus widths, DMA burst lengths etc
|
|
||||||
for the peripheral.
|
|
||||||
|
|
||||||
If some DMA controllers have more parameters to be sent then they
|
|
||||||
should try to embed struct dma_slave_config in their controller
|
|
||||||
specific structure. That gives flexibility to client to pass more
|
|
||||||
parameters, if required.
|
|
||||||
|
|
||||||
Interface:
|
|
||||||
int dmaengine_slave_config(struct dma_chan *chan,
|
|
||||||
struct dma_slave_config *config)
|
|
||||||
|
|
||||||
Please see the dma_slave_config structure definition in dmaengine.h
|
|
||||||
for a detailed explanation of the struct members. Please note
|
|
||||||
that the 'direction' member will be going away as it duplicates the
|
|
||||||
direction given in the prepare call.
|
|
||||||
|
|
||||||
3. Get a descriptor for transaction
|
|
||||||
|
|
||||||
For slave usage the various modes of slave transfers supported by the
|
|
||||||
DMA-engine are:
|
|
||||||
|
|
||||||
slave_sg - DMA a list of scatter gather buffers from/to a peripheral
|
|
||||||
dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the
|
|
||||||
operation is explicitly stopped.
|
|
||||||
interleaved_dma - This is common to Slave as well as M2M clients. For slave
|
|
||||||
address of devices' fifo could be already known to the driver.
|
|
||||||
Various types of operations could be expressed by setting
|
|
||||||
appropriate values to the 'dma_interleaved_template' members.
|
|
||||||
|
|
||||||
A non-NULL return of this transfer API represents a "descriptor" for
|
|
||||||
the given transaction.
|
|
||||||
|
|
||||||
Interface:
|
|
||||||
struct dma_async_tx_descriptor *dmaengine_prep_slave_sg(
|
|
||||||
struct dma_chan *chan, struct scatterlist *sgl,
|
|
||||||
unsigned int sg_len, enum dma_data_direction direction,
|
|
||||||
unsigned long flags);
|
|
||||||
|
|
||||||
struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
|
|
||||||
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
|
|
||||||
size_t period_len, enum dma_data_direction direction);
|
|
||||||
|
|
||||||
struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
|
|
||||||
struct dma_chan *chan, struct dma_interleaved_template *xt,
|
|
||||||
unsigned long flags);
|
|
||||||
|
|
||||||
The peripheral driver is expected to have mapped the scatterlist for
|
|
||||||
the DMA operation prior to calling dmaengine_prep_slave_sg(), and must
|
|
||||||
keep the scatterlist mapped until the DMA operation has completed.
|
|
||||||
The scatterlist must be mapped using the DMA struct device.
|
|
||||||
If a mapping needs to be synchronized later, dma_sync_*_for_*() must be
|
|
||||||
called using the DMA struct device, too.
|
|
||||||
So, normal setup should look like this:
|
|
||||||
|
|
||||||
nr_sg = dma_map_sg(chan->device->dev, sgl, sg_len);
|
|
||||||
if (nr_sg == 0)
|
|
||||||
/* error */
|
|
||||||
|
|
||||||
desc = dmaengine_prep_slave_sg(chan, sgl, nr_sg, direction, flags);
|
|
||||||
|
|
||||||
Once a descriptor has been obtained, the callback information can be
|
|
||||||
added and the descriptor must then be submitted. Some DMA engine
|
|
||||||
drivers may hold a spinlock between a successful preparation and
|
|
||||||
submission so it is important that these two operations are closely
|
|
||||||
paired.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
Although the async_tx API specifies that completion callback
|
|
||||||
routines cannot submit any new operations, this is not the
|
|
||||||
case for slave/cyclic DMA.
|
|
||||||
|
|
||||||
For slave DMA, the subsequent transaction may not be available
|
|
||||||
for submission prior to callback function being invoked, so
|
|
||||||
slave DMA callbacks are permitted to prepare and submit a new
|
|
||||||
transaction.
|
|
||||||
|
|
||||||
For cyclic DMA, a callback function may wish to terminate the
|
|
||||||
DMA via dmaengine_terminate_async().
|
|
||||||
|
|
||||||
Therefore, it is important that DMA engine drivers drop any
|
|
||||||
locks before calling the callback function which may cause a
|
|
||||||
deadlock.
|
|
||||||
|
|
||||||
Note that callbacks will always be invoked from the DMA
|
|
||||||
engines tasklet, never from interrupt context.
|
|
||||||
|
|
||||||
4. Submit the transaction
|
|
||||||
|
|
||||||
Once the descriptor has been prepared and the callback information
|
|
||||||
added, it must be placed on the DMA engine drivers pending queue.
|
|
||||||
|
|
||||||
Interface:
|
|
||||||
dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
|
|
||||||
|
|
||||||
This returns a cookie can be used to check the progress of DMA engine
|
|
||||||
activity via other DMA engine calls not covered in this document.
|
|
||||||
|
|
||||||
dmaengine_submit() will not start the DMA operation, it merely adds
|
|
||||||
it to the pending queue. For this, see step 5, dma_async_issue_pending.
|
|
||||||
|
|
||||||
5. Issue pending DMA requests and wait for callback notification
|
|
||||||
|
|
||||||
The transactions in the pending queue can be activated by calling the
|
|
||||||
issue_pending API. If channel is idle then the first transaction in
|
|
||||||
queue is started and subsequent ones queued up.
|
|
||||||
|
|
||||||
On completion of each DMA operation, the next in queue is started and
|
|
||||||
a tasklet triggered. The tasklet will then call the client driver
|
|
||||||
completion callback routine for notification, if set.
|
|
||||||
|
|
||||||
Interface:
|
|
||||||
void dma_async_issue_pending(struct dma_chan *chan);
|
|
||||||
|
|
||||||
Further APIs:
|
|
||||||
|
|
||||||
1. int dmaengine_terminate_sync(struct dma_chan *chan)
|
|
||||||
int dmaengine_terminate_async(struct dma_chan *chan)
|
|
||||||
int dmaengine_terminate_all(struct dma_chan *chan) /* DEPRECATED */
|
|
||||||
|
|
||||||
This causes all activity for the DMA channel to be stopped, and may
|
|
||||||
discard data in the DMA FIFO which hasn't been fully transferred.
|
|
||||||
No callback functions will be called for any incomplete transfers.
|
|
||||||
|
|
||||||
Two variants of this function are available.
|
|
||||||
|
|
||||||
dmaengine_terminate_async() might not wait until the DMA has been fully
|
|
||||||
stopped or until any running complete callbacks have finished. But it is
|
|
||||||
possible to call dmaengine_terminate_async() from atomic context or from
|
|
||||||
within a complete callback. dmaengine_synchronize() must be called before it
|
|
||||||
is safe to free the memory accessed by the DMA transfer or free resources
|
|
||||||
accessed from within the complete callback.
|
|
||||||
|
|
||||||
dmaengine_terminate_sync() will wait for the transfer and any running
|
|
||||||
complete callbacks to finish before it returns. But the function must not be
|
|
||||||
called from atomic context or from within a complete callback.
|
|
||||||
|
|
||||||
dmaengine_terminate_all() is deprecated and should not be used in new code.
|
|
||||||
|
|
||||||
2. int dmaengine_pause(struct dma_chan *chan)
|
|
||||||
|
|
||||||
This pauses activity on the DMA channel without data loss.
|
|
||||||
|
|
||||||
3. int dmaengine_resume(struct dma_chan *chan)
|
|
||||||
|
|
||||||
Resume a previously paused DMA channel. It is invalid to resume a
|
|
||||||
channel which is not currently paused.
|
|
||||||
|
|
||||||
4. enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
|
|
||||||
dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
|
|
||||||
|
|
||||||
This can be used to check the status of the channel. Please see
|
|
||||||
the documentation in include/linux/dmaengine.h for a more complete
|
|
||||||
description of this API.
|
|
||||||
|
|
||||||
This can be used in conjunction with dma_async_is_complete() and
|
|
||||||
the cookie returned from dmaengine_submit() to check for
|
|
||||||
completion of a specific DMA transaction.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
Not all DMA engine drivers can return reliable information for
|
|
||||||
a running DMA channel. It is recommended that DMA engine users
|
|
||||||
pause or stop (via dmaengine_terminate_all()) the channel before
|
|
||||||
using this API.
|
|
||||||
|
|
||||||
5. void dmaengine_synchronize(struct dma_chan *chan)
|
|
||||||
|
|
||||||
Synchronize the termination of the DMA channel to the current context.
|
|
||||||
|
|
||||||
This function should be used after dmaengine_terminate_async() to synchronize
|
|
||||||
the termination of the DMA channel to the current context. The function will
|
|
||||||
wait for the transfer and any running complete callbacks to finish before it
|
|
||||||
returns.
|
|
||||||
|
|
||||||
If dmaengine_terminate_async() is used to stop the DMA channel this function
|
|
||||||
must be called before it is safe to free memory accessed by previously
|
|
||||||
submitted descriptors or to free any resources accessed within the complete
|
|
||||||
callback of previously submitted descriptors.
|
|
||||||
|
|
||||||
The behavior of this function is undefined if dma_async_issue_pending() has
|
|
||||||
been called between dmaengine_terminate_async() and this function.
|
|
@@ -1,424 +0,0 @@
|
|||||||
DMAengine controller documentation
|
|
||||||
==================================
|
|
||||||
|
|
||||||
Hardware Introduction
|
|
||||||
+++++++++++++++++++++
|
|
||||||
|
|
||||||
Most of the Slave DMA controllers have the same general principles of
|
|
||||||
operations.
|
|
||||||
|
|
||||||
They have a given number of channels to use for the DMA transfers, and
|
|
||||||
a given number of requests lines.
|
|
||||||
|
|
||||||
Requests and channels are pretty much orthogonal. Channels can be used
|
|
||||||
to serve several to any requests. To simplify, channels are the
|
|
||||||
entities that will be doing the copy, and requests what endpoints are
|
|
||||||
involved.
|
|
||||||
|
|
||||||
The request lines actually correspond to physical lines going from the
|
|
||||||
DMA-eligible devices to the controller itself. Whenever the device
|
|
||||||
will want to start a transfer, it will assert a DMA request (DRQ) by
|
|
||||||
asserting that request line.
|
|
||||||
|
|
||||||
A very simple DMA controller would only take into account a single
|
|
||||||
parameter: the transfer size. At each clock cycle, it would transfer a
|
|
||||||
byte of data from one buffer to another, until the transfer size has
|
|
||||||
been reached.
|
|
||||||
|
|
||||||
That wouldn't work well in the real world, since slave devices might
|
|
||||||
require a specific number of bits to be transferred in a single
|
|
||||||
cycle. For example, we may want to transfer as much data as the
|
|
||||||
physical bus allows to maximize performances when doing a simple
|
|
||||||
memory copy operation, but our audio device could have a narrower FIFO
|
|
||||||
that requires data to be written exactly 16 or 24 bits at a time. This
|
|
||||||
is why most if not all of the DMA controllers can adjust this, using a
|
|
||||||
parameter called the transfer width.
|
|
||||||
|
|
||||||
Moreover, some DMA controllers, whenever the RAM is used as a source
|
|
||||||
or destination, can group the reads or writes in memory into a buffer,
|
|
||||||
so instead of having a lot of small memory accesses, which is not
|
|
||||||
really efficient, you'll get several bigger transfers. This is done
|
|
||||||
using a parameter called the burst size, that defines how many single
|
|
||||||
reads/writes it's allowed to do without the controller splitting the
|
|
||||||
transfer into smaller sub-transfers.
|
|
||||||
|
|
||||||
Our theoretical DMA controller would then only be able to do transfers
|
|
||||||
that involve a single contiguous block of data. However, some of the
|
|
||||||
transfers we usually have are not, and want to copy data from
|
|
||||||
non-contiguous buffers to a contiguous buffer, which is called
|
|
||||||
scatter-gather.
|
|
||||||
|
|
||||||
DMAEngine, at least for mem2dev transfers, require support for
|
|
||||||
scatter-gather. So we're left with two cases here: either we have a
|
|
||||||
quite simple DMA controller that doesn't support it, and we'll have to
|
|
||||||
implement it in software, or we have a more advanced DMA controller,
|
|
||||||
that implements in hardware scatter-gather.
|
|
||||||
|
|
||||||
The latter are usually programmed using a collection of chunks to
|
|
||||||
transfer, and whenever the transfer is started, the controller will go
|
|
||||||
over that collection, doing whatever we programmed there.
|
|
||||||
|
|
||||||
This collection is usually either a table or a linked list. You will
|
|
||||||
then push either the address of the table and its number of elements,
|
|
||||||
or the first item of the list to one channel of the DMA controller,
|
|
||||||
and whenever a DRQ will be asserted, it will go through the collection
|
|
||||||
to know where to fetch the data from.
|
|
||||||
|
|
||||||
Either way, the format of this collection is completely dependent on
|
|
||||||
your hardware. Each DMA controller will require a different structure,
|
|
||||||
but all of them will require, for every chunk, at least the source and
|
|
||||||
destination addresses, whether it should increment these addresses or
|
|
||||||
not and the three parameters we saw earlier: the burst size, the
|
|
||||||
transfer width and the transfer size.
|
|
||||||
|
|
||||||
The one last thing is that usually, slave devices won't issue DRQ by
|
|
||||||
default, and you have to enable this in your slave device driver first
|
|
||||||
whenever you're willing to use DMA.
|
|
||||||
|
|
||||||
These were just the general memory-to-memory (also called mem2mem) or
|
|
||||||
memory-to-device (mem2dev) kind of transfers. Most devices often
|
|
||||||
support other kind of transfers or memory operations that dmaengine
|
|
||||||
support and will be detailed later in this document.
|
|
||||||
|
|
||||||
DMA Support in Linux
|
|
||||||
++++++++++++++++++++
|
|
||||||
|
|
||||||
Historically, DMA controller drivers have been implemented using the
|
|
||||||
async TX API, to offload operations such as memory copy, XOR,
|
|
||||||
cryptography, etc., basically any memory to memory operation.
|
|
||||||
|
|
||||||
Over time, the need for memory to device transfers arose, and
|
|
||||||
dmaengine was extended. Nowadays, the async TX API is written as a
|
|
||||||
layer on top of dmaengine, and acts as a client. Still, dmaengine
|
|
||||||
accommodates that API in some cases, and made some design choices to
|
|
||||||
ensure that it stayed compatible.
|
|
||||||
|
|
||||||
For more information on the Async TX API, please look the relevant
|
|
||||||
documentation file in Documentation/crypto/async-tx-api.txt.
|
|
||||||
|
|
||||||
DMAEngine Registration
|
|
||||||
++++++++++++++++++++++
|
|
||||||
|
|
||||||
struct dma_device Initialization
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Just like any other kernel framework, the whole DMAEngine registration
|
|
||||||
relies on the driver filling a structure and registering against the
|
|
||||||
framework. In our case, that structure is dma_device.
|
|
||||||
|
|
||||||
The first thing you need to do in your driver is to allocate this
|
|
||||||
structure. Any of the usual memory allocators will do, but you'll also
|
|
||||||
need to initialize a few fields in there:
|
|
||||||
|
|
||||||
* channels: should be initialized as a list using the
|
|
||||||
INIT_LIST_HEAD macro for example
|
|
||||||
|
|
||||||
* src_addr_widths:
|
|
||||||
- should contain a bitmask of the supported source transfer width
|
|
||||||
|
|
||||||
* dst_addr_widths:
|
|
||||||
- should contain a bitmask of the supported destination transfer
|
|
||||||
width
|
|
||||||
|
|
||||||
* directions:
|
|
||||||
- should contain a bitmask of the supported slave directions
|
|
||||||
(i.e. excluding mem2mem transfers)
|
|
||||||
|
|
||||||
* residue_granularity:
|
|
||||||
- Granularity of the transfer residue reported to dma_set_residue.
|
|
||||||
- This can be either:
|
|
||||||
+ Descriptor
|
|
||||||
-> Your device doesn't support any kind of residue
|
|
||||||
reporting. The framework will only know that a particular
|
|
||||||
transaction descriptor is done.
|
|
||||||
+ Segment
|
|
||||||
-> Your device is able to report which chunks have been
|
|
||||||
transferred
|
|
||||||
+ Burst
|
|
||||||
-> Your device is able to report which burst have been
|
|
||||||
transferred
|
|
||||||
|
|
||||||
* dev: should hold the pointer to the struct device associated
|
|
||||||
to your current driver instance.
|
|
||||||
|
|
||||||
Supported transaction types
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
The next thing you need is to set which transaction types your device
|
|
||||||
(and driver) supports.
|
|
||||||
|
|
||||||
Our dma_device structure has a field called cap_mask that holds the
|
|
||||||
various types of transaction supported, and you need to modify this
|
|
||||||
mask using the dma_cap_set function, with various flags depending on
|
|
||||||
transaction types you support as an argument.
|
|
||||||
|
|
||||||
All those capabilities are defined in the dma_transaction_type enum,
|
|
||||||
in include/linux/dmaengine.h
|
|
||||||
|
|
||||||
Currently, the types available are:
|
|
||||||
* DMA_MEMCPY
|
|
||||||
- The device is able to do memory to memory copies
|
|
||||||
|
|
||||||
* DMA_XOR
|
|
||||||
- The device is able to perform XOR operations on memory areas
|
|
||||||
- Used to accelerate XOR intensive tasks, such as RAID5
|
|
||||||
|
|
||||||
* DMA_XOR_VAL
|
|
||||||
- The device is able to perform parity check using the XOR
|
|
||||||
algorithm against a memory buffer.
|
|
||||||
|
|
||||||
* DMA_PQ
|
|
||||||
- The device is able to perform RAID6 P+Q computations, P being a
|
|
||||||
simple XOR, and Q being a Reed-Solomon algorithm.
|
|
||||||
|
|
||||||
* DMA_PQ_VAL
|
|
||||||
- The device is able to perform parity check using RAID6 P+Q
|
|
||||||
algorithm against a memory buffer.
|
|
||||||
|
|
||||||
* DMA_INTERRUPT
|
|
||||||
- The device is able to trigger a dummy transfer that will
|
|
||||||
generate periodic interrupts
|
|
||||||
- Used by the client drivers to register a callback that will be
|
|
||||||
called on a regular basis through the DMA controller interrupt
|
|
||||||
|
|
||||||
* DMA_PRIVATE
|
|
||||||
- The devices only supports slave transfers, and as such isn't
|
|
||||||
available for async transfers.
|
|
||||||
|
|
||||||
* DMA_ASYNC_TX
|
|
||||||
- Must not be set by the device, and will be set by the framework
|
|
||||||
if needed
|
|
||||||
- /* TODO: What is it about? */
|
|
||||||
|
|
||||||
* DMA_SLAVE
|
|
||||||
- The device can handle device to memory transfers, including
|
|
||||||
scatter-gather transfers.
|
|
||||||
- While in the mem2mem case we were having two distinct types to
|
|
||||||
deal with a single chunk to copy or a collection of them, here,
|
|
||||||
we just have a single transaction type that is supposed to
|
|
||||||
handle both.
|
|
||||||
- If you want to transfer a single contiguous memory buffer,
|
|
||||||
simply build a scatter list with only one item.
|
|
||||||
|
|
||||||
* DMA_CYCLIC
|
|
||||||
- The device can handle cyclic transfers.
|
|
||||||
- A cyclic transfer is a transfer where the chunk collection will
|
|
||||||
loop over itself, with the last item pointing to the first.
|
|
||||||
- It's usually used for audio transfers, where you want to operate
|
|
||||||
on a single ring buffer that you will fill with your audio data.
|
|
||||||
|
|
||||||
* DMA_INTERLEAVE
|
|
||||||
- The device supports interleaved transfer.
|
|
||||||
- These transfers can transfer data from a non-contiguous buffer
|
|
||||||
to a non-contiguous buffer, opposed to DMA_SLAVE that can
|
|
||||||
transfer data from a non-contiguous data set to a continuous
|
|
||||||
destination buffer.
|
|
||||||
- It's usually used for 2d content transfers, in which case you
|
|
||||||
want to transfer a portion of uncompressed data directly to the
|
|
||||||
display to print it
|
|
||||||
|
|
||||||
These various types will also affect how the source and destination
|
|
||||||
addresses change over time.
|
|
||||||
|
|
||||||
Addresses pointing to RAM are typically incremented (or decremented)
|
|
||||||
after each transfer. In case of a ring buffer, they may loop
|
|
||||||
(DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO)
|
|
||||||
are typically fixed.
|
|
||||||
|
|
||||||
Device operations
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Our dma_device structure also requires a few function pointers in
|
|
||||||
order to implement the actual logic, now that we described what
|
|
||||||
operations we were able to perform.
|
|
||||||
|
|
||||||
The functions that we have to fill in there, and hence have to
|
|
||||||
implement, obviously depend on the transaction types you reported as
|
|
||||||
supported.
|
|
||||||
|
|
||||||
* device_alloc_chan_resources
|
|
||||||
* device_free_chan_resources
|
|
||||||
- These functions will be called whenever a driver will call
|
|
||||||
dma_request_channel or dma_release_channel for the first/last
|
|
||||||
time on the channel associated to that driver.
|
|
||||||
- They are in charge of allocating/freeing all the needed
|
|
||||||
resources in order for that channel to be useful for your
|
|
||||||
driver.
|
|
||||||
- These functions can sleep.
|
|
||||||
|
|
||||||
* device_prep_dma_*
|
|
||||||
- These functions are matching the capabilities you registered
|
|
||||||
previously.
|
|
||||||
- These functions all take the buffer or the scatterlist relevant
|
|
||||||
for the transfer being prepared, and should create a hardware
|
|
||||||
descriptor or a list of hardware descriptors from it
|
|
||||||
- These functions can be called from an interrupt context
|
|
||||||
- Any allocation you might do should be using the GFP_NOWAIT
|
|
||||||
flag, in order not to potentially sleep, but without depleting
|
|
||||||
the emergency pool either.
|
|
||||||
- Drivers should try to pre-allocate any memory they might need
|
|
||||||
during the transfer setup at probe time to avoid putting to
|
|
||||||
much pressure on the nowait allocator.
|
|
||||||
|
|
||||||
- It should return a unique instance of the
|
|
||||||
dma_async_tx_descriptor structure, that further represents this
|
|
||||||
particular transfer.
|
|
||||||
|
|
||||||
- This structure can be initialized using the function
|
|
||||||
dma_async_tx_descriptor_init.
|
|
||||||
- You'll also need to set two fields in this structure:
|
|
||||||
+ flags:
|
|
||||||
TODO: Can it be modified by the driver itself, or
|
|
||||||
should it be always the flags passed in the arguments
|
|
||||||
|
|
||||||
+ tx_submit: A pointer to a function you have to implement,
|
|
||||||
that is supposed to push the current
|
|
||||||
transaction descriptor to a pending queue, waiting
|
|
||||||
for issue_pending to be called.
|
|
||||||
- In this structure the function pointer callback_result can be
|
|
||||||
initialized in order for the submitter to be notified that a
|
|
||||||
transaction has completed. In the earlier code the function pointer
|
|
||||||
callback has been used. However it does not provide any status to the
|
|
||||||
transaction and will be deprecated. The result structure defined as
|
|
||||||
dmaengine_result that is passed in to callback_result has two fields:
|
|
||||||
+ result: This provides the transfer result defined by
|
|
||||||
dmaengine_tx_result. Either success or some error
|
|
||||||
condition.
|
|
||||||
+ residue: Provides the residue bytes of the transfer for those that
|
|
||||||
support residue.
|
|
||||||
|
|
||||||
* device_issue_pending
|
|
||||||
- Takes the first transaction descriptor in the pending queue,
|
|
||||||
and starts the transfer. Whenever that transfer is done, it
|
|
||||||
should move to the next transaction in the list.
|
|
||||||
- This function can be called in an interrupt context
|
|
||||||
|
|
||||||
* device_tx_status
|
|
||||||
- Should report the bytes left to go over on the given channel
|
|
||||||
- Should only care about the transaction descriptor passed as
|
|
||||||
argument, not the currently active one on a given channel
|
|
||||||
- The tx_state argument might be NULL
|
|
||||||
- Should use dma_set_residue to report it
|
|
||||||
- In the case of a cyclic transfer, it should only take into
|
|
||||||
account the current period.
|
|
||||||
- This function can be called in an interrupt context.
|
|
||||||
|
|
||||||
* device_config
|
|
||||||
- Reconfigures the channel with the configuration given as
|
|
||||||
argument
|
|
||||||
- This command should NOT perform synchronously, or on any
|
|
||||||
currently queued transfers, but only on subsequent ones
|
|
||||||
- In this case, the function will receive a dma_slave_config
|
|
||||||
structure pointer as an argument, that will detail which
|
|
||||||
configuration to use.
|
|
||||||
- Even though that structure contains a direction field, this
|
|
||||||
field is deprecated in favor of the direction argument given to
|
|
||||||
the prep_* functions
|
|
||||||
- This call is mandatory for slave operations only. This should NOT be
|
|
||||||
set or expected to be set for memcpy operations.
|
|
||||||
If a driver support both, it should use this call for slave
|
|
||||||
operations only and not for memcpy ones.
|
|
||||||
|
|
||||||
* device_pause
|
|
||||||
- Pauses a transfer on the channel
|
|
||||||
- This command should operate synchronously on the channel,
|
|
||||||
pausing right away the work of the given channel
|
|
||||||
|
|
||||||
* device_resume
|
|
||||||
- Resumes a transfer on the channel
|
|
||||||
- This command should operate synchronously on the channel,
|
|
||||||
resuming right away the work of the given channel
|
|
||||||
|
|
||||||
* device_terminate_all
|
|
||||||
- Aborts all the pending and ongoing transfers on the channel
|
|
||||||
- For aborted transfers the complete callback should not be called
|
|
||||||
- Can be called from atomic context or from within a complete
|
|
||||||
callback of a descriptor. Must not sleep. Drivers must be able
|
|
||||||
to handle this correctly.
|
|
||||||
- Termination may be asynchronous. The driver does not have to
|
|
||||||
wait until the currently active transfer has completely stopped.
|
|
||||||
See device_synchronize.
|
|
||||||
|
|
||||||
* device_synchronize
|
|
||||||
- Must synchronize the termination of a channel to the current
|
|
||||||
context.
|
|
||||||
- Must make sure that memory for previously submitted
|
|
||||||
descriptors is no longer accessed by the DMA controller.
|
|
||||||
- Must make sure that all complete callbacks for previously
|
|
||||||
submitted descriptors have finished running and none are
|
|
||||||
scheduled to run.
|
|
||||||
- May sleep.
|
|
||||||
|
|
||||||
|
|
||||||
Misc notes (stuff that should be documented, but don't really know
|
|
||||||
where to put them)
|
|
||||||
------------------------------------------------------------------
|
|
||||||
* dma_run_dependencies
|
|
||||||
- Should be called at the end of an async TX transfer, and can be
|
|
||||||
ignored in the slave transfers case.
|
|
||||||
- Makes sure that dependent operations are run before marking it
|
|
||||||
as complete.
|
|
||||||
|
|
||||||
* dma_cookie_t
|
|
||||||
- it's a DMA transaction ID that will increment over time.
|
|
||||||
- Not really relevant any more since the introduction of virt-dma
|
|
||||||
that abstracts it away.
|
|
||||||
|
|
||||||
* DMA_CTRL_ACK
|
|
||||||
- If clear, the descriptor cannot be reused by provider until the
|
|
||||||
client acknowledges receipt, i.e. has has a chance to establish any
|
|
||||||
dependency chains
|
|
||||||
- This can be acked by invoking async_tx_ack()
|
|
||||||
- If set, does not mean descriptor can be reused
|
|
||||||
|
|
||||||
* DMA_CTRL_REUSE
|
|
||||||
- If set, the descriptor can be reused after being completed. It should
|
|
||||||
not be freed by provider if this flag is set.
|
|
||||||
- The descriptor should be prepared for reuse by invoking
|
|
||||||
dmaengine_desc_set_reuse() which will set DMA_CTRL_REUSE.
|
|
||||||
- dmaengine_desc_set_reuse() will succeed only when channel support
|
|
||||||
reusable descriptor as exhibited by capabilities
|
|
||||||
- As a consequence, if a device driver wants to skip the dma_map_sg() and
|
|
||||||
dma_unmap_sg() in between 2 transfers, because the DMA'd data wasn't used,
|
|
||||||
it can resubmit the transfer right after its completion.
|
|
||||||
- Descriptor can be freed in few ways
|
|
||||||
- Clearing DMA_CTRL_REUSE by invoking dmaengine_desc_clear_reuse()
|
|
||||||
and submitting for last txn
|
|
||||||
- Explicitly invoking dmaengine_desc_free(), this can succeed only
|
|
||||||
when DMA_CTRL_REUSE is already set
|
|
||||||
- Terminating the channel
|
|
||||||
|
|
||||||
* DMA_PREP_CMD
|
|
||||||
- If set, the client driver tells DMA controller that passed data in DMA
|
|
||||||
API is command data.
|
|
||||||
- Interpretation of command data is DMA controller specific. It can be
|
|
||||||
used for issuing commands to other peripherals/register reads/register
|
|
||||||
writes for which the descriptor should be in different format from
|
|
||||||
normal data descriptors.
|
|
||||||
|
|
||||||
General Design Notes
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Most of the DMAEngine drivers you'll see are based on a similar design
|
|
||||||
that handles the end of transfer interrupts in the handler, but defer
|
|
||||||
most work to a tasklet, including the start of a new transfer whenever
|
|
||||||
the previous transfer ended.
|
|
||||||
|
|
||||||
This is a rather inefficient design though, because the inter-transfer
|
|
||||||
latency will be not only the interrupt latency, but also the
|
|
||||||
scheduling latency of the tasklet, which will leave the channel idle
|
|
||||||
in between, which will slow down the global transfer rate.
|
|
||||||
|
|
||||||
You should avoid this kind of practice, and instead of electing a new
|
|
||||||
transfer in your tasklet, move that part to the interrupt handler in
|
|
||||||
order to have a shorter idle window (that we can't really avoid
|
|
||||||
anyway).
|
|
||||||
|
|
||||||
Glossary
|
|
||||||
--------
|
|
||||||
|
|
||||||
Burst: A number of consecutive read or write operations
|
|
||||||
that can be queued to buffers before being flushed to
|
|
||||||
memory.
|
|
||||||
Chunk: A contiguous collection of bursts
|
|
||||||
Transfer: A collection of chunks (be it contiguous or not)
|
|
@@ -1,153 +0,0 @@
|
|||||||
PXA/MMP - DMA Slave controller
|
|
||||||
==============================
|
|
||||||
|
|
||||||
Constraints
|
|
||||||
-----------
|
|
||||||
a) Transfers hot queuing
|
|
||||||
A driver submitting a transfer and issuing it should be granted the transfer
|
|
||||||
is queued even on a running DMA channel.
|
|
||||||
This implies that the queuing doesn't wait for the previous transfer end,
|
|
||||||
and that the descriptor chaining is not only done in the irq/tasklet code
|
|
||||||
triggered by the end of the transfer.
|
|
||||||
A transfer which is submitted and issued on a phy doesn't wait for a phy to
|
|
||||||
stop and restart, but is submitted on a "running channel". The other
|
|
||||||
drivers, especially mmp_pdma waited for the phy to stop before relaunching
|
|
||||||
a new transfer.
|
|
||||||
|
|
||||||
b) All transfers having asked for confirmation should be signaled
|
|
||||||
Any issued transfer with DMA_PREP_INTERRUPT should trigger a callback call.
|
|
||||||
This implies that even if an irq/tasklet is triggered by end of tx1, but
|
|
||||||
at the time of irq/dma tx2 is already finished, tx1->complete() and
|
|
||||||
tx2->complete() should be called.
|
|
||||||
|
|
||||||
c) Channel running state
|
|
||||||
A driver should be able to query if a channel is running or not. For the
|
|
||||||
multimedia case, such as video capture, if a transfer is submitted and then
|
|
||||||
a check of the DMA channel reports a "stopped channel", the transfer should
|
|
||||||
not be issued until the next "start of frame interrupt", hence the need to
|
|
||||||
know if a channel is in running or stopped state.
|
|
||||||
|
|
||||||
d) Bandwidth guarantee
|
|
||||||
The PXA architecture has 4 levels of DMAs priorities : high, normal, low.
|
|
||||||
The high priorities get twice as much bandwidth as the normal, which get twice
|
|
||||||
as much as the low priorities.
|
|
||||||
A driver should be able to request a priority, especially the real-time
|
|
||||||
ones such as pxa_camera with (big) throughputs.
|
|
||||||
|
|
||||||
Design
|
|
||||||
------
|
|
||||||
a) Virtual channels
|
|
||||||
Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
|
|
||||||
channel" linked to the requestor line, and the physical DMA channel is
|
|
||||||
assigned on the fly when the transfer is issued.
|
|
||||||
|
|
||||||
b) Transfer anatomy for a scatter-gather transfer
|
|
||||||
+------------+-----+---------------+----------------+-----------------+
|
|
||||||
| desc-sg[0] | ... | desc-sg[last] | status updater | finisher/linker |
|
|
||||||
+------------+-----+---------------+----------------+-----------------+
|
|
||||||
|
|
||||||
This structure is pointed by dma->sg_cpu.
|
|
||||||
The descriptors are used as follows :
|
|
||||||
- desc-sg[i]: i-th descriptor, transferring the i-th sg
|
|
||||||
element to the video buffer scatter gather
|
|
||||||
- status updater
|
|
||||||
Transfers a single u32 to a well known dma coherent memory to leave
|
|
||||||
a trace that this transfer is done. The "well known" is unique per
|
|
||||||
physical channel, meaning that a read of this value will tell which
|
|
||||||
is the last finished transfer at that point in time.
|
|
||||||
- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
|
|
||||||
- linker: has ddadr= desc-sg[0] of next transfer, dcmd=0
|
|
||||||
|
|
||||||
c) Transfers hot-chaining
|
|
||||||
Suppose the running chain is :
|
|
||||||
Buffer 1 Buffer 2
|
|
||||||
+---------+----+---+ +----+----+----+---+
|
|
||||||
| d0 | .. | dN | l | | d0 | .. | dN | f |
|
|
||||||
+---------+----+-|-+ ^----+----+----+---+
|
|
||||||
| |
|
|
||||||
+----+
|
|
||||||
|
|
||||||
After a call to dmaengine_submit(b3), the chain will look like :
|
|
||||||
Buffer 1 Buffer 2 Buffer 3
|
|
||||||
+---------+----+---+ +----+----+----+---+ +----+----+----+---+
|
|
||||||
| d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f |
|
|
||||||
+---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+
|
|
||||||
| | | |
|
|
||||||
+----+ +----+
|
|
||||||
new_link
|
|
||||||
|
|
||||||
If while new_link was created the DMA channel stopped, it is _not_
|
|
||||||
restarted. Hot-chaining doesn't break the assumption that
|
|
||||||
dma_async_issue_pending() is to be used to ensure the transfer is actually started.
|
|
||||||
|
|
||||||
One exception to this rule :
|
|
||||||
- if Buffer1 and Buffer2 had all their addresses 8 bytes aligned
|
|
||||||
- and if Buffer3 has at least one address not 4 bytes aligned
|
|
||||||
- then hot-chaining cannot happen, as the channel must be stopped, the
|
|
||||||
"align bit" must be set, and the channel restarted As a consequence,
|
|
||||||
such a transfer tx_submit() will be queued on the submitted queue, and
|
|
||||||
this specific case if the DMA is already running in aligned mode.
|
|
||||||
|
|
||||||
d) Transfers completion updater
|
|
||||||
Each time a transfer is completed on a channel, an interrupt might be
|
|
||||||
generated or not, up to the client's request. But in each case, the last
|
|
||||||
descriptor of a transfer, the "status updater", will write the latest
|
|
||||||
transfer being completed into the physical channel's completion mark.
|
|
||||||
|
|
||||||
This will speed up residue calculation, for large transfers such as video
|
|
||||||
buffers which hold around 6k descriptors or more. This also allows without
|
|
||||||
any lock to find out what is the latest completed transfer in a running
|
|
||||||
DMA chain.
|
|
||||||
|
|
||||||
e) Transfers completion, irq and tasklet
|
|
||||||
When a transfer flagged as "DMA_PREP_INTERRUPT" is finished, the dma irq
|
|
||||||
is raised. Upon this interrupt, a tasklet is scheduled for the physical
|
|
||||||
channel.
|
|
||||||
The tasklet is responsible for :
|
|
||||||
- reading the physical channel last updater mark
|
|
||||||
- calling all the transfer callbacks of finished transfers, based on
|
|
||||||
that mark, and each transfer flags.
|
|
||||||
If a transfer is completed while this handling is done, a dma irq will
|
|
||||||
be raised, and the tasklet will be scheduled once again, having a new
|
|
||||||
updater mark.
|
|
||||||
|
|
||||||
f) Residue
|
|
||||||
Residue granularity will be descriptor based. The issued but not completed
|
|
||||||
transfers will be scanned for all of their descriptors against the
|
|
||||||
currently running descriptor.
|
|
||||||
|
|
||||||
g) Most complicated case of driver's tx queues
|
|
||||||
The most tricky situation is when :
|
|
||||||
- there are not "acked" transfers (tx0)
|
|
||||||
- a driver submitted an aligned tx1, not chained
|
|
||||||
- a driver submitted an aligned tx2 => tx2 is cold chained to tx1
|
|
||||||
- a driver issued tx1+tx2 => channel is running in aligned mode
|
|
||||||
- a driver submitted an aligned tx3 => tx3 is hot-chained
|
|
||||||
- a driver submitted an unaligned tx4 => tx4 is put in submitted queue,
|
|
||||||
not chained
|
|
||||||
- a driver issued tx4 => tx4 is put in issued queue, not chained
|
|
||||||
- a driver submitted an aligned tx5 => tx5 is put in submitted queue, not
|
|
||||||
chained
|
|
||||||
- a driver submitted an aligned tx6 => tx6 is put in submitted queue,
|
|
||||||
cold chained to tx5
|
|
||||||
|
|
||||||
This translates into (after tx4 is issued) :
|
|
||||||
- issued queue
|
|
||||||
+-----+ +-----+ +-----+ +-----+
|
|
||||||
| tx1 | | tx2 | | tx3 | | tx4 |
|
|
||||||
+---|-+ ^---|-+ ^-----+ +-----+
|
|
||||||
| | | |
|
|
||||||
+---+ +---+
|
|
||||||
- submitted queue
|
|
||||||
+-----+ +-----+
|
|
||||||
| tx5 | | tx6 |
|
|
||||||
+---|-+ ^-----+
|
|
||||||
| |
|
|
||||||
+---+
|
|
||||||
- completed queue : empty
|
|
||||||
- allocated queue : tx0
|
|
||||||
|
|
||||||
It should be noted that after tx3 is completed, the channel is stopped, and
|
|
||||||
restarted in "unaligned mode" to handle tx4.
|
|
||||||
|
|
||||||
Author: Robert Jarzmik <robert.jarzmik@free.fr>
|
|
@@ -65,7 +65,7 @@ Without options, the kernel-doc directive includes all documentation comments
|
|||||||
from the source file.
|
from the source file.
|
||||||
|
|
||||||
The kernel-doc extension is included in the kernel source tree, at
|
The kernel-doc extension is included in the kernel source tree, at
|
||||||
``Documentation/sphinx/kernel-doc.py``. Internally, it uses the
|
``Documentation/sphinx/kerneldoc.py``. Internally, it uses the
|
||||||
``scripts/kernel-doc`` script to extract the documentation comments from the
|
``scripts/kernel-doc`` script to extract the documentation comments from the
|
||||||
source.
|
source.
|
||||||
|
|
||||||
|
275
Documentation/driver-api/dmaengine/client.rst
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
====================
|
||||||
|
DMA Engine API Guide
|
||||||
|
====================
|
||||||
|
|
||||||
|
Vinod Koul <vinod dot koul at intel.com>
|
||||||
|
|
||||||
|
.. note:: For DMA Engine usage in async_tx please see:
|
||||||
|
``Documentation/crypto/async-tx-api.txt``
|
||||||
|
|
||||||
|
|
||||||
|
Below is a guide to device driver writers on how to use the Slave-DMA API of the
|
||||||
|
DMA Engine. This is applicable only for slave DMA usage only.
|
||||||
|
|
||||||
|
DMA usage
|
||||||
|
=========
|
||||||
|
|
||||||
|
The slave DMA usage consists of following steps:
|
||||||
|
|
||||||
|
- Allocate a DMA slave channel
|
||||||
|
|
||||||
|
- Set slave and controller specific parameters
|
||||||
|
|
||||||
|
- Get a descriptor for transaction
|
||||||
|
|
||||||
|
- Submit the transaction
|
||||||
|
|
||||||
|
- Issue pending requests and wait for callback notification
|
||||||
|
|
||||||
|
The details of these operations are:
|
||||||
|
|
||||||
|
1. Allocate a DMA slave channel
|
||||||
|
|
||||||
|
Channel allocation is slightly different in the slave DMA context,
|
||||||
|
client drivers typically need a channel from a particular DMA
|
||||||
|
controller only and even in some cases a specific channel is desired.
|
||||||
|
To request a channel dma_request_chan() API is used.
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
|
||||||
|
|
||||||
|
Which will find and return the ``name`` DMA channel associated with the 'dev'
|
||||||
|
device. The association is done via DT, ACPI or board file based
|
||||||
|
dma_slave_map matching table.
|
||||||
|
|
||||||
|
A channel allocated via this interface is exclusive to the caller,
|
||||||
|
until dma_release_channel() is called.
|
||||||
|
|
||||||
|
2. Set slave and controller specific parameters
|
||||||
|
|
||||||
|
Next step is always to pass some specific information to the DMA
|
||||||
|
driver. Most of the generic information which a slave DMA can use
|
||||||
|
is in struct dma_slave_config. This allows the clients to specify
|
||||||
|
DMA direction, DMA addresses, bus widths, DMA burst lengths etc
|
||||||
|
for the peripheral.
|
||||||
|
|
||||||
|
If some DMA controllers have more parameters to be sent then they
|
||||||
|
should try to embed struct dma_slave_config in their controller
|
||||||
|
specific structure. That gives flexibility to client to pass more
|
||||||
|
parameters, if required.
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int dmaengine_slave_config(struct dma_chan *chan,
|
||||||
|
struct dma_slave_config *config)
|
||||||
|
|
||||||
|
Please see the dma_slave_config structure definition in dmaengine.h
|
||||||
|
for a detailed explanation of the struct members. Please note
|
||||||
|
that the 'direction' member will be going away as it duplicates the
|
||||||
|
direction given in the prepare call.
|
||||||
|
|
||||||
|
3. Get a descriptor for transaction
|
||||||
|
|
||||||
|
For slave usage the various modes of slave transfers supported by the
|
||||||
|
DMA-engine are:
|
||||||
|
|
||||||
|
- slave_sg: DMA a list of scatter gather buffers from/to a peripheral
|
||||||
|
|
||||||
|
- dma_cyclic: Perform a cyclic DMA operation from/to a peripheral till the
|
||||||
|
operation is explicitly stopped.
|
||||||
|
|
||||||
|
- interleaved_dma: This is common to Slave as well as M2M clients. For slave
|
||||||
|
address of devices' fifo could be already known to the driver.
|
||||||
|
Various types of operations could be expressed by setting
|
||||||
|
appropriate values to the 'dma_interleaved_template' members.
|
||||||
|
|
||||||
|
A non-NULL return of this transfer API represents a "descriptor" for
|
||||||
|
the given transaction.
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct dma_async_tx_descriptor *dmaengine_prep_slave_sg(
|
||||||
|
struct dma_chan *chan, struct scatterlist *sgl,
|
||||||
|
unsigned int sg_len, enum dma_data_direction direction,
|
||||||
|
unsigned long flags);
|
||||||
|
|
||||||
|
struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
|
||||||
|
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
|
||||||
|
size_t period_len, enum dma_data_direction direction);
|
||||||
|
|
||||||
|
struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
|
||||||
|
struct dma_chan *chan, struct dma_interleaved_template *xt,
|
||||||
|
unsigned long flags);
|
||||||
|
|
||||||
|
The peripheral driver is expected to have mapped the scatterlist for
|
||||||
|
the DMA operation prior to calling dmaengine_prep_slave_sg(), and must
|
||||||
|
keep the scatterlist mapped until the DMA operation has completed.
|
||||||
|
The scatterlist must be mapped using the DMA struct device.
|
||||||
|
If a mapping needs to be synchronized later, dma_sync_*_for_*() must be
|
||||||
|
called using the DMA struct device, too.
|
||||||
|
So, normal setup should look like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
nr_sg = dma_map_sg(chan->device->dev, sgl, sg_len);
|
||||||
|
if (nr_sg == 0)
|
||||||
|
/* error */
|
||||||
|
|
||||||
|
desc = dmaengine_prep_slave_sg(chan, sgl, nr_sg, direction, flags);
|
||||||
|
|
||||||
|
Once a descriptor has been obtained, the callback information can be
|
||||||
|
added and the descriptor must then be submitted. Some DMA engine
|
||||||
|
drivers may hold a spinlock between a successful preparation and
|
||||||
|
submission so it is important that these two operations are closely
|
||||||
|
paired.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Although the async_tx API specifies that completion callback
|
||||||
|
routines cannot submit any new operations, this is not the
|
||||||
|
case for slave/cyclic DMA.
|
||||||
|
|
||||||
|
For slave DMA, the subsequent transaction may not be available
|
||||||
|
for submission prior to callback function being invoked, so
|
||||||
|
slave DMA callbacks are permitted to prepare and submit a new
|
||||||
|
transaction.
|
||||||
|
|
||||||
|
For cyclic DMA, a callback function may wish to terminate the
|
||||||
|
DMA via dmaengine_terminate_async().
|
||||||
|
|
||||||
|
Therefore, it is important that DMA engine drivers drop any
|
||||||
|
locks before calling the callback function which may cause a
|
||||||
|
deadlock.
|
||||||
|
|
||||||
|
Note that callbacks will always be invoked from the DMA
|
||||||
|
engines tasklet, never from interrupt context.
|
||||||
|
|
||||||
|
4. Submit the transaction
|
||||||
|
|
||||||
|
Once the descriptor has been prepared and the callback information
|
||||||
|
added, it must be placed on the DMA engine drivers pending queue.
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
|
||||||
|
|
||||||
|
This returns a cookie can be used to check the progress of DMA engine
|
||||||
|
activity via other DMA engine calls not covered in this document.
|
||||||
|
|
||||||
|
dmaengine_submit() will not start the DMA operation, it merely adds
|
||||||
|
it to the pending queue. For this, see step 5, dma_async_issue_pending.
|
||||||
|
|
||||||
|
5. Issue pending DMA requests and wait for callback notification
|
||||||
|
|
||||||
|
The transactions in the pending queue can be activated by calling the
|
||||||
|
issue_pending API. If channel is idle then the first transaction in
|
||||||
|
queue is started and subsequent ones queued up.
|
||||||
|
|
||||||
|
On completion of each DMA operation, the next in queue is started and
|
||||||
|
a tasklet triggered. The tasklet will then call the client driver
|
||||||
|
completion callback routine for notification, if set.
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void dma_async_issue_pending(struct dma_chan *chan);
|
||||||
|
|
||||||
|
Further APIs:
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. Terminate APIs
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int dmaengine_terminate_sync(struct dma_chan *chan)
|
||||||
|
int dmaengine_terminate_async(struct dma_chan *chan)
|
||||||
|
int dmaengine_terminate_all(struct dma_chan *chan) /* DEPRECATED */
|
||||||
|
|
||||||
|
This causes all activity for the DMA channel to be stopped, and may
|
||||||
|
discard data in the DMA FIFO which hasn't been fully transferred.
|
||||||
|
No callback functions will be called for any incomplete transfers.
|
||||||
|
|
||||||
|
Two variants of this function are available.
|
||||||
|
|
||||||
|
dmaengine_terminate_async() might not wait until the DMA has been fully
|
||||||
|
stopped or until any running complete callbacks have finished. But it is
|
||||||
|
possible to call dmaengine_terminate_async() from atomic context or from
|
||||||
|
within a complete callback. dmaengine_synchronize() must be called before it
|
||||||
|
is safe to free the memory accessed by the DMA transfer or free resources
|
||||||
|
accessed from within the complete callback.
|
||||||
|
|
||||||
|
dmaengine_terminate_sync() will wait for the transfer and any running
|
||||||
|
complete callbacks to finish before it returns. But the function must not be
|
||||||
|
called from atomic context or from within a complete callback.
|
||||||
|
|
||||||
|
dmaengine_terminate_all() is deprecated and should not be used in new code.
|
||||||
|
|
||||||
|
2. Pause API
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int dmaengine_pause(struct dma_chan *chan)
|
||||||
|
|
||||||
|
This pauses activity on the DMA channel without data loss.
|
||||||
|
|
||||||
|
3. Resume API
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int dmaengine_resume(struct dma_chan *chan)
|
||||||
|
|
||||||
|
Resume a previously paused DMA channel. It is invalid to resume a
|
||||||
|
channel which is not currently paused.
|
||||||
|
|
||||||
|
4. Check Txn complete
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
|
||||||
|
dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
|
||||||
|
|
||||||
|
This can be used to check the status of the channel. Please see
|
||||||
|
the documentation in include/linux/dmaengine.h for a more complete
|
||||||
|
description of this API.
|
||||||
|
|
||||||
|
This can be used in conjunction with dma_async_is_complete() and
|
||||||
|
the cookie returned from dmaengine_submit() to check for
|
||||||
|
completion of a specific DMA transaction.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Not all DMA engine drivers can return reliable information for
|
||||||
|
a running DMA channel. It is recommended that DMA engine users
|
||||||
|
pause or stop (via dmaengine_terminate_all()) the channel before
|
||||||
|
using this API.
|
||||||
|
|
||||||
|
5. Synchronize termination API
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void dmaengine_synchronize(struct dma_chan *chan)
|
||||||
|
|
||||||
|
Synchronize the termination of the DMA channel to the current context.
|
||||||
|
|
||||||
|
This function should be used after dmaengine_terminate_async() to synchronize
|
||||||
|
the termination of the DMA channel to the current context. The function will
|
||||||
|
wait for the transfer and any running complete callbacks to finish before it
|
||||||
|
returns.
|
||||||
|
|
||||||
|
If dmaengine_terminate_async() is used to stop the DMA channel this function
|
||||||
|
must be called before it is safe to free memory accessed by previously
|
||||||
|
submitted descriptors or to free any resources accessed within the complete
|
||||||
|
callback of previously submitted descriptors.
|
||||||
|
|
||||||
|
The behavior of this function is undefined if dma_async_issue_pending() has
|
||||||
|
been called between dmaengine_terminate_async() and this function.
|
@@ -1,11 +1,13 @@
|
|||||||
DMA Test Guide
|
==============
|
||||||
==============
|
DMA Test Guide
|
||||||
|
==============
|
||||||
|
|
||||||
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||||
|
|
||||||
This small document introduces how to test DMA drivers using dmatest module.
|
This small document introduces how to test DMA drivers using dmatest module.
|
||||||
|
|
||||||
Part 1 - How to build the test module
|
Part 1 - How to build the test module
|
||||||
|
=====================================
|
||||||
|
|
||||||
The menuconfig contains an option that could be found by following path:
|
The menuconfig contains an option that could be found by following path:
|
||||||
Device Drivers -> DMA Engine support -> DMA Test client
|
Device Drivers -> DMA Engine support -> DMA Test client
|
||||||
@@ -13,25 +15,31 @@ The menuconfig contains an option that could be found by following path:
|
|||||||
In the configuration file the option called CONFIG_DMATEST. The dmatest could
|
In the configuration file the option called CONFIG_DMATEST. The dmatest could
|
||||||
be built as module or inside kernel. Let's consider those cases.
|
be built as module or inside kernel. Let's consider those cases.
|
||||||
|
|
||||||
Part 2 - When dmatest is built as a module...
|
Part 2 - When dmatest is built as a module
|
||||||
|
==========================================
|
||||||
|
|
||||||
Example of usage:
|
Example of usage: ::
|
||||||
% modprobe dmatest channel=dma0chan0 timeout=2000 iterations=1 run=1
|
|
||||||
|
|
||||||
...or:
|
% modprobe dmatest channel=dma0chan0 timeout=2000 iterations=1 run=1
|
||||||
% modprobe dmatest
|
|
||||||
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
|
|
||||||
% echo 2000 > /sys/module/dmatest/parameters/timeout
|
|
||||||
% echo 1 > /sys/module/dmatest/parameters/iterations
|
|
||||||
% echo 1 > /sys/module/dmatest/parameters/run
|
|
||||||
|
|
||||||
...or on the kernel command line:
|
...or: ::
|
||||||
|
|
||||||
dmatest.channel=dma0chan0 dmatest.timeout=2000 dmatest.iterations=1 dmatest.run=1
|
% modprobe dmatest
|
||||||
|
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
|
||||||
|
% echo 2000 > /sys/module/dmatest/parameters/timeout
|
||||||
|
% echo 1 > /sys/module/dmatest/parameters/iterations
|
||||||
|
% echo 1 > /sys/module/dmatest/parameters/run
|
||||||
|
|
||||||
Hint: available channel list could be extracted by running the following
|
...or on the kernel command line: ::
|
||||||
command:
|
|
||||||
% ls -1 /sys/class/dma/
|
dmatest.channel=dma0chan0 dmatest.timeout=2000 dmatest.iterations=1 dmatest.run=1
|
||||||
|
|
||||||
|
..hint:: available channel list could be extracted by running the following
|
||||||
|
command:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
% ls -1 /sys/class/dma/
|
||||||
|
|
||||||
Once started a message like "dmatest: Started 1 threads using dma0chan0" is
|
Once started a message like "dmatest: Started 1 threads using dma0chan0" is
|
||||||
emitted. After that only test failure messages are reported until the test
|
emitted. After that only test failure messages are reported until the test
|
||||||
@@ -39,8 +47,9 @@ stops.
|
|||||||
|
|
||||||
Note that running a new test will not stop any in progress test.
|
Note that running a new test will not stop any in progress test.
|
||||||
|
|
||||||
The following command returns the state of the test.
|
The following command returns the state of the test. ::
|
||||||
% cat /sys/module/dmatest/parameters/run
|
|
||||||
|
% cat /sys/module/dmatest/parameters/run
|
||||||
|
|
||||||
To wait for test completion userpace can poll 'run' until it is false, or use
|
To wait for test completion userpace can poll 'run' until it is false, or use
|
||||||
the wait parameter. Specifying 'wait=1' when loading the module causes module
|
the wait parameter. Specifying 'wait=1' when loading the module causes module
|
||||||
@@ -50,15 +59,19 @@ before returning. For example, the following scripts wait for 42 tests
|
|||||||
to complete before exiting. Note that if 'iterations' is set to 'infinite' then
|
to complete before exiting. Note that if 'iterations' is set to 'infinite' then
|
||||||
waiting is disabled.
|
waiting is disabled.
|
||||||
|
|
||||||
Example:
|
Example: ::
|
||||||
% modprobe dmatest run=1 iterations=42 wait=1
|
|
||||||
% modprobe -r dmatest
|
|
||||||
...or:
|
|
||||||
% modprobe dmatest run=1 iterations=42
|
|
||||||
% cat /sys/module/dmatest/parameters/wait
|
|
||||||
% modprobe -r dmatest
|
|
||||||
|
|
||||||
Part 3 - When built-in in the kernel...
|
% modprobe dmatest run=1 iterations=42 wait=1
|
||||||
|
% modprobe -r dmatest
|
||||||
|
|
||||||
|
...or: ::
|
||||||
|
|
||||||
|
% modprobe dmatest run=1 iterations=42
|
||||||
|
% cat /sys/module/dmatest/parameters/wait
|
||||||
|
% modprobe -r dmatest
|
||||||
|
|
||||||
|
Part 3 - When built-in in the kernel
|
||||||
|
====================================
|
||||||
|
|
||||||
The module parameters that is supplied to the kernel command line will be used
|
The module parameters that is supplied to the kernel command line will be used
|
||||||
for the first performed test. After user gets a control, the test could be
|
for the first performed test. After user gets a control, the test could be
|
||||||
@@ -66,27 +79,32 @@ re-run with the same or different parameters. For the details see the above
|
|||||||
section "Part 2 - When dmatest is built as a module..."
|
section "Part 2 - When dmatest is built as a module..."
|
||||||
|
|
||||||
In both cases the module parameters are used as the actual values for the test
|
In both cases the module parameters are used as the actual values for the test
|
||||||
case. You always could check them at run-time by running
|
case. You always could check them at run-time by running ::
|
||||||
% grep -H . /sys/module/dmatest/parameters/*
|
|
||||||
|
|
||||||
Part 4 - Gathering the test results
|
% grep -H . /sys/module/dmatest/parameters/*
|
||||||
|
|
||||||
Test results are printed to the kernel log buffer with the format:
|
Part 4 - Gathering the test results
|
||||||
|
===================================
|
||||||
|
|
||||||
"dmatest: result <channel>: <test id>: '<error msg>' with src_off=<val> dst_off=<val> len=<val> (<err code>)"
|
Test results are printed to the kernel log buffer with the format: ::
|
||||||
|
|
||||||
Example of output:
|
"dmatest: result <channel>: <test id>: '<error msg>' with src_off=<val> dst_off=<val> len=<val> (<err code>)"
|
||||||
% dmesg | tail -n 1
|
|
||||||
dmatest: result dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
|
Example of output: ::
|
||||||
|
|
||||||
|
|
||||||
|
% dmesg | tail -n 1
|
||||||
|
dmatest: result dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
|
||||||
|
|
||||||
The message format is unified across the different types of errors. A number in
|
The message format is unified across the different types of errors. A number in
|
||||||
the parens represents additional information, e.g. error code, error counter,
|
the parens represents additional information, e.g. error code, error counter,
|
||||||
or status. A test thread also emits a summary line at completion listing the
|
or status. A test thread also emits a summary line at completion listing the
|
||||||
number of tests executed, number that failed, and a result code.
|
number of tests executed, number that failed, and a result code.
|
||||||
|
|
||||||
Example:
|
Example: ::
|
||||||
% dmesg | tail -n 1
|
|
||||||
dmatest: dma0chan0-copy0: summary 1 test, 0 failures 1000 iops 100000 KB/s (0)
|
% dmesg | tail -n 1
|
||||||
|
dmatest: dma0chan0-copy0: summary 1 test, 0 failures 1000 iops 100000 KB/s (0)
|
||||||
|
|
||||||
The details of a data miscompare error are also emitted, but do not follow the
|
The details of a data miscompare error are also emitted, but do not follow the
|
||||||
above format.
|
above format.
|
55
Documentation/driver-api/dmaengine/index.rst
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
=======================
|
||||||
|
DMAEngine documentation
|
||||||
|
=======================
|
||||||
|
|
||||||
|
DMAEngine documentation provides documents for various aspects of DMAEngine
|
||||||
|
framework.
|
||||||
|
|
||||||
|
DMAEngine documentation
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
This book helps with DMAengine internal APIs and guide for DMAEngine device
|
||||||
|
driver writers.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
provider
|
||||||
|
|
||||||
|
DMAEngine client documentation
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
This book is a guide to device driver writers on how to use the Slave-DMA
|
||||||
|
API of the DMAEngine. This is applicable only for slave DMA usage only.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
client
|
||||||
|
|
||||||
|
DMA Test documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
This book introduces how to test DMA drivers using dmatest module.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
dmatest
|
||||||
|
|
||||||
|
PXA DMA documentation
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
This book adds some notes about PXA DMA
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
pxa_dma
|
||||||
|
|
||||||
|
.. only:: subproject
|
||||||
|
|
||||||
|
Indices
|
||||||
|
=======
|
||||||
|
|
||||||
|
* :ref:`genindex`
|
508
Documentation/driver-api/dmaengine/provider.rst
Normal file
@@ -0,0 +1,508 @@
|
|||||||
|
==================================
|
||||||
|
DMAengine controller documentation
|
||||||
|
==================================
|
||||||
|
|
||||||
|
Hardware Introduction
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Most of the Slave DMA controllers have the same general principles of
|
||||||
|
operations.
|
||||||
|
|
||||||
|
They have a given number of channels to use for the DMA transfers, and
|
||||||
|
a given number of requests lines.
|
||||||
|
|
||||||
|
Requests and channels are pretty much orthogonal. Channels can be used
|
||||||
|
to serve several to any requests. To simplify, channels are the
|
||||||
|
entities that will be doing the copy, and requests what endpoints are
|
||||||
|
involved.
|
||||||
|
|
||||||
|
The request lines actually correspond to physical lines going from the
|
||||||
|
DMA-eligible devices to the controller itself. Whenever the device
|
||||||
|
will want to start a transfer, it will assert a DMA request (DRQ) by
|
||||||
|
asserting that request line.
|
||||||
|
|
||||||
|
A very simple DMA controller would only take into account a single
|
||||||
|
parameter: the transfer size. At each clock cycle, it would transfer a
|
||||||
|
byte of data from one buffer to another, until the transfer size has
|
||||||
|
been reached.
|
||||||
|
|
||||||
|
That wouldn't work well in the real world, since slave devices might
|
||||||
|
require a specific number of bits to be transferred in a single
|
||||||
|
cycle. For example, we may want to transfer as much data as the
|
||||||
|
physical bus allows to maximize performances when doing a simple
|
||||||
|
memory copy operation, but our audio device could have a narrower FIFO
|
||||||
|
that requires data to be written exactly 16 or 24 bits at a time. This
|
||||||
|
is why most if not all of the DMA controllers can adjust this, using a
|
||||||
|
parameter called the transfer width.
|
||||||
|
|
||||||
|
Moreover, some DMA controllers, whenever the RAM is used as a source
|
||||||
|
or destination, can group the reads or writes in memory into a buffer,
|
||||||
|
so instead of having a lot of small memory accesses, which is not
|
||||||
|
really efficient, you'll get several bigger transfers. This is done
|
||||||
|
using a parameter called the burst size, that defines how many single
|
||||||
|
reads/writes it's allowed to do without the controller splitting the
|
||||||
|
transfer into smaller sub-transfers.
|
||||||
|
|
||||||
|
Our theoretical DMA controller would then only be able to do transfers
|
||||||
|
that involve a single contiguous block of data. However, some of the
|
||||||
|
transfers we usually have are not, and want to copy data from
|
||||||
|
non-contiguous buffers to a contiguous buffer, which is called
|
||||||
|
scatter-gather.
|
||||||
|
|
||||||
|
DMAEngine, at least for mem2dev transfers, require support for
|
||||||
|
scatter-gather. So we're left with two cases here: either we have a
|
||||||
|
quite simple DMA controller that doesn't support it, and we'll have to
|
||||||
|
implement it in software, or we have a more advanced DMA controller,
|
||||||
|
that implements in hardware scatter-gather.
|
||||||
|
|
||||||
|
The latter are usually programmed using a collection of chunks to
|
||||||
|
transfer, and whenever the transfer is started, the controller will go
|
||||||
|
over that collection, doing whatever we programmed there.
|
||||||
|
|
||||||
|
This collection is usually either a table or a linked list. You will
|
||||||
|
then push either the address of the table and its number of elements,
|
||||||
|
or the first item of the list to one channel of the DMA controller,
|
||||||
|
and whenever a DRQ will be asserted, it will go through the collection
|
||||||
|
to know where to fetch the data from.
|
||||||
|
|
||||||
|
Either way, the format of this collection is completely dependent on
|
||||||
|
your hardware. Each DMA controller will require a different structure,
|
||||||
|
but all of them will require, for every chunk, at least the source and
|
||||||
|
destination addresses, whether it should increment these addresses or
|
||||||
|
not and the three parameters we saw earlier: the burst size, the
|
||||||
|
transfer width and the transfer size.
|
||||||
|
|
||||||
|
The one last thing is that usually, slave devices won't issue DRQ by
|
||||||
|
default, and you have to enable this in your slave device driver first
|
||||||
|
whenever you're willing to use DMA.
|
||||||
|
|
||||||
|
These were just the general memory-to-memory (also called mem2mem) or
|
||||||
|
memory-to-device (mem2dev) kind of transfers. Most devices often
|
||||||
|
support other kind of transfers or memory operations that dmaengine
|
||||||
|
support and will be detailed later in this document.
|
||||||
|
|
||||||
|
DMA Support in Linux
|
||||||
|
====================
|
||||||
|
|
||||||
|
Historically, DMA controller drivers have been implemented using the
|
||||||
|
async TX API, to offload operations such as memory copy, XOR,
|
||||||
|
cryptography, etc., basically any memory to memory operation.
|
||||||
|
|
||||||
|
Over time, the need for memory to device transfers arose, and
|
||||||
|
dmaengine was extended. Nowadays, the async TX API is written as a
|
||||||
|
layer on top of dmaengine, and acts as a client. Still, dmaengine
|
||||||
|
accommodates that API in some cases, and made some design choices to
|
||||||
|
ensure that it stayed compatible.
|
||||||
|
|
||||||
|
For more information on the Async TX API, please look the relevant
|
||||||
|
documentation file in Documentation/crypto/async-tx-api.txt.
|
||||||
|
|
||||||
|
DMAEngine APIs
|
||||||
|
==============
|
||||||
|
|
||||||
|
``struct dma_device`` Initialization
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Just like any other kernel framework, the whole DMAEngine registration
|
||||||
|
relies on the driver filling a structure and registering against the
|
||||||
|
framework. In our case, that structure is dma_device.
|
||||||
|
|
||||||
|
The first thing you need to do in your driver is to allocate this
|
||||||
|
structure. Any of the usual memory allocators will do, but you'll also
|
||||||
|
need to initialize a few fields in there:
|
||||||
|
|
||||||
|
- channels: should be initialized as a list using the
|
||||||
|
INIT_LIST_HEAD macro for example
|
||||||
|
|
||||||
|
- src_addr_widths:
|
||||||
|
should contain a bitmask of the supported source transfer width
|
||||||
|
|
||||||
|
- dst_addr_widths:
|
||||||
|
should contain a bitmask of the supported destination transfer width
|
||||||
|
|
||||||
|
- directions:
|
||||||
|
should contain a bitmask of the supported slave directions
|
||||||
|
(i.e. excluding mem2mem transfers)
|
||||||
|
|
||||||
|
- residue_granularity:
|
||||||
|
|
||||||
|
- Granularity of the transfer residue reported to dma_set_residue.
|
||||||
|
This can be either:
|
||||||
|
|
||||||
|
- Descriptor
|
||||||
|
|
||||||
|
- Your device doesn't support any kind of residue
|
||||||
|
reporting. The framework will only know that a particular
|
||||||
|
transaction descriptor is done.
|
||||||
|
|
||||||
|
- Segment
|
||||||
|
|
||||||
|
- Your device is able to report which chunks have been transferred
|
||||||
|
|
||||||
|
- Burst
|
||||||
|
|
||||||
|
- Your device is able to report which burst have been transferred
|
||||||
|
|
||||||
|
- dev: should hold the pointer to the ``struct device`` associated
|
||||||
|
to your current driver instance.
|
||||||
|
|
||||||
|
Supported transaction types
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
The next thing you need is to set which transaction types your device
|
||||||
|
(and driver) supports.
|
||||||
|
|
||||||
|
Our ``dma_device structure`` has a field called cap_mask that holds the
|
||||||
|
various types of transaction supported, and you need to modify this
|
||||||
|
mask using the dma_cap_set function, with various flags depending on
|
||||||
|
transaction types you support as an argument.
|
||||||
|
|
||||||
|
All those capabilities are defined in the ``dma_transaction_type enum``,
|
||||||
|
in ``include/linux/dmaengine.h``
|
||||||
|
|
||||||
|
Currently, the types available are:
|
||||||
|
|
||||||
|
- DMA_MEMCPY
|
||||||
|
|
||||||
|
- The device is able to do memory to memory copies
|
||||||
|
|
||||||
|
- DMA_XOR
|
||||||
|
|
||||||
|
- The device is able to perform XOR operations on memory areas
|
||||||
|
|
||||||
|
- Used to accelerate XOR intensive tasks, such as RAID5
|
||||||
|
|
||||||
|
- DMA_XOR_VAL
|
||||||
|
|
||||||
|
- The device is able to perform parity check using the XOR
|
||||||
|
algorithm against a memory buffer.
|
||||||
|
|
||||||
|
- DMA_PQ
|
||||||
|
|
||||||
|
- The device is able to perform RAID6 P+Q computations, P being a
|
||||||
|
simple XOR, and Q being a Reed-Solomon algorithm.
|
||||||
|
|
||||||
|
- DMA_PQ_VAL
|
||||||
|
|
||||||
|
- The device is able to perform parity check using RAID6 P+Q
|
||||||
|
algorithm against a memory buffer.
|
||||||
|
|
||||||
|
- DMA_INTERRUPT
|
||||||
|
|
||||||
|
- The device is able to trigger a dummy transfer that will
|
||||||
|
generate periodic interrupts
|
||||||
|
|
||||||
|
- Used by the client drivers to register a callback that will be
|
||||||
|
called on a regular basis through the DMA controller interrupt
|
||||||
|
|
||||||
|
- DMA_PRIVATE
|
||||||
|
|
||||||
|
- The devices only supports slave transfers, and as such isn't
|
||||||
|
available for async transfers.
|
||||||
|
|
||||||
|
- DMA_ASYNC_TX
|
||||||
|
|
||||||
|
- Must not be set by the device, and will be set by the framework
|
||||||
|
if needed
|
||||||
|
|
||||||
|
- TODO: What is it about?
|
||||||
|
|
||||||
|
- DMA_SLAVE
|
||||||
|
|
||||||
|
- The device can handle device to memory transfers, including
|
||||||
|
scatter-gather transfers.
|
||||||
|
|
||||||
|
- While in the mem2mem case we were having two distinct types to
|
||||||
|
deal with a single chunk to copy or a collection of them, here,
|
||||||
|
we just have a single transaction type that is supposed to
|
||||||
|
handle both.
|
||||||
|
|
||||||
|
- If you want to transfer a single contiguous memory buffer,
|
||||||
|
simply build a scatter list with only one item.
|
||||||
|
|
||||||
|
- DMA_CYCLIC
|
||||||
|
|
||||||
|
- The device can handle cyclic transfers.
|
||||||
|
|
||||||
|
- A cyclic transfer is a transfer where the chunk collection will
|
||||||
|
loop over itself, with the last item pointing to the first.
|
||||||
|
|
||||||
|
- It's usually used for audio transfers, where you want to operate
|
||||||
|
on a single ring buffer that you will fill with your audio data.
|
||||||
|
|
||||||
|
- DMA_INTERLEAVE
|
||||||
|
|
||||||
|
- The device supports interleaved transfer.
|
||||||
|
|
||||||
|
- These transfers can transfer data from a non-contiguous buffer
|
||||||
|
to a non-contiguous buffer, opposed to DMA_SLAVE that can
|
||||||
|
transfer data from a non-contiguous data set to a continuous
|
||||||
|
destination buffer.
|
||||||
|
|
||||||
|
- It's usually used for 2d content transfers, in which case you
|
||||||
|
want to transfer a portion of uncompressed data directly to the
|
||||||
|
display to print it
|
||||||
|
|
||||||
|
These various types will also affect how the source and destination
|
||||||
|
addresses change over time.
|
||||||
|
|
||||||
|
Addresses pointing to RAM are typically incremented (or decremented)
|
||||||
|
after each transfer. In case of a ring buffer, they may loop
|
||||||
|
(DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO)
|
||||||
|
are typically fixed.
|
||||||
|
|
||||||
|
Device operations
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Our dma_device structure also requires a few function pointers in
|
||||||
|
order to implement the actual logic, now that we described what
|
||||||
|
operations we were able to perform.
|
||||||
|
|
||||||
|
The functions that we have to fill in there, and hence have to
|
||||||
|
implement, obviously depend on the transaction types you reported as
|
||||||
|
supported.
|
||||||
|
|
||||||
|
- ``device_alloc_chan_resources``
|
||||||
|
|
||||||
|
- ``device_free_chan_resources``
|
||||||
|
|
||||||
|
- These functions will be called whenever a driver will call
|
||||||
|
``dma_request_channel`` or ``dma_release_channel`` for the first/last
|
||||||
|
time on the channel associated to that driver.
|
||||||
|
|
||||||
|
- They are in charge of allocating/freeing all the needed
|
||||||
|
resources in order for that channel to be useful for your driver.
|
||||||
|
|
||||||
|
- These functions can sleep.
|
||||||
|
|
||||||
|
- ``device_prep_dma_*``
|
||||||
|
|
||||||
|
- These functions are matching the capabilities you registered
|
||||||
|
previously.
|
||||||
|
|
||||||
|
- These functions all take the buffer or the scatterlist relevant
|
||||||
|
for the transfer being prepared, and should create a hardware
|
||||||
|
descriptor or a list of hardware descriptors from it
|
||||||
|
|
||||||
|
- These functions can be called from an interrupt context
|
||||||
|
|
||||||
|
- Any allocation you might do should be using the GFP_NOWAIT
|
||||||
|
flag, in order not to potentially sleep, but without depleting
|
||||||
|
the emergency pool either.
|
||||||
|
|
||||||
|
- Drivers should try to pre-allocate any memory they might need
|
||||||
|
during the transfer setup at probe time to avoid putting to
|
||||||
|
much pressure on the nowait allocator.
|
||||||
|
|
||||||
|
- It should return a unique instance of the
|
||||||
|
``dma_async_tx_descriptor structure``, that further represents this
|
||||||
|
particular transfer.
|
||||||
|
|
||||||
|
- This structure can be initialized using the function
|
||||||
|
``dma_async_tx_descriptor_init``.
|
||||||
|
|
||||||
|
- You'll also need to set two fields in this structure:
|
||||||
|
|
||||||
|
- flags:
|
||||||
|
TODO: Can it be modified by the driver itself, or
|
||||||
|
should it be always the flags passed in the arguments
|
||||||
|
|
||||||
|
- tx_submit: A pointer to a function you have to implement,
|
||||||
|
that is supposed to push the current transaction descriptor to a
|
||||||
|
pending queue, waiting for issue_pending to be called.
|
||||||
|
|
||||||
|
- In this structure the function pointer callback_result can be
|
||||||
|
initialized in order for the submitter to be notified that a
|
||||||
|
transaction has completed. In the earlier code the function pointer
|
||||||
|
callback has been used. However it does not provide any status to the
|
||||||
|
transaction and will be deprecated. The result structure defined as
|
||||||
|
``dmaengine_result`` that is passed in to callback_result
|
||||||
|
has two fields:
|
||||||
|
|
||||||
|
- result: This provides the transfer result defined by
|
||||||
|
``dmaengine_tx_result``. Either success or some error condition.
|
||||||
|
|
||||||
|
- residue: Provides the residue bytes of the transfer for those that
|
||||||
|
support residue.
|
||||||
|
|
||||||
|
- ``device_issue_pending``
|
||||||
|
|
||||||
|
- Takes the first transaction descriptor in the pending queue,
|
||||||
|
and starts the transfer. Whenever that transfer is done, it
|
||||||
|
should move to the next transaction in the list.
|
||||||
|
|
||||||
|
- This function can be called in an interrupt context
|
||||||
|
|
||||||
|
- ``device_tx_status``
|
||||||
|
|
||||||
|
- Should report the bytes left to go over on the given channel
|
||||||
|
|
||||||
|
- Should only care about the transaction descriptor passed as
|
||||||
|
argument, not the currently active one on a given channel
|
||||||
|
|
||||||
|
- The tx_state argument might be NULL
|
||||||
|
|
||||||
|
- Should use dma_set_residue to report it
|
||||||
|
|
||||||
|
- In the case of a cyclic transfer, it should only take into
|
||||||
|
account the current period.
|
||||||
|
|
||||||
|
- This function can be called in an interrupt context.
|
||||||
|
|
||||||
|
- device_config
|
||||||
|
|
||||||
|
- Reconfigures the channel with the configuration given as argument
|
||||||
|
|
||||||
|
- This command should NOT perform synchronously, or on any
|
||||||
|
currently queued transfers, but only on subsequent ones
|
||||||
|
|
||||||
|
- In this case, the function will receive a ``dma_slave_config``
|
||||||
|
structure pointer as an argument, that will detail which
|
||||||
|
configuration to use.
|
||||||
|
|
||||||
|
- Even though that structure contains a direction field, this
|
||||||
|
field is deprecated in favor of the direction argument given to
|
||||||
|
the prep_* functions
|
||||||
|
|
||||||
|
- This call is mandatory for slave operations only. This should NOT be
|
||||||
|
set or expected to be set for memcpy operations.
|
||||||
|
If a driver support both, it should use this call for slave
|
||||||
|
operations only and not for memcpy ones.
|
||||||
|
|
||||||
|
- device_pause
|
||||||
|
|
||||||
|
- Pauses a transfer on the channel
|
||||||
|
|
||||||
|
- This command should operate synchronously on the channel,
|
||||||
|
pausing right away the work of the given channel
|
||||||
|
|
||||||
|
- device_resume
|
||||||
|
|
||||||
|
- Resumes a transfer on the channel
|
||||||
|
|
||||||
|
- This command should operate synchronously on the channel,
|
||||||
|
resuming right away the work of the given channel
|
||||||
|
|
||||||
|
- device_terminate_all
|
||||||
|
|
||||||
|
- Aborts all the pending and ongoing transfers on the channel
|
||||||
|
|
||||||
|
- For aborted transfers the complete callback should not be called
|
||||||
|
|
||||||
|
- Can be called from atomic context or from within a complete
|
||||||
|
callback of a descriptor. Must not sleep. Drivers must be able
|
||||||
|
to handle this correctly.
|
||||||
|
|
||||||
|
- Termination may be asynchronous. The driver does not have to
|
||||||
|
wait until the currently active transfer has completely stopped.
|
||||||
|
See device_synchronize.
|
||||||
|
|
||||||
|
- device_synchronize
|
||||||
|
|
||||||
|
- Must synchronize the termination of a channel to the current
|
||||||
|
context.
|
||||||
|
|
||||||
|
- Must make sure that memory for previously submitted
|
||||||
|
descriptors is no longer accessed by the DMA controller.
|
||||||
|
|
||||||
|
- Must make sure that all complete callbacks for previously
|
||||||
|
submitted descriptors have finished running and none are
|
||||||
|
scheduled to run.
|
||||||
|
|
||||||
|
- May sleep.
|
||||||
|
|
||||||
|
|
||||||
|
Misc notes
|
||||||
|
==========
|
||||||
|
|
||||||
|
(stuff that should be documented, but don't really know
|
||||||
|
where to put them)
|
||||||
|
|
||||||
|
``dma_run_dependencies``
|
||||||
|
|
||||||
|
- Should be called at the end of an async TX transfer, and can be
|
||||||
|
ignored in the slave transfers case.
|
||||||
|
|
||||||
|
- Makes sure that dependent operations are run before marking it
|
||||||
|
as complete.
|
||||||
|
|
||||||
|
dma_cookie_t
|
||||||
|
|
||||||
|
- it's a DMA transaction ID that will increment over time.
|
||||||
|
|
||||||
|
- Not really relevant any more since the introduction of ``virt-dma``
|
||||||
|
that abstracts it away.
|
||||||
|
|
||||||
|
DMA_CTRL_ACK
|
||||||
|
|
||||||
|
- If clear, the descriptor cannot be reused by provider until the
|
||||||
|
client acknowledges receipt, i.e. has has a chance to establish any
|
||||||
|
dependency chains
|
||||||
|
|
||||||
|
- This can be acked by invoking async_tx_ack()
|
||||||
|
|
||||||
|
- If set, does not mean descriptor can be reused
|
||||||
|
|
||||||
|
DMA_CTRL_REUSE
|
||||||
|
|
||||||
|
- If set, the descriptor can be reused after being completed. It should
|
||||||
|
not be freed by provider if this flag is set.
|
||||||
|
|
||||||
|
- The descriptor should be prepared for reuse by invoking
|
||||||
|
``dmaengine_desc_set_reuse()`` which will set DMA_CTRL_REUSE.
|
||||||
|
|
||||||
|
- ``dmaengine_desc_set_reuse()`` will succeed only when channel support
|
||||||
|
reusable descriptor as exhibited by capabilities
|
||||||
|
|
||||||
|
- As a consequence, if a device driver wants to skip the
|
||||||
|
``dma_map_sg()`` and ``dma_unmap_sg()`` in between 2 transfers,
|
||||||
|
because the DMA'd data wasn't used, it can resubmit the transfer right after
|
||||||
|
its completion.
|
||||||
|
|
||||||
|
- Descriptor can be freed in few ways
|
||||||
|
|
||||||
|
- Clearing DMA_CTRL_REUSE by invoking
|
||||||
|
``dmaengine_desc_clear_reuse()`` and submitting for last txn
|
||||||
|
|
||||||
|
- Explicitly invoking ``dmaengine_desc_free()``, this can succeed only
|
||||||
|
when DMA_CTRL_REUSE is already set
|
||||||
|
|
||||||
|
- Terminating the channel
|
||||||
|
|
||||||
|
- DMA_PREP_CMD
|
||||||
|
|
||||||
|
- If set, the client driver tells DMA controller that passed data in DMA
|
||||||
|
API is command data.
|
||||||
|
|
||||||
|
- Interpretation of command data is DMA controller specific. It can be
|
||||||
|
used for issuing commands to other peripherals/register reads/register
|
||||||
|
writes for which the descriptor should be in different format from
|
||||||
|
normal data descriptors.
|
||||||
|
|
||||||
|
General Design Notes
|
||||||
|
====================
|
||||||
|
|
||||||
|
Most of the DMAEngine drivers you'll see are based on a similar design
|
||||||
|
that handles the end of transfer interrupts in the handler, but defer
|
||||||
|
most work to a tasklet, including the start of a new transfer whenever
|
||||||
|
the previous transfer ended.
|
||||||
|
|
||||||
|
This is a rather inefficient design though, because the inter-transfer
|
||||||
|
latency will be not only the interrupt latency, but also the
|
||||||
|
scheduling latency of the tasklet, which will leave the channel idle
|
||||||
|
in between, which will slow down the global transfer rate.
|
||||||
|
|
||||||
|
You should avoid this kind of practice, and instead of electing a new
|
||||||
|
transfer in your tasklet, move that part to the interrupt handler in
|
||||||
|
order to have a shorter idle window (that we can't really avoid
|
||||||
|
anyway).
|
||||||
|
|
||||||
|
Glossary
|
||||||
|
========
|
||||||
|
|
||||||
|
- Burst: A number of consecutive read or write operations that
|
||||||
|
can be queued to buffers before being flushed to memory.
|
||||||
|
|
||||||
|
- Chunk: A contiguous collection of bursts
|
||||||
|
|
||||||
|
- Transfer: A collection of chunks (be it contiguous or not)
|
190
Documentation/driver-api/dmaengine/pxa_dma.rst
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
==============================
|
||||||
|
PXA/MMP - DMA Slave controller
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Constraints
|
||||||
|
===========
|
||||||
|
|
||||||
|
a) Transfers hot queuing
|
||||||
|
A driver submitting a transfer and issuing it should be granted the transfer
|
||||||
|
is queued even on a running DMA channel.
|
||||||
|
This implies that the queuing doesn't wait for the previous transfer end,
|
||||||
|
and that the descriptor chaining is not only done in the irq/tasklet code
|
||||||
|
triggered by the end of the transfer.
|
||||||
|
A transfer which is submitted and issued on a phy doesn't wait for a phy to
|
||||||
|
stop and restart, but is submitted on a "running channel". The other
|
||||||
|
drivers, especially mmp_pdma waited for the phy to stop before relaunching
|
||||||
|
a new transfer.
|
||||||
|
|
||||||
|
b) All transfers having asked for confirmation should be signaled
|
||||||
|
Any issued transfer with DMA_PREP_INTERRUPT should trigger a callback call.
|
||||||
|
This implies that even if an irq/tasklet is triggered by end of tx1, but
|
||||||
|
at the time of irq/dma tx2 is already finished, tx1->complete() and
|
||||||
|
tx2->complete() should be called.
|
||||||
|
|
||||||
|
c) Channel running state
|
||||||
|
A driver should be able to query if a channel is running or not. For the
|
||||||
|
multimedia case, such as video capture, if a transfer is submitted and then
|
||||||
|
a check of the DMA channel reports a "stopped channel", the transfer should
|
||||||
|
not be issued until the next "start of frame interrupt", hence the need to
|
||||||
|
know if a channel is in running or stopped state.
|
||||||
|
|
||||||
|
d) Bandwidth guarantee
|
||||||
|
The PXA architecture has 4 levels of DMAs priorities : high, normal, low.
|
||||||
|
The high priorities get twice as much bandwidth as the normal, which get twice
|
||||||
|
as much as the low priorities.
|
||||||
|
A driver should be able to request a priority, especially the real-time
|
||||||
|
ones such as pxa_camera with (big) throughputs.
|
||||||
|
|
||||||
|
Design
|
||||||
|
======
|
||||||
|
a) Virtual channels
|
||||||
|
Same concept as in sa11x0 driver, ie. a driver was assigned a "virtual
|
||||||
|
channel" linked to the requestor line, and the physical DMA channel is
|
||||||
|
assigned on the fly when the transfer is issued.
|
||||||
|
|
||||||
|
b) Transfer anatomy for a scatter-gather transfer
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
+------------+-----+---------------+----------------+-----------------+
|
||||||
|
| desc-sg[0] | ... | desc-sg[last] | status updater | finisher/linker |
|
||||||
|
+------------+-----+---------------+----------------+-----------------+
|
||||||
|
|
||||||
|
This structure is pointed by dma->sg_cpu.
|
||||||
|
The descriptors are used as follows :
|
||||||
|
|
||||||
|
- desc-sg[i]: i-th descriptor, transferring the i-th sg
|
||||||
|
element to the video buffer scatter gather
|
||||||
|
|
||||||
|
- status updater
|
||||||
|
Transfers a single u32 to a well known dma coherent memory to leave
|
||||||
|
a trace that this transfer is done. The "well known" is unique per
|
||||||
|
physical channel, meaning that a read of this value will tell which
|
||||||
|
is the last finished transfer at that point in time.
|
||||||
|
|
||||||
|
- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
|
||||||
|
|
||||||
|
- linker: has ddadr= desc-sg[0] of next transfer, dcmd=0
|
||||||
|
|
||||||
|
c) Transfers hot-chaining
|
||||||
|
Suppose the running chain is:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Buffer 1 Buffer 2
|
||||||
|
+---------+----+---+ +----+----+----+---+
|
||||||
|
| d0 | .. | dN | l | | d0 | .. | dN | f |
|
||||||
|
+---------+----+-|-+ ^----+----+----+---+
|
||||||
|
| |
|
||||||
|
+----+
|
||||||
|
|
||||||
|
After a call to dmaengine_submit(b3), the chain will look like:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Buffer 1 Buffer 2 Buffer 3
|
||||||
|
+---------+----+---+ +----+----+----+---+ +----+----+----+---+
|
||||||
|
| d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f |
|
||||||
|
+---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+
|
||||||
|
| | | |
|
||||||
|
+----+ +----+
|
||||||
|
new_link
|
||||||
|
|
||||||
|
If while new_link was created the DMA channel stopped, it is _not_
|
||||||
|
restarted. Hot-chaining doesn't break the assumption that
|
||||||
|
dma_async_issue_pending() is to be used to ensure the transfer is actually started.
|
||||||
|
|
||||||
|
One exception to this rule :
|
||||||
|
|
||||||
|
- if Buffer1 and Buffer2 had all their addresses 8 bytes aligned
|
||||||
|
|
||||||
|
- and if Buffer3 has at least one address not 4 bytes aligned
|
||||||
|
|
||||||
|
- then hot-chaining cannot happen, as the channel must be stopped, the
|
||||||
|
"align bit" must be set, and the channel restarted As a consequence,
|
||||||
|
such a transfer tx_submit() will be queued on the submitted queue, and
|
||||||
|
this specific case if the DMA is already running in aligned mode.
|
||||||
|
|
||||||
|
d) Transfers completion updater
|
||||||
|
Each time a transfer is completed on a channel, an interrupt might be
|
||||||
|
generated or not, up to the client's request. But in each case, the last
|
||||||
|
descriptor of a transfer, the "status updater", will write the latest
|
||||||
|
transfer being completed into the physical channel's completion mark.
|
||||||
|
|
||||||
|
This will speed up residue calculation, for large transfers such as video
|
||||||
|
buffers which hold around 6k descriptors or more. This also allows without
|
||||||
|
any lock to find out what is the latest completed transfer in a running
|
||||||
|
DMA chain.
|
||||||
|
|
||||||
|
e) Transfers completion, irq and tasklet
|
||||||
|
When a transfer flagged as "DMA_PREP_INTERRUPT" is finished, the dma irq
|
||||||
|
is raised. Upon this interrupt, a tasklet is scheduled for the physical
|
||||||
|
channel.
|
||||||
|
|
||||||
|
The tasklet is responsible for :
|
||||||
|
|
||||||
|
- reading the physical channel last updater mark
|
||||||
|
|
||||||
|
- calling all the transfer callbacks of finished transfers, based on
|
||||||
|
that mark, and each transfer flags.
|
||||||
|
|
||||||
|
If a transfer is completed while this handling is done, a dma irq will
|
||||||
|
be raised, and the tasklet will be scheduled once again, having a new
|
||||||
|
updater mark.
|
||||||
|
|
||||||
|
f) Residue
|
||||||
|
Residue granularity will be descriptor based. The issued but not completed
|
||||||
|
transfers will be scanned for all of their descriptors against the
|
||||||
|
currently running descriptor.
|
||||||
|
|
||||||
|
g) Most complicated case of driver's tx queues
|
||||||
|
The most tricky situation is when :
|
||||||
|
|
||||||
|
- there are not "acked" transfers (tx0)
|
||||||
|
|
||||||
|
- a driver submitted an aligned tx1, not chained
|
||||||
|
|
||||||
|
- a driver submitted an aligned tx2 => tx2 is cold chained to tx1
|
||||||
|
|
||||||
|
- a driver issued tx1+tx2 => channel is running in aligned mode
|
||||||
|
|
||||||
|
- a driver submitted an aligned tx3 => tx3 is hot-chained
|
||||||
|
|
||||||
|
- a driver submitted an unaligned tx4 => tx4 is put in submitted queue,
|
||||||
|
not chained
|
||||||
|
|
||||||
|
- a driver issued tx4 => tx4 is put in issued queue, not chained
|
||||||
|
|
||||||
|
- a driver submitted an aligned tx5 => tx5 is put in submitted queue, not
|
||||||
|
chained
|
||||||
|
|
||||||
|
- a driver submitted an aligned tx6 => tx6 is put in submitted queue,
|
||||||
|
cold chained to tx5
|
||||||
|
|
||||||
|
This translates into (after tx4 is issued) :
|
||||||
|
|
||||||
|
- issued queue
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
+-----+ +-----+ +-----+ +-----+
|
||||||
|
| tx1 | | tx2 | | tx3 | | tx4 |
|
||||||
|
+---|-+ ^---|-+ ^-----+ +-----+
|
||||||
|
| | | |
|
||||||
|
+---+ +---+
|
||||||
|
- submitted queue
|
||||||
|
+-----+ +-----+
|
||||||
|
| tx5 | | tx6 |
|
||||||
|
+---|-+ ^-----+
|
||||||
|
| |
|
||||||
|
+---+
|
||||||
|
|
||||||
|
- completed queue : empty
|
||||||
|
|
||||||
|
- allocated queue : tx0
|
||||||
|
|
||||||
|
It should be noted that after tx3 is completed, the channel is stopped, and
|
||||||
|
restarted in "unaligned mode" to handle tx4.
|
||||||
|
|
||||||
|
Author: Robert Jarzmik <robert.jarzmik@free.fr>
|
@@ -46,6 +46,7 @@ available subsections can be seen below.
|
|||||||
pinctl
|
pinctl
|
||||||
gpio
|
gpio
|
||||||
misc_devices
|
misc_devices
|
||||||
|
dmaengine/index
|
||||||
|
|
||||||
.. only:: subproject and html
|
.. only:: subproject and html
|
||||||
|
|
||||||
|
@@ -690,9 +690,7 @@ The USB devices are now exported via debugfs:
|
|||||||
This file is handy for status viewing tools in user mode, which can scan
|
This file is handy for status viewing tools in user mode, which can scan
|
||||||
the text format and ignore most of it. More detailed device status
|
the text format and ignore most of it. More detailed device status
|
||||||
(including class and vendor status) is available from device-specific
|
(including class and vendor status) is available from device-specific
|
||||||
files. For information about the current format of this file, see the
|
files. For information about the current format of this file, see below.
|
||||||
``Documentation/usb/proc_usb_info.txt`` file in your Linux kernel
|
|
||||||
sources.
|
|
||||||
|
|
||||||
This file, in combination with the poll() system call, can also be used
|
This file, in combination with the poll() system call, can also be used
|
||||||
to detect when devices are added or removed::
|
to detect when devices are added or removed::
|
||||||
|
@@ -6,41 +6,11 @@ specified notifier chain callbacks. It is useful to test the error handling of
|
|||||||
notifier call chain failures which is rarely executed. There are kernel
|
notifier call chain failures which is rarely executed. There are kernel
|
||||||
modules that can be used to test the following notifiers.
|
modules that can be used to test the following notifiers.
|
||||||
|
|
||||||
* CPU notifier
|
|
||||||
* PM notifier
|
* PM notifier
|
||||||
* Memory hotplug notifier
|
* Memory hotplug notifier
|
||||||
* powerpc pSeries reconfig notifier
|
* powerpc pSeries reconfig notifier
|
||||||
* Netdevice notifier
|
* Netdevice notifier
|
||||||
|
|
||||||
CPU notifier error injection module
|
|
||||||
-----------------------------------
|
|
||||||
This feature can be used to test the error handling of the CPU notifiers by
|
|
||||||
injecting artificial errors to CPU notifier chain callbacks.
|
|
||||||
|
|
||||||
If the notifier call chain should be failed with some events notified, write
|
|
||||||
the error code to debugfs interface
|
|
||||||
/sys/kernel/debug/notifier-error-inject/cpu/actions/<notifier event>/error
|
|
||||||
|
|
||||||
Possible CPU notifier events to be failed are:
|
|
||||||
|
|
||||||
* CPU_UP_PREPARE
|
|
||||||
* CPU_UP_PREPARE_FROZEN
|
|
||||||
* CPU_DOWN_PREPARE
|
|
||||||
* CPU_DOWN_PREPARE_FROZEN
|
|
||||||
|
|
||||||
Example1: Inject CPU offline error (-1 == -EPERM)
|
|
||||||
|
|
||||||
# cd /sys/kernel/debug/notifier-error-inject/cpu
|
|
||||||
# echo -1 > actions/CPU_DOWN_PREPARE/error
|
|
||||||
# echo 0 > /sys/devices/system/cpu/cpu1/online
|
|
||||||
bash: echo: write error: Operation not permitted
|
|
||||||
|
|
||||||
Example2: inject CPU online error (-2 == -ENOENT)
|
|
||||||
|
|
||||||
# echo -2 > actions/CPU_UP_PREPARE/error
|
|
||||||
# echo 1 > /sys/devices/system/cpu/cpu1/online
|
|
||||||
bash: echo: write error: No such file or directory
|
|
||||||
|
|
||||||
PM notifier error injection module
|
PM notifier error injection module
|
||||||
----------------------------------
|
----------------------------------
|
||||||
This feature is controlled through debugfs interface
|
This feature is controlled through debugfs interface
|
||||||
|
@@ -77,8 +77,8 @@ C. Boot options
|
|||||||
1. fbcon=font:<name>
|
1. fbcon=font:<name>
|
||||||
|
|
||||||
Select the initial font to use. The value 'name' can be any of the
|
Select the initial font to use. The value 'name' can be any of the
|
||||||
compiled-in fonts: VGA8x16, 7x14, 10x18, VGA8x8, MINI4x6, RomanLarge,
|
compiled-in fonts: 10x18, 6x10, 7x14, Acorn8x8, MINI4x6,
|
||||||
SUN8x16, SUN12x22, ProFont6x11, Acorn8x8, PEARL8x8.
|
PEARL8x8, ProFont6x11, SUN12x22, SUN8x16, VGA8x16, VGA8x8.
|
||||||
|
|
||||||
Note, not all drivers can handle font with widths not divisible by 8,
|
Note, not all drivers can handle font with widths not divisible by 8,
|
||||||
such as vga16fb.
|
such as vga16fb.
|
||||||
|
@@ -34,6 +34,6 @@
|
|||||||
| tile: | TODO |
|
| tile: | TODO |
|
||||||
| um: | TODO |
|
| um: | TODO |
|
||||||
| unicore32: | TODO |
|
| unicore32: | TODO |
|
||||||
| x86: | ok |
|
| x86: | ok | 64-bit only
|
||||||
| xtensa: | TODO |
|
| xtensa: | TODO |
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@@ -62,7 +62,7 @@ disabled, fcntl(fd, F_NOTIFY, ...) will return -EINVAL.
|
|||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
See Documentation/filesystems/dnotify_test.c for an example.
|
See tools/testing/selftests/filesystems/dnotify_test.c for an example.
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
----
|
----
|
||||||
|
@@ -94,10 +94,10 @@ Note: More extensive information for getting started with ext4 can be
|
|||||||
* ability to pack bitmaps and inode tables into larger virtual groups via the
|
* ability to pack bitmaps and inode tables into larger virtual groups via the
|
||||||
flex_bg feature
|
flex_bg feature
|
||||||
* large file support
|
* large file support
|
||||||
* Inode allocation using large virtual block groups via flex_bg
|
* inode allocation using large virtual block groups via flex_bg
|
||||||
* delayed allocation
|
* delayed allocation
|
||||||
* large block (up to pagesize) support
|
* large block (up to pagesize) support
|
||||||
* efficient new ordered mode in JBD2 and ext4(avoid using buffer head to force
|
* efficient new ordered mode in JBD2 and ext4 (avoid using buffer head to force
|
||||||
the ordering)
|
the ordering)
|
||||||
|
|
||||||
[1] Filesystems with a block size of 1k may see a limit imposed by the
|
[1] Filesystems with a block size of 1k may see a limit imposed by the
|
||||||
@@ -105,7 +105,7 @@ directory hash tree having a maximum depth of two.
|
|||||||
|
|
||||||
2.2 Candidate features for future inclusion
|
2.2 Candidate features for future inclusion
|
||||||
|
|
||||||
* Online defrag (patches available but not well tested)
|
* online defrag (patches available but not well tested)
|
||||||
* reduced mke2fs time via lazy itable initialization in conjunction with
|
* reduced mke2fs time via lazy itable initialization in conjunction with
|
||||||
the uninit_bg feature (capability to do this is available in e2fsprogs
|
the uninit_bg feature (capability to do this is available in e2fsprogs
|
||||||
but a kernel thread to do lazy zeroing of unused inode table blocks
|
but a kernel thread to do lazy zeroing of unused inode table blocks
|
||||||
@@ -602,7 +602,7 @@ Table of Ext4 specific ioctls
|
|||||||
bitmaps and inode table, the userspace tool thus
|
bitmaps and inode table, the userspace tool thus
|
||||||
just passes the new number of blocks.
|
just passes the new number of blocks.
|
||||||
|
|
||||||
EXT4_IOC_SWAP_BOOT Swap i_blocks and associated attributes
|
EXT4_IOC_SWAP_BOOT Swap i_blocks and associated attributes
|
||||||
(like i_blocks, i_size, i_flags, ...) from
|
(like i_blocks, i_size, i_flags, ...) from
|
||||||
the specified inode with inode
|
the specified inode with inode
|
||||||
EXT4_BOOT_LOADER_INO (#5). This is typically
|
EXT4_BOOT_LOADER_INO (#5). This is typically
|
||||||
|
@@ -826,9 +826,9 @@ If the filesystem may need to revalidate dcache entries, then
|
|||||||
*is* passed the dentry but does not have access to the `inode` or the
|
*is* passed the dentry but does not have access to the `inode` or the
|
||||||
`seq` number from the `nameidata`, so it needs to be extra careful
|
`seq` number from the `nameidata`, so it needs to be extra careful
|
||||||
when accessing fields in the dentry. This "extra care" typically
|
when accessing fields in the dentry. This "extra care" typically
|
||||||
involves using `ACCESS_ONCE()` or the newer [`READ_ONCE()`] to access
|
involves using [`READ_ONCE()`] to access fields, and verifying the
|
||||||
fields, and verifying the result is not NULL before using it. This
|
result is not NULL before using it. This pattern can be seen in
|
||||||
pattern can be see in `nfs_lookup_revalidate()`.
|
`nfs_lookup_revalidate()`.
|
||||||
|
|
||||||
A pair of patterns
|
A pair of patterns
|
||||||
------------------
|
------------------
|
||||||
|
@@ -12,7 +12,7 @@ To support these disparate requirements, the Linux USB system provides
|
|||||||
HID events to two separate interfaces:
|
HID events to two separate interfaces:
|
||||||
* the input subsystem, which converts HID events into normal input
|
* the input subsystem, which converts HID events into normal input
|
||||||
device interfaces (such as keyboard, mouse and joystick) and a
|
device interfaces (such as keyboard, mouse and joystick) and a
|
||||||
normalised event interface - see Documentation/input/input.txt
|
normalised event interface - see Documentation/input/input.rst
|
||||||
* the hiddev interface, which provides fairly raw HID events
|
* the hiddev interface, which provides fairly raw HID events
|
||||||
|
|
||||||
The data flow for a HID event produced by a device is something like
|
The data flow for a HID event produced by a device is something like
|
||||||
|
51
Documentation/hwmon/max31785
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
Kernel driver max31785
|
||||||
|
======================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Maxim MAX31785, MAX31785A
|
||||||
|
Prefix: 'max31785' or 'max31785a'
|
||||||
|
Addresses scanned: -
|
||||||
|
Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
|
||||||
|
|
||||||
|
Author: Andrew Jeffery <andrew@aj.id.au>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan
|
||||||
|
management with temperature and remote voltage sensing. Various fan control
|
||||||
|
features are provided, including PWM frequency control, temperature hysteresis,
|
||||||
|
dual tachometer measurements, and fan health monitoring.
|
||||||
|
|
||||||
|
For dual rotor fan configuration, the MAX31785 exposes the slowest rotor of the
|
||||||
|
two in the fan[1-4]_input attributes.
|
||||||
|
|
||||||
|
Usage Notes
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver does not probe for PMBus devices. You will have to instantiate
|
||||||
|
devices explicitly.
|
||||||
|
|
||||||
|
Sysfs attributes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
fan[1-4]_alarm Fan alarm.
|
||||||
|
fan[1-4]_fault Fan fault.
|
||||||
|
fan[1-4]_input Fan RPM.
|
||||||
|
|
||||||
|
in[1-6]_crit Critical maximum output voltage
|
||||||
|
in[1-6]_crit_alarm Output voltage critical high alarm
|
||||||
|
in[1-6]_input Measured output voltage
|
||||||
|
in[1-6]_label "vout[18-23]"
|
||||||
|
in[1-6]_lcrit Critical minimum output voltage
|
||||||
|
in[1-6]_lcrit_alarm Output voltage critical low alarm
|
||||||
|
in[1-6]_max Maximum output voltage
|
||||||
|
in[1-6]_max_alarm Output voltage high alarm
|
||||||
|
in[1-6]_min Minimum output voltage
|
||||||
|
in[1-6]_min_alarm Output voltage low alarm
|
||||||
|
|
||||||
|
temp[1-11]_crit Critical high temperature
|
||||||
|
temp[1-11]_crit_alarm Chip temperature critical high alarm
|
||||||
|
temp[1-11]_input Measured temperature
|
||||||
|
temp[1-11]_max Maximum temperature
|
||||||
|
temp[1-11]_max_alarm Chip temperature high alarm
|
@@ -42,8 +42,7 @@ chip. These coefficients are used to internally calibrate the signals from the
|
|||||||
sensors. Disabling the reload of those coefficients allows saving 10ms for each
|
sensors. Disabling the reload of those coefficients allows saving 10ms for each
|
||||||
measurement and decrease power consumption, while losing on precision.
|
measurement and decrease power consumption, while losing on precision.
|
||||||
|
|
||||||
Some options may be set directly in the sht15_platform_data structure
|
Some options may be set via sysfs attributes.
|
||||||
or via sysfs attributes.
|
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
* The regulator supply name is set to "vcc".
|
* The regulator supply name is set to "vcc".
|
||||||
|
@@ -230,4 +230,5 @@ Historic Edits
|
|||||||
2005-03-19 - Dominic Cerquetti <binary1230@yahoo.com>
|
2005-03-19 - Dominic Cerquetti <binary1230@yahoo.com>
|
||||||
- added stuff for dance pads, new d-pad->axes mappings
|
- added stuff for dance pads, new d-pad->axes mappings
|
||||||
|
|
||||||
Later changes may be viewed with 'git log Documentation/input/xpad.txt'
|
Later changes may be viewed with
|
||||||
|
'git log --follow Documentation/input/devices/xpad.rst'
|
||||||
|
@@ -8,7 +8,7 @@ Kernel Probes (Kprobes)
|
|||||||
|
|
||||||
.. CONTENTS
|
.. CONTENTS
|
||||||
|
|
||||||
1. Concepts: Kprobes, Jprobes, Return Probes
|
1. Concepts: Kprobes, and Return Probes
|
||||||
2. Architectures Supported
|
2. Architectures Supported
|
||||||
3. Configuring Kprobes
|
3. Configuring Kprobes
|
||||||
4. API Reference
|
4. API Reference
|
||||||
@@ -16,12 +16,12 @@ Kernel Probes (Kprobes)
|
|||||||
6. Probe Overhead
|
6. Probe Overhead
|
||||||
7. TODO
|
7. TODO
|
||||||
8. Kprobes Example
|
8. Kprobes Example
|
||||||
9. Jprobes Example
|
9. Kretprobes Example
|
||||||
10. Kretprobes Example
|
10. Deprecated Features
|
||||||
Appendix A: The kprobes debugfs interface
|
Appendix A: The kprobes debugfs interface
|
||||||
Appendix B: The kprobes sysctl interface
|
Appendix B: The kprobes sysctl interface
|
||||||
|
|
||||||
Concepts: Kprobes, Jprobes, Return Probes
|
Concepts: Kprobes and Return Probes
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
Kprobes enables you to dynamically break into any kernel routine and
|
Kprobes enables you to dynamically break into any kernel routine and
|
||||||
@@ -32,12 +32,10 @@ routine to be invoked when the breakpoint is hit.
|
|||||||
.. [1] some parts of the kernel code can not be trapped, see
|
.. [1] some parts of the kernel code can not be trapped, see
|
||||||
:ref:`kprobes_blacklist`)
|
:ref:`kprobes_blacklist`)
|
||||||
|
|
||||||
There are currently three types of probes: kprobes, jprobes, and
|
There are currently two types of probes: kprobes, and kretprobes
|
||||||
kretprobes (also called return probes). A kprobe can be inserted
|
(also called return probes). A kprobe can be inserted on virtually
|
||||||
on virtually any instruction in the kernel. A jprobe is inserted at
|
any instruction in the kernel. A return probe fires when a specified
|
||||||
the entry to a kernel function, and provides convenient access to the
|
function returns.
|
||||||
function's arguments. A return probe fires when a specified function
|
|
||||||
returns.
|
|
||||||
|
|
||||||
In the typical case, Kprobes-based instrumentation is packaged as
|
In the typical case, Kprobes-based instrumentation is packaged as
|
||||||
a kernel module. The module's init function installs ("registers")
|
a kernel module. The module's init function installs ("registers")
|
||||||
@@ -82,45 +80,6 @@ After the instruction is single-stepped, Kprobes executes the
|
|||||||
"post_handler," if any, that is associated with the kprobe.
|
"post_handler," if any, that is associated with the kprobe.
|
||||||
Execution then continues with the instruction following the probepoint.
|
Execution then continues with the instruction following the probepoint.
|
||||||
|
|
||||||
How Does a Jprobe Work?
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
A jprobe is implemented using a kprobe that is placed on a function's
|
|
||||||
entry point. It employs a simple mirroring principle to allow
|
|
||||||
seamless access to the probed function's arguments. The jprobe
|
|
||||||
handler routine should have the same signature (arg list and return
|
|
||||||
type) as the function being probed, and must always end by calling
|
|
||||||
the Kprobes function jprobe_return().
|
|
||||||
|
|
||||||
Here's how it works. When the probe is hit, Kprobes makes a copy of
|
|
||||||
the saved registers and a generous portion of the stack (see below).
|
|
||||||
Kprobes then points the saved instruction pointer at the jprobe's
|
|
||||||
handler routine, and returns from the trap. As a result, control
|
|
||||||
passes to the handler, which is presented with the same register and
|
|
||||||
stack contents as the probed function. When it is done, the handler
|
|
||||||
calls jprobe_return(), which traps again to restore the original stack
|
|
||||||
contents and processor state and switch to the probed function.
|
|
||||||
|
|
||||||
By convention, the callee owns its arguments, so gcc may produce code
|
|
||||||
that unexpectedly modifies that portion of the stack. This is why
|
|
||||||
Kprobes saves a copy of the stack and restores it after the jprobe
|
|
||||||
handler has run. Up to MAX_STACK_SIZE bytes are copied -- e.g.,
|
|
||||||
64 bytes on i386.
|
|
||||||
|
|
||||||
Note that the probed function's args may be passed on the stack
|
|
||||||
or in registers. The jprobe will work in either case, so long as the
|
|
||||||
handler's prototype matches that of the probed function.
|
|
||||||
|
|
||||||
Note that in some architectures (e.g.: arm64 and sparc64) the stack
|
|
||||||
copy is not done, as the actual location of stacked parameters may be
|
|
||||||
outside of a reasonable MAX_STACK_SIZE value and because that location
|
|
||||||
cannot be determined by the jprobes code. In this case the jprobes
|
|
||||||
user must be careful to make certain the calling signature of the
|
|
||||||
function does not cause parameters to be passed on the stack (e.g.:
|
|
||||||
more than eight function arguments, an argument of more than sixteen
|
|
||||||
bytes, or more than 64 bytes of argument data, depending on
|
|
||||||
architecture).
|
|
||||||
|
|
||||||
Return Probes
|
Return Probes
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@@ -245,8 +204,7 @@ Pre-optimization
|
|||||||
After preparing the detour buffer, Kprobes verifies that none of the
|
After preparing the detour buffer, Kprobes verifies that none of the
|
||||||
following situations exist:
|
following situations exist:
|
||||||
|
|
||||||
- The probe has either a break_handler (i.e., it's a jprobe) or a
|
- The probe has a post_handler.
|
||||||
post_handler.
|
|
||||||
- Other instructions in the optimized region are probed.
|
- Other instructions in the optimized region are probed.
|
||||||
- The probe is disabled.
|
- The probe is disabled.
|
||||||
|
|
||||||
@@ -331,7 +289,7 @@ rejects registering it, if the given address is in the blacklist.
|
|||||||
Architectures Supported
|
Architectures Supported
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Kprobes, jprobes, and return probes are implemented on the following
|
Kprobes and return probes are implemented on the following
|
||||||
architectures:
|
architectures:
|
||||||
|
|
||||||
- i386 (Supports jump optimization)
|
- i386 (Supports jump optimization)
|
||||||
@@ -446,27 +404,6 @@ architecture-specific trap number associated with the fault (e.g.,
|
|||||||
on i386, 13 for a general protection fault or 14 for a page fault).
|
on i386, 13 for a general protection fault or 14 for a page fault).
|
||||||
Returns 1 if it successfully handled the exception.
|
Returns 1 if it successfully handled the exception.
|
||||||
|
|
||||||
register_jprobe
|
|
||||||
---------------
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
#include <linux/kprobes.h>
|
|
||||||
int register_jprobe(struct jprobe *jp)
|
|
||||||
|
|
||||||
Sets a breakpoint at the address jp->kp.addr, which must be the address
|
|
||||||
of the first instruction of a function. When the breakpoint is hit,
|
|
||||||
Kprobes runs the handler whose address is jp->entry.
|
|
||||||
|
|
||||||
The handler should have the same arg list and return type as the probed
|
|
||||||
function; and just before it returns, it must call jprobe_return().
|
|
||||||
(The handler never actually returns, since jprobe_return() returns
|
|
||||||
control to Kprobes.) If the probed function is declared asmlinkage
|
|
||||||
or anything else that affects how args are passed, the handler's
|
|
||||||
declaration must match.
|
|
||||||
|
|
||||||
register_jprobe() returns 0 on success, or a negative errno otherwise.
|
|
||||||
|
|
||||||
register_kretprobe
|
register_kretprobe
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@@ -513,7 +450,6 @@ unregister_*probe
|
|||||||
|
|
||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
void unregister_kprobe(struct kprobe *kp);
|
void unregister_kprobe(struct kprobe *kp);
|
||||||
void unregister_jprobe(struct jprobe *jp);
|
|
||||||
void unregister_kretprobe(struct kretprobe *rp);
|
void unregister_kretprobe(struct kretprobe *rp);
|
||||||
|
|
||||||
Removes the specified probe. The unregister function can be called
|
Removes the specified probe. The unregister function can be called
|
||||||
@@ -532,7 +468,6 @@ register_*probes
|
|||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
int register_kprobes(struct kprobe **kps, int num);
|
int register_kprobes(struct kprobe **kps, int num);
|
||||||
int register_kretprobes(struct kretprobe **rps, int num);
|
int register_kretprobes(struct kretprobe **rps, int num);
|
||||||
int register_jprobes(struct jprobe **jps, int num);
|
|
||||||
|
|
||||||
Registers each of the num probes in the specified array. If any
|
Registers each of the num probes in the specified array. If any
|
||||||
error occurs during registration, all probes in the array, up to
|
error occurs during registration, all probes in the array, up to
|
||||||
@@ -555,7 +490,6 @@ unregister_*probes
|
|||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
void unregister_kprobes(struct kprobe **kps, int num);
|
void unregister_kprobes(struct kprobe **kps, int num);
|
||||||
void unregister_kretprobes(struct kretprobe **rps, int num);
|
void unregister_kretprobes(struct kretprobe **rps, int num);
|
||||||
void unregister_jprobes(struct jprobe **jps, int num);
|
|
||||||
|
|
||||||
Removes each of the num probes in the specified array at once.
|
Removes each of the num probes in the specified array at once.
|
||||||
|
|
||||||
@@ -574,7 +508,6 @@ disable_*probe
|
|||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
int disable_kprobe(struct kprobe *kp);
|
int disable_kprobe(struct kprobe *kp);
|
||||||
int disable_kretprobe(struct kretprobe *rp);
|
int disable_kretprobe(struct kretprobe *rp);
|
||||||
int disable_jprobe(struct jprobe *jp);
|
|
||||||
|
|
||||||
Temporarily disables the specified ``*probe``. You can enable it again by using
|
Temporarily disables the specified ``*probe``. You can enable it again by using
|
||||||
enable_*probe(). You must specify the probe which has been registered.
|
enable_*probe(). You must specify the probe which has been registered.
|
||||||
@@ -587,7 +520,6 @@ enable_*probe
|
|||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
int enable_kprobe(struct kprobe *kp);
|
int enable_kprobe(struct kprobe *kp);
|
||||||
int enable_kretprobe(struct kretprobe *rp);
|
int enable_kretprobe(struct kretprobe *rp);
|
||||||
int enable_jprobe(struct jprobe *jp);
|
|
||||||
|
|
||||||
Enables ``*probe`` which has been disabled by disable_*probe(). You must specify
|
Enables ``*probe`` which has been disabled by disable_*probe(). You must specify
|
||||||
the probe which has been registered.
|
the probe which has been registered.
|
||||||
@@ -595,12 +527,10 @@ the probe which has been registered.
|
|||||||
Kprobes Features and Limitations
|
Kprobes Features and Limitations
|
||||||
================================
|
================================
|
||||||
|
|
||||||
Kprobes allows multiple probes at the same address. Currently,
|
Kprobes allows multiple probes at the same address. Also,
|
||||||
however, there cannot be multiple jprobes on the same function at
|
a probepoint for which there is a post_handler cannot be optimized.
|
||||||
the same time. Also, a probepoint for which there is a jprobe or
|
So if you install a kprobe with a post_handler, at an optimized
|
||||||
a post_handler cannot be optimized. So if you install a jprobe,
|
probepoint, the probepoint will be unoptimized automatically.
|
||||||
or a kprobe with a post_handler, at an optimized probepoint, the
|
|
||||||
probepoint will be unoptimized automatically.
|
|
||||||
|
|
||||||
In general, you can install a probe anywhere in the kernel.
|
In general, you can install a probe anywhere in the kernel.
|
||||||
In particular, you can probe interrupt handlers. Known exceptions
|
In particular, you can probe interrupt handlers. Known exceptions
|
||||||
@@ -662,7 +592,7 @@ We're unaware of other specific cases where this could be a problem.
|
|||||||
If, upon entry to or exit from a function, the CPU is running on
|
If, upon entry to or exit from a function, the CPU is running on
|
||||||
a stack other than that of the current task, registering a return
|
a stack other than that of the current task, registering a return
|
||||||
probe on that function may produce undesirable results. For this
|
probe on that function may produce undesirable results. For this
|
||||||
reason, Kprobes doesn't support return probes (or kprobes or jprobes)
|
reason, Kprobes doesn't support return probes (or kprobes)
|
||||||
on the x86_64 version of __switch_to(); the registration functions
|
on the x86_64 version of __switch_to(); the registration functions
|
||||||
return -EINVAL.
|
return -EINVAL.
|
||||||
|
|
||||||
@@ -706,24 +636,24 @@ Probe Overhead
|
|||||||
On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
|
On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
|
||||||
microseconds to process. Specifically, a benchmark that hits the same
|
microseconds to process. Specifically, a benchmark that hits the same
|
||||||
probepoint repeatedly, firing a simple handler each time, reports 1-2
|
probepoint repeatedly, firing a simple handler each time, reports 1-2
|
||||||
million hits per second, depending on the architecture. A jprobe or
|
million hits per second, depending on the architecture. A return-probe
|
||||||
return-probe hit typically takes 50-75% longer than a kprobe hit.
|
hit typically takes 50-75% longer than a kprobe hit.
|
||||||
When you have a return probe set on a function, adding a kprobe at
|
When you have a return probe set on a function, adding a kprobe at
|
||||||
the entry to that function adds essentially no overhead.
|
the entry to that function adds essentially no overhead.
|
||||||
|
|
||||||
Here are sample overhead figures (in usec) for different architectures::
|
Here are sample overhead figures (in usec) for different architectures::
|
||||||
|
|
||||||
k = kprobe; j = jprobe; r = return probe; kr = kprobe + return probe
|
k = kprobe; r = return probe; kr = kprobe + return probe
|
||||||
on same function; jr = jprobe + return probe on same function::
|
on same function
|
||||||
|
|
||||||
i386: Intel Pentium M, 1495 MHz, 2957.31 bogomips
|
i386: Intel Pentium M, 1495 MHz, 2957.31 bogomips
|
||||||
k = 0.57 usec; j = 1.00; r = 0.92; kr = 0.99; jr = 1.40
|
k = 0.57 usec; r = 0.92; kr = 0.99
|
||||||
|
|
||||||
x86_64: AMD Opteron 246, 1994 MHz, 3971.48 bogomips
|
x86_64: AMD Opteron 246, 1994 MHz, 3971.48 bogomips
|
||||||
k = 0.49 usec; j = 0.76; r = 0.80; kr = 0.82; jr = 1.07
|
k = 0.49 usec; r = 0.80; kr = 0.82
|
||||||
|
|
||||||
ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
|
ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
|
||||||
k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99
|
k = 0.77 usec; r = 1.26; kr = 1.45
|
||||||
|
|
||||||
Optimized Probe Overhead
|
Optimized Probe Overhead
|
||||||
------------------------
|
------------------------
|
||||||
@@ -755,11 +685,6 @@ Kprobes Example
|
|||||||
|
|
||||||
See samples/kprobes/kprobe_example.c
|
See samples/kprobes/kprobe_example.c
|
||||||
|
|
||||||
Jprobes Example
|
|
||||||
===============
|
|
||||||
|
|
||||||
See samples/kprobes/jprobe_example.c
|
|
||||||
|
|
||||||
Kretprobes Example
|
Kretprobes Example
|
||||||
==================
|
==================
|
||||||
|
|
||||||
@@ -772,6 +697,37 @@ For additional information on Kprobes, refer to the following URLs:
|
|||||||
- http://www-users.cs.umn.edu/~boutcher/kprobes/
|
- http://www-users.cs.umn.edu/~boutcher/kprobes/
|
||||||
- http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
|
- http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
|
||||||
|
|
||||||
|
Deprecated Features
|
||||||
|
===================
|
||||||
|
|
||||||
|
Jprobes is now a deprecated feature. People who are depending on it should
|
||||||
|
migrate to other tracing features or use older kernels. Please consider to
|
||||||
|
migrate your tool to one of the following options:
|
||||||
|
|
||||||
|
- Use trace-event to trace target function with arguments.
|
||||||
|
|
||||||
|
trace-event is a low-overhead (and almost no visible overhead if it
|
||||||
|
is off) statically defined event interface. You can define new events
|
||||||
|
and trace it via ftrace or any other tracing tools.
|
||||||
|
|
||||||
|
See the following urls:
|
||||||
|
|
||||||
|
- https://lwn.net/Articles/379903/
|
||||||
|
- https://lwn.net/Articles/381064/
|
||||||
|
- https://lwn.net/Articles/383362/
|
||||||
|
|
||||||
|
- Use ftrace dynamic events (kprobe event) with perf-probe.
|
||||||
|
|
||||||
|
If you build your kernel with debug info (CONFIG_DEBUG_INFO=y), you can
|
||||||
|
find which register/stack is assigned to which local variable or arguments
|
||||||
|
by using perf-probe and set up new event to trace it.
|
||||||
|
|
||||||
|
See following documents:
|
||||||
|
|
||||||
|
- Documentation/trace/kprobetrace.txt
|
||||||
|
- Documentation/trace/events.txt
|
||||||
|
- tools/perf/Documentation/perf-probe.txt
|
||||||
|
|
||||||
|
|
||||||
The kprobes debugfs interface
|
The kprobes debugfs interface
|
||||||
=============================
|
=============================
|
||||||
@@ -783,14 +739,13 @@ under the /sys/kernel/debug/kprobes/ directory (assuming debugfs is mounted at /
|
|||||||
/sys/kernel/debug/kprobes/list: Lists all registered probes on the system::
|
/sys/kernel/debug/kprobes/list: Lists all registered probes on the system::
|
||||||
|
|
||||||
c015d71a k vfs_read+0x0
|
c015d71a k vfs_read+0x0
|
||||||
c011a316 j do_fork+0x0
|
|
||||||
c03dedc5 r tcp_v4_rcv+0x0
|
c03dedc5 r tcp_v4_rcv+0x0
|
||||||
|
|
||||||
The first column provides the kernel address where the probe is inserted.
|
The first column provides the kernel address where the probe is inserted.
|
||||||
The second column identifies the type of probe (k - kprobe, r - kretprobe
|
The second column identifies the type of probe (k - kprobe and r - kretprobe)
|
||||||
and j - jprobe), while the third column specifies the symbol+offset of
|
while the third column specifies the symbol+offset of the probe.
|
||||||
the probe. If the probed function belongs to a module, the module name
|
If the probed function belongs to a module, the module name is also
|
||||||
is also specified. Following columns show probe status. If the probe is on
|
specified. Following columns show probe status. If the probe is on
|
||||||
a virtual address that is no longer valid (module init sections, module
|
a virtual address that is no longer valid (module init sections, module
|
||||||
virtual addresses that correspond to modules that've been unloaded),
|
virtual addresses that correspond to modules that've been unloaded),
|
||||||
such probes are marked with [GONE]. If the probe is temporarily disabled,
|
such probes are marked with [GONE]. If the probe is temporarily disabled,
|
||||||
|
@@ -184,7 +184,7 @@ is done when dirty_ratio is reached.
|
|||||||
DO_CPU:
|
DO_CPU:
|
||||||
|
|
||||||
Enable CPU frequency scaling when in laptop mode. (Requires CPUFreq to be setup.
|
Enable CPU frequency scaling when in laptop mode. (Requires CPUFreq to be setup.
|
||||||
See Documentation/cpu-freq/user-guide.txt for more info. Disabled by default.)
|
See Documentation/admin-guide/pm/cpufreq.rst for more info. Disabled by default.)
|
||||||
|
|
||||||
CPU_MAXFREQ:
|
CPU_MAXFREQ:
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ MINIMUM_BATTERY_MINUTES=10
|
|||||||
|
|
||||||
# Should the maximum CPU frequency be adjusted down while on battery?
|
# Should the maximum CPU frequency be adjusted down while on battery?
|
||||||
# Requires CPUFreq to be setup.
|
# Requires CPUFreq to be setup.
|
||||||
# See Documentation/cpu-freq/user-guide.txt for more info
|
# See Documentation/admin-guide/pm/cpufreq.rst for more info
|
||||||
#DO_CPU=0
|
#DO_CPU=0
|
||||||
|
|
||||||
# When on battery what is the maximum CPU speed that the system should
|
# When on battery what is the maximum CPU speed that the system should
|
||||||
@@ -378,7 +378,7 @@ BATT_HD=${BATT_HD:-'4'}
|
|||||||
DIRTY_RATIO=${DIRTY_RATIO:-'40'}
|
DIRTY_RATIO=${DIRTY_RATIO:-'40'}
|
||||||
|
|
||||||
# cpu frequency scaling
|
# cpu frequency scaling
|
||||||
# See Documentation/cpu-freq/user-guide.txt for more info
|
# See Documentation/admin-guide/pm/cpufreq.rst for more info
|
||||||
DO_CPU=${CPU_MANAGE:-'0'}
|
DO_CPU=${CPU_MANAGE:-'0'}
|
||||||
CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
|
CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'}
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ RT-mutex implementation design
|
|||||||
|
|
||||||
This document tries to describe the design of the rtmutex.c implementation.
|
This document tries to describe the design of the rtmutex.c implementation.
|
||||||
It doesn't describe the reasons why rtmutex.c exists. For that please see
|
It doesn't describe the reasons why rtmutex.c exists. For that please see
|
||||||
Documentation/rt-mutex.txt. Although this document does explain problems
|
Documentation/locking/rt-mutex.txt. Although this document does explain problems
|
||||||
that happen without this code, but that is in the concept to understand
|
that happen without this code, but that is in the concept to understand
|
||||||
what the code actually is doing.
|
what the code actually is doing.
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ General information
|
|||||||
|
|
||||||
This class of cards has a bt878a as the PCI interface, and require the bttv driver
|
This class of cards has a bt878a as the PCI interface, and require the bttv driver
|
||||||
for accessing the i2c bus and the gpio pins of the bt8xx chipset.
|
for accessing the i2c bus and the gpio pins of the bt8xx chipset.
|
||||||
Please see Documentation/dvb/cards.txt => o Cards based on the Conexant Bt8xx PCI bridge:
|
Please see Documentation/media/dvb-drivers/cards.rst => o Cards based on the Conexant Bt8xx PCI bridge:
|
||||||
|
|
||||||
Compiling kernel please enable:
|
Compiling kernel please enable:
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ Loading Modules
|
|||||||
Regular case: If the bttv driver detects a bt8xx-based DVB card, all frontend and backend modules will be loaded automatically.
|
Regular case: If the bttv driver detects a bt8xx-based DVB card, all frontend and backend modules will be loaded automatically.
|
||||||
Exceptions are:
|
Exceptions are:
|
||||||
- Old TwinHan DST cards or clones with or without CA slot and not containing an Eeprom.
|
- Old TwinHan DST cards or clones with or without CA slot and not containing an Eeprom.
|
||||||
People running udev please see Documentation/dvb/udev.txt.
|
People running udev please see Documentation/media/dvb-drivers/udev.rst.
|
||||||
|
|
||||||
In the following cases overriding the PCI type detection for dvb-bt8xx might be necessary:
|
In the following cases overriding the PCI type detection for dvb-bt8xx might be necessary:
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ Useful parameters for verbosity level and debugging the dst module:
|
|||||||
The autodetected values are determined by the cards' "response string".
|
The autodetected values are determined by the cards' "response string".
|
||||||
In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI].
|
In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI].
|
||||||
For bug reports please send in a complete log with verbose=4 activated.
|
For bug reports please send in a complete log with verbose=4 activated.
|
||||||
Please also see Documentation/dvb/ci.txt.
|
Please also see Documentation/media/dvb-drivers/ci.rst.
|
||||||
|
|
||||||
Running multiple cards
|
Running multiple cards
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -100,7 +100,7 @@ Examples of card ID's:
|
|||||||
|
|
||||||
$ modprobe bttv card=113 card=135
|
$ modprobe bttv card=113 card=135
|
||||||
|
|
||||||
For a full list of card ID's please see Documentation/video4linux/CARDLIST.bttv.
|
For a full list of card ID's please see Documentation/media/v4l-drivers/bttv-cardlist.rst.
|
||||||
In case of further problems please subscribe and send questions to the mailing list: linux-dvb@linuxtv.org.
|
In case of further problems please subscribe and send questions to the mailing list: linux-dvb@linuxtv.org.
|
||||||
|
|
||||||
Probing the cards with broken PCI subsystem ID
|
Probing the cards with broken PCI subsystem ID
|
||||||
|
@@ -431,7 +431,7 @@ MPEG stream.
|
|||||||
*Historical context*: This format specification originates from a
|
*Historical context*: This format specification originates from a
|
||||||
custom, embedded, sliced VBI data format used by the ``ivtv`` driver.
|
custom, embedded, sliced VBI data format used by the ``ivtv`` driver.
|
||||||
This format has already been informally specified in the kernel sources
|
This format has already been informally specified in the kernel sources
|
||||||
in the file ``Documentation/video4linux/cx2341x/README.vbi`` . The
|
in the file ``Documentation/media/v4l-drivers/cx2341x.rst`` . The
|
||||||
maximum size of the payload and other aspects of this format are driven
|
maximum size of the payload and other aspects of this format are driven
|
||||||
by the CX23415 MPEG decoder's capabilities and limitations with respect
|
by the CX23415 MPEG decoder's capabilities and limitations with respect
|
||||||
to extracting, decoding, and displaying sliced VBI data embedded within
|
to extracting, decoding, and displaying sliced VBI data embedded within
|
||||||
|
@@ -284,7 +284,7 @@ enum v4l2_mpeg_stream_vbi_fmt -
|
|||||||
* - ``V4L2_MPEG_STREAM_VBI_FMT_IVTV``
|
* - ``V4L2_MPEG_STREAM_VBI_FMT_IVTV``
|
||||||
- VBI in private packets, IVTV format (documented in the kernel
|
- VBI in private packets, IVTV format (documented in the kernel
|
||||||
sources in the file
|
sources in the file
|
||||||
``Documentation/video4linux/cx2341x/README.vbi``)
|
``Documentation/media/v4l-drivers/cx2341x.rst``)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -52,7 +52,7 @@ please make a proposal on the linux-media mailing list.
|
|||||||
`http://www.ivtvdriver.org/ <http://www.ivtvdriver.org/>`__
|
`http://www.ivtvdriver.org/ <http://www.ivtvdriver.org/>`__
|
||||||
|
|
||||||
The format is documented in the kernel sources in the file
|
The format is documented in the kernel sources in the file
|
||||||
``Documentation/video4linux/cx2341x/README.hm12``
|
``Documentation/media/v4l-drivers/cx2341x.rst``
|
||||||
* .. _V4L2-PIX-FMT-CPIA1:
|
* .. _V4L2-PIX-FMT-CPIA1:
|
||||||
|
|
||||||
- ``V4L2_PIX_FMT_CPIA1``
|
- ``V4L2_PIX_FMT_CPIA1``
|
||||||
|
@@ -307,7 +307,7 @@ console and let some terminal application log the messages. /me uses
|
|||||||
screen. See Documentation/admin-guide/serial-console.rst for details on setting
|
screen. See Documentation/admin-guide/serial-console.rst for details on setting
|
||||||
up a serial console.
|
up a serial console.
|
||||||
|
|
||||||
Read Documentation/admin-guide/oops-tracing.rst to learn how to get any useful
|
Read Documentation/admin-guide/bug-hunting.rst to learn how to get any useful
|
||||||
information out of a register+stack dump printed by the kernel on
|
information out of a register+stack dump printed by the kernel on
|
||||||
protection faults (so-called "kernel oops").
|
protection faults (so-called "kernel oops").
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@ The MAX2175 driver implements the following driver-specific controls:
|
|||||||
-------------------------------
|
-------------------------------
|
||||||
Enable/Disable I2S output of the tuner. This is a private control
|
Enable/Disable I2S output of the tuner. This is a private control
|
||||||
that can be accessed only using the subdev interface.
|
that can be accessed only using the subdev interface.
|
||||||
Refer to Documentation/media/kapi/v4l2-controls for more details.
|
Refer to Documentation/media/kapi/v4l2-controls.rst for more details.
|
||||||
|
|
||||||
.. flat-table::
|
.. flat-table::
|
||||||
:header-rows: 0
|
:header-rows: 0
|
||||||
|
@@ -53,7 +53,7 @@ CONTENTS
|
|||||||
- SMP barrier pairing.
|
- SMP barrier pairing.
|
||||||
- Examples of memory barrier sequences.
|
- Examples of memory barrier sequences.
|
||||||
- Read memory barriers vs load speculation.
|
- Read memory barriers vs load speculation.
|
||||||
- Transitivity
|
- Multicopy atomicity.
|
||||||
|
|
||||||
(*) Explicit kernel barriers.
|
(*) Explicit kernel barriers.
|
||||||
|
|
||||||
@@ -383,8 +383,8 @@ Memory barriers come in four basic varieties:
|
|||||||
to have any effect on loads.
|
to have any effect on loads.
|
||||||
|
|
||||||
A CPU can be viewed as committing a sequence of store operations to the
|
A CPU can be viewed as committing a sequence of store operations to the
|
||||||
memory system as time progresses. All stores before a write barrier will
|
memory system as time progresses. All stores _before_ a write barrier
|
||||||
occur in the sequence _before_ all the stores after the write barrier.
|
will occur _before_ all the stores after the write barrier.
|
||||||
|
|
||||||
[!] Note that write barriers should normally be paired with read or data
|
[!] Note that write barriers should normally be paired with read or data
|
||||||
dependency barriers; see the "SMP barrier pairing" subsection.
|
dependency barriers; see the "SMP barrier pairing" subsection.
|
||||||
@@ -635,6 +635,11 @@ can be used to record rare error conditions and the like, and the CPUs'
|
|||||||
naturally occurring ordering prevents such records from being lost.
|
naturally occurring ordering prevents such records from being lost.
|
||||||
|
|
||||||
|
|
||||||
|
Note well that the ordering provided by a data dependency is local to
|
||||||
|
the CPU containing it. See the section on "Multicopy atomicity" for
|
||||||
|
more information.
|
||||||
|
|
||||||
|
|
||||||
The data dependency barrier is very important to the RCU system,
|
The data dependency barrier is very important to the RCU system,
|
||||||
for example. See rcu_assign_pointer() and rcu_dereference() in
|
for example. See rcu_assign_pointer() and rcu_dereference() in
|
||||||
include/linux/rcupdate.h. This permits the current target of an RCU'd
|
include/linux/rcupdate.h. This permits the current target of an RCU'd
|
||||||
@@ -851,38 +856,11 @@ In short, control dependencies apply only to the stores in the then-clause
|
|||||||
and else-clause of the if-statement in question (including functions
|
and else-clause of the if-statement in question (including functions
|
||||||
invoked by those two clauses), not to code following that if-statement.
|
invoked by those two clauses), not to code following that if-statement.
|
||||||
|
|
||||||
Finally, control dependencies do -not- provide transitivity. This is
|
|
||||||
demonstrated by two related examples, with the initial values of
|
|
||||||
'x' and 'y' both being zero:
|
|
||||||
|
|
||||||
CPU 0 CPU 1
|
Note well that the ordering provided by a control dependency is local
|
||||||
======================= =======================
|
to the CPU containing it. See the section on "Multicopy atomicity"
|
||||||
r1 = READ_ONCE(x); r2 = READ_ONCE(y);
|
for more information.
|
||||||
if (r1 > 0) if (r2 > 0)
|
|
||||||
WRITE_ONCE(y, 1); WRITE_ONCE(x, 1);
|
|
||||||
|
|
||||||
assert(!(r1 == 1 && r2 == 1));
|
|
||||||
|
|
||||||
The above two-CPU example will never trigger the assert(). However,
|
|
||||||
if control dependencies guaranteed transitivity (which they do not),
|
|
||||||
then adding the following CPU would guarantee a related assertion:
|
|
||||||
|
|
||||||
CPU 2
|
|
||||||
=====================
|
|
||||||
WRITE_ONCE(x, 2);
|
|
||||||
|
|
||||||
assert(!(r1 == 2 && r2 == 1 && x == 2)); /* FAILS!!! */
|
|
||||||
|
|
||||||
But because control dependencies do -not- provide transitivity, the above
|
|
||||||
assertion can fail after the combined three-CPU example completes. If you
|
|
||||||
need the three-CPU example to provide ordering, you will need smp_mb()
|
|
||||||
between the loads and stores in the CPU 0 and CPU 1 code fragments,
|
|
||||||
that is, just before or just after the "if" statements. Furthermore,
|
|
||||||
the original two-CPU example is very fragile and should be avoided.
|
|
||||||
|
|
||||||
These two examples are the LB and WWC litmus tests from this paper:
|
|
||||||
http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf and this
|
|
||||||
site: https://www.cl.cam.ac.uk/~pes20/ppcmem/index.html.
|
|
||||||
|
|
||||||
In summary:
|
In summary:
|
||||||
|
|
||||||
@@ -922,8 +900,8 @@ In summary:
|
|||||||
|
|
||||||
(*) Control dependencies pair normally with other types of barriers.
|
(*) Control dependencies pair normally with other types of barriers.
|
||||||
|
|
||||||
(*) Control dependencies do -not- provide transitivity. If you
|
(*) Control dependencies do -not- provide multicopy atomicity. If you
|
||||||
need transitivity, use smp_mb().
|
need all the CPUs to see a given store at the same time, use smp_mb().
|
||||||
|
|
||||||
(*) Compilers do not understand control dependencies. It is therefore
|
(*) Compilers do not understand control dependencies. It is therefore
|
||||||
your job to ensure that they do not break your code.
|
your job to ensure that they do not break your code.
|
||||||
@@ -936,13 +914,14 @@ When dealing with CPU-CPU interactions, certain types of memory barrier should
|
|||||||
always be paired. A lack of appropriate pairing is almost certainly an error.
|
always be paired. A lack of appropriate pairing is almost certainly an error.
|
||||||
|
|
||||||
General barriers pair with each other, though they also pair with most
|
General barriers pair with each other, though they also pair with most
|
||||||
other types of barriers, albeit without transitivity. An acquire barrier
|
other types of barriers, albeit without multicopy atomicity. An acquire
|
||||||
pairs with a release barrier, but both may also pair with other barriers,
|
barrier pairs with a release barrier, but both may also pair with other
|
||||||
including of course general barriers. A write barrier pairs with a data
|
barriers, including of course general barriers. A write barrier pairs
|
||||||
dependency barrier, a control dependency, an acquire barrier, a release
|
with a data dependency barrier, a control dependency, an acquire barrier,
|
||||||
barrier, a read barrier, or a general barrier. Similarly a read barrier,
|
a release barrier, a read barrier, or a general barrier. Similarly a
|
||||||
control dependency, or a data dependency barrier pairs with a write
|
read barrier, control dependency, or a data dependency barrier pairs
|
||||||
barrier, an acquire barrier, a release barrier, or a general barrier:
|
with a write barrier, an acquire barrier, a release barrier, or a
|
||||||
|
general barrier:
|
||||||
|
|
||||||
CPU 1 CPU 2
|
CPU 1 CPU 2
|
||||||
=============== ===============
|
=============== ===============
|
||||||
@@ -968,7 +947,7 @@ Or even:
|
|||||||
=============== ===============================
|
=============== ===============================
|
||||||
r1 = READ_ONCE(y);
|
r1 = READ_ONCE(y);
|
||||||
<general barrier>
|
<general barrier>
|
||||||
WRITE_ONCE(y, 1); if (r2 = READ_ONCE(x)) {
|
WRITE_ONCE(x, 1); if (r2 = READ_ONCE(x)) {
|
||||||
<implicit control dependency>
|
<implicit control dependency>
|
||||||
WRITE_ONCE(y, 1);
|
WRITE_ONCE(y, 1);
|
||||||
}
|
}
|
||||||
@@ -1359,64 +1338,79 @@ the speculation will be cancelled and the value reloaded:
|
|||||||
retrieved : : +-------+
|
retrieved : : +-------+
|
||||||
|
|
||||||
|
|
||||||
TRANSITIVITY
|
MULTICOPY ATOMICITY
|
||||||
------------
|
--------------------
|
||||||
|
|
||||||
Transitivity is a deeply intuitive notion about ordering that is not
|
Multicopy atomicity is a deeply intuitive notion about ordering that is
|
||||||
always provided by real computer systems. The following example
|
not always provided by real computer systems, namely that a given store
|
||||||
demonstrates transitivity:
|
becomes visible at the same time to all CPUs, or, alternatively, that all
|
||||||
|
CPUs agree on the order in which all stores become visible. However,
|
||||||
|
support of full multicopy atomicity would rule out valuable hardware
|
||||||
|
optimizations, so a weaker form called ``other multicopy atomicity''
|
||||||
|
instead guarantees only that a given store becomes visible at the same
|
||||||
|
time to all -other- CPUs. The remainder of this document discusses this
|
||||||
|
weaker form, but for brevity will call it simply ``multicopy atomicity''.
|
||||||
|
|
||||||
|
The following example demonstrates multicopy atomicity:
|
||||||
|
|
||||||
CPU 1 CPU 2 CPU 3
|
CPU 1 CPU 2 CPU 3
|
||||||
======================= ======================= =======================
|
======================= ======================= =======================
|
||||||
{ X = 0, Y = 0 }
|
{ X = 0, Y = 0 }
|
||||||
STORE X=1 LOAD X STORE Y=1
|
STORE X=1 r1=LOAD X (reads 1) LOAD Y (reads 1)
|
||||||
<general barrier> <general barrier>
|
<general barrier> <read barrier>
|
||||||
LOAD Y LOAD X
|
STORE Y=r1 LOAD X
|
||||||
|
|
||||||
Suppose that CPU 2's load from X returns 1 and its load from Y returns 0.
|
Suppose that CPU 2's load from X returns 1, which it then stores to Y,
|
||||||
This indicates that CPU 2's load from X in some sense follows CPU 1's
|
and CPU 3's load from Y returns 1. This indicates that CPU 1's store
|
||||||
store to X and that CPU 2's load from Y in some sense preceded CPU 3's
|
to X precedes CPU 2's load from X and that CPU 2's store to Y precedes
|
||||||
store to Y. The question is then "Can CPU 3's load from X return 0?"
|
CPU 3's load from Y. In addition, the memory barriers guarantee that
|
||||||
|
CPU 2 executes its load before its store, and CPU 3 loads from Y before
|
||||||
|
it loads from X. The question is then "Can CPU 3's load from X return 0?"
|
||||||
|
|
||||||
Because CPU 2's load from X in some sense came after CPU 1's store, it
|
Because CPU 3's load from X in some sense comes after CPU 2's load, it
|
||||||
is natural to expect that CPU 3's load from X must therefore return 1.
|
is natural to expect that CPU 3's load from X must therefore return 1.
|
||||||
This expectation is an example of transitivity: if a load executing on
|
This expectation follows from multicopy atomicity: if a load executing
|
||||||
CPU A follows a load from the same variable executing on CPU B, then
|
on CPU B follows a load from the same variable executing on CPU A (and
|
||||||
CPU A's load must either return the same value that CPU B's load did,
|
CPU A did not originally store the value which it read), then on
|
||||||
or must return some later value.
|
multicopy-atomic systems, CPU B's load must return either the same value
|
||||||
|
that CPU A's load did or some later value. However, the Linux kernel
|
||||||
|
does not require systems to be multicopy atomic.
|
||||||
|
|
||||||
In the Linux kernel, use of general memory barriers guarantees
|
The use of a general memory barrier in the example above compensates
|
||||||
transitivity. Therefore, in the above example, if CPU 2's load from X
|
for any lack of multicopy atomicity. In the example, if CPU 2's load
|
||||||
returns 1 and its load from Y returns 0, then CPU 3's load from X must
|
from X returns 1 and CPU 3's load from Y returns 1, then CPU 3's load
|
||||||
also return 1.
|
from X must indeed also return 1.
|
||||||
|
|
||||||
However, transitivity is -not- guaranteed for read or write barriers.
|
However, dependencies, read barriers, and write barriers are not always
|
||||||
For example, suppose that CPU 2's general barrier in the above example
|
able to compensate for non-multicopy atomicity. For example, suppose
|
||||||
is changed to a read barrier as shown below:
|
that CPU 2's general barrier is removed from the above example, leaving
|
||||||
|
only the data dependency shown below:
|
||||||
|
|
||||||
CPU 1 CPU 2 CPU 3
|
CPU 1 CPU 2 CPU 3
|
||||||
======================= ======================= =======================
|
======================= ======================= =======================
|
||||||
{ X = 0, Y = 0 }
|
{ X = 0, Y = 0 }
|
||||||
STORE X=1 LOAD X STORE Y=1
|
STORE X=1 r1=LOAD X (reads 1) LOAD Y (reads 1)
|
||||||
<read barrier> <general barrier>
|
<data dependency> <read barrier>
|
||||||
LOAD Y LOAD X
|
STORE Y=r1 LOAD X (reads 0)
|
||||||
|
|
||||||
This substitution destroys transitivity: in this example, it is perfectly
|
This substitution allows non-multicopy atomicity to run rampant: in
|
||||||
legal for CPU 2's load from X to return 1, its load from Y to return 0,
|
this example, it is perfectly legal for CPU 2's load from X to return 1,
|
||||||
and CPU 3's load from X to return 0.
|
CPU 3's load from Y to return 1, and its load from X to return 0.
|
||||||
|
|
||||||
The key point is that although CPU 2's read barrier orders its pair
|
The key point is that although CPU 2's data dependency orders its load
|
||||||
of loads, it does not guarantee to order CPU 1's store. Therefore, if
|
and store, it does not guarantee to order CPU 1's store. Thus, if this
|
||||||
this example runs on a system where CPUs 1 and 2 share a store buffer
|
example runs on a non-multicopy-atomic system where CPUs 1 and 2 share a
|
||||||
or a level of cache, CPU 2 might have early access to CPU 1's writes.
|
store buffer or a level of cache, CPU 2 might have early access to CPU 1's
|
||||||
General barriers are therefore required to ensure that all CPUs agree
|
writes. General barriers are therefore required to ensure that all CPUs
|
||||||
on the combined order of CPU 1's and CPU 2's accesses.
|
agree on the combined order of multiple accesses.
|
||||||
|
|
||||||
General barriers provide "global transitivity", so that all CPUs will
|
General barriers can compensate not only for non-multicopy atomicity,
|
||||||
agree on the order of operations. In contrast, a chain of release-acquire
|
but can also generate additional ordering that can ensure that -all-
|
||||||
pairs provides only "local transitivity", so that only those CPUs on
|
CPUs will perceive the same order of -all- operations. In contrast, a
|
||||||
the chain are guaranteed to agree on the combined order of the accesses.
|
chain of release-acquire pairs do not provide this additional ordering,
|
||||||
For example, switching to C code in deference to Herman Hollerith:
|
which means that only those CPUs on the chain are guaranteed to agree
|
||||||
|
on the combined order of the accesses. For example, switching to C code
|
||||||
|
in deference to the ghost of Herman Hollerith:
|
||||||
|
|
||||||
int u, v, x, y, z;
|
int u, v, x, y, z;
|
||||||
|
|
||||||
@@ -1448,9 +1442,9 @@ For example, switching to C code in deference to Herman Hollerith:
|
|||||||
r3 = READ_ONCE(u);
|
r3 = READ_ONCE(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
Because cpu0(), cpu1(), and cpu2() participate in a local transitive
|
Because cpu0(), cpu1(), and cpu2() participate in a chain of
|
||||||
chain of smp_store_release()/smp_load_acquire() pairs, the following
|
smp_store_release()/smp_load_acquire() pairs, the following outcome
|
||||||
outcome is prohibited:
|
is prohibited:
|
||||||
|
|
||||||
r0 == 1 && r1 == 1 && r2 == 1
|
r0 == 1 && r1 == 1 && r2 == 1
|
||||||
|
|
||||||
@@ -1460,9 +1454,9 @@ outcome is prohibited:
|
|||||||
|
|
||||||
r1 == 1 && r5 == 0
|
r1 == 1 && r5 == 0
|
||||||
|
|
||||||
However, the transitivity of release-acquire is local to the participating
|
However, the ordering provided by a release-acquire chain is local
|
||||||
CPUs and does not apply to cpu3(). Therefore, the following outcome
|
to the CPUs participating in that chain and does not apply to cpu3(),
|
||||||
is possible:
|
at least aside from stores. Therefore, the following outcome is possible:
|
||||||
|
|
||||||
r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0
|
r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0
|
||||||
|
|
||||||
@@ -1490,8 +1484,8 @@ following outcome is possible:
|
|||||||
Note that this outcome can happen even on a mythical sequentially
|
Note that this outcome can happen even on a mythical sequentially
|
||||||
consistent system where nothing is ever reordered.
|
consistent system where nothing is ever reordered.
|
||||||
|
|
||||||
To reiterate, if your code requires global transitivity, use general
|
To reiterate, if your code requires full ordering of all operations,
|
||||||
barriers throughout.
|
use general barriers throughout.
|
||||||
|
|
||||||
|
|
||||||
========================
|
========================
|
||||||
@@ -1886,18 +1880,6 @@ There are some more advanced barrier functions:
|
|||||||
See Documentation/atomic_{t,bitops}.txt for more information.
|
See Documentation/atomic_{t,bitops}.txt for more information.
|
||||||
|
|
||||||
|
|
||||||
(*) lockless_dereference();
|
|
||||||
|
|
||||||
This can be thought of as a pointer-fetch wrapper around the
|
|
||||||
smp_read_barrier_depends() data-dependency barrier.
|
|
||||||
|
|
||||||
This is also similar to rcu_dereference(), but in cases where
|
|
||||||
object lifetime is handled by some mechanism other than RCU, for
|
|
||||||
example, when the objects removed only when the system goes down.
|
|
||||||
In addition, lockless_dereference() is used in some data structures
|
|
||||||
that can be used both with and without RCU.
|
|
||||||
|
|
||||||
|
|
||||||
(*) dma_wmb();
|
(*) dma_wmb();
|
||||||
(*) dma_rmb();
|
(*) dma_rmb();
|
||||||
|
|
||||||
@@ -3101,6 +3083,9 @@ AMD64 Architecture Programmer's Manual Volume 2: System Programming
|
|||||||
Chapter 7.1: Memory-Access Ordering
|
Chapter 7.1: Memory-Access Ordering
|
||||||
Chapter 7.4: Buffering and Combining Memory Writes
|
Chapter 7.4: Buffering and Combining Memory Writes
|
||||||
|
|
||||||
|
ARM Architecture Reference Manual (ARMv8, for ARMv8-A architecture profile)
|
||||||
|
Chapter B2: The AArch64 Application Level Memory Model
|
||||||
|
|
||||||
IA-32 Intel Architecture Software Developer's Manual, Volume 3:
|
IA-32 Intel Architecture Software Developer's Manual, Volume 3:
|
||||||
System Programming Guide
|
System Programming Guide
|
||||||
Chapter 7.1: Locked Atomic Operations
|
Chapter 7.1: Locked Atomic Operations
|
||||||
@@ -3112,6 +3097,8 @@ The SPARC Architecture Manual, Version 9
|
|||||||
Appendix D: Formal Specification of the Memory Models
|
Appendix D: Formal Specification of the Memory Models
|
||||||
Appendix J: Programming with the Memory Models
|
Appendix J: Programming with the Memory Models
|
||||||
|
|
||||||
|
Storage in the PowerPC (Stone and Fitzgerald)
|
||||||
|
|
||||||
UltraSPARC Programmer Reference Manual
|
UltraSPARC Programmer Reference Manual
|
||||||
Chapter 5: Memory Accesses and Cacheability
|
Chapter 5: Memory Accesses and Cacheability
|
||||||
Chapter 15: Sparc-V9 Memory Models
|
Chapter 15: Sparc-V9 Memory Models
|
||||||
|
@@ -332,8 +332,8 @@ References
|
|||||||
[5] "MBIM (Mobile Broadband Interface Model) Registry"
|
[5] "MBIM (Mobile Broadband Interface Model) Registry"
|
||||||
- http://compliance.usb.org/mbim/
|
- http://compliance.usb.org/mbim/
|
||||||
|
|
||||||
[6] "/dev/bus/usb filesystem output"
|
[6] "/sys/kernel/debug/usb/devices output format"
|
||||||
- Documentation/usb/proc_usb_info.txt
|
- Documentation/driver-api/usb/usb.rst
|
||||||
|
|
||||||
[7] "/sys/bus/usb/devices/.../descriptors"
|
[7] "/sys/bus/usb/devices/.../descriptors"
|
||||||
- Documentation/ABI/stable/sysfs-bus-usb
|
- Documentation/ABI/stable/sysfs-bus-usb
|
||||||
|
@@ -47,7 +47,7 @@ The requirements for GSO are more complicated, because when segmenting an
|
|||||||
(section 'E') for more details.
|
(section 'E') for more details.
|
||||||
|
|
||||||
A driver declares its offload capabilities in netdev->hw_features; see
|
A driver declares its offload capabilities in netdev->hw_features; see
|
||||||
Documentation/networking/netdev-features for more. Note that a device
|
Documentation/networking/netdev-features.txt for more. Note that a device
|
||||||
which only advertises NETIF_F_IP[V6]_CSUM must still obey the csum_start
|
which only advertises NETIF_F_IP[V6]_CSUM must still obey the csum_start
|
||||||
and csum_offset given in the SKB; if it tries to deduce these itself in
|
and csum_offset given in the SKB; if it tries to deduce these itself in
|
||||||
hardware (as some NICs do) the driver should check that the values in the
|
hardware (as some NICs do) the driver should check that the values in the
|
||||||
|
@@ -1055,7 +1055,7 @@ TX_RING part only TP_STATUS_AVAILABLE is set, then the tp_sec and tp_{n,u}sec
|
|||||||
members do not contain a valid value. For TX_RINGs, by default no timestamp
|
members do not contain a valid value. For TX_RINGs, by default no timestamp
|
||||||
is generated!
|
is generated!
|
||||||
|
|
||||||
See include/linux/net_tstamp.h and Documentation/networking/timestamping
|
See include/linux/net_tstamp.h and Documentation/networking/timestamping.txt
|
||||||
for more information on hardware timestamps.
|
for more information on hardware timestamps.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@@ -7,13 +7,7 @@ target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
|
|||||||
For information about OpenRISC processors and ongoing development:
|
For information about OpenRISC processors and ongoing development:
|
||||||
|
|
||||||
website http://openrisc.io
|
website http://openrisc.io
|
||||||
|
email openrisc@lists.librecores.org
|
||||||
For more information about Linux on OpenRISC, please contact South Pole AB.
|
|
||||||
|
|
||||||
email: info@southpole.se
|
|
||||||
|
|
||||||
website: http://southpole.se
|
|
||||||
http://southpoleconsulting.com
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -24,37 +18,54 @@ In order to build and run Linux for OpenRISC, you'll need at least a basic
|
|||||||
toolchain and, perhaps, the architectural simulator. Steps to get these bits
|
toolchain and, perhaps, the architectural simulator. Steps to get these bits
|
||||||
in place are outlined here.
|
in place are outlined here.
|
||||||
|
|
||||||
1) The toolchain can be obtained from openrisc.io. Instructions for building
|
1) Toolchain
|
||||||
a toolchain can be found at:
|
|
||||||
|
|
||||||
https://github.com/openrisc/tutorials
|
Toolchain binaries can be obtained from openrisc.io or our github releases page.
|
||||||
|
Instructions for building the different toolchains can be found on openrisc.io
|
||||||
|
or Stafford's toolchain build and release scripts.
|
||||||
|
|
||||||
2) or1ksim (optional)
|
binaries https://github.com/openrisc/or1k-gcc/releases
|
||||||
|
toolchains https://openrisc.io/software
|
||||||
|
building https://github.com/stffrdhrn/or1k-toolchain-build
|
||||||
|
|
||||||
or1ksim is the architectural simulator which will allow you to actually run
|
2) Building
|
||||||
your OpenRISC Linux kernel if you don't have an OpenRISC processor at hand.
|
|
||||||
|
|
||||||
git clone https://github.com/openrisc/or1ksim.git
|
Build the Linux kernel as usual
|
||||||
|
|
||||||
cd or1ksim
|
|
||||||
./configure --prefix=$OPENRISC_PREFIX
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
3) Linux kernel
|
|
||||||
|
|
||||||
Build the kernel as usual
|
|
||||||
|
|
||||||
make ARCH=openrisc defconfig
|
make ARCH=openrisc defconfig
|
||||||
make ARCH=openrisc
|
make ARCH=openrisc
|
||||||
|
|
||||||
4) Run in architectural simulator
|
3) Running on FPGA (optional)
|
||||||
|
|
||||||
Grab the or1ksim platform configuration file (from the or1ksim source) and
|
The OpenRISC community typically uses FuseSoC to manage building and programming
|
||||||
together with your freshly built vmlinux, run your kernel with the following
|
an SoC into an FPGA. The below is an example of programming a De0 Nano
|
||||||
incantation:
|
development board with the OpenRISC SoC. During the build FPGA RTL is code
|
||||||
|
downloaded from the FuseSoC IP cores repository and built using the FPGA vendor
|
||||||
|
tools. Binaries are loaded onto the board with openocd.
|
||||||
|
|
||||||
sim -f arch/openrisc/or1ksim.cfg vmlinux
|
git clone https://github.com/olofk/fusesoc
|
||||||
|
cd fusesoc
|
||||||
|
sudo pip install -e .
|
||||||
|
|
||||||
|
fusesoc init
|
||||||
|
fusesoc build de0_nano
|
||||||
|
fusesoc pgm de0_nano
|
||||||
|
|
||||||
|
openocd -f interface/altera-usb-blaster.cfg \
|
||||||
|
-f board/or1k_generic.cfg
|
||||||
|
|
||||||
|
telnet localhost 4444
|
||||||
|
> init
|
||||||
|
> halt; load_image vmlinux ; reset
|
||||||
|
|
||||||
|
4) Running on a Simulator (optional)
|
||||||
|
|
||||||
|
QEMU is a processor emulator which we recommend for simulating the OpenRISC
|
||||||
|
platform. Please follow the OpenRISC instructions on the QEMU website to get
|
||||||
|
Linux running on QEMU. You can build QEMU yourself, but your Linux distribution
|
||||||
|
likely provides binary packages to support OpenRISC.
|
||||||
|
|
||||||
|
qemu openrisc https://wiki.qemu.org/Documentation/Platforms/OpenRISC
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
|
@@ -119,4 +119,4 @@ properties of futexes, and all four combinations are possible: futex,
|
|||||||
robust-futex, PI-futex, robust+PI-futex.
|
robust-futex, PI-futex, robust+PI-futex.
|
||||||
|
|
||||||
More details about priority inheritance can be found in
|
More details about priority inheritance can be found in
|
||||||
Documentation/rt-mutex.txt.
|
Documentation/locking/rt-mutex.txt.
|
||||||
|
@@ -24,7 +24,8 @@ platform.
|
|||||||
|
|
||||||
If one of the strings listed in /sys/power/state is written to it, the system
|
If one of the strings listed in /sys/power/state is written to it, the system
|
||||||
will attempt to transition into the corresponding sleep state. Refer to
|
will attempt to transition into the corresponding sleep state. Refer to
|
||||||
Documentation/power/states.txt for a description of each of those states.
|
Documentation/admin-guide/pm/sleep-states.rst for a description of each of
|
||||||
|
those states.
|
||||||
|
|
||||||
/sys/power/disk controls the operating mode of hibernation (Suspend-to-Disk).
|
/sys/power/disk controls the operating mode of hibernation (Suspend-to-Disk).
|
||||||
Specifically, it tells the kernel what to do after creating a hibernation image.
|
Specifically, it tells the kernel what to do after creating a hibernation image.
|
||||||
@@ -42,7 +43,7 @@ The currently selected option is printed in square brackets.
|
|||||||
The 'platform' option is only available if the platform provides a special
|
The 'platform' option is only available if the platform provides a special
|
||||||
mechanism to put the system to sleep after creating a hibernation image (ACPI
|
mechanism to put the system to sleep after creating a hibernation image (ACPI
|
||||||
does that, for example). The 'suspend' option is available if Suspend-to-RAM
|
does that, for example). The 'suspend' option is available if Suspend-to-RAM
|
||||||
is supported. Refer to Documentation/power/basic_pm_debugging.txt for the
|
is supported. Refer to Documentation/power/basic-pm-debugging.txt for the
|
||||||
description of the 'test_resume' option.
|
description of the 'test_resume' option.
|
||||||
|
|
||||||
To select an option, write the string representing it to /sys/power/disk.
|
To select an option, write the string representing it to /sys/power/disk.
|
||||||
|