aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/RCU/UP.txt
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/RCU/UP.txt
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'Documentation/RCU/UP.txt')
-rw-r--r--Documentation/RCU/UP.txt64
1 files changed, 64 insertions, 0 deletions
diff --git a/Documentation/RCU/UP.txt b/Documentation/RCU/UP.txt
new file mode 100644
index 000000000000..551a803d82a8
--- /dev/null
+++ b/Documentation/RCU/UP.txt
@@ -0,0 +1,64 @@
1RCU on Uniprocessor Systems
2
3
4A common misconception is that, on UP systems, the call_rcu() primitive
5may immediately invoke its function, and that the synchronize_kernel
6primitive may return immediately. The basis of this misconception
7is that since there is only one CPU, it should not be necessary to
8wait for anything else to get done, since there are no other CPUs for
9anything else to be happening on. Although this approach will sort of
10work a surprising amount of the time, it is a very bad idea in general.
11This document presents two examples that demonstrate exactly how bad an
12idea this is.
13
14
15Example 1: softirq Suicide
16
17Suppose that an RCU-based algorithm scans a linked list containing
18elements A, B, and C in process context, and can delete elements from
19this same list in softirq context. Suppose that the process-context scan
20is referencing element B when it is interrupted by softirq processing,
21which deletes element B, and then invokes call_rcu() to free element B
22after a grace period.
23
24Now, if call_rcu() were to directly invoke its arguments, then upon return
25from softirq, the list scan would find itself referencing a newly freed
26element B. This situation can greatly decrease the life expectancy of
27your kernel.
28
29
30Example 2: Function-Call Fatality
31
32Of course, one could avert the suicide described in the preceding example
33by having call_rcu() directly invoke its arguments only if it was called
34from process context. However, this can fail in a similar manner.
35
36Suppose that an RCU-based algorithm again scans a linked list containing
37elements A, B, and C in process contexts, but that it invokes a function
38on each element as it is scanned. Suppose further that this function
39deletes element B from the list, then passes it to call_rcu() for deferred
40freeing. This may be a bit unconventional, but it is perfectly legal
41RCU usage, since call_rcu() must wait for a grace period to elapse.
42Therefore, in this case, allowing call_rcu() to immediately invoke
43its arguments would cause it to fail to make the fundamental guarantee
44underlying RCU, namely that call_rcu() defers invoking its arguments until
45all RCU read-side critical sections currently executing have completed.
46
47Quick Quiz: why is it -not- legal to invoke synchronize_kernel() in
48this case?
49
50
51Summary
52
53Permitting call_rcu() to immediately invoke its arguments or permitting
54synchronize_kernel() to immediately return breaks RCU, even on a UP system.
55So do not do it! Even on a UP system, the RCU infrastructure -must-
56respect grace periods.
57
58
59Answer to Quick Quiz
60
61The calling function is scanning an RCU-protected linked list, and
62is therefore within an RCU read-side critical section. Therefore,
63the called function has been invoked within an RCU read-side critical
64section, and is not permitted to block.