Merge branch 'linus' into perf/urgent, to pick up dependent commits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
@ -1,5 +1,5 @@
|
|||
# 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
|
||||
Date: February 2015
|
||||
|
|
|
@ -7,17 +7,37 @@ Description:
|
|||
HMAC-sha1 value across the extended attributes, storing the
|
||||
value as the extended attribute 'security.evm'.
|
||||
|
||||
EVM depends on the Kernel Key Retention System to provide it
|
||||
with a trusted/encrypted key for the HMAC-sha1 operation.
|
||||
The key is loaded onto the root's keyring using keyctl. Until
|
||||
EVM receives notification that the key has been successfully
|
||||
loaded onto the keyring (echo 1 > <securityfs>/evm), EVM
|
||||
can not create or validate the 'security.evm' xattr, but
|
||||
returns INTEGRITY_UNKNOWN. Loading the key 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/keys-trusted-encrypted.txt. (A sample dracut
|
||||
patch, which loads the trusted/encrypted key and enables
|
||||
EVM, is available from http://linux-ima.sourceforge.net/#EVM.)
|
||||
EVM supports two classes of security.evm. The first is
|
||||
an HMAC-sha1 generated locally with a
|
||||
trusted/encrypted key stored in the Kernel Key
|
||||
Retention System. The second is a digital signature
|
||||
generated either locally or remotely using an
|
||||
asymmetric key. These keys are loaded onto root's
|
||||
keyring using keyctl, and EVM is then enabled by
|
||||
echoing a value to <securityfs>/evm:
|
||||
|
||||
1: enable HMAC validation and creation
|
||||
2: enable digital signature validation
|
||||
3: enable HMAC and digital signature validation and HMAC
|
||||
creation
|
||||
|
||||
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.
|
||||
|
|
|
@ -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.
|
||||
Boosting allows the CPU and the firmware to run at a frequency
|
||||
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
|
||||
|
@ -223,7 +224,8 @@ Description: Parameters for the Intel P-state driver
|
|||
no_turbo: limits the driver to selecting P states below the turbo
|
||||
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>
|
||||
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
|
||||
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
|
||||
Date: November 2016
|
||||
|
@ -35,7 +36,8 @@ Description:
|
|||
represented by it to be used on subsequent attempts to suspend
|
||||
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
|
||||
Date: September 2006
|
||||
|
|
|
@ -97,6 +97,9 @@ endif # HAVE_SPHINX
|
|||
# The following targets are independent of HAVE_SPHINX, and the rules should
|
||||
# work or silently pass without Sphinx.
|
||||
|
||||
refcheckdocs:
|
||||
$(Q)cd $(srctree);scripts/documentation-file-ref-check
|
||||
|
||||
cleandocs:
|
||||
$(Q)rm -rf $(BUILDDIR)
|
||||
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
||||
|
@ -109,6 +112,7 @@ dochelp:
|
|||
@echo ' epubdocs - EPUB'
|
||||
@echo ' xmldocs - XML'
|
||||
@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
|
||||
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
||||
|
@ -116,3 +120,5 @@ dochelp:
|
|||
@echo
|
||||
@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
|
||||
@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
|
||||
account for POSIX signals sent to user tasks,
|
||||
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>
|
||||
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>
|
После Ширина: | Высота: | Размер: 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>
|
После Ширина: | Высота: | Размер: 23 KiB |
|
@ -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>
|
После Ширина: | Высота: | Размер: 25 KiB |
После Ширина: | Высота: | Размер: 42 KiB |
После Ширина: | Высота: | Размер: 50 KiB |
|
@ -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>
|
После Ширина: | Высота: | Размер: 23 KiB |
|
@ -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>
|
После Ширина: | Высота: | Размер: 24 KiB |
|
@ -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>
|
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 208 KiB |
|
@ -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>
|
После Ширина: | Высота: | Размер: 28 KiB |
После Ширина: | Высота: | Размер: 43 KiB |
|
@ -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>
|
После Ширина: | Высота: | Размер: 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.
|
||||
This can result in the "All QSes seen" console-log message.
|
||||
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
|
||||
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
|
||||
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
|
||||
interrupt on a CPU that is not in dyntick-idle mode. This
|
||||
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,
|
||||
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,
|
||||
and that the stall was affecting RCU-sched. This message will normally be
|
||||
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
|
||||
This message indicates that CPU 32 detected that CPUs 2 and 16 were both
|
||||
causing stalls, and that the stall was affecting RCU-sched. This message
|
||||
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,
|
||||
and that the tasks will be indicated by PID, for example, "P3421".
|
||||
It is even possible for a rcu_preempt_state stall to be caused by both
|
||||
CPUs -and- tasks, in which case the offending CPUs and tasks will all
|
||||
be called out in the list.
|
||||
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 even
|
||||
possible for a rcu_preempt_state stall to be caused by both CPUs -and-
|
||||
tasks, in which case the offending CPUs and tasks will all be called
|
||||
out in the list.
|
||||
|
||||
Finally, if the grace period ends just as the stall warning starts
|
||||
printing, there will be a spurious stall-warning message:
|
||||
|
||||
INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
|
||||
|
||||
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.
|
||||
CPU 2's "(3 GPs behind)" indicates that this CPU has not interacted with
|
||||
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
|
||||
interrupts during the current stalled grace period.
|
||||
|
||||
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
|
||||
dynticks counter, which will have an even-numbered value if the CPU 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
|
||||
be a small positive number if in the idle loop and a very large positive
|
||||
number (as shown above) otherwise.
|
||||
dynticks counter, which will have an even-numbered value if the CPU
|
||||
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 be
|
||||
a small non-negative number if in the idle loop (as shown above) and a
|
||||
very large positive number otherwise.
|
||||
|
||||
The "softirq=" portion of the message tracks the number of RCU softirq
|
||||
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
|
||||
kernels, if a high-priority process is starving RCU's softirq handler.
|
||||
|
||||
For CONFIG_RCU_FAST_NO_HZ kernels, 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).
|
||||
The "fps=" shows the number of force-quiescent-state idle/offline
|
||||
detection passes that the grace-period kthread has made across this
|
||||
CPU since the last time that this CPU noted the beginning of a grace
|
||||
period.
|
||||
|
||||
The "detected by" line indicates which CPU detected the stall (in this
|
||||
case, CPU 32), how many jiffies have elapsed since the start of the
|
||||
grace period (in this case 2603), the number of the last grace period
|
||||
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
|
||||
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
|
||||
RCU CPU stall warnings even when all CPUs and tasks have passed through
|
||||
the required quiescent states.
|
||||
Starving the grace-period kthreads of CPU time can of course result
|
||||
in RCU CPU stall warnings even when all CPUs and tasks have passed
|
||||
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
|
||||
|
@ -264,13 +293,28 @@ Stall Warnings for Expedited Grace Periods
|
|||
If an expedited grace period detects a stall, it will place a message
|
||||
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
|
||||
reschedule IPI, that the expedited grace period has been going on for
|
||||
26,009 jiffies, and that the expedited grace-period sequence counter is
|
||||
1043. The fact that this last value is odd indicates that an expedited
|
||||
grace period is in flight.
|
||||
This indicates that CPU 7 has failed to respond to a reschedule IPI.
|
||||
The three periods (".") following the CPU number indicate that the CPU
|
||||
is online (otherwise the first period would instead have been "O"),
|
||||
that the CPU was online at the beginning of the expedited grace period
|
||||
(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
|
||||
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
|
||||
important: it tells something about why the kernel dumped code (in
|
||||
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
|
||||
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
|
||||
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::
|
||||
|
||||
$ ./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
|
||||
development of this file);
|
||||
- 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 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,
|
||||
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?
|
||||
|
||||
If you decide to take this way, once you have worked out a fix please submit
|
||||
it upstream.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@
|
|||
amijoy.map= [HW,JOY] Amiga joystick support
|
||||
Map of devices attached to JOY0DAT and JOY1DAT
|
||||
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
|
||||
Specifies type or capabilities of an analog joystick
|
||||
|
@ -439,7 +439,7 @@
|
|||
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
|
||||
bttv.radio= Most important insmod options are available as
|
||||
kernel args too.
|
||||
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
|
||||
bttv.pll= See Documentation/media/v4l-drivers/bttv.rst
|
||||
bttv.tuner=
|
||||
|
||||
bulk_remove=off [PPC] This parameter disables the use of the pSeries
|
||||
|
@ -641,8 +641,8 @@
|
|||
For now, only VisioBraille is supported.
|
||||
|
||||
consoleblank= [KNL] The console blank (screen saver) timeout in
|
||||
seconds. Defaults to 10*60 = 10mins. A value of 0
|
||||
disables the blank timer.
|
||||
seconds. A value of 0 disables the blank timer.
|
||||
Defaults to 0.
|
||||
|
||||
coredump_filter=
|
||||
[KNL] Change the default value for
|
||||
|
@ -709,6 +709,9 @@
|
|||
It will be ignored when crashkernel=X,high is not used
|
||||
or memory reserved is below 4G.
|
||||
|
||||
crossrelease_fullstack
|
||||
[KNL] Allow to record full stack trace in cross-release
|
||||
|
||||
cryptomgr.notests
|
||||
[KNL] Disable crypto self-tests
|
||||
|
||||
|
@ -724,7 +727,7 @@
|
|||
db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port
|
||||
(one device per port)
|
||||
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
|
||||
time. See
|
||||
|
@ -1220,7 +1223,7 @@
|
|||
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
||||
support via parallel port (up to 5 devices per port)
|
||||
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]
|
||||
|
||||
|
@ -1713,6 +1716,13 @@
|
|||
irqaffinity= [SMP] Set the default irq affinity mask
|
||||
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]
|
||||
When an interrupt is not handled search all handlers
|
||||
for it. Intended to get systems with badly broken
|
||||
|
@ -1727,20 +1737,33 @@
|
|||
isapnp= [ISAPNP]
|
||||
Format: <RDP>,<reset>,<pci_scan>,<verbosity>
|
||||
|
||||
isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler.
|
||||
The argument is a cpu list, as described above.
|
||||
isolcpus= [KNL,SMP] Isolate a given set of CPUs from disturbance.
|
||||
[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]
|
||||
|
||||
|
@ -1766,7 +1789,7 @@
|
|||
ivrs_acpihid[00:14.5]=AMD0020:0
|
||||
|
||||
js= [HW,JOY] Analog joystick
|
||||
See Documentation/input/joystick.txt.
|
||||
See Documentation/input/joydev/joystick.rst.
|
||||
|
||||
nokaslr [KNL]
|
||||
When CONFIG_RANDOMIZE_BASE is set, this disables
|
||||
|
@ -2248,10 +2271,10 @@
|
|||
s2idle - Suspend-To-Idle
|
||||
shallow - Power-On Suspend 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
|
||||
See Documentation/video4linux/meye.txt.
|
||||
See Documentation/media/v4l-drivers/meye.rst.
|
||||
|
||||
mfgpt_irq= [IA-32] Specify the IRQ to use for the
|
||||
Multi-Function General Purpose Timers on AMD Geode
|
||||
|
@ -2548,6 +2571,9 @@
|
|||
|
||||
noalign [KNL,ARM]
|
||||
|
||||
noaltinstr [S390] Disables alternative instructions patching
|
||||
(CPU alternatives feature).
|
||||
|
||||
noapic [SMP,APIC] Tells the kernel to not make use of any
|
||||
IOAPICs that may be present in the system.
|
||||
|
||||
|
@ -3134,7 +3160,7 @@
|
|||
|
||||
plip= [PPT,NET] Parallel port network link
|
||||
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.
|
||||
Override pmtimer IOPort with a hex value.
|
||||
|
@ -3539,6 +3565,9 @@
|
|||
rcutorture.stall_cpu_holdoff= [KNL]
|
||||
Time to wait (s) after boot before inducing stall.
|
||||
|
||||
rcutorture.stall_cpu_irqsoff= [KNL]
|
||||
Disable interrupts while stalling if set.
|
||||
|
||||
rcutorture.stat_interval= [KNL]
|
||||
Time (s) between statistics printk()s.
|
||||
|
||||
|
@ -3885,6 +3914,12 @@
|
|||
[KNL] Should the soft-lockup detector generate panics.
|
||||
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=
|
||||
[KNL] Should the soft-lockup detector generate
|
||||
backtraces on all cpus.
|
||||
|
@ -4194,12 +4229,15 @@
|
|||
Used to run time disable IRQ_TIME_ACCOUNTING on any
|
||||
platforms where RDTSC is slow and this accounting
|
||||
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 parallel port interface
|
||||
Format:
|
||||
<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
|
||||
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
|
||||
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
|
||||
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:
|
||||
[5.] Most recent kernel version which did not have the bug:
|
||||
[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
|
||||
problem (if possible)
|
||||
[8.] Environment
|
||||
|
|
|
@ -70,6 +70,7 @@ stable kernels.
|
|||
| | | | |
|
||||
| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
|
||||
| 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 | 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 the options:
|
||||
|
||||
Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
|
||||
ATA/ATAPI/MFM/RLL 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
|
||||
specify additional configuration options. See
|
||||
Documentation/ide/ide.txt.
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
The Linux Kernel API
|
||||
====================
|
||||
|
||||
Data Types
|
||||
==========
|
||||
|
||||
Doubly Linked Lists
|
||||
-------------------
|
||||
List Management Functions
|
||||
=========================
|
||||
|
||||
.. kernel-doc:: include/linux/list.h
|
||||
:internal:
|
||||
|
@ -55,12 +53,27 @@ The Linux kernel provides more basic utility functions.
|
|||
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
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/bitmap.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: include/linux/bitmap.h
|
||||
:internal:
|
||||
|
||||
Command-line Parsing
|
||||
--------------------
|
||||
|
||||
|
@ -70,20 +83,26 @@ Command-line Parsing
|
|||
CRC Functions
|
||||
-------------
|
||||
|
||||
.. kernel-doc:: lib/crc4.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/crc7.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/crc8.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/crc16.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/crc-itu-t.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/crc32.c
|
||||
|
||||
.. kernel-doc:: lib/crc-ccitt.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: lib/crc-itu-t.c
|
||||
:export:
|
||||
|
||||
idr/ida Functions
|
||||
-----------------
|
||||
|
||||
|
@ -96,6 +115,30 @@ idr/ida Functions
|
|||
.. kernel-doc:: lib/idr.c
|
||||
: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
|
||||
==========================
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ err.log will now have the profiling information, while stdout will
|
|||
provide some progress information as Coccinelle moves forward with
|
||||
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
|
||||
--------------------
|
||||
|
|
|
@ -31,6 +31,17 @@ To build and run the tests with a single command, use::
|
|||
|
||||
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
|
||||
=============================
|
||||
|
@ -46,10 +57,21 @@ You can specify multiple tests to build and run::
|
|||
|
||||
$ 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
|
||||
possible targets.
|
||||
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
executable which is not tested by default.
|
||||
TEST_FILES, TEST_GEN_FILES mean it is the file which is used by
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -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
|
||||
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,
|
||||
#size-cells and ranges properties for the reg property of all ITS
|
||||
nodes.
|
||||
|
|
|
@ -2,7 +2,8 @@ Broadcom Generic Level 2 Interrupt Controller
|
|||
|
||||
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
|
||||
- interrupt-controller: identifies the node as an interrupt controller
|
||||
- #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-r8a7794" (R-Car E2)
|
||||
- "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
|
||||
interrupts.txt in this directory
|
||||
- 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:
|
||||
|
||||
- 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
|
||||
- interrupt-controller: Indentifies the node as an interrupt controller
|
||||
- #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-sd: controller is limited to send sd 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
|
||||
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.
|
||||
|
||||
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
|
||||
- clocks: MSDC source clock, HCLK
|
||||
- clock-names: "source", "hclk"
|
||||
- clocks: Should contain phandle for the clock feeding the MMC controller
|
||||
- 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-0: should contain default/high speed 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
|
||||
If present,HS400 command responses are sampled on rising 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:
|
||||
mmc0: mmc@11230000 {
|
||||
|
|
|
@ -15,6 +15,8 @@ Required properties:
|
|||
Optional properties:
|
||||
- vqmmc-supply: phandle to the regulator device tree node, mentioned
|
||||
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:
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ Required properties:
|
|||
"core" - SDC MMC clock (MCLK) (required)
|
||||
"bus" - SDCC bus voter clock (optional)
|
||||
"xo" - TCXO clock (optional)
|
||||
"cal" - reference clock for RCLK delay calibration (optional)
|
||||
"sleep" - sleep clock for RCLK delay calibration (optional)
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
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-r7s72100" - SDHI IP on R7S72100 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-r8a7795" - SDHI IP on R8A7795 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
|
||||
some variations of this controller, the internal card detection
|
||||
|
@ -43,3 +53,61 @@ Optional properties:
|
|||
- pinctrl-names: should be "default", "state_uhs"
|
||||
- pinctrl-0: should contain default/high speed 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:
|
||||
- compatible: "dlg,da9211" or "dlg,da9212" or "dlg,da9213"
|
||||
or "dlg,da9214" or "dlg,da9215"
|
||||
- compatible: "dlg,da9211" or "dlg,da9212" or "dlg,da9213" or "dlg,da9223"
|
||||
or "dlg,da9214" or "dlg,da9224" or "dlg,da9215" or "dlg,da9225"
|
||||
- reg: I2C slave address, usually 0x68.
|
||||
- interrupts: the interrupt outputs of the controller
|
||||
- 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
|
||||
|
||||
Example 1) DA9211
|
||||
|
||||
pmic: da9211@68 {
|
||||
compatible = "dlg,da9211";
|
||||
reg = <0x68>;
|
||||
|
@ -35,7 +35,6 @@ Example 1) DA9211
|
|||
};
|
||||
|
||||
Example 2) DA9212
|
||||
|
||||
pmic: da9212@68 {
|
||||
compatible = "dlg,da9212";
|
||||
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 {
|
||||
compatible = "dlg,da9214";
|
||||
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 {
|
||||
compatible = "dlg,da9215";
|
||||
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
|
||||
|
||||
pmic: pfuze100@08 {
|
||||
pmic: pfuze100@8 {
|
||||
compatible = "fsl,pfuze100";
|
||||
reg = <0x08>;
|
||||
|
||||
|
@ -122,7 +122,7 @@ Example 1: PFUZE100
|
|||
|
||||
Example 2: PFUZE200
|
||||
|
||||
pmic: pfuze200@08 {
|
||||
pmic: pfuze200@8 {
|
||||
compatible = "fsl,pfuze200";
|
||||
reg = <0x08>;
|
||||
|
||||
|
@ -216,7 +216,7 @@ Example 2: PFUZE200
|
|||
|
||||
Example 3: PFUZE3000
|
||||
|
||||
pmic: pfuze3000@08 {
|
||||
pmic: pfuze3000@8 {
|
||||
compatible = "fsl,pfuze3000";
|
||||
reg = <0x08>;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ Qualcomm SPMI Regulators
|
|||
"qcom,pm8916-regulators"
|
||||
"qcom,pm8941-regulators"
|
||||
"qcom,pm8994-regulators"
|
||||
"qcom,pmi8994-regulators"
|
||||
|
||||
- interrupts:
|
||||
Usage: optional
|
||||
|
@ -100,6 +101,15 @@ Qualcomm SPMI Regulators
|
|||
Definition: Reference to regulator supplying the input pin, as
|
||||
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
|
||||
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,
|
||||
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 -
|
||||
see regulator.txt - with additional custom properties described below:
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
Renesas MSIOF spi controller
|
||||
|
||||
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-r8a7792" (R-Car V2H)
|
||||
"renesas,msiof-r8a7793" (R-Car M2-N)
|
||||
|
@ -10,7 +12,7 @@ Required properties:
|
|||
"renesas,msiof-r8a7796" (R-Car M3-W)
|
||||
"renesas,msiof-sh73a0" (SH-Mobile AG5)
|
||||
"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,sh-msiof" (deprecated)
|
||||
|
||||
|
|
|
@ -24,6 +24,16 @@ Required properties:
|
|||
based on a specific SoC configuration.
|
||||
- interrupts: interrupt number mapped to CPU.
|
||||
- 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:
|
||||
- cs-gpios: gpio chip selects
|
||||
|
|
|
@ -5,11 +5,14 @@ Required properties:
|
|||
"renesas,rspi-<soctype>", "renesas,rspi" as fallback.
|
||||
For Renesas Serial Peripheral Interface on RZ/A1H:
|
||||
"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.
|
||||
Examples with soctypes are:
|
||||
- "renesas,rspi-sh7757" (SH)
|
||||
- "renesas,rspi-r7s72100" (RZ/A1H)
|
||||
- "renesas,qspi-r8a7743" (RZ/G1M)
|
||||
- "renesas,qspi-r8a7745" (RZ/G1E)
|
||||
- "renesas,qspi-r8a7790" (R-Car H2)
|
||||
- "renesas,qspi-r8a7791" (R-Car M2-W)
|
||||
- "renesas,qspi-r8a7792" (R-Car V2H)
|
||||
|
|
|
@ -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)
|
||||
This is a fallback for the above renesas,cmt-48-* entries.
|
||||
|
||||
- "renesas,cmt0-r8a73a4" for the 32-bit CMT0 device included in r8a73a4.
|
||||
- "renesas,cmt1-r8a73a4" for the 48-bit CMT1 device included in r8a73a4.
|
||||
- "renesas,cmt0-r8a7790" for the 32-bit CMT0 device included in r8a7790.
|
||||
- "renesas,cmt1-r8a7790" for the 48-bit CMT1 device included in r8a7790.
|
||||
- "renesas,cmt0-r8a7791" for the 32-bit CMT0 device included in r8a7791.
|
||||
- "renesas,cmt1-r8a7791" for the 48-bit CMT1 device included in r8a7791.
|
||||
- "renesas,cmt0-r8a7793" for the 32-bit CMT0 device included in r8a7793.
|
||||
- "renesas,cmt1-r8a7793" for the 48-bit CMT1 device included in r8a7793.
|
||||
- "renesas,cmt0-r8a7794" for the 32-bit CMT0 device included in r8a7794.
|
||||
- "renesas,cmt1-r8a7794" for the 48-bit CMT1 device included in r8a7794.
|
||||
- "renesas,r8a73a4-cmt0" for the 32-bit CMT0 device included in r8a73a4.
|
||||
- "renesas,r8a73a4-cmt1" for the 48-bit CMT1 device included in r8a73a4.
|
||||
- "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
|
||||
- "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790.
|
||||
- "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791.
|
||||
- "renesas,r8a7791-cmt1" for the 48-bit CMT1 device included in r8a7791.
|
||||
- "renesas,r8a7793-cmt0" for the 32-bit CMT0 device included in r8a7793.
|
||||
- "renesas,r8a7793-cmt1" for the 48-bit CMT1 device included in r8a7793.
|
||||
- "renesas,r8a7794-cmt0" for the 32-bit CMT0 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-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
|
||||
|
||||
cmt0: timer@ffca0000 {
|
||||
compatible = "renesas,cmt0-r8a7790", "renesas,rcar-gen2-cmt0";
|
||||
compatible = "renesas,r8a7790-cmt0", "renesas,rcar-gen2-cmt0";
|
||||
reg = <0 0xffca0000 0 0x1004>;
|
||||
interrupts = <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 {
|
||||
compatible = "renesas,cmt1-r8a7790", "renesas,rcar-gen2-cmt1";
|
||||
compatible = "renesas,r8a7790-cmt1", "renesas,rcar-gen2-cmt1";
|
||||
reg = <0 0xe6130000 0 0x1004>;
|
||||
interrupts = <0 120 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
|
||||
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
|
||||
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
|
||||
mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
||||
mcube,mc3230 mCube 3-axis 8-bit digital accelerometer
|
||||
|
|
|
@ -246,6 +246,7 @@ onion Onion Corporation
|
|||
onnn ON Semiconductor Corp.
|
||||
ontat On Tat Industrial Company
|
||||
opencores OpenCores.org
|
||||
openrisc OpenRISC.io
|
||||
option Option NV
|
||||
ORCL Oracle Corporation
|
||||
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.
|
||||
|
||||
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
|
||||
source.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
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:
|
||||
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
|
||||
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:
|
||||
% modprobe dmatest channel=dma0chan0 timeout=2000 iterations=1 run=1
|
||||
Example of usage: ::
|
||||
|
||||
...or:
|
||||
% 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
|
||||
% modprobe dmatest channel=dma0chan0 timeout=2000 iterations=1 run=1
|
||||
|
||||
...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
|
||||
command:
|
||||
% ls -1 /sys/class/dma/
|
||||
...or on the kernel command line: ::
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
The following command returns the state of the test.
|
||||
% cat /sys/module/dmatest/parameters/run
|
||||
The following command returns the state of the test. ::
|
||||
|
||||
% cat /sys/module/dmatest/parameters/run
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
waiting is disabled.
|
||||
|
||||
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
|
||||
Example: ::
|
||||
|
||||
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
|
||||
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..."
|
||||
|
||||
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
|
||||
% grep -H . /sys/module/dmatest/parameters/*
|
||||
case. You always could check them at run-time by running ::
|
||||
|
||||
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:
|
||||
% dmesg | tail -n 1
|
||||
dmatest: result dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
|
||||
"dmatest: result <channel>: <test id>: '<error msg>' with src_off=<val> dst_off=<val> len=<val> (<err code>)"
|
||||
|
||||
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 parens represents additional information, e.g. error code, error counter,
|
||||
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.
|
||||
|
||||
Example:
|
||||
% dmesg | tail -n 1
|
||||
dmatest: dma0chan0-copy0: summary 1 test, 0 failures 1000 iops 100000 KB/s (0)
|
||||
Example: ::
|
||||
|
||||
% 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
|
||||
above format.
|
|
@ -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`
|
|
@ -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)
|
|
@ -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
|
||||
gpio
|
||||
misc_devices
|
||||
dmaengine/index
|
||||
|
||||
.. 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
|
||||
the text format and ignore most of it. More detailed device status
|
||||
(including class and vendor status) is available from device-specific
|
||||
files. For information about the current format of this file, see the
|
||||
``Documentation/usb/proc_usb_info.txt`` file in your Linux kernel
|
||||
sources.
|
||||
files. For information about the current format of this file, see below.
|
||||
|
||||
This file, in combination with the poll() system call, can also be used
|
||||
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
|
||||
modules that can be used to test the following notifiers.
|
||||
|
||||
* CPU notifier
|
||||
* PM notifier
|
||||
* Memory hotplug notifier
|
||||
* powerpc pSeries reconfig 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
|
||||
----------------------------------
|
||||
This feature is controlled through debugfs interface
|
||||
|
|
|
@ -77,8 +77,8 @@ C. Boot options
|
|||
1. fbcon=font:<name>
|
||||
|
||||
Select the initial font to use. The value 'name' can be any of the
|
||||
compiled-in fonts: VGA8x16, 7x14, 10x18, VGA8x8, MINI4x6, RomanLarge,
|
||||
SUN8x16, SUN12x22, ProFont6x11, Acorn8x8, PEARL8x8.
|
||||
compiled-in fonts: 10x18, 6x10, 7x14, Acorn8x8, MINI4x6,
|
||||
PEARL8x8, ProFont6x11, SUN12x22, SUN8x16, VGA8x16, VGA8x8.
|
||||
|
||||
Note, not all drivers can handle font with widths not divisible by 8,
|
||||
such as vga16fb.
|
||||
|
|
|
@ -34,6 +34,6 @@
|
|||
| tile: | TODO |
|
||||
| um: | TODO |
|
||||
| unicore32: | TODO |
|
||||
| x86: | ok |
|
||||
| x86: | ok | 64-bit only
|
||||
| xtensa: | TODO |
|
||||
-----------------------
|
||||
|
|
|
@ -62,7 +62,7 @@ disabled, fcntl(fd, F_NOTIFY, ...) will return -EINVAL.
|
|||
|
||||
Example
|
||||
-------
|
||||
See Documentation/filesystems/dnotify_test.c for an example.
|
||||
See tools/testing/selftests/filesystems/dnotify_test.c for an example.
|
||||
|
||||
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
|
||||
flex_bg feature
|
||||
* 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
|
||||
* 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)
|
||||
|
||||
[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
|
||||
|
||||
* 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
|
||||
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
|
||||
|
@ -602,7 +602,7 @@ Table of Ext4 specific ioctls
|
|||
bitmaps and inode table, the userspace tool thus
|
||||
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
|
||||
the specified inode with inode
|
||||
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
|
||||
`seq` number from the `nameidata`, so it needs to be extra careful
|
||||
when accessing fields in the dentry. This "extra care" typically
|
||||
involves using `ACCESS_ONCE()` or the newer [`READ_ONCE()`] to access
|
||||
fields, and verifying the result is not NULL before using it. This
|
||||
pattern can be see in `nfs_lookup_revalidate()`.
|
||||
involves using [`READ_ONCE()`] to access fields, and verifying the
|
||||
result is not NULL before using it. This pattern can be seen in
|
||||
`nfs_lookup_revalidate()`.
|
||||
|
||||
A pair of patterns
|
||||
------------------
|
||||
|
|
|
@ -12,7 +12,7 @@ To support these disparate requirements, the Linux USB system provides
|
|||
HID events to two separate interfaces:
|
||||
* the input subsystem, which converts HID events into normal input
|
||||
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 data flow for a HID event produced by a device is something like
|
||||
|
|
|
@ -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
|
||||
measurement and decrease power consumption, while losing on precision.
|
||||
|
||||
Some options may be set directly in the sht15_platform_data structure
|
||||
or via sysfs attributes.
|
||||
Some options may be set via sysfs attributes.
|
||||
|
||||
Notes:
|
||||
* The regulator supply name is set to "vcc".
|
||||
|
|
|
@ -230,4 +230,5 @@ Historic Edits
|
|||
2005-03-19 - Dominic Cerquetti <binary1230@yahoo.com>
|
||||
- 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
|
||||
|
||||
1. Concepts: Kprobes, Jprobes, Return Probes
|
||||
1. Concepts: Kprobes, and Return Probes
|
||||
2. Architectures Supported
|
||||
3. Configuring Kprobes
|
||||
4. API Reference
|
||||
|
@ -16,12 +16,12 @@ Kernel Probes (Kprobes)
|
|||
6. Probe Overhead
|
||||
7. TODO
|
||||
8. Kprobes Example
|
||||
9. Jprobes Example
|
||||
10. Kretprobes Example
|
||||
9. Kretprobes Example
|
||||
10. Deprecated Features
|
||||
Appendix A: The kprobes debugfs 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
|
||||
|
@ -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
|
||||
:ref:`kprobes_blacklist`)
|
||||
|
||||
There are currently three types of probes: kprobes, jprobes, and
|
||||
kretprobes (also called return probes). A kprobe can be inserted
|
||||
on virtually any instruction in the kernel. A jprobe is inserted at
|
||||
the entry to a kernel function, and provides convenient access to the
|
||||
function's arguments. A return probe fires when a specified function
|
||||
returns.
|
||||
There are currently two types of probes: kprobes, and kretprobes
|
||||
(also called return probes). A kprobe can be inserted on virtually
|
||||
any instruction in the kernel. A return probe fires when a specified
|
||||
function returns.
|
||||
|
||||
In the typical case, Kprobes-based instrumentation is packaged as
|
||||
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.
|
||||
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
|
||||
-------------
|
||||
|
||||
|
@ -245,8 +204,7 @@ Pre-optimization
|
|||
After preparing the detour buffer, Kprobes verifies that none of the
|
||||
following situations exist:
|
||||
|
||||
- The probe has either a break_handler (i.e., it's a jprobe) or a
|
||||
post_handler.
|
||||
- The probe has a post_handler.
|
||||
- Other instructions in the optimized region are probed.
|
||||
- The probe is disabled.
|
||||
|
||||
|
@ -331,7 +289,7 @@ rejects registering it, if the given address is in the blacklist.
|
|||
Architectures Supported
|
||||
=======================
|
||||
|
||||
Kprobes, jprobes, and return probes are implemented on the following
|
||||
Kprobes and return probes are implemented on the following
|
||||
architectures:
|
||||
|
||||
- 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).
|
||||
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
|
||||
------------------
|
||||
|
||||
|
@ -513,7 +450,6 @@ unregister_*probe
|
|||
|
||||
#include <linux/kprobes.h>
|
||||
void unregister_kprobe(struct kprobe *kp);
|
||||
void unregister_jprobe(struct jprobe *jp);
|
||||
void unregister_kretprobe(struct kretprobe *rp);
|
||||
|
||||
Removes the specified probe. The unregister function can be called
|
||||
|
@ -532,7 +468,6 @@ register_*probes
|
|||
#include <linux/kprobes.h>
|
||||
int register_kprobes(struct kprobe **kps, 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
|
||||
error occurs during registration, all probes in the array, up to
|
||||
|
@ -555,7 +490,6 @@ unregister_*probes
|
|||
#include <linux/kprobes.h>
|
||||
void unregister_kprobes(struct kprobe **kps, 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.
|
||||
|
||||
|
@ -574,7 +508,6 @@ disable_*probe
|
|||
#include <linux/kprobes.h>
|
||||
int disable_kprobe(struct kprobe *kp);
|
||||
int disable_kretprobe(struct kretprobe *rp);
|
||||
int disable_jprobe(struct jprobe *jp);
|
||||
|
||||
Temporarily disables the specified ``*probe``. You can enable it again by using
|
||||
enable_*probe(). You must specify the probe which has been registered.
|
||||
|
@ -587,7 +520,6 @@ enable_*probe
|
|||
#include <linux/kprobes.h>
|
||||
int enable_kprobe(struct kprobe *kp);
|
||||
int enable_kretprobe(struct kretprobe *rp);
|
||||
int enable_jprobe(struct jprobe *jp);
|
||||
|
||||
Enables ``*probe`` which has been disabled by disable_*probe(). You must specify
|
||||
the probe which has been registered.
|
||||
|
@ -595,12 +527,10 @@ the probe which has been registered.
|
|||
Kprobes Features and Limitations
|
||||
================================
|
||||
|
||||
Kprobes allows multiple probes at the same address. Currently,
|
||||
however, there cannot be multiple jprobes on the same function at
|
||||
the same time. Also, a probepoint for which there is a jprobe or
|
||||
a post_handler cannot be optimized. So if you install a jprobe,
|
||||
or a kprobe with a post_handler, at an optimized probepoint, the
|
||||
probepoint will be unoptimized automatically.
|
||||
Kprobes allows multiple probes at the same address. Also,
|
||||
a probepoint for which there is a post_handler cannot be optimized.
|
||||
So if you install 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 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
|
||||
a stack other than that of the current task, registering a return
|
||||
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
|
||||
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
|
||||
microseconds to process. Specifically, a benchmark that hits the same
|
||||
probepoint repeatedly, firing a simple handler each time, reports 1-2
|
||||
million hits per second, depending on the architecture. A jprobe or
|
||||
return-probe hit typically takes 50-75% longer than a kprobe hit.
|
||||
million hits per second, depending on the architecture. A return-probe
|
||||
hit typically takes 50-75% longer than a kprobe hit.
|
||||
When you have a return probe set on a function, adding a kprobe at
|
||||
the entry to that function adds essentially no overhead.
|
||||
|
||||
Here are sample overhead figures (in usec) for different architectures::
|
||||
|
||||
k = kprobe; j = jprobe; r = return probe; kr = kprobe + return probe
|
||||
on same function; jr = jprobe + return probe on same function::
|
||||
k = kprobe; r = return probe; kr = kprobe + return probe
|
||||
on same function
|
||||
|
||||
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
|
||||
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)
|
||||
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
|
||||
------------------------
|
||||
|
@ -755,11 +685,6 @@ Kprobes Example
|
|||
|
||||
See samples/kprobes/kprobe_example.c
|
||||
|
||||
Jprobes Example
|
||||
===============
|
||||
|
||||
See samples/kprobes/jprobe_example.c
|
||||
|
||||
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.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
|
||||
=============================
|
||||
|
@ -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::
|
||||
|
||||
c015d71a k vfs_read+0x0
|
||||
c011a316 j do_fork+0x0
|
||||
c03dedc5 r tcp_v4_rcv+0x0
|
||||
|
||||
The first column provides the kernel address where the probe is inserted.
|
||||
The second column identifies the type of probe (k - kprobe, r - kretprobe
|
||||
and j - jprobe), while the third column specifies the symbol+offset of
|
||||
the probe. If the probed function belongs to a module, the module name
|
||||
is also specified. Following columns show probe status. If the probe is on
|
||||
The second column identifies the type of probe (k - kprobe and r - kretprobe)
|
||||
while the third column specifies the symbol+offset of the probe.
|
||||
If the probed function belongs to a module, the module name is also
|
||||
specified. Following columns show probe status. If the probe is on
|
||||
a virtual address that is no longer valid (module init sections, module
|
||||
virtual addresses that correspond to modules that've been unloaded),
|
||||
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:
|
||||
|
||||
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:
|
||||
|
||||
|
@ -287,7 +287,7 @@ MINIMUM_BATTERY_MINUTES=10
|
|||
|
||||
# Should the maximum CPU frequency be adjusted down while on battery?
|
||||
# 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
|
||||
|
||||
# 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'}
|
||||
|
||||
# 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'}
|
||||
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.
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
|
@ -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.
|
||||
Exceptions are:
|
||||
- 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:
|
||||
|
||||
|
@ -72,7 +72,7 @@ Useful parameters for verbosity level and debugging the dst module:
|
|||
The autodetected values are determined by the cards' "response string".
|
||||
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.
|
||||
Please also see Documentation/dvb/ci.txt.
|
||||
Please also see Documentation/media/dvb-drivers/ci.rst.
|
||||
|
||||
Running multiple cards
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -100,7 +100,7 @@ Examples of card ID's:
|
|||
|
||||
$ 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.
|
||||
|
||||
Probing the cards with broken PCI subsystem ID
|
||||
|
|
|
@ -431,7 +431,7 @@ MPEG stream.
|
|||
*Historical context*: This format specification originates from a
|
||||
custom, embedded, sliced VBI data format used by the ``ivtv`` driver.
|
||||
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
|
||||
by the CX23415 MPEG decoder's capabilities and limitations with respect
|
||||
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``
|
||||
- VBI in private packets, IVTV format (documented in the kernel
|
||||
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/>`__
|
||||
|
||||
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``
|
||||
|
|
|
@ -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
|
||||
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
|
||||
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
|
||||
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::
|
||||
:header-rows: 0
|
||||
|
|
|
@ -53,7 +53,7 @@ CONTENTS
|
|||
- SMP barrier pairing.
|
||||
- Examples of memory barrier sequences.
|
||||
- Read memory barriers vs load speculation.
|
||||
- Transitivity
|
||||
- Multicopy atomicity.
|
||||
|
||||
(*) Explicit kernel barriers.
|
||||
|
||||
|
@ -383,8 +383,8 @@ Memory barriers come in four basic varieties:
|
|||
to have any effect on loads.
|
||||
|
||||
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
|
||||
occur in the sequence _before_ all the stores after the write barrier.
|
||||
memory system as time progresses. All stores _before_ a write barrier
|
||||
will occur _before_ all the stores after the write barrier.
|
||||
|
||||
[!] Note that write barriers should normally be paired with read or data
|
||||
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.
|
||||
|
||||
|
||||
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,
|
||||
for example. See rcu_assign_pointer() and rcu_dereference() in
|
||||
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
|
||||
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
|
||||
======================= =======================
|
||||
r1 = READ_ONCE(x); r2 = READ_ONCE(y);
|
||||
if (r1 > 0) if (r2 > 0)
|
||||
WRITE_ONCE(y, 1); WRITE_ONCE(x, 1);
|
||||
Note well that the ordering provided by a control dependency is local
|
||||
to the CPU containing it. See the section on "Multicopy atomicity"
|
||||
for more information.
|
||||
|
||||
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:
|
||||
|
||||
|
@ -922,8 +900,8 @@ In summary:
|
|||
|
||||
(*) Control dependencies pair normally with other types of barriers.
|
||||
|
||||
(*) Control dependencies do -not- provide transitivity. If you
|
||||
need transitivity, use smp_mb().
|
||||
(*) Control dependencies do -not- provide multicopy atomicity. If you
|
||||
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
|
||||
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.
|
||||
|
||||
General barriers pair with each other, though they also pair with most
|
||||
other types of barriers, albeit without transitivity. An acquire barrier
|
||||
pairs with a release barrier, but both may also pair with other barriers,
|
||||
including of course general barriers. A write barrier pairs with a data
|
||||
dependency barrier, a control dependency, an acquire barrier, a release
|
||||
barrier, a read barrier, or a general barrier. Similarly a read barrier,
|
||||
control dependency, or a data dependency barrier pairs with a write
|
||||
barrier, an acquire barrier, a release barrier, or a general barrier:
|
||||
other types of barriers, albeit without multicopy atomicity. An acquire
|
||||
barrier pairs with a release barrier, but both may also pair with other
|
||||
barriers, including of course general barriers. A write barrier pairs
|
||||
with a data dependency barrier, a control dependency, an acquire barrier,
|
||||
a release barrier, a read barrier, or a general barrier. Similarly a
|
||||
read barrier, control dependency, or a data dependency barrier pairs
|
||||
with a write barrier, an acquire barrier, a release barrier, or a
|
||||
general barrier:
|
||||
|
||||
CPU 1 CPU 2
|
||||
=============== ===============
|
||||
|
@ -968,7 +947,7 @@ Or even:
|
|||
=============== ===============================
|
||||
r1 = READ_ONCE(y);
|
||||
<general barrier>
|
||||
WRITE_ONCE(y, 1); if (r2 = READ_ONCE(x)) {
|
||||
WRITE_ONCE(x, 1); if (r2 = READ_ONCE(x)) {
|
||||
<implicit control dependency>
|
||||
WRITE_ONCE(y, 1);
|
||||
}
|
||||
|
@ -1359,64 +1338,79 @@ the speculation will be cancelled and the value reloaded:
|
|||
retrieved : : +-------+
|
||||
|
||||
|
||||
TRANSITIVITY
|
||||
------------
|
||||
MULTICOPY ATOMICITY
|
||||
--------------------
|
||||
|
||||
Transitivity is a deeply intuitive notion about ordering that is not
|
||||
always provided by real computer systems. The following example
|
||||
demonstrates transitivity:
|
||||
Multicopy atomicity is a deeply intuitive notion about ordering that is
|
||||
not always provided by real computer systems, namely that a given store
|
||||
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
|
||||
======================= ======================= =======================
|
||||
{ X = 0, Y = 0 }
|
||||
STORE X=1 LOAD X STORE Y=1
|
||||
<general barrier> <general barrier>
|
||||
LOAD Y LOAD X
|
||||
STORE X=1 r1=LOAD X (reads 1) LOAD Y (reads 1)
|
||||
<general barrier> <read barrier>
|
||||
STORE Y=r1 LOAD X
|
||||
|
||||
Suppose that CPU 2's load from X returns 1 and its load from Y returns 0.
|
||||
This indicates that CPU 2's load from X in some sense follows CPU 1's
|
||||
store to X and that CPU 2's load from Y in some sense preceded CPU 3's
|
||||
store to Y. The question is then "Can CPU 3's load from X return 0?"
|
||||
Suppose that CPU 2's load from X returns 1, which it then stores to Y,
|
||||
and CPU 3's load from Y returns 1. This indicates that CPU 1's store
|
||||
to X precedes CPU 2's load from X and that CPU 2's store to Y precedes
|
||||
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.
|
||||
This expectation is an example of transitivity: if a load executing on
|
||||
CPU A follows a load from the same variable executing on CPU B, then
|
||||
CPU A's load must either return the same value that CPU B's load did,
|
||||
or must return some later value.
|
||||
This expectation follows from multicopy atomicity: if a load executing
|
||||
on CPU B follows a load from the same variable executing on CPU A (and
|
||||
CPU A did not originally store the value which it read), then on
|
||||
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
|
||||
transitivity. Therefore, in the above example, if CPU 2's load from X
|
||||
returns 1 and its load from Y returns 0, then CPU 3's load from X must
|
||||
also return 1.
|
||||
The use of a general memory barrier in the example above compensates
|
||||
for any lack of multicopy atomicity. In the example, if CPU 2's load
|
||||
from X returns 1 and CPU 3's load from Y returns 1, then CPU 3's load
|
||||
from X must indeed also return 1.
|
||||
|
||||
However, transitivity is -not- guaranteed for read or write barriers.
|
||||
For example, suppose that CPU 2's general barrier in the above example
|
||||
is changed to a read barrier as shown below:
|
||||
However, dependencies, read barriers, and write barriers are not always
|
||||
able to compensate for non-multicopy atomicity. For example, suppose
|
||||
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
|
||||
======================= ======================= =======================
|
||||
{ X = 0, Y = 0 }
|
||||
STORE X=1 LOAD X STORE Y=1
|
||||
<read barrier> <general barrier>
|
||||
LOAD Y LOAD X
|
||||
STORE X=1 r1=LOAD X (reads 1) LOAD Y (reads 1)
|
||||
<data dependency> <read barrier>
|
||||
STORE Y=r1 LOAD X (reads 0)
|
||||
|
||||
This substitution destroys transitivity: in this example, it is perfectly
|
||||
legal for CPU 2's load from X to return 1, its load from Y to return 0,
|
||||
and CPU 3's load from X to return 0.
|
||||
This substitution allows non-multicopy atomicity to run rampant: in
|
||||
this example, it is perfectly legal for CPU 2's load from X to return 1,
|
||||
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
|
||||
of loads, it does not guarantee to order CPU 1's store. Therefore, if
|
||||
this example runs on a system where CPUs 1 and 2 share a store buffer
|
||||
or a level of cache, CPU 2 might have early access to CPU 1's writes.
|
||||
General barriers are therefore required to ensure that all CPUs agree
|
||||
on the combined order of CPU 1's and CPU 2's accesses.
|
||||
The key point is that although CPU 2's data dependency orders its load
|
||||
and store, it does not guarantee to order CPU 1's store. Thus, if this
|
||||
example runs on a non-multicopy-atomic system where CPUs 1 and 2 share a
|
||||
store buffer or a level of cache, CPU 2 might have early access to CPU 1's
|
||||
writes. General barriers are therefore required to ensure that all CPUs
|
||||
agree on the combined order of multiple accesses.
|
||||
|
||||
General barriers provide "global transitivity", so that all CPUs will
|
||||
agree on the order of operations. In contrast, a chain of release-acquire
|
||||
pairs provides only "local transitivity", so 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 Herman Hollerith:
|
||||
General barriers can compensate not only for non-multicopy atomicity,
|
||||
but can also generate additional ordering that can ensure that -all-
|
||||
CPUs will perceive the same order of -all- operations. In contrast, a
|
||||
chain of release-acquire pairs do not provide this additional ordering,
|
||||
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;
|
||||
|
||||
|
@ -1448,9 +1442,9 @@ For example, switching to C code in deference to Herman Hollerith:
|
|||
r3 = READ_ONCE(u);
|
||||
}
|
||||
|
||||
Because cpu0(), cpu1(), and cpu2() participate in a local transitive
|
||||
chain of smp_store_release()/smp_load_acquire() pairs, the following
|
||||
outcome is prohibited:
|
||||
Because cpu0(), cpu1(), and cpu2() participate in a chain of
|
||||
smp_store_release()/smp_load_acquire() pairs, the following outcome
|
||||
is prohibited:
|
||||
|
||||
r0 == 1 && r1 == 1 && r2 == 1
|
||||
|
||||
|
@ -1460,9 +1454,9 @@ outcome is prohibited:
|
|||
|
||||
r1 == 1 && r5 == 0
|
||||
|
||||
However, the transitivity of release-acquire is local to the participating
|
||||
CPUs and does not apply to cpu3(). Therefore, the following outcome
|
||||
is possible:
|
||||
However, the ordering provided by a release-acquire chain is local
|
||||
to the CPUs participating in that chain and does not apply to cpu3(),
|
||||
at least aside from stores. Therefore, the following outcome is possible:
|
||||
|
||||
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
|
||||
consistent system where nothing is ever reordered.
|
||||
|
||||
To reiterate, if your code requires global transitivity, use general
|
||||
barriers throughout.
|
||||
To reiterate, if your code requires full ordering of all operations,
|
||||
use general barriers throughout.
|
||||
|
||||
|
||||
========================
|
||||
|
@ -1886,18 +1880,6 @@ There are some more advanced barrier functions:
|
|||
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_rmb();
|
||||
|
||||
|
@ -3101,6 +3083,9 @@ AMD64 Architecture Programmer's Manual Volume 2: System Programming
|
|||
Chapter 7.1: Memory-Access Ordering
|
||||
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:
|
||||
System Programming Guide
|
||||
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 J: Programming with the Memory Models
|
||||
|
||||
Storage in the PowerPC (Stone and Fitzgerald)
|
||||
|
||||
UltraSPARC Programmer Reference Manual
|
||||
Chapter 5: Memory Accesses and Cacheability
|
||||
Chapter 15: Sparc-V9 Memory Models
|
||||
|
|
|
@ -332,8 +332,8 @@ References
|
|||
[5] "MBIM (Mobile Broadband Interface Model) Registry"
|
||||
- http://compliance.usb.org/mbim/
|
||||
|
||||
[6] "/dev/bus/usb filesystem output"
|
||||
- Documentation/usb/proc_usb_info.txt
|
||||
[6] "/sys/kernel/debug/usb/devices output format"
|
||||
- Documentation/driver-api/usb/usb.rst
|
||||
|
||||
[7] "/sys/bus/usb/devices/.../descriptors"
|
||||
- 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.
|
||||
|
||||
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
|
||||
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
|
||||
|
|
|
@ -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
|
||||
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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -7,13 +7,7 @@ target architecture, specifically, is the 32-bit OpenRISC 1000 family (or1k).
|
|||
For information about OpenRISC processors and ongoing development:
|
||||
|
||||
website http://openrisc.io
|
||||
|
||||
For more information about Linux on OpenRISC, please contact South Pole AB.
|
||||
|
||||
email: info@southpole.se
|
||||
|
||||
website: http://southpole.se
|
||||
http://southpoleconsulting.com
|
||||
email openrisc@lists.librecores.org
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
|
@ -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
|
||||
in place are outlined here.
|
||||
|
||||
1) The toolchain can be obtained from openrisc.io. Instructions for building
|
||||
a toolchain can be found at:
|
||||
1) Toolchain
|
||||
|
||||
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
|
||||
your OpenRISC Linux kernel if you don't have an OpenRISC processor at hand.
|
||||
2) Building
|
||||
|
||||
git clone https://github.com/openrisc/or1ksim.git
|
||||
|
||||
cd or1ksim
|
||||
./configure --prefix=$OPENRISC_PREFIX
|
||||
make
|
||||
make install
|
||||
|
||||
3) Linux kernel
|
||||
|
||||
Build the kernel as usual
|
||||
Build the Linux kernel as usual
|
||||
|
||||
make ARCH=openrisc defconfig
|
||||
make ARCH=openrisc
|
||||
|
||||
4) Run in architectural simulator
|
||||
3) Running on FPGA (optional)
|
||||
|
||||
Grab the or1ksim platform configuration file (from the or1ksim source) and
|
||||
together with your freshly built vmlinux, run your kernel with the following
|
||||
incantation:
|
||||
The OpenRISC community typically uses FuseSoC to manage building and programming
|
||||
an SoC into an FPGA. The below is an example of programming a De0 Nano
|
||||
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.
|
||||
|
||||
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
|
||||
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).
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
To select an option, write the string representing it to /sys/power/disk.
|
||||
|
|
|
@ -8,7 +8,7 @@ management. Based on previous work by Patrick Mochel <mochel@transmeta.com>
|
|||
|
||||
This document only covers the aspects of power management specific to PCI
|
||||
devices. For general description of the kernel's interfaces related to device
|
||||
power management refer to Documentation/power/admin-guide/devices.rst and
|
||||
power management refer to Documentation/driver-api/pm/devices.rst and
|
||||
Documentation/power/runtime_pm.txt.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
@ -417,7 +417,7 @@ pm->runtime_idle() callback.
|
|||
2.4. System-Wide Power Transitions
|
||||
----------------------------------
|
||||
There are a few different types of system-wide power transitions, described in
|
||||
Documentation/power/admin-guide/devices.rst. Each of them requires devices to be handled
|
||||
Documentation/driver-api/pm/devices.rst. Each of them requires devices to be handled
|
||||
in a specific way and the PM core executes subsystem-level power management
|
||||
callbacks for this purpose. They are executed in phases such that each phase
|
||||
involves executing the same subsystem-level callback for every device belonging
|
||||
|
@ -623,7 +623,7 @@ System restore requires a hibernation image to be loaded into memory and the
|
|||
pre-hibernation memory contents to be restored before the pre-hibernation system
|
||||
activity can be resumed.
|
||||
|
||||
As described in Documentation/power/admin-guide/devices.rst, the hibernation image is loaded
|
||||
As described in Documentation/driver-api/pm/devices.rst, the hibernation image is loaded
|
||||
into memory by a fresh instance of the kernel, called the boot kernel, which in
|
||||
turn is loaded and run by a boot loader in the usual way. After the boot kernel
|
||||
has loaded the image, it needs to replace its own code and data with the code
|
||||
|
@ -677,7 +677,7 @@ controlling the runtime power management of their devices.
|
|||
|
||||
At the time of this writing there are two ways to define power management
|
||||
callbacks for a PCI device driver, the recommended one, based on using a
|
||||
dev_pm_ops structure described in Documentation/power/admin-guide/devices.rst, and the
|
||||
dev_pm_ops structure described in Documentation/driver-api/pm/devices.rst, and the
|
||||
"legacy" one, in which the .suspend(), .suspend_late(), .resume_early(), and
|
||||
.resume() callbacks from struct pci_driver are used. The legacy approach,
|
||||
however, doesn't allow one to define runtime power management callbacks and is
|
||||
|
@ -1046,5 +1046,5 @@ PCI Local Bus Specification, Rev. 3.0
|
|||
PCI Bus Power Management Interface Specification, Rev. 1.2
|
||||
Advanced Configuration and Power Interface (ACPI) Specification, Rev. 3.0b
|
||||
PCI Express Base Specification, Rev. 2.0
|
||||
Documentation/power/admin-guide/devices.rst
|
||||
Documentation/driver-api/pm/devices.rst
|
||||
Documentation/power/runtime_pm.txt
|
||||
|
|
|
@ -680,7 +680,7 @@ left in runtime suspend. If that happens, the PM core will not execute any
|
|||
system suspend and resume callbacks for all of those devices, except for the
|
||||
complete callback, which is then entirely responsible for handling the device
|
||||
as appropriate. This only applies to system suspend transitions that are not
|
||||
related to hibernation (see Documentation/power/admin-guide/devices.rst for more
|
||||
related to hibernation (see Documentation/driver-api/pm/devices.rst for more
|
||||
information).
|
||||
|
||||
The PM core does its best to reduce the probability of race conditions between
|
||||
|
|