/Documentation/RCU/UP.txt

https://bitbucket.org/evzijst/gittest · Plain Text · 64 lines · 47 code · 17 blank · 0 comment · 0 complexity · e4b53ae361d9d6095ace342d7d30cd29 MD5 · raw file

  1. RCU on Uniprocessor Systems
  2. A common misconception is that, on UP systems, the call_rcu() primitive
  3. may immediately invoke its function, and that the synchronize_kernel
  4. primitive may return immediately. The basis of this misconception
  5. is that since there is only one CPU, it should not be necessary to
  6. wait for anything else to get done, since there are no other CPUs for
  7. anything else to be happening on. Although this approach will sort of
  8. work a surprising amount of the time, it is a very bad idea in general.
  9. This document presents two examples that demonstrate exactly how bad an
  10. idea this is.
  11. Example 1: softirq Suicide
  12. Suppose that an RCU-based algorithm scans a linked list containing
  13. elements A, B, and C in process context, and can delete elements from
  14. this same list in softirq context. Suppose that the process-context scan
  15. is referencing element B when it is interrupted by softirq processing,
  16. which deletes element B, and then invokes call_rcu() to free element B
  17. after a grace period.
  18. Now, if call_rcu() were to directly invoke its arguments, then upon return
  19. from softirq, the list scan would find itself referencing a newly freed
  20. element B. This situation can greatly decrease the life expectancy of
  21. your kernel.
  22. Example 2: Function-Call Fatality
  23. Of course, one could avert the suicide described in the preceding example
  24. by having call_rcu() directly invoke its arguments only if it was called
  25. from process context. However, this can fail in a similar manner.
  26. Suppose that an RCU-based algorithm again scans a linked list containing
  27. elements A, B, and C in process contexts, but that it invokes a function
  28. on each element as it is scanned. Suppose further that this function
  29. deletes element B from the list, then passes it to call_rcu() for deferred
  30. freeing. This may be a bit unconventional, but it is perfectly legal
  31. RCU usage, since call_rcu() must wait for a grace period to elapse.
  32. Therefore, in this case, allowing call_rcu() to immediately invoke
  33. its arguments would cause it to fail to make the fundamental guarantee
  34. underlying RCU, namely that call_rcu() defers invoking its arguments until
  35. all RCU read-side critical sections currently executing have completed.
  36. Quick Quiz: why is it -not- legal to invoke synchronize_kernel() in
  37. this case?
  38. Summary
  39. Permitting call_rcu() to immediately invoke its arguments or permitting
  40. synchronize_kernel() to immediately return breaks RCU, even on a UP system.
  41. So do not do it! Even on a UP system, the RCU infrastructure -must-
  42. respect grace periods.
  43. Answer to Quick Quiz
  44. The calling function is scanning an RCU-protected linked list, and
  45. is therefore within an RCU read-side critical section. Therefore,
  46. the called function has been invoked within an RCU read-side critical
  47. section, and is not permitted to block.