[PATCH 1/3] dyntickrcu: Apply 'cleveref' way of cross reference

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From dd4e9bca30a58e14ab8babcdc149e6c9c49e6cbf Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@xxxxxxxxx>
Date: Sat, 28 Sep 2019 16:24:59 +0900
Subject: [PATCH 1/3] dyntickrcu: Apply 'cleveref' way of cross reference

Also use \clnref, \clnrefrange, and their upper-case variants for
cross-referencing line labels.

Note: There remains a few \lnref{}s, which can't be expressed
by the available macros as of this change. I.e.:

    "Lines 6 through 12"

Signed-off-by: Akira Yokosawa <akiyks@xxxxxxxxx>
---
 formal/dyntickrcu.tex | 291 +++++++++++++++++++-----------------------
 1 file changed, 132 insertions(+), 159 deletions(-)

diff --git a/formal/dyntickrcu.tex b/formal/dyntickrcu.tex
index a7dd2d74..7b7c3909 100644
--- a/formal/dyntickrcu.tex
+++ b/formal/dyntickrcu.tex
@@ -75,7 +75,7 @@ More important, Promela and Spin did find a very subtle bug for me!
 	\begin{enumerate}
 	\item	Try compiler flags \co{-DCOLLAPSE} and \co{-DMA=N}
 		to reduce memory consumption.
-		See Section~\ref{sec:formal:Running the QRCU Example}.
+		See \cref{sec:formal:Running the QRCU Example}.
 	\item	Further optimize the model, reducing its memory consumption.
 	\item	Work out a pencil-and-paper proof, perhaps starting with the
 		comments in the code in the Linux kernel.
@@ -98,10 +98,11 @@ that has a smaller state space.
 Even better would be an algorithm so simple that its correctness was
 obvious to the casual observer!
 
-Sections~\ref{sec:formal:Introduction to Preemptible RCU and dynticks}-\ref{sec:formal:Grace-Period Interface}
+\Crefrange{sec:formal:Introduction to Preemptible RCU and dynticks}
+{sec:formal:Grace-Period Interface}
 give an overview of preemptible RCU's dynticks interface,
 followed by
-Section~\ref{sec:formal:Validating Preemptible RCU and dynticks}'s
+\cref{sec:formal:Validating Preemptible RCU and dynticks}'s
 discussion of the validation of the interface.
 
 \subsubsection{Introduction to Preemptible RCU and dynticks}
@@ -214,16 +215,15 @@ void rcu_irq_enter(void)
 \end{linelabel}
 
 \begin{lineref}[ln:formal:dyntickrcu:rcu_irq_enter]
-Line~\lnref{fetch} fetches the current CPU's number, while
-lines~\lnref{inc:b} and~\lnref{inc:e}
+\Clnref{fetch} fetches the current CPU's number, while \clnref{inc:b,inc:e}
 increment the \co{rcu_update_flag} nesting counter if it
 is already non-zero.
-Lines~\lnref{chk_lv:b}-\lnref{chk_lv:e} check to see whether we are
+\Clnrefrange{chk_lv:b}{chk_lv:e} check to see whether we are
 the outermost level of
 interrupt, and, if so, whether \co{dynticks_progress_counter}
 needs to be incremented.
-If so, line~\lnref{inc_cnt} increments \co{dynticks_progress_counter},
-line~\lnref{mb} executes a memory barrier, and line~\lnref{inc_flg} increments
+If so, \clnref{inc_cnt} increments \co{dynticks_progress_counter},
+\clnref{mb} executes a memory barrier, and \clnref{inc_flg} increments
 \co{rcu_update_flag}.
 As with \co{rcu_exit_nohz()}, the memory barrier ensures that
 any other CPU that sees the effects of an RCU read-side critical section
@@ -255,7 +255,7 @@ invocation) will also see the increment of
 
 \QuickQuiz{}
 	\begin{lineref}[ln:formal:dyntickrcu:rcu_irq_enter]
-	But if line~\lnref{chk_lv:b} finds that we are the outermost interrupt,
+	But if \clnref{chk_lv:b} finds that we are the outermost interrupt,
 	wouldn't we \emph{always} need to increment
 	\co{dynticks_progress_counter}?
 	\end{lineref}
@@ -289,17 +289,17 @@ void rcu_irq_exit(void)
 \end{linelabel}
 
 \begin{lineref}[ln:formal:dyntickrcu:rcu_irq_exit]
-Line~\lnref{fetch} fetches the current CPU's number, as before.
-Line~\lnref{chk_flg} checks to see if the \co{rcu_update_flag} is
+\Clnref{fetch} fetches the current CPU's number, as before.
+\Clnref{chk_flg} checks to see if the \co{rcu_update_flag} is
 non-zero, returning immediately (via falling off the end of the
 function) if not.
 Otherwise, lines~\lnref{dec_flg} through~\lnref{vrf_even:e} come into play.
-Line~\lnref{dec_flg} decrements \co{rcu_update_flag}, returning
+\Clnref{dec_flg} decrements \co{rcu_update_flag}, returning
 if the result is not zero.
-Line~\lnref{verify} verifies that we are indeed leaving the outermost
-level of nested interrupts, line~\lnref{mb} executes a memory barrier,
-line~\lnref{inc_cnt} increments \co{dynticks_progress_counter},
-and lines~\lnref{vrf_even:b} and~\lnref{vrf_even:e} verify that this
+\Clnref{verify} verifies that we are indeed leaving the outermost
+level of nested interrupts, \clnref{mb} executes a memory barrier,
+\clnref{inc_cnt} increments \co{dynticks_progress_counter},
+and \clnref{vrf_even:b,vrf_even:e} verify that this
 variable is now even.
 As with \co{rcu_enter_nohz()}, the memory barrier ensures that
 any other CPU that sees the increment of
@@ -327,7 +327,7 @@ preemptible RCU's grace-period machinery.
 \end{figure}
 
 Of the four preemptible RCU grace-period states shown in
-Figure~\ref{fig:formal:Preemptible RCU State Machine},
+\cref{fig:formal:Preemptible RCU State Machine},
 only the \co{rcu_try_flip_waitack_state}
 and \co{rcu_try_flip_waitmb_state} states need to wait
 for other CPUs to respond.
@@ -374,22 +374,22 @@ rcu_try_flip_waitack_needed(int cpu)
 \end{linelabel}
 
 \begin{lineref}[ln:formal:dyntickrcu:rcu_try_flip_waitack_needed]
-Lines~\lnref{curr} and~\lnref{snap} pick up current and snapshot versions of
+\Clnref{curr,snap} pick up current and snapshot versions of
 \co{dynticks_progress_counter}, respectively.
-The memory barrier on line~\lnref{mb} ensures that the counter checks
+The memory barrier on \clnref{mb} ensures that the counter checks
 in the later \co{rcu_try_flip_waitzero_state} follow
 the fetches of these counters.
-Lines~\lnref{chk_remain} and~\lnref{ret_0_r} return zero
+\Clnref{chk_remain,ret_0_r} return zero
 (meaning no communication with the
 specified CPU is required) if that CPU has remained in dynticks-idle
 state since the time that the snapshot was taken.
-Similarly, lines~\lnref{chk_idle} and~\lnref{ret_0_i} return zero
+Similarly, \clnref{chk_idle,ret_0_i} return zero
 if that CPU was initially
 in dynticks-idle state or if it has completely passed through a
 dynticks-idle state.
 In both these cases, there is no way that that CPU could have retained
 the old value of the grace-period counter.
-If neither of these conditions hold, line~\lnref{ret_1} returns one, meaning
+If neither of these conditions hold, \clnref{ret_1} returns one, meaning
 that the CPU needs to explicitly respond.
 \end{lineref}
 
@@ -418,8 +418,7 @@ rcu_try_flip_waitmb_needed(int cpu)
 
 \begin{lineref}[ln:formal:dyntickrcu:rcu_try_flip_waitmb_needed]
 This is quite similar to \co{rcu_try_flip_waitack_needed()},
-the difference being in lines~\lnref{chk_to_from} and~\lnref{ret_0},
-because any transition
+the difference being in \clnref{chk_to_from,ret_0}, because any transition
 either to or from dynticks-idle state executes the memory barrier
 needed by the \co{rcu_try_flip_waitmb_state} state.
 \end{lineref}
@@ -440,13 +439,13 @@ code.
 
 This section develops a Promela model for the interface between
 dynticks and RCU step by step, with each of
-Sections~\ref{sec:formal:Basic Model}-\ref{sec:formal:Validating NMI Handlers}
+\crefrange{sec:formal:Basic Model}{sec:formal:Validating NMI Handlers}
 illustrating one step, starting with the process-level code,
 adding assertions, interrupts, and finally NMIs.
 
-Section~\ref{sec:formal:Lessons (Re)Learned} lists
+\Cref{sec:formal:Lessons (Re)Learned} lists
 lessons (re)learned during this effort, and
-Sections~\ref{sec:formal:Simplicity Avoids Formal Verification}-\ref{sec:formal:Discussion}
+\crefrange{sec:formal:Simplicity Avoids Formal Verification}{sec:formal:Discussion}
 present a simpler solution to RCU's dynticks problem.
 
 \subsubsection{Basic Model}
@@ -464,26 +463,26 @@ a loop as follows:
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-base@dyntick_nohz.fcv}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-base:dyntick_nohz]
-Lines~\lnref{do} and~\lnref{od} define a loop.
-Line~\lnref{break} exits the loop once the loop counter \co{i}
+\Clnref{do,od} define a loop.
+\Clnref{break} exits the loop once the loop counter \co{i}
 has exceeded the limit \co{MAX_DYNTICK_LOOP_NOHZ}.
-Line~\lnref{kick_loop} tells the loop construct to execute
-lines~\lnref{ex_inc:b}-\lnref{inc_i}
+\Clnref{kick_loop} tells the loop construct to execute
+\clnrefrange{ex_inc:b}{inc_i}
 for each pass through the loop.
-Because the conditionals on lines~\lnref{break} and~\lnref{kick_loop}
+Because the conditionals on \clnref{break,kick_loop}
 are exclusive of
 each other, the normal Promela random selection of true conditions
 is disabled.
-Lines~\lnref{ex_inc:b} and~\lnref{ex_inc:e} model
+\Clnref{ex_inc:b,ex_inc:e} model
 \co{rcu_exit_nohz()}'s non-atomic
 increment of \co{dynticks_progress_counter}, while
-line~\lnref{ex_assert} models the \co{WARN_ON()}.
+\clnref{ex_assert} models the \co{WARN_ON()}.
 The \co{atomic} construct simply reduces the Promela state space,
 given that the \co{WARN_ON()} is not strictly speaking part
 of the algorithm.
-Lines~\lnref{ent_inc:b}-\lnref{ent_inc:e} similarly models the increment and
+\Clnrefrange{ent_inc:b}{ent_inc:e} similarly models the increment and
 \co{WARN_ON()} for \co{rcu_enter_nohz()}.
-Finally, line~\lnref{inc_i} increments the loop counter.
+Finally, \clnref{inc_i} increments the loop counter.
 \end{lineref}
 
 Each pass through the loop therefore models a CPU exiting
@@ -498,7 +497,7 @@ re-entering dynticks-idle mode (for example, that same task blocking).
 	it is not necessary to model memory barriers.
 	In fact, one must instead explicitly model lack of memory barriers,
 	for example, as shown in
-	Listing~\ref{lst:formal:QRCU Unordered Summation} on
+	\cref{lst:formal:QRCU Unordered Summation} on
 	page~\pageref{lst:formal:QRCU Unordered Summation}.
 } \QuickQuizEnd
 
@@ -527,7 +526,7 @@ through preemptible RCU's grace-period processing.
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-base@grace_period.fcv}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-base:grace_period]
-Lines~\lnref{print:b}-\lnref{print:e} print out the loop limit
+\Clnrefrange{print:b}{print:e} print out the loop limit
 (but only into the .trail file
 in case of error) and models a line of code
 from \co{rcu_try_flip_idle()} and its call to
@@ -536,19 +535,19 @@ snapshot of the current CPU's \co{dynticks_progress_counter}
 variable.
 These two lines are executed atomically to reduce state space.
 
-Lines~\lnref{do1}-\lnref{od1} model the relevant code in
+\Clnrefrange{do1}{od1} model the relevant code in
 \co{rcu_try_flip_waitack()} and its call to
 \co{rcu_try_flip_waitack_needed()}.
 This loop is modeling the grace-period state machine waiting for
 a counter-flip acknowledgement from each CPU, but only that part
 that interacts with dynticks-idle CPUs.
 
-Line~\lnref{snap} models a line from \co{rcu_try_flip_waitzero()}
+\Clnref{snap} models a line from \co{rcu_try_flip_waitzero()}
 and its call to \co{dyntick_save_progress_counter()}, again
 taking a snapshot of the CPU's \co{dynticks_progress_counter}
 variable.
 
-Finally, lines~\lnref{do2}-\lnref{od2} model the relevant code in
+Finally, \clnrefrange{do2}{od2} model the relevant code in
 \co{rcu_try_flip_waitack()} and its call to
 \co{rcu_try_flip_waitack_needed()}.
 This loop is modeling the grace-period state-machine waiting for
@@ -599,8 +598,7 @@ progresses through the grace-period phases, as shown below:
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-base-s@grace_period.fcv}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-base-s:grace_period]
-Lines~\lnref{upd_gps1}, \lnref{upd_gps2}, \lnref{upd_gps3},
-\lnref{upd_gps4}, \lnref{upd_gps5}, and~\lnref{upd_gps6}
+\Clnref{upd_gps1,upd_gps2,upd_gps3,upd_gps4,upd_gps5,upd_gps6}
 update this variable (combining
 atomically with algorithmic operations where feasible) to
 allow the \co{dyntick_nohz()} process to verify the basic
@@ -614,9 +612,8 @@ over which RCU readers could plausibly persist.
 \QuickQuiz{}
 	\begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-base-s:grace_period]
 	Given there are a pair of back-to-back changes to
-	\co{grace_period_state} on
-	lines~\lnref{upd_gps3} and~\lnref{upd_gps4},
-	how can we be sure that line~\lnref{upd_gps3}'s changes won't be lost?
+	\co{grace_period_state} on \clnref{upd_gps3,upd_gps4},
+	how can we be sure that \clnref{upd_gps3}'s changes won't be lost?
 	\end{lineref}
 \QuickQuizAnswer{
 	Recall that Promela and Spin trace out
@@ -633,10 +630,10 @@ this verification as shown below:
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-base-s@dyntick_nohz.fcv}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-base-s:dyntick_nohz]
-Line~\lnref{new_flg} sets a new \co{old_gp_idle} flag if the
+\Clnref{new_flg} sets a new \co{old_gp_idle} flag if the
 value of the \co{grace_period_state} variable is
 \co{GP_IDLE} at the beginning of task execution,
-and the assertion at lines~\lnref{assert:b} and~\lnref{assert:e}
+and the assertion at \clnref{assert:b,assert:e}
 fire if the \co{grace_period_state}
 variable has advanced to \co{GP_DONE} during task execution,
 which would be illegal given that a single RCU read-side critical
@@ -659,7 +656,7 @@ Although liveness can be difficult to prove, there is a simple
 trick that applies here.
 The first step is to make \co{dyntick_nohz()} indicate that
 it is done via a \co{dyntick_nohz_done} variable, as shown on
-line~\lnref{done} of the following:
+\clnref{done} of the following:
 \end{lineref}
 
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-base-sl-busted@dyntick_nohz.fcv}
@@ -671,10 +668,10 @@ as follows:
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-base-sl-busted@grace_period.fcv}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-base-sl-busted:grace_period]
-We have added the \co{shouldexit} variable on line~\lnref{shex},
-which we initialize to zero on line~\lnref{init_shex}.
-Line~\lnref{assert_shex} asserts that \co{shouldexit} is not set, while
-line~\lnref{set_shex} sets \co{shouldexit} to the \co{dyntick_nohz_done}
+We have added the \co{shouldexit} variable on \clnref{shex},
+which we initialize to zero on \clnref{init_shex}.
+\Clnref{assert_shex} asserts that \co{shouldexit} is not set, while
+\clnref{set_shex} sets \co{shouldexit} to the \co{dyntick_nohz_done}
 variable maintained by \co{dyntick_nohz()}.
 This assertion will therefore trigger if we attempt to take more than
 one pass through the wait-for-counter-flip-acknowledgement
@@ -685,13 +682,12 @@ any more state changes to force us out of the loop, so going through twice
 in this state means an infinite loop, which in turn means no end to the
 grace period.
 
-Lines~\lnref{init_shex2}, \lnref{assert_shex2}, and~\lnref{set_shex2}
-operate in a similar manner for the
-second (memory-barrier) loop.
+\Clnref{init_shex2,assert_shex2,set_shex2} operate in a similar manner
+for the second (memory-barrier) loop.
 
 However, running this
 model (\path{dyntickRCU-base-sl-busted.spin})
-results in failure, as line~\lnref{chk_2} is checking that
+results in failure, as \clnref{chk_2} is checking that
 the wrong variable
 is even.
 Upon failure, \co{spin} writes out a
@@ -713,9 +709,9 @@ at step 34 (search for ``34:''), but that the
 \co{grace_period()} process nonetheless failed to exit the loop.
 The value of \co{curr} is \co{6} (see step 35)
 and that the value of \co{snap} is \co{5} (see step 17).
-Therefore the first condition on line~\lnref{chk_1} above
+Therefore the first condition on \clnref{chk_1} above
 does not hold because
-\qco{curr != snap}, and the second condition on line~\lnref{chk_2}
+\qco{curr != snap}, and the second condition on \clnref{chk_2}
 does not hold either because \co{snap} is odd and because
 \co{curr} is only one greater than \co{snap}.
 \end{lineref}
@@ -777,7 +773,7 @@ rcu_try_flip_waitack_needed(int cpu)
 \end{linelabel}
 
 \begin{lineref}[ln:formal:dyntickrcu:rcu_try_flip_waitack_needed_fixed]
-Lines~\lnref{if:b}-\lnref{if:e} can now be combined and simplified,
+\Clnrefrange{if:b}{if:e} can now be combined and simplified,
 resulting in the following.
 A similar simplification can be applied to
 \co{rcu_try_flip_waitmb_needed()}.
@@ -849,13 +845,13 @@ EXECUTE_MAINLINE(stmt1,
 \end{VerbatimU}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irqnn-ssl:EXECUTE_MAINLINE]
-Line~\lnref{label} of the macro creates the specified statement label.
-Lines~\lnref{atm:b}-\lnref{atm:e} are an atomic block that tests
+\Clnref{label} of the macro creates the specified statement label.
+\Clnrefrange{atm:b}{atm:e} are an atomic block that tests
 the \co{in_dyntick_irq}
 variable, and if this variable is set (indicating that the interrupt
 handler is active), branches out of the atomic block back to the
 label.
-Otherwise, line~\lnref{else} executes the specified statement.
+Otherwise, \clnref{else} executes the specified statement.
 The overall effect is that mainline execution stalls any time an interrupt
 is active, as required.
 \end{lineref}
@@ -870,8 +866,7 @@ The first step is to convert \co{dyntick_nohz()} to
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irqnn-ssl:dyntick_nohz]
 It is important to note that when a group of statements is passed
-to \co{EXECUTE_MAINLINE()}, as in
-lines~\lnref{stmt2:b}-\lnref{stmt2:e}, all
+to \co{EXECUTE_MAINLINE()}, as in \clnrefrange{stmt2:b}{stmt2:e}, all
 statements in that group execute atomically.
 \end{lineref}
 
@@ -927,23 +922,19 @@ to model an interrupt handler:
 \input{CodeSamples/formal/promela/dyntick/dyntickRCU-irqnn-ssl@dyntick_irq.fcv}
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irqnn-ssl:dyntick_irq]
-The loop from lines~\lnref{do}-\lnref{od} models up to
-\co{MAX_DYNTICK_LOOP_IRQ}
-interrupts, with lines~\lnref{cond1} and~\lnref{cond2} forming
-the loop condition and line~\lnref{inc_i}
-incrementing the control variable.
-Line~\lnref{in_irq} tells \co{dyntick_nohz()} that an interrupt handler
-is running, and line~\lnref{clr_in_irq} tells \co{dyntick_nohz()} that this
+The loop from \clnrefrange{do}{od} models up to \co{MAX_DYNTICK_LOOP_IRQ}
+interrupts, with \clnref{cond1,cond2} forming the loop condition and
+\clnref{inc_i} incrementing the control variable.
+\Clnref{in_irq} tells \co{dyntick_nohz()} that an interrupt handler
+is running, and \clnref{clr_in_irq} tells \co{dyntick_nohz()} that this
 handler has completed.
-Line~\lnref{irq_done} is used for liveness verification,
-just like the corresponding
+\Clnref{irq_done} is used for liveness verification, just like the corresponding
 line of \co{dyntick_nohz()}.
 \end{lineref}
 
 \QuickQuiz{}
 	\begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irqnn-ssl:dyntick_irq]
-	Why are lines~\lnref{clr_in_irq} and~\lnref{inc_i}
-	(the \qco{in_dyntick_irq = 0;}
+	Why are \clnref{clr_in_irq,inc_i} (the \qco{in_dyntick_irq = 0;}
 	and the \qco{i++;}) executed atomically?
 	\end{lineref}
 \QuickQuizAnswer{
@@ -955,15 +946,13 @@ line of \co{dyntick_nohz()}.
 } \QuickQuizEnd
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irqnn-ssl:dyntick_irq]
-Lines~\lnref{enter:b}-\lnref{enter:e} model \co{rcu_irq_enter()}, and
-lines~\lnref{add_prmt_cnt:b} and~\lnref{add_prmt_cnt:e}
-model the relevant snippet of \co{__irq_enter()}.
-Lines~\lnref{vrf_safe:b}-\lnref{vrf_safe:e} verify
-safety in much the same manner as do the
-corresponding lines of \co{dynticks_nohz()}.
-Lines~\lnref{irq_exit:b} and~\lnref{irq_exit:e} model the relevant snippet
-of \co{__irq_exit()},
-and finally lines~\lnref{exit:b}-\lnref{exit:e} model \co{rcu_irq_exit()}.
+\Clnrefrange{enter:b}{enter:e} model \co{rcu_irq_enter()}, and
+\clnref{add_prmt_cnt:b,add_prmt_cnt:e} model the relevant snippet
+of \co{__irq_enter()}.
+\Clnrefrange{vrf_safe:b}{vrf_safe:e} verify safety in much the same manner
+as do the corresponding lines of \co{dynticks_nohz()}.
+\Clnref{irq_exit:b,irq_exit:e} model the relevant snippet of \co{__irq_exit()},
+and finally \clnrefrange{exit:b}{exit:e} model \co{rcu_irq_exit()}.
 \end{lineref}
 
 \QuickQuiz{}
@@ -981,12 +970,10 @@ The \co{grace_period()} process then becomes as follows:
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irqnn-ssl:grace_period]
 The implementation of \co{grace_period()} is very similar
 to the earlier one.
-The only changes are the addition of line~\lnref{MDLI} to add the new
+The only changes are the addition of \clnref{MDLI} to add the new
 interrupt-count parameter, changes to
-lines~\lnref{edit1} and~\lnref{edit3} to
-add the new \co{dyntick_irq_done} variable to the liveness
-checks, and of course the optimizations on
-lines~\lnref{edit2} and~\lnref{edit4}.
+\clnref{edit1,edit3} to add the new \co{dyntick_irq_done} variable
+to the liveness checks, and of course the optimizations on \clnref{edit2,edit4}.
 \end{lineref}
 
 This model (\path{dyntickRCU-irqnn-ssl.spin})
@@ -1006,34 +993,30 @@ the loop in \co{dyntick_irq()} as follows:
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irq-ssl:dyntick_irq]
 This is similar to the earlier \co{dynticks_irq()} process.
-It adds a second counter variable \co{j} on line~\lnref{j}, so that
+It adds a second counter variable \co{j} on \clnref{j}, so that
 \co{i} counts entries to interrupt handlers and \co{j}
 counts exits.
-The \co{outermost} variable on line~\lnref{om} helps determine
+The \co{outermost} variable on \clnref{om} helps determine
 when the \co{grace_period_state} variable needs to be sampled
 for the safety checks.
-The loop-exit check on lines~\lnref{chk_ex:b} and~\lnref{chk_ex:e}
-is updated to require that the
+The loop-exit check on \clnref{chk_ex:b,chk_ex:e} is updated to require that the
 specified number of interrupt handlers are exited as well as entered,
-and the increment of \co{i} is moved to line~\lnref{inc_i}, which is
+and the increment of \co{i} is moved to \clnref{inc_i}, which is
 the end of the interrupt-entry model.
-Lines~\lnref{atm1:b}-\lnref{atm1:e}
-set the \co{outermost} variable to indicate
+\Clnrefrange{atm1:b}{atm1:e} set the \co{outermost} variable to indicate
 whether this is the outermost of a set of nested interrupts and to
 set the \co{in_dyntick_irq} variable that is used by the
 \co{dyntick_nohz()} process.
-Lines~\lnref{atm2:b}-\lnref{atm2:e}
-capture the state of the \co{grace_period_state}
+\Clnrefrange{atm2:b}{atm2:e} capture the state of the \co{grace_period_state}
 variable, but only when in the outermost interrupt handler.
 
-Line~\lnref{cnd_ex} has the do-loop conditional for interrupt-exit modeling:
+\Clnref{cnd_ex} has the do-loop conditional for interrupt-exit modeling:
 as long as we have exited fewer interrupts than we have entered, it is
 legal to exit another interrupt.
-Lines~\lnref{atm3:b}-\lnref{atm3:e}
+\Clnrefrange{atm3:b}{atm3:e}
 check the safety criterion, but only if we are exiting
 from the outermost interrupt level.
-Finally, lines~\lnref{atm4:b}-\lnref{atm4:e}
-increment the interrupt-exit count \co{j}
+Finally, \clnrefrange{atm4:b}{atm4:e} increment the interrupt-exit count \co{j}
 and, if this is the outermost interrupt level, clears
 \co{in_dyntick_irq}.
 \end{lineref}
@@ -1075,9 +1058,9 @@ to \co{EXECUTE_IRQ()} as follows:
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irq-nmi-ssl:dyntick_irq]
 Note that we have open-coded the ``if'' statements
-(for example, lines~\lnref{stmt1:b}-\lnref{stmt1:e}).
+(for example, \clnrefrange{stmt1:b}{stmt1:e}).
 In addition, statements that process strictly local state
-(such as line~\lnref{inc_i}) need not exclude \co{dyntick_nmi()}.
+(such as \clnref{inc_i}) need not exclude \co{dyntick_nmi()}.
 \end{lineref}
 
 Finally, \co{grace_period()} requires only a few changes:
@@ -1086,9 +1069,9 @@ Finally, \co{grace_period()} requires only a few changes:
 
 \begin{lineref}[ln:formal:promela:dyntick:dyntickRCU-irq-nmi-ssl:grace_period]
 We have added the \co{printf()} for the new
-\co{MAX_DYNTICK_LOOP_NMI} parameter on line~\lnref{MDL_NMI} and
+\co{MAX_DYNTICK_LOOP_NMI} parameter on \clnref{MDL_NMI} and
 added \co{dyntick_nmi_done} to the \co{shouldexit}
-assignments on lines~\lnref{nmi_done1} and~\lnref{nmi_done2}.
+assignments on \clnref{nmi_done1,nmi_done2}.
 \end{lineref}
 
 The model (\path{dyntickRCU-irq-nmi-ssl.spin})
