/proc Filesystem Entries for RCU


CONFIG_RCU_STATS

The CONFIG_RCU_STATS config option is available only in conjunction with
CONFIG_PREEMPT_RCU.  It makes four /proc entries available, namely: rcuctrs,
rcuptrs, rcugp, and rcustats.

/proc/rcuctrs

	CPU last cur
	  0    1   1
	  1    1   1
	  2    1   1
	  3    0   2
	ggp = 230725

This displays the number of processes that started RCU read-side critical
sections on each CPU.  In absence of preemption, the "last" and "cur"
counts for a given CPU will always sum to one.  Therefore, in the example
output above, each CPU has started one RCU read-side critical section
that was later preempted.  The "last" column counts RCU read-side critical
sections that started prior to the last counter flip, while the "cur"
column counts critical sections that started after the last counter flip.

The "ggp" count is a count of the number of counter flips since boot.
Since this is shown as an odd number, the "cur" counts are stored in
the zero-th element of each of the per-CPU arrays, and the "last" counts
are stored in the first element of each of the per-CPU arrays.


/proc/rcuptrs

	nl=c04c7160/c04c7960 nt=c04c72d0
	 wl=c04c7168/c04c794c wt=c04c72bc dl=c04c7170/00000000 dt=c04c7170

This displays the head and tail of each of CONFIG_PREEMPT_RCU's three
callback lists.  This will soon change to display this on a per-CPU
basis, since each CPU will soon have its own set of callback lists.
In the example above, the "next" list header is located at hex address
0xc04c7160, the first element on the list at hex address 0xc04c7960,
and the last element on the list at hex address 0xc04c72d0.  The "wl="
and "wt=" output is similar for the "wait" list, and the "dl=" and "dt="
output for the "done" list.  The "done" list is normally emptied very
quickly after being filled, so will usually be empty as shown above.
Note that the tail pointer points into the list header in this case.

Callbacks are placed in the "next" list by call_rcu(), moved to the
"wait" list after the next counter flip, and moved to the "done" list
on the counter flip after that.  Once on the "done" list, the callbacks
are invoked.


/proc/rcugp

	oldggp=241419  newggp=241421

This entry invokes synchronize_rcu() and prints out the number of counter
flips since boot before and after the synchronize_rcu().  These two
numbers will always differ by at least two.  Unless RCU is broken.  ;-)


/proc/rcustats

	ggp=242416 lgp=242416 sr=0 rcc=396233
	na=2090938 nl=9 wa=2090929 wl=9 dl=0 dr=2090920 di=2090920
	rtf1=22230730 rtf2=20139162 rtf3=242416 rtfe1=2085911 rtfe2=5657 rtfe3=19896746

The quantities printed are as follows:

o	"ggp=": The number of flips since boot.

o	"lgp=": The number of flips sensed by the local structure since
	boot.  This will soon be per-CPU.

o	"sr=": The number of explicit call to synchronize_rcu().
	Except that this is currently broken, so always reads as zero.
	It is likely to be removed...

o	"rcc=": The number of calls to rcu_check_callbacks().

o	"na=": The number of callbacks that call_rcu() has registered
	since boot.

o	"nl=": The number of callbacks currently on the "next" list.

o	"wa=": The number of callbacks that have moved to the "wait"
	list since boot.

o	"wl=": The number of callbacks currently on the "wait" list.

o	"da=": The number of callbacks that have been moved to the
	"done" list since boot.

o	"dl=": The number of callbacks currently on the "done" list.

o	"dr=": The number of callbacks that have been removed from the
	"done" list since boot.

o	"di=": The number of callbacks that have been invoked after being
	removed from the "done" list.

o	"rtf1=": The number of attempts to flip the counters.

o	"rtf2=": The number of attempts to flip the counters that successfully
	acquired the fliplock.

o	"rtf3=": The number of successful counter flips.

o	"rtfe1=": The number of attempts to flip the counters that failed
	due to the lock being held by someone else.

o	"rtfe2=": The number of attempts to flip the counters that were
	abandoned due to someone else doing the job for us.

o	"rtfe3=": The number of attempts to flip the counters that failed
	due to some task still being in an RCU read-side critical section
	starting from before the last successful counter flip.


CONFIG_RCU_TORTURE_TEST

The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
implementations.  It makes three /proc entries available, namely: rcutw,
rcutr, and rcuts.


/proc/rcutw

Reading this entry starts a new torture test, or ends an earlier one
if one is already in progress (in other words, there can be only one
writer at a time).  This sleeps uninterruptibly, so be sure to run
it in the background.  One could argue that it would be good to have
multiple writers, but Linux uses RCU heavily enough that you will get
write-side contention whether you want it or not.  If you want additional
write-side contention, repeatedly create and destroy several large file
trees in parallel.  Or use some other RCU-protected update.


/proc/rcutr

Reading this entry starts a new torture reader, which runs until sent
a signal (e.g., control-C).  If testing an RCU implementation with
preemptible read-side critical sections, make sure to spawn at least
two /proc/rcutr instances for each CPU.


/proc/rcuts

Displays the current state of the torture test:

	ggp = 20961
	rtc: c04496f4 ver: 8734 tfle: 0 rta: 8734 rtaf: 0 rtf: 8715
	Reader Pipe:  88024120 63914 0 0 0 0 0 0 0 0 0
	Reader Batch:  88024097 63937 0 0 0 0 0 0 0 0
	Free-Block Circulation:  8733 8731 8729 8727 8725 8723 8721 8719 8717 8715 0

The entries are as follows:

o	"ggp": The number of counter flips (or batches) since boot.

o	"rtc": The hexadecimal address of the structure currently visible
	to readers.

o	"ver": The number of times since boot that the rcutw writer task
	has changed the structure visible to readers.

o	"tfle": If non-zero, indicates that the "torture freelist"
	containing structure to be placed into the "rtc" area is empty.
	This condition is important, since it can fool you into thinking
	that RCU is working when it is not.  :-/

o	"rta": Number of structures allocated from the torture freelist.

o	"rtaf": Number of allocations from the torture freelist that have
	failed due to the list being empty.

o	"rtf": Number of frees into the torture freelist.

o	"Reader Pipe": Histogram of "ages" of structures seen by readers.
	If any entries past the first two are non-zero, RCU is broken.
	And /proc/rcuts prints "!!!" to make sure you notice.  The age
	of a newly allocated structure is zero, it becomes one when
	removed from reader visibility, and is incremented once per
	grace period subsequently -- and is freed after passing through
	(RCU_TORTURE_PIPE_LEN-2) grace periods.

	The output displayed above was taken from a correctly working
	RCU.  If you want to see what it looks like when broken, break
	it yourself.  ;-)

o	"Reader Batch": Another histogram of "ages" of structures seen
	by readers, but in terms of counter flips (or batches) rather
	than in terms of grace periods.  The legal number of non-zero
	entries is again two.  The reason for this separate view is
	that it is easier to get the third entry to show up in the
	"Reader Batch" list than in the "Reader Pipe" list.

o	"Free-Block Circulation": Shows the number of torture structures
	that have reached a given point in the pipeline.  The first element
	should closely correspond to the number of structures allocated,
	the second to the number that have been removed from reader view,
	and all but the last remaining to the corresponding number of
	passes through a grace period.  The last entry should be zero,
	as it is only incremented if a torture structure's counter
	somehow gets incremented farther than it should.