@@ -1229,7 +1212,7 @@ struct rcu_data {
 \label{lst:formal:Variables for Simple Dynticks Interface}
 \end{listing}
 
-Listing~\ref{lst:formal:Variables for Simple Dynticks Interface}
+\Cref{lst:formal:Variables for Simple Dynticks Interface}
 shows the new per-CPU state variables.
 These variables are grouped into structs to allow multiple independent
 RCU implementations (e.g., \co{rcu} and \co{rcu_bh}) to conveniently
@@ -1329,22 +1312,22 @@ void rcu_exit_nohz(void)
 \label{lst:formal:Entering and Exiting Dynticks-Idle Mode}
 \end{listing}
 
-Listing~\ref{lst:formal:Entering and Exiting Dynticks-Idle Mode}
+\Cref{lst:formal:Entering and Exiting Dynticks-Idle Mode}
 shows the \co{rcu_enter_nohz()} and \co{rcu_exit_nohz()},
 which enter and exit dynticks-idle mode, also known as ``nohz'' mode.
 These two functions are invoked from process context.
 
 \begin{lineref}[ln:formal:Entering and Exiting Dynticks-Idle Mode]
-Line~\lnref{mb} ensures that any prior memory accesses (which might
+\Clnref{mb} ensures that any prior memory accesses (which might
 include accesses from RCU read-side critical sections) are seen
 by other CPUs before those marking entry to dynticks-idle mode.
-Lines~\lnref{irq_sv} and~\lnref{irq_rs} disable and reenable \IRQ s.
-Line~\lnref{get_ptr} acquires a pointer to the current CPU's \co{rcu_dynticks}
+\Clnref{irq_sv,irq_rs} disable and reenable \IRQ s.
+\Clnref{get_ptr} acquires a pointer to the current CPU's \co{rcu_dynticks}
 structure, and
-line~\lnref{inc_cnt} increments the current CPU's \co{dynticks} counter, which
+\clnref{inc_cnt} increments the current CPU's \co{dynticks} counter, which
 should now be even, given that we are entering dynticks-idle mode
 in process context.
-Finally, line~\lnref{dec_nst} decrements \co{dynticks_nesting},
+Finally, \clnref{dec_nst} decrements \co{dynticks_nesting},
 which should now be zero.
 \end{lineref}
 
@@ -1389,21 +1372,19 @@ void rcu_nmi_exit(void)
 \end{listing}
 
 \begin{lineref}[ln:formal:NMIs From Dynticks-Idle Mode]
-Listing~\ref{lst:formal:NMIs From Dynticks-Idle Mode}
+\Cref{lst:formal:NMIs From Dynticks-Idle Mode}
 shows the \co{rcu_nmi_enter()} and \co{rcu_nmi_exit()} functions,
 which inform RCU of NMI entry and exit, respectively, from dynticks-idle
 mode.
 However, if the NMI arrives during an \IRQ\ handler, then RCU will already
 be on the lookout for RCU read-side critical sections from this CPU,
-so lines~\lnref{chk_ext1} and~\lnref{ret1} of \co{rcu_nmi_enter()}
-and lines~\lnref{chk_ext2} and~\lnref{ret2}
+so \clnref{chk_ext1,ret1} of \co{rcu_nmi_enter()} and \clnref{chk_ext2,ret2}
 of \co{rcu_nmi_exit()} silently return if \co{dynticks} is odd.
 Otherwise, the two functions increment \co{dynticks_nmi}, with
 \co{rcu_nmi_enter()} leaving it with an odd value and \co{rcu_nmi_exit()}
 leaving it with an even value.
 Both functions execute memory barriers between this increment
-and possible RCU read-side critical sections on
-lines~\lnref{mb1} and~\lnref{mb2},
+and possible RCU read-side critical sections on \clnref{mb1,mb2},
 respectively.
 \end{lineref}
 
@@ -1447,31 +1428,30 @@ void rcu_irq_exit(void)
 \end{listing}
 
 \begin{lineref}[ln:formal:Interrupts From Dynticks-Idle Mode]
-Listing~\ref{lst:formal:Interrupts From Dynticks-Idle Mode}
+\Cref{lst:formal:Interrupts From Dynticks-Idle Mode}
 shows \co{rcu_irq_enter()} and \co{rcu_irq_exit()}, which
 inform RCU of entry to and exit from, respectively, \IRQ\ context.
-Line~\lnref{inc_nst} of \co{rcu_irq_enter()}
-increments \co{dynticks_nesting},
-and if this variable was already non-zero, line~\lnref{ret1} silently returns.
-Otherwise, line~\lnref{inc_dynt1} increments \co{dynticks},
+\Clnref{inc_nst} of \co{rcu_irq_enter()} increments \co{dynticks_nesting},
+and if this variable was already non-zero, \clnref{ret1} silently returns.
+Otherwise, \clnref{inc_dynt1} increments \co{dynticks},
 which will then have
 an odd value, consistent with the fact that this CPU can now
 execute RCU read-side critical sections.
-Line~\lnref{mb1} therefore executes a memory barrier to ensure that
+\Clnref{mb1} therefore executes a memory barrier to ensure that
 the increment of \co{dynticks} is seen before any
 RCU read-side critical sections that the subsequent \IRQ\ handler
 might execute.
 
-Line~\lnref{dec_nst} of \co{rcu_irq_exit()} decrements
+\Clnref{dec_nst} of \co{rcu_irq_exit()} decrements
 \co{dynticks_nesting}, and
-if the result is non-zero, line~\lnref{ret2} silently returns.
-Otherwise, line~\lnref{mb2} executes a memory barrier to ensure that the
-increment of \co{dynticks} on line~\lnref{inc_dynt2} is seen after any RCU
+if the result is non-zero, \clnref{ret2} silently returns.
+Otherwise, \clnref{mb2} executes a memory barrier to ensure that the
+increment of \co{dynticks} on \clnref{inc_dynt2} is seen after any RCU
 read-side critical sections that the prior \IRQ\ handler might have executed.
-Line~\lnref{chk_even} verifies that \co{dynticks} is now even, consistent with
+\Clnref{chk_even} verifies that \co{dynticks} is now even, consistent with
 the fact that no RCU read-side critical sections may appear in
 dynticks-idle mode.
-Lines~\lnref{chk_cb:b}-\lnref{chk_cb:e} check to see
+\Clnrefrange{chk_cb:b}{chk_cb:e} check to see
 if the prior \IRQ\ handlers enqueued any
 RCU callbacks, forcing this CPU out of dynticks-idle mode via
 a reschedule API if so.
@@ -1509,25 +1489,21 @@ dyntick_save_progress_counter(struct rcu_data *rdp)
 
 \noindent% @@@ \NoIndentAfterThis commented out above has side effect. @@@
 \begin{lineref}[ln:formal:Saving Dyntick Progress Counters]
-Listing~\ref{lst:formal:Saving Dyntick Progress Counters}
+\Cref{lst:formal:Saving Dyntick Progress Counters}
 shows \co{dyntick_save_progress_counter()}, which takes a snapshot
 of the specified CPU's \co{dynticks} and \co{dynticks_nmi}
 counters.
-Lines~\lnref{snap} and~\lnref{snapn} snapshot these two variables to locals,
-line~\lnref{mb}
-executes a memory barrier to pair with the memory barriers in
-the functions in
-Listings~\ref{lst:formal:Entering and Exiting Dynticks-Idle Mode},
-\ref{lst:formal:NMIs From Dynticks-Idle Mode},
-and~\ref{lst:formal:Interrupts From Dynticks-Idle Mode}.
-Lines~\lnref{rec_snap} and~\lnref{rec_snapn}
-record the snapshots for later calls to
+\Clnref{snap,snapn} snapshot these two variables to locals, \clnref{mb}
+executes a memory barrier to pair with the memory barriers in the functions in
+\cref{lst:formal:Entering and Exiting Dynticks-Idle Mode,%
+lst:formal:NMIs From Dynticks-Idle Mode,%
+lst:formal:Interrupts From Dynticks-Idle Mode}.
+\Clnref{rec_snap,rec_snapn} record the snapshots for later calls to
 \co{rcu_implicit_dynticks_qs()},
-and line~\lnref{chk_prgs} checks to see if the CPU is in dynticks-idle mode with
+and \clnref{chk_prgs} checks to see if the CPU is in dynticks-idle mode with
 neither \IRQ s nor NMIs in progress (in other words, both snapshots
 have even values), hence in an extended quiescent state.
-If so, lines~\lnref{cnt:b} and~\lnref{cnt:e} count this event,
-and line~\lnref{ret} returns
+If so, \clnref{cnt:b,cnt:e} count this event, and \clnref{ret} returns
 true if the CPU was in a quiescent state.
 \end{lineref}
 
@@ -1561,33 +1537,30 @@ rcu_implicit_dynticks_qs(struct rcu_data *rdp)
 \end{listing}
 
 \begin{lineref}[ln:formal:Checking Dyntick Progress Counters]
-Listing~\ref{lst:formal:Checking Dyntick Progress Counters}
+\Cref{lst:formal:Checking Dyntick Progress Counters}
 shows \co{rcu_implicit_dynticks_qs()}, which is called to check
 whether a CPU has entered dyntick-idle mode subsequent to a call
 to \co{dynticks_save_progress_counter()}.
-Lines~\lnref{curr} and~\lnref{currn}
-take new snapshots of the corresponding CPU's
+\Clnref{curr,currn} take new snapshots of the corresponding CPU's
 \co{dynticks} and \co{dynticks_nmi} variables, while
-lines~\lnref{snap} and~\lnref{snapn}
-retrieve the snapshots saved earlier by
+\clnref{snap,snapn} retrieve the snapshots saved earlier by
 \co{dynticks_save_progress_counter()}.
-Line~\lnref{mb} then
+\Clnref{mb} then
 executes a memory barrier to pair with the memory barriers in
 the functions in
-Listings~\ref{lst:formal:Entering and Exiting Dynticks-Idle Mode},
-\ref{lst:formal:NMIs From Dynticks-Idle Mode}, and
-\ref{lst:formal:Interrupts From Dynticks-Idle Mode}.
-Lines~\lnref{chk_q:b}-\lnref{chk_q:e}
+\cref{lst:formal:Entering and Exiting Dynticks-Idle Mode,%
+lst:formal:NMIs From Dynticks-Idle Mode,%
+lst:formal:Interrupts From Dynticks-Idle Mode}.
+\Clnrefrange{chk_q:b}{chk_q:e}
 then check to see if the CPU is either currently in
 a quiescent state (\co{curr} and \co{curr_nmi} having even values) or
 has passed through a quiescent state since the last call to
 \co{dynticks_save_progress_counter()} (the values of
 \co{dynticks} and \co{dynticks_nmi} having changed).
 If these checks confirm that the CPU has passed through a dyntick-idle
-quiescent state, then line~\lnref{cnt} counts that fact and
-line~\lnref{ret_1} returns
-an indication of this fact.
-Either way, line~\lnref{chk_race}
+quiescent state, then \clnref{cnt} counts that fact and
+\clnref{ret_1} returns an indication of this fact.
+Either way, \clnref{chk_race}
 checks for race conditions that can result in RCU
 waiting for a CPU that is offline.
 \end{lineref}
@@ -1623,7 +1596,7 @@ of the NMI handler.
 This limitation of sharing allows the individual functions to be
 understood one at a time, in happy contrast to the situation
 described in
-Section~\ref{sec:formal:Promela Parable: dynticks and Preemptible RCU},
+\cref{sec:formal:Promela Parable: dynticks and Preemptible RCU},
 where an NMI might change shared state at any point during execution of
 the \IRQ\ functions.
 
-- 
2.17.1





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux