From mboxrd@z Thu Jan 1 00:00:00 1970 From: tranmanphong at gmail.com (Phong Tran) Date: Sat, 2 Nov 2019 19:00:49 +0700 Subject: [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst In-Reply-To: References: <20191030233128.14997-1-tranmanphong@gmail.com> Message-ID: List-Id: On Sat, Nov 2, 2019 at 3:31 PM Madhuparna Bhowmik < madhuparnabhowmik04 at gmail.com> wrote: > I reviewed this patch, and I have the following suggestions: > > Thank for feedback. I did some change adding the cross-ref. patch sent also apply in rcu-dev branch. https://lists.linuxfoundation.org/pipermail/linux-kernel-mentees/2019-November/001019.html Regards, Phong. > On Thu, Oct 31, 2019 at 5:04 AM Phong Tran wrote: > >> Sync the format with current state of kernel documentation. >> This change base on rcu-dev branch >> what changed: >> - Format bullet lists >> - Add literal blocks >> >> Signed-off-by: Phong Tran >> --- >> Documentation/RCU/index.rst | 1 + >> .../RCU/{whatisRCU.txt => whatisRCU.rst} | 150 +++++++++++------- >> 2 files changed, 90 insertions(+), 61 deletions(-) >> rename Documentation/RCU/{whatisRCU.txt => whatisRCU.rst} (91%) >> >> diff --git a/Documentation/RCU/index.rst b/Documentation/RCU/index.rst >> index 627128c230dc..b9b11481c727 100644 >> --- a/Documentation/RCU/index.rst >> +++ b/Documentation/RCU/index.rst >> @@ -8,6 +8,7 @@ RCU concepts >> :maxdepth: 3 >> >> arrayRCU >> + whatisRCU >> rcu >> listRCU >> NMI-RCU >> diff --git a/Documentation/RCU/whatisRCU.txt >> b/Documentation/RCU/whatisRCU.rst >> similarity index 91% >> rename from Documentation/RCU/whatisRCU.txt >> rename to Documentation/RCU/whatisRCU.rst >> index 58ba05c4d97f..70d0e4c21917 100644 >> --- a/Documentation/RCU/whatisRCU.txt >> +++ b/Documentation/RCU/whatisRCU.rst >> @@ -1,15 +1,18 @@ >> +.. _rcu_doc: >> + >> What is RCU? -- "Read, Copy, Update" >> +====================================== >> >> Please note that the "What is RCU?" LWN series is an excellent place >> to start learning about RCU: >> >> -1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ >> -2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ >> -3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ >> -4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ >> - 2010 Big API Table http://lwn.net/Articles/419086/ >> -5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ >> - 2014 Big API Table http://lwn.net/Articles/609973/ >> +| 1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ >> +| 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ >> +| 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ >> +| 4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ >> +| 2010 Big API Table http://lwn.net/Articles/419086/ >> +| 5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ >> +| 2014 Big API Table http://lwn.net/Articles/609973/ >> >> > Adding an external link here would be better. > like this : `text `_ > > What is RCU? >> @@ -51,6 +54,7 @@ never need this document anyway. ;-) >> >> >> > There is a list of topics that are covered in this documentation. > Like this: > > 1. RCU OVERVIEW > 2. WHAT IS RCU?S CORE API? > 3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API? > 4. WHAT IF MY UPDATING THREAD CANNOT BLOCK? > ... > > since this document is quite big adding cross-references to the above > would be helpful. > > >> 1. RCU OVERVIEW >> +---------------- >> >> The basic idea behind RCU is to split updates into "removal" and >> "reclamation" phases. The removal phase removes references to data items >> @@ -118,6 +122,7 @@ Read on to learn about how RCU's API makes this easy. >> >> >> 2. WHAT IS RCU'S CORE API? >> +--------------------------- >> >> The core RCU API is quite small: >> >> @@ -166,7 +171,7 @@ synchronize_rcu() >> read-side critical sections on all CPUs have completed. >> Note that synchronize_rcu() will -not- necessarily wait for >> any subsequent RCU read-side critical sections to complete. >> - For example, consider the following sequence of events: >> + For example, consider the following sequence of events:: >> >> CPU 0 CPU 1 CPU 2 >> ----------------- ------------------------- --------------- >> @@ -248,13 +253,13 @@ rcu_dereference() >> >> Common coding practice uses rcu_dereference() to copy an >> RCU-protected pointer to a local variable, then dereferences >> - this local variable, for example as follows: >> + this local variable, for example as follows:: >> >> p = rcu_dereference(head.next); >> return p->data; >> >> However, in this case, one could just as easily combine these >> - into one statement: >> + into one statement:: >> >> return rcu_dereference(head.next)->data; >> >> @@ -267,7 +272,7 @@ rcu_dereference() >> >> Note that the value returned by rcu_dereference() is valid >> only within the enclosing RCU read-side critical section [1]. >> - For example, the following is -not- legal: >> + For example, the following is -not- legal:: >> >> rcu_read_lock(); >> p = rcu_dereference(head.next); >> @@ -315,6 +320,7 @@ rcu_dereference() >> >> The following diagram shows how each API communicates among the >> reader, updater, and reclaimer. >> +:: >> >> >> rcu_assign_pointer() >> @@ -377,10 +383,12 @@ for specialized uses, but are relatively uncommon. >> >> >> 3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API? >> +----------------------------------------------- >> >> This section shows a simple use of the core RCU API to protect a >> global pointer to a dynamically allocated structure. More-typical >> uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt. >> +:: >> >> struct foo { >> int a; >> @@ -467,13 +475,14 @@ arrayRCU.txt, and NMI-RCU.txt. >> >> >> 4. WHAT IF MY UPDATING THREAD CANNOT BLOCK? >> +-------------------------------------------- >> >> In the example above, foo_update_a() blocks until a grace period elapses. >> This is quite simple, but in some cases one cannot afford to wait so >> long -- there might be other high-priority work to be done. >> >> In such cases, one uses call_rcu() rather than synchronize_rcu(). >> -The call_rcu() API is as follows: >> +The call_rcu() API is as follows:: >> >> void call_rcu(struct rcu_head * head, >> void (*func)(struct rcu_head *head)); >> @@ -481,7 +490,7 @@ The call_rcu() API is as follows: >> This function invokes func(head) after a grace period has elapsed. >> This invocation might happen from either softirq or process context, >> so the function is not permitted to block. The foo struct needs to >> -have an rcu_head structure added, perhaps as follows: >> +have an rcu_head structure added, perhaps as follows:: >> >> struct foo { >> int a; >> @@ -490,7 +499,7 @@ have an rcu_head structure added, perhaps as follows: >> struct rcu_head rcu; >> }; >> >> -The foo_update_a() function might then be written as follows: >> +The foo_update_a() function might then be written as follows:: >> >> /* >> * Create a new struct foo that is the same as the one currently >> @@ -520,7 +529,7 @@ The foo_update_a() function might then be written as >> follows: >> call_rcu(&old_fp->rcu, foo_reclaim); >> } >> >> -The foo_reclaim() function might appear as follows: >> +The foo_reclaim() function might appear as follows:: >> >> void foo_reclaim(struct rcu_head *rp) >> { >> @@ -552,7 +561,7 @@ o Use call_rcu() -after- removing a data element >> from an >> >> If the callback for call_rcu() is not doing anything more than calling >> kfree() on the structure, you can use kfree_rcu() instead of call_rcu() >> -to avoid having to write your own callback: >> +to avoid having to write your own callback:: >> >> kfree_rcu(old_fp, rcu); >> >> @@ -560,6 +569,7 @@ Again, see checklist.txt for additional rules >> governing the use of RCU. >> >> >> 5. WHAT ARE SOME SIMPLE IMPLEMENTATIONS OF RCU? >> +------------------------------------------------ >> >> One of the nice things about RCU is that it has extremely simple "toy" >> implementations that are a good first step towards understanding the >> @@ -591,7 +601,7 @@ you allow nested rcu_read_lock() calls, you can >> deadlock. >> However, it is probably the easiest implementation to relate to, so is >> a good starting point. >> >> -It is extremely simple: >> +It is extremely simple:: >> >> static DEFINE_RWLOCK(rcu_gp_mutex); >> >> @@ -614,7 +624,7 @@ It is extremely simple: >> >> [You can ignore rcu_assign_pointer() and rcu_dereference() without >> missing >> much. But here are simplified versions anyway. And whatever you do, >> -don't forget about them when submitting patches making use of RCU!] >> +don't forget about them when submitting patches making use of RCU!]:: >> >> #define rcu_assign_pointer(p, v) \ >> ({ \ >> @@ -659,6 +669,7 @@ This section presents a "toy" RCU implementation that >> is based on >> on features such as hotplug CPU and the ability to run in CONFIG_PREEMPT >> kernels. The definitions of rcu_dereference() and rcu_assign_pointer() >> are the same as those shown in the preceding section, so they are >> omitted. >> +:: >> >> void rcu_read_lock(void) { } >> >> @@ -707,10 +718,12 @@ Quick Quiz #3: If it is illegal to block in an RCU >> read-side >> >> >> 6. ANALOGY WITH READER-WRITER LOCKING >> +-------------------------------------- >> >> Although RCU can be used in many different ways, a very common use of >> RCU is analogous to reader-writer locking. The following unified >> diff shows how closely related RCU and reader-writer locking can be. >> +:: >> >> @@ -5,5 +5,5 @@ struct el { >> int data; >> @@ -762,7 +775,7 @@ diff shows how closely related RCU and reader-writer >> locking can be. >> return 0; >> } >> >> -Or, for those who prefer a side-by-side listing: >> +Or, for those who prefer a side-by-side listing:: >> >> 1 struct el { 1 struct el { >> 2 struct list_head list; 2 struct list_head list; >> @@ -774,40 +787,44 @@ Or, for those who prefer a side-by-side listing: >> 8 rwlock_t listmutex; 8 spinlock_t listmutex; >> 9 struct el head; 9 struct el head; >> >> - 1 int search(long key, int *result) 1 int search(long key, int >> *result) >> - 2 { 2 { >> - 3 struct list_head *lp; 3 struct list_head *lp; >> - 4 struct el *p; 4 struct el *p; >> - 5 5 >> - 6 read_lock(&listmutex); 6 rcu_read_lock(); >> - 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, >> head, lp) { >> - 8 if (p->key == key) { 8 if (p->key == key) { >> - 9 *result = p->data; 9 *result = p->data; >> -10 read_unlock(&listmutex); 10 rcu_read_unlock(); >> -11 return 1; 11 return 1; >> -12 } 12 } >> -13 } 13 } >> -14 read_unlock(&listmutex); 14 rcu_read_unlock(); >> -15 return 0; 15 return 0; >> -16 } 16 } >> - >> - 1 int delete(long key) 1 int delete(long key) >> - 2 { 2 { >> - 3 struct el *p; 3 struct el *p; >> - 4 4 >> - 5 write_lock(&listmutex); 5 spin_lock(&listmutex); >> - 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, head, >> lp) { >> - 7 if (p->key == key) { 7 if (p->key == key) { >> - 8 list_del(&p->list); 8 list_del_rcu(&p->list); >> - 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex); >> - 10 synchronize_rcu(); >> -10 kfree(p); 11 kfree(p); >> -11 return 1; 12 return 1; >> -12 } 13 } >> -13 } 14 } >> -14 write_unlock(&listmutex); 15 spin_unlock(&listmutex); >> -15 return 0; 16 return 0; >> -16 } 17 } >> +:: >> + >> + 1 int search(long key, int *result) 1 int search(long key, int >> *result) >> + 2 { 2 { >> + 3 struct list_head *lp; 3 struct list_head *lp; >> + 4 struct el *p; 4 struct el *p; >> + 5 5 >> + 6 read_lock(&listmutex); 6 rcu_read_lock(); >> + 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, >> head, lp) { >> + 8 if (p->key == key) { 8 if (p->key == key) { >> + 9 *result = p->data; 9 *result = p->data; >> + 10 read_unlock(&listmutex); 10 rcu_read_unlock(); >> + 11 return 1; 11 return 1; >> + 12 } 12 } >> + 13 } 13 } >> + 14 read_unlock(&listmutex); 14 rcu_read_unlock(); >> + 15 return 0; 15 return 0; >> + 16 } 16 } >> + >> +:: >> + >> + 1 int delete(long key) 1 int delete(long key) >> + 2 { 2 { >> + 3 struct el *p; 3 struct el *p; >> + 4 4 >> + 5 write_lock(&listmutex); 5 spin_lock(&listmutex); >> + 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, >> head, lp) { >> + 7 if (p->key == key) { 7 if (p->key == key) { >> + 8 list_del(&p->list); 8 list_del_rcu(&p->list); >> + 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex); >> + 10 synchronize_rcu(); >> + 10 kfree(p); 11 kfree(p); >> + 11 return 1; 12 return 1; >> + 12 } 13 } >> + 13 } 14 } >> + 14 write_unlock(&listmutex); 15 spin_unlock(&listmutex); >> + 15 return 0; 16 return 0; >> + 16 } 17 } >> >> Either way, the differences are quite small. Read-side locking moves >> to rcu_read_lock() and rcu_read_unlock, update-side locking moves from >> @@ -827,13 +844,14 @@ be used in place of synchronize_rcu(). >> >> >> 7. FULL LIST OF RCU APIs >> +------------------------- >> >> The RCU APIs are documented in docbook-format header comments in the >> Linux-kernel source code, but it helps to have a full list of the >> APIs, since there does not appear to be a way to categorize them >> in docbook. Here is the list, by category. >> >> -RCU list traversal: >> +RCU list traversal:: >> >> list_entry_rcu >> list_first_entry_rcu >> @@ -854,7 +872,7 @@ RCU list traversal: >> hlist_bl_first_rcu >> hlist_bl_for_each_entry_rcu >> >> -RCU pointer/list update: >> +RCU pointer/list udate:: >> >> rcu_assign_pointer >> list_add_rcu >> @@ -876,7 +894,9 @@ RCU pointer/list update: >> hlist_bl_del_rcu >> hlist_bl_set_first_rcu >> >> -RCU: Critical sections Grace period Barrier >> +RCU:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock synchronize_net rcu_barrier >> rcu_read_unlock synchronize_rcu >> @@ -885,7 +905,9 @@ RCU: Critical sections Grace period >> Barrier >> rcu_dereference_check kfree_rcu >> rcu_dereference_protected >> >> -bh: Critical sections Grace period Barrier >> +bh:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock_bh call_rcu rcu_barrier >> rcu_read_unlock_bh synchronize_rcu >> @@ -896,7 +918,9 @@ bh: Critical sections Grace period >> Barrier >> rcu_dereference_bh_protected >> rcu_read_lock_bh_held >> >> -sched: Critical sections Grace period Barrier >> +sched:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock_sched call_rcu rcu_barrier >> rcu_read_unlock_sched synchronize_rcu >> @@ -910,7 +934,9 @@ sched: Critical sections Grace period >> Barrier >> rcu_read_lock_sched_held >> >> >> -SRCU: Critical sections Grace period Barrier >> +SRCU:: >> + >> + Critical sections Grace period Barrier >> >> srcu_read_lock call_srcu srcu_barrier >> srcu_read_unlock synchronize_srcu >> @@ -918,13 +944,14 @@ SRCU: Critical sections Grace period >> Barrier >> srcu_dereference_check >> srcu_read_lock_held >> >> -SRCU: Initialization/cleanup >> +SRCU: Initialization/cleanup:: >> + >> DEFINE_SRCU >> DEFINE_STATIC_SRCU >> init_srcu_struct >> cleanup_srcu_struct >> >> -All: lockdep-checked RCU-protected pointer access >> +All: lockdep-checked RCU-protected pointer access:: >> >> rcu_access_pointer >> rcu_dereference_raw >> @@ -976,6 +1003,7 @@ the right tool for your job. >> >> >> 8. ANSWERS TO QUICK QUIZZES >> +---------------------------- >> >> Quick Quiz #1: Why is this argument naive? How could a deadlock >> occur when using this algorithm in a real-world Linux >> > > Here, the formatting is not proper. In the rst file, the question should > be added in the next line after Quick Quiz #1. Currently, half of the > question appears in bold and the rest half does not. > Also, as followed in all the documents there should be a cross-reference > to the answer to this question. As this document is quite big having > references would be helpful. > The same applies to all other quick quiz questions in this document and in > the Answers section as well the questions do not appear properly, half in > bold text and half not bold. > > Apart from this, the other added changes look good! > > Thank you > Madhuparna > > -- >> 2.20.1 >> >> _______________________________________________ >> Linux-kernel-mentees mailing list >> Linux-kernel-mentees at lists.linuxfoundation.org >> https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees >> > ? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mboxrd@z Thu Jan 1 00:00:00 1970 From: tranmanphong@gmail.com (Phong Tran) Date: Sat, 2 Nov 2019 19:00:49 +0700 Subject: [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst In-Reply-To: References: <20191030233128.14997-1-tranmanphong@gmail.com> Message-ID: List-Id: Content-Type: text/plain; charset="UTF-8" Message-ID: <20191102120049.zGNxcaQIXzCjEBSinD_7siuap9htcDXQ9Cx1jQEIilw@z> On Sat, Nov 2, 2019 at 3:31 PM Madhuparna Bhowmik < madhuparnabhowmik04 at gmail.com> wrote: > I reviewed this patch, and I have the following suggestions: > > Thank for feedback. I did some change adding the cross-ref. patch sent also apply in rcu-dev branch. https://lists.linuxfoundation.org/pipermail/linux-kernel-mentees/2019-November/001019.html Regards, Phong. > On Thu, Oct 31, 2019 at 5:04 AM Phong Tran wrote: > >> Sync the format with current state of kernel documentation. >> This change base on rcu-dev branch >> what changed: >> - Format bullet lists >> - Add literal blocks >> >> Signed-off-by: Phong Tran >> --- >> Documentation/RCU/index.rst | 1 + >> .../RCU/{whatisRCU.txt => whatisRCU.rst} | 150 +++++++++++------- >> 2 files changed, 90 insertions(+), 61 deletions(-) >> rename Documentation/RCU/{whatisRCU.txt => whatisRCU.rst} (91%) >> >> diff --git a/Documentation/RCU/index.rst b/Documentation/RCU/index.rst >> index 627128c230dc..b9b11481c727 100644 >> --- a/Documentation/RCU/index.rst >> +++ b/Documentation/RCU/index.rst >> @@ -8,6 +8,7 @@ RCU concepts >> :maxdepth: 3 >> >> arrayRCU >> + whatisRCU >> rcu >> listRCU >> NMI-RCU >> diff --git a/Documentation/RCU/whatisRCU.txt >> b/Documentation/RCU/whatisRCU.rst >> similarity index 91% >> rename from Documentation/RCU/whatisRCU.txt >> rename to Documentation/RCU/whatisRCU.rst >> index 58ba05c4d97f..70d0e4c21917 100644 >> --- a/Documentation/RCU/whatisRCU.txt >> +++ b/Documentation/RCU/whatisRCU.rst >> @@ -1,15 +1,18 @@ >> +.. _rcu_doc: >> + >> What is RCU? -- "Read, Copy, Update" >> +====================================== >> >> Please note that the "What is RCU?" LWN series is an excellent place >> to start learning about RCU: >> >> -1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ >> -2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ >> -3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ >> -4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ >> - 2010 Big API Table http://lwn.net/Articles/419086/ >> -5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ >> - 2014 Big API Table http://lwn.net/Articles/609973/ >> +| 1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ >> +| 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ >> +| 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ >> +| 4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ >> +| 2010 Big API Table http://lwn.net/Articles/419086/ >> +| 5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ >> +| 2014 Big API Table http://lwn.net/Articles/609973/ >> >> > Adding an external link here would be better. > like this : `text `_ > > What is RCU? >> @@ -51,6 +54,7 @@ never need this document anyway. ;-) >> >> >> > There is a list of topics that are covered in this documentation. > Like this: > > 1. RCU OVERVIEW > 2. WHAT IS RCU?S CORE API? > 3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API? > 4. WHAT IF MY UPDATING THREAD CANNOT BLOCK? > ... > > since this document is quite big adding cross-references to the above > would be helpful. > > >> 1. RCU OVERVIEW >> +---------------- >> >> The basic idea behind RCU is to split updates into "removal" and >> "reclamation" phases. The removal phase removes references to data items >> @@ -118,6 +122,7 @@ Read on to learn about how RCU's API makes this easy. >> >> >> 2. WHAT IS RCU'S CORE API? >> +--------------------------- >> >> The core RCU API is quite small: >> >> @@ -166,7 +171,7 @@ synchronize_rcu() >> read-side critical sections on all CPUs have completed. >> Note that synchronize_rcu() will -not- necessarily wait for >> any subsequent RCU read-side critical sections to complete. >> - For example, consider the following sequence of events: >> + For example, consider the following sequence of events:: >> >> CPU 0 CPU 1 CPU 2 >> ----------------- ------------------------- --------------- >> @@ -248,13 +253,13 @@ rcu_dereference() >> >> Common coding practice uses rcu_dereference() to copy an >> RCU-protected pointer to a local variable, then dereferences >> - this local variable, for example as follows: >> + this local variable, for example as follows:: >> >> p = rcu_dereference(head.next); >> return p->data; >> >> However, in this case, one could just as easily combine these >> - into one statement: >> + into one statement:: >> >> return rcu_dereference(head.next)->data; >> >> @@ -267,7 +272,7 @@ rcu_dereference() >> >> Note that the value returned by rcu_dereference() is valid >> only within the enclosing RCU read-side critical section [1]. >> - For example, the following is -not- legal: >> + For example, the following is -not- legal:: >> >> rcu_read_lock(); >> p = rcu_dereference(head.next); >> @@ -315,6 +320,7 @@ rcu_dereference() >> >> The following diagram shows how each API communicates among the >> reader, updater, and reclaimer. >> +:: >> >> >> rcu_assign_pointer() >> @@ -377,10 +383,12 @@ for specialized uses, but are relatively uncommon. >> >> >> 3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API? >> +----------------------------------------------- >> >> This section shows a simple use of the core RCU API to protect a >> global pointer to a dynamically allocated structure. More-typical >> uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt. >> +:: >> >> struct foo { >> int a; >> @@ -467,13 +475,14 @@ arrayRCU.txt, and NMI-RCU.txt. >> >> >> 4. WHAT IF MY UPDATING THREAD CANNOT BLOCK? >> +-------------------------------------------- >> >> In the example above, foo_update_a() blocks until a grace period elapses. >> This is quite simple, but in some cases one cannot afford to wait so >> long -- there might be other high-priority work to be done. >> >> In such cases, one uses call_rcu() rather than synchronize_rcu(). >> -The call_rcu() API is as follows: >> +The call_rcu() API is as follows:: >> >> void call_rcu(struct rcu_head * head, >> void (*func)(struct rcu_head *head)); >> @@ -481,7 +490,7 @@ The call_rcu() API is as follows: >> This function invokes func(head) after a grace period has elapsed. >> This invocation might happen from either softirq or process context, >> so the function is not permitted to block. The foo struct needs to >> -have an rcu_head structure added, perhaps as follows: >> +have an rcu_head structure added, perhaps as follows:: >> >> struct foo { >> int a; >> @@ -490,7 +499,7 @@ have an rcu_head structure added, perhaps as follows: >> struct rcu_head rcu; >> }; >> >> -The foo_update_a() function might then be written as follows: >> +The foo_update_a() function might then be written as follows:: >> >> /* >> * Create a new struct foo that is the same as the one currently >> @@ -520,7 +529,7 @@ The foo_update_a() function might then be written as >> follows: >> call_rcu(&old_fp->rcu, foo_reclaim); >> } >> >> -The foo_reclaim() function might appear as follows: >> +The foo_reclaim() function might appear as follows:: >> >> void foo_reclaim(struct rcu_head *rp) >> { >> @@ -552,7 +561,7 @@ o Use call_rcu() -after- removing a data element >> from an >> >> If the callback for call_rcu() is not doing anything more than calling >> kfree() on the structure, you can use kfree_rcu() instead of call_rcu() >> -to avoid having to write your own callback: >> +to avoid having to write your own callback:: >> >> kfree_rcu(old_fp, rcu); >> >> @@ -560,6 +569,7 @@ Again, see checklist.txt for additional rules >> governing the use of RCU. >> >> >> 5. WHAT ARE SOME SIMPLE IMPLEMENTATIONS OF RCU? >> +------------------------------------------------ >> >> One of the nice things about RCU is that it has extremely simple "toy" >> implementations that are a good first step towards understanding the >> @@ -591,7 +601,7 @@ you allow nested rcu_read_lock() calls, you can >> deadlock. >> However, it is probably the easiest implementation to relate to, so is >> a good starting point. >> >> -It is extremely simple: >> +It is extremely simple:: >> >> static DEFINE_RWLOCK(rcu_gp_mutex); >> >> @@ -614,7 +624,7 @@ It is extremely simple: >> >> [You can ignore rcu_assign_pointer() and rcu_dereference() without >> missing >> much. But here are simplified versions anyway. And whatever you do, >> -don't forget about them when submitting patches making use of RCU!] >> +don't forget about them when submitting patches making use of RCU!]:: >> >> #define rcu_assign_pointer(p, v) \ >> ({ \ >> @@ -659,6 +669,7 @@ This section presents a "toy" RCU implementation that >> is based on >> on features such as hotplug CPU and the ability to run in CONFIG_PREEMPT >> kernels. The definitions of rcu_dereference() and rcu_assign_pointer() >> are the same as those shown in the preceding section, so they are >> omitted. >> +:: >> >> void rcu_read_lock(void) { } >> >> @@ -707,10 +718,12 @@ Quick Quiz #3: If it is illegal to block in an RCU >> read-side >> >> >> 6. ANALOGY WITH READER-WRITER LOCKING >> +-------------------------------------- >> >> Although RCU can be used in many different ways, a very common use of >> RCU is analogous to reader-writer locking. The following unified >> diff shows how closely related RCU and reader-writer locking can be. >> +:: >> >> @@ -5,5 +5,5 @@ struct el { >> int data; >> @@ -762,7 +775,7 @@ diff shows how closely related RCU and reader-writer >> locking can be. >> return 0; >> } >> >> -Or, for those who prefer a side-by-side listing: >> +Or, for those who prefer a side-by-side listing:: >> >> 1 struct el { 1 struct el { >> 2 struct list_head list; 2 struct list_head list; >> @@ -774,40 +787,44 @@ Or, for those who prefer a side-by-side listing: >> 8 rwlock_t listmutex; 8 spinlock_t listmutex; >> 9 struct el head; 9 struct el head; >> >> - 1 int search(long key, int *result) 1 int search(long key, int >> *result) >> - 2 { 2 { >> - 3 struct list_head *lp; 3 struct list_head *lp; >> - 4 struct el *p; 4 struct el *p; >> - 5 5 >> - 6 read_lock(&listmutex); 6 rcu_read_lock(); >> - 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, >> head, lp) { >> - 8 if (p->key == key) { 8 if (p->key == key) { >> - 9 *result = p->data; 9 *result = p->data; >> -10 read_unlock(&listmutex); 10 rcu_read_unlock(); >> -11 return 1; 11 return 1; >> -12 } 12 } >> -13 } 13 } >> -14 read_unlock(&listmutex); 14 rcu_read_unlock(); >> -15 return 0; 15 return 0; >> -16 } 16 } >> - >> - 1 int delete(long key) 1 int delete(long key) >> - 2 { 2 { >> - 3 struct el *p; 3 struct el *p; >> - 4 4 >> - 5 write_lock(&listmutex); 5 spin_lock(&listmutex); >> - 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, head, >> lp) { >> - 7 if (p->key == key) { 7 if (p->key == key) { >> - 8 list_del(&p->list); 8 list_del_rcu(&p->list); >> - 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex); >> - 10 synchronize_rcu(); >> -10 kfree(p); 11 kfree(p); >> -11 return 1; 12 return 1; >> -12 } 13 } >> -13 } 14 } >> -14 write_unlock(&listmutex); 15 spin_unlock(&listmutex); >> -15 return 0; 16 return 0; >> -16 } 17 } >> +:: >> + >> + 1 int search(long key, int *result) 1 int search(long key, int >> *result) >> + 2 { 2 { >> + 3 struct list_head *lp; 3 struct list_head *lp; >> + 4 struct el *p; 4 struct el *p; >> + 5 5 >> + 6 read_lock(&listmutex); 6 rcu_read_lock(); >> + 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, >> head, lp) { >> + 8 if (p->key == key) { 8 if (p->key == key) { >> + 9 *result = p->data; 9 *result = p->data; >> + 10 read_unlock(&listmutex); 10 rcu_read_unlock(); >> + 11 return 1; 11 return 1; >> + 12 } 12 } >> + 13 } 13 } >> + 14 read_unlock(&listmutex); 14 rcu_read_unlock(); >> + 15 return 0; 15 return 0; >> + 16 } 16 } >> + >> +:: >> + >> + 1 int delete(long key) 1 int delete(long key) >> + 2 { 2 { >> + 3 struct el *p; 3 struct el *p; >> + 4 4 >> + 5 write_lock(&listmutex); 5 spin_lock(&listmutex); >> + 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, >> head, lp) { >> + 7 if (p->key == key) { 7 if (p->key == key) { >> + 8 list_del(&p->list); 8 list_del_rcu(&p->list); >> + 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex); >> + 10 synchronize_rcu(); >> + 10 kfree(p); 11 kfree(p); >> + 11 return 1; 12 return 1; >> + 12 } 13 } >> + 13 } 14 } >> + 14 write_unlock(&listmutex); 15 spin_unlock(&listmutex); >> + 15 return 0; 16 return 0; >> + 16 } 17 } >> >> Either way, the differences are quite small. Read-side locking moves >> to rcu_read_lock() and rcu_read_unlock, update-side locking moves from >> @@ -827,13 +844,14 @@ be used in place of synchronize_rcu(). >> >> >> 7. FULL LIST OF RCU APIs >> +------------------------- >> >> The RCU APIs are documented in docbook-format header comments in the >> Linux-kernel source code, but it helps to have a full list of the >> APIs, since there does not appear to be a way to categorize them >> in docbook. Here is the list, by category. >> >> -RCU list traversal: >> +RCU list traversal:: >> >> list_entry_rcu >> list_first_entry_rcu >> @@ -854,7 +872,7 @@ RCU list traversal: >> hlist_bl_first_rcu >> hlist_bl_for_each_entry_rcu >> >> -RCU pointer/list update: >> +RCU pointer/list udate:: >> >> rcu_assign_pointer >> list_add_rcu >> @@ -876,7 +894,9 @@ RCU pointer/list update: >> hlist_bl_del_rcu >> hlist_bl_set_first_rcu >> >> -RCU: Critical sections Grace period Barrier >> +RCU:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock synchronize_net rcu_barrier >> rcu_read_unlock synchronize_rcu >> @@ -885,7 +905,9 @@ RCU: Critical sections Grace period >> Barrier >> rcu_dereference_check kfree_rcu >> rcu_dereference_protected >> >> -bh: Critical sections Grace period Barrier >> +bh:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock_bh call_rcu rcu_barrier >> rcu_read_unlock_bh synchronize_rcu >> @@ -896,7 +918,9 @@ bh: Critical sections Grace period >> Barrier >> rcu_dereference_bh_protected >> rcu_read_lock_bh_held >> >> -sched: Critical sections Grace period Barrier >> +sched:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock_sched call_rcu rcu_barrier >> rcu_read_unlock_sched synchronize_rcu >> @@ -910,7 +934,9 @@ sched: Critical sections Grace period >> Barrier >> rcu_read_lock_sched_held >> >> >> -SRCU: Critical sections Grace period Barrier >> +SRCU:: >> + >> + Critical sections Grace period Barrier >> >> srcu_read_lock call_srcu srcu_barrier >> srcu_read_unlock synchronize_srcu >> @@ -918,13 +944,14 @@ SRCU: Critical sections Grace period >> Barrier >> srcu_dereference_check >> srcu_read_lock_held >> >> -SRCU: Initialization/cleanup >> +SRCU: Initialization/cleanup:: >> + >> DEFINE_SRCU >> DEFINE_STATIC_SRCU >> init_srcu_struct >> cleanup_srcu_struct >> >> -All: lockdep-checked RCU-protected pointer access >> +All: lockdep-checked RCU-protected pointer access:: >> >> rcu_access_pointer >> rcu_dereference_raw >> @@ -976,6 +1003,7 @@ the right tool for your job. >> >> >> 8. ANSWERS TO QUICK QUIZZES >> +---------------------------- >> >> Quick Quiz #1: Why is this argument naive? How could a deadlock >> occur when using this algorithm in a real-world Linux >> > > Here, the formatting is not proper. In the rst file, the question should > be added in the next line after Quick Quiz #1. Currently, half of the > question appears in bold and the rest half does not. > Also, as followed in all the documents there should be a cross-reference > to the answer to this question. As this document is quite big having > references would be helpful. > The same applies to all other quick quiz questions in this document and in > the Answers section as well the questions do not appear properly, half in > bold text and half not bold. > > Apart from this, the other added changes look good! > > Thank you > Madhuparna > > -- >> 2.20.1 >> >> _______________________________________________ >> Linux-kernel-mentees mailing list >> Linux-kernel-mentees at lists.linuxfoundation.org >> https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees >> > ? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_FONT_LOW_CONTRAST,HTML_MESSAGE, INCLUDES_PATCH,MAILING_LIST_MULTI,MIME_HTML_MOSTLY,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3ED6ACA9EC7 for ; Sat, 2 Nov 2019 12:01:07 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0873420679 for ; Sat, 2 Nov 2019 12:01:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="uFFyl0BR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0873420679 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=linux-kernel-mentees-bounces@lists.linuxfoundation.org Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D4E10E47; Sat, 2 Nov 2019 12:01:06 +0000 (UTC) Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 1F2A6E39 for ; Sat, 2 Nov 2019 12:01:05 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6F9A714D for ; Sat, 2 Nov 2019 12:01:02 +0000 (UTC) Received: by mail-wr1-f67.google.com with SMTP id a15so12170352wrf.9 for ; Sat, 02 Nov 2019 05:01:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=O2KsGLiND+W2Yh38SHZotwgs3GY4+1KC+dZGrW9Cuaw=; b=uFFyl0BRdklhtV42n5lj8mSjkErSE5z6u9D9Lv1X2zqCjYuyGUg89MC/bmm577XYVp UcmEdvjxMoFNp4esbZ6eNVHtAVqKBDNSmavrxrWqE4Js26sUOwdHPNCEFjtyrJ5vRzsO 4FmWlgevKfu0cRQRBoXlG3IWK/gA9pgsPg/bqfzygqEvaH9YfhA6xrnRRPz+AssivhFV Sfm/LUWn6A9zT1gZOiSs0GuJDlCSVgDFeEipkM6D2vGbvmsnlXKCXQhlsAzyVcy7q1z/ mVd5YcYTY+RkP3CLvZEP3H/jYx+agSam6C76EyFeVsuVg5/kZ1Oi3+1iLVITCVpgA4gm tYog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=O2KsGLiND+W2Yh38SHZotwgs3GY4+1KC+dZGrW9Cuaw=; b=IrVS1bxK+G7J+PPeCAwQk4g/NfSAMfgXp37WRPKd0KLWVF998kT85w03Q1fDIV1nJg I3IhxP6st59McfOfhQ4j1e5s1xwuv50F8soTfoLZOaztA/ktBd2oTnOdedCznPOGOP4p 8zOwcJbqnf9VKNyBu0Apkqao7hORyT5WFlNkdbydSexhPrBl1uKDEb9SeqJ2R6FxZuzm P47movR3LAQGWN1M/oHTHv6cb5wuNVArcrNIY9NNcHQtykNxs9h8anQXkMNi2nPm8/IK Bh/GiT6WkFPRR5kiZjsGfuEmDIZlKyuhsDQLmLLzAyWNY8p/8WHcDLu3a6R8Uh56pNHE MX2g== X-Gm-Message-State: APjAAAV1S2z5rjeJ+BD5bOZSqYBe50fJOOlVpoHfGRIWIU5PeiMN1bZA wZ2mHbBGYZ+hbubEZ86nl/OdUMBXh+qCasb7/R0= X-Google-Smtp-Source: APXvYqwVx6fss6ZrZNqsCwpcEB/fB9MKfVwBwfmJxIdTlVOW2lC9F3jVFpAwmjYrGGviOcpKlvPiOj1WJT1rqO4G/wI= X-Received: by 2002:adf:e386:: with SMTP id e6mr1249796wrm.397.1572696060845; Sat, 02 Nov 2019 05:01:00 -0700 (PDT) MIME-Version: 1.0 References: <20191030233128.14997-1-tranmanphong@gmail.com> In-Reply-To: From: Phong Tran Date: Sat, 2 Nov 2019 19:00:49 +0700 Message-ID: To: Madhuparna Bhowmik Cc: paulmck@kernel.org, Jonathan Corbet , linux-doc@vger.kernel.org, jiangshanlai@gmail.com, josh@joshtriplett.org, rostedt@goodmis.org, linux-kernel@vger.kernel.org, rcu@vger.kernel.org, mathieu.desnoyers@efficios.com, Joel Fernandes , linux-kernel-mentees@lists.linuxfoundation.org Subject: Re: [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst X-BeenThere: linux-kernel-mentees@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: multipart/mixed; boundary="===============8788838115013394139==" Sender: linux-kernel-mentees-bounces@lists.linuxfoundation.org Errors-To: linux-kernel-mentees-bounces@lists.linuxfoundation.org Message-ID: <20191102120049.oC0at3vkppmRTSFEt8CwG-MgWLEBlxBM1uuDv-rdrNQ@z> --===============8788838115013394139== Content-Type: multipart/alternative; boundary="0000000000000be2e305965bd6bd" --0000000000000be2e305965bd6bd Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, Nov 2, 2019 at 3:31 PM Madhuparna Bhowmik < madhuparnabhowmik04@gmail.com> wrote: > I reviewed this patch, and I have the following suggestions: > > Thank for feedback. I did some change adding the cross-ref. patch sent also apply in rcu-dev branch. https://lists.linuxfoundation.org/pipermail/linux-kernel-mentees/2019-Novem= ber/001019.html Regards, Phong. > On Thu, Oct 31, 2019 at 5:04 AM Phong Tran wrote= : > >> Sync the format with current state of kernel documentation. >> This change base on rcu-dev branch >> what changed: >> - Format bullet lists >> - Add literal blocks >> >> Signed-off-by: Phong Tran >> --- >> Documentation/RCU/index.rst | 1 + >> .../RCU/{whatisRCU.txt =3D> whatisRCU.rst} | 150 +++++++++++------= - >> 2 files changed, 90 insertions(+), 61 deletions(-) >> rename Documentation/RCU/{whatisRCU.txt =3D> whatisRCU.rst} (91%) >> >> diff --git a/Documentation/RCU/index.rst b/Documentation/RCU/index.rst >> index 627128c230dc..b9b11481c727 100644 >> --- a/Documentation/RCU/index.rst >> +++ b/Documentation/RCU/index.rst >> @@ -8,6 +8,7 @@ RCU concepts >> :maxdepth: 3 >> >> arrayRCU >> + whatisRCU >> rcu >> listRCU >> NMI-RCU >> diff --git a/Documentation/RCU/whatisRCU.txt >> b/Documentation/RCU/whatisRCU.rst >> similarity index 91% >> rename from Documentation/RCU/whatisRCU.txt >> rename to Documentation/RCU/whatisRCU.rst >> index 58ba05c4d97f..70d0e4c21917 100644 >> --- a/Documentation/RCU/whatisRCU.txt >> +++ b/Documentation/RCU/whatisRCU.rst >> @@ -1,15 +1,18 @@ >> +.. _rcu_doc: >> + >> What is RCU? -- "Read, Copy, Update" >> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> >> Please note that the "What is RCU?" LWN series is an excellent place >> to start learning about RCU: >> >> -1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ >> -2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ >> -3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ >> -4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ >> - 2010 Big API Table http://lwn.net/Articles/419086/ >> -5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ >> - 2014 Big API Table http://lwn.net/Articles/609973/ >> +| 1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ >> +| 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ >> +| 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ >> +| 4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ >> +| 2010 Big API Table http://lwn.net/Articles/419086/ >> +| 5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/ >> +| 2014 Big API Table http://lwn.net/Articles/609973/ >> >> > Adding an external link here would be better. > like this : `text `_ > > What is RCU? >> @@ -51,6 +54,7 @@ never need this document anyway. ;-) >> >> >> > There is a list of topics that are covered in this documentation. > Like this: > > 1. RCU OVERVIEW > 2. WHAT IS RCU=E2=80=99S CORE API? > 3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API? > 4. WHAT IF MY UPDATING THREAD CANNOT BLOCK? > ... > > since this document is quite big adding cross-references to the above > would be helpful. > > >> 1. RCU OVERVIEW >> +---------------- >> >> The basic idea behind RCU is to split updates into "removal" and >> "reclamation" phases. The removal phase removes references to data ite= ms >> @@ -118,6 +122,7 @@ Read on to learn about how RCU's API makes this easy= . >> >> >> 2. WHAT IS RCU'S CORE API? >> +--------------------------- >> >> The core RCU API is quite small: >> >> @@ -166,7 +171,7 @@ synchronize_rcu() >> read-side critical sections on all CPUs have completed. >> Note that synchronize_rcu() will -not- necessarily wait for >> any subsequent RCU read-side critical sections to complete. >> - For example, consider the following sequence of events: >> + For example, consider the following sequence of events:: >> >> CPU 0 CPU 1 CPU 2 >> ----------------- ------------------------- --------------- >> @@ -248,13 +253,13 @@ rcu_dereference() >> >> Common coding practice uses rcu_dereference() to copy an >> RCU-protected pointer to a local variable, then dereferences >> - this local variable, for example as follows: >> + this local variable, for example as follows:: >> >> p =3D rcu_dereference(head.next); >> return p->data; >> >> However, in this case, one could just as easily combine these >> - into one statement: >> + into one statement:: >> >> return rcu_dereference(head.next)->data; >> >> @@ -267,7 +272,7 @@ rcu_dereference() >> >> Note that the value returned by rcu_dereference() is valid >> only within the enclosing RCU read-side critical section [1]. >> - For example, the following is -not- legal: >> + For example, the following is -not- legal:: >> >> rcu_read_lock(); >> p =3D rcu_dereference(head.next); >> @@ -315,6 +320,7 @@ rcu_dereference() >> >> The following diagram shows how each API communicates among the >> reader, updater, and reclaimer. >> +:: >> >> >> rcu_assign_pointer() >> @@ -377,10 +383,12 @@ for specialized uses, but are relatively uncommon. >> >> >> 3. WHAT ARE SOME EXAMPLE USES OF CORE RCU API? >> +----------------------------------------------- >> >> This section shows a simple use of the core RCU API to protect a >> global pointer to a dynamically allocated structure. More-typical >> uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.txt. >> +:: >> >> struct foo { >> int a; >> @@ -467,13 +475,14 @@ arrayRCU.txt, and NMI-RCU.txt. >> >> >> 4. WHAT IF MY UPDATING THREAD CANNOT BLOCK? >> +-------------------------------------------- >> >> In the example above, foo_update_a() blocks until a grace period elapse= s. >> This is quite simple, but in some cases one cannot afford to wait so >> long -- there might be other high-priority work to be done. >> >> In such cases, one uses call_rcu() rather than synchronize_rcu(). >> -The call_rcu() API is as follows: >> +The call_rcu() API is as follows:: >> >> void call_rcu(struct rcu_head * head, >> void (*func)(struct rcu_head *head)); >> @@ -481,7 +490,7 @@ The call_rcu() API is as follows: >> This function invokes func(head) after a grace period has elapsed. >> This invocation might happen from either softirq or process context, >> so the function is not permitted to block. The foo struct needs to >> -have an rcu_head structure added, perhaps as follows: >> +have an rcu_head structure added, perhaps as follows:: >> >> struct foo { >> int a; >> @@ -490,7 +499,7 @@ have an rcu_head structure added, perhaps as follows= : >> struct rcu_head rcu; >> }; >> >> -The foo_update_a() function might then be written as follows: >> +The foo_update_a() function might then be written as follows:: >> >> /* >> * Create a new struct foo that is the same as the one currently >> @@ -520,7 +529,7 @@ The foo_update_a() function might then be written as >> follows: >> call_rcu(&old_fp->rcu, foo_reclaim); >> } >> >> -The foo_reclaim() function might appear as follows: >> +The foo_reclaim() function might appear as follows:: >> >> void foo_reclaim(struct rcu_head *rp) >> { >> @@ -552,7 +561,7 @@ o Use call_rcu() -after- removing a data element >> from an >> >> If the callback for call_rcu() is not doing anything more than calling >> kfree() on the structure, you can use kfree_rcu() instead of call_rcu() >> -to avoid having to write your own callback: >> +to avoid having to write your own callback:: >> >> kfree_rcu(old_fp, rcu); >> >> @@ -560,6 +569,7 @@ Again, see checklist.txt for additional rules >> governing the use of RCU. >> >> >> 5. WHAT ARE SOME SIMPLE IMPLEMENTATIONS OF RCU? >> +------------------------------------------------ >> >> One of the nice things about RCU is that it has extremely simple "toy" >> implementations that are a good first step towards understanding the >> @@ -591,7 +601,7 @@ you allow nested rcu_read_lock() calls, you can >> deadlock. >> However, it is probably the easiest implementation to relate to, so is >> a good starting point. >> >> -It is extremely simple: >> +It is extremely simple:: >> >> static DEFINE_RWLOCK(rcu_gp_mutex); >> >> @@ -614,7 +624,7 @@ It is extremely simple: >> >> [You can ignore rcu_assign_pointer() and rcu_dereference() without >> missing >> much. But here are simplified versions anyway. And whatever you do, >> -don't forget about them when submitting patches making use of RCU!] >> +don't forget about them when submitting patches making use of RCU!]:: >> >> #define rcu_assign_pointer(p, v) \ >> ({ \ >> @@ -659,6 +669,7 @@ This section presents a "toy" RCU implementation tha= t >> is based on >> on features such as hotplug CPU and the ability to run in CONFIG_PREEMP= T >> kernels. The definitions of rcu_dereference() and rcu_assign_pointer() >> are the same as those shown in the preceding section, so they are >> omitted. >> +:: >> >> void rcu_read_lock(void) { } >> >> @@ -707,10 +718,12 @@ Quick Quiz #3: If it is illegal to block in an RC= U >> read-side >> >> >> 6. ANALOGY WITH READER-WRITER LOCKING >> +-------------------------------------- >> >> Although RCU can be used in many different ways, a very common use of >> RCU is analogous to reader-writer locking. The following unified >> diff shows how closely related RCU and reader-writer locking can be. >> +:: >> >> @@ -5,5 +5,5 @@ struct el { >> int data; >> @@ -762,7 +775,7 @@ diff shows how closely related RCU and reader-writer >> locking can be. >> return 0; >> } >> >> -Or, for those who prefer a side-by-side listing: >> +Or, for those who prefer a side-by-side listing:: >> >> 1 struct el { 1 struct el { >> 2 struct list_head list; 2 struct list_head list; >> @@ -774,40 +787,44 @@ Or, for those who prefer a side-by-side listing: >> 8 rwlock_t listmutex; 8 spinlock_t listmutex; >> 9 struct el head; 9 struct el head; >> >> - 1 int search(long key, int *result) 1 int search(long key, int >> *result) >> - 2 { 2 { >> - 3 struct list_head *lp; 3 struct list_head *lp; >> - 4 struct el *p; 4 struct el *p; >> - 5 5 >> - 6 read_lock(&listmutex); 6 rcu_read_lock(); >> - 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, >> head, lp) { >> - 8 if (p->key =3D=3D key) { 8 if (p->key =3D=3D key= ) { >> - 9 *result =3D p->data; 9 *result =3D p->data; >> -10 read_unlock(&listmutex); 10 rcu_read_unlock(); >> -11 return 1; 11 return 1; >> -12 } 12 } >> -13 } 13 } >> -14 read_unlock(&listmutex); 14 rcu_read_unlock(); >> -15 return 0; 15 return 0; >> -16 } 16 } >> - >> - 1 int delete(long key) 1 int delete(long key) >> - 2 { 2 { >> - 3 struct el *p; 3 struct el *p; >> - 4 4 >> - 5 write_lock(&listmutex); 5 spin_lock(&listmutex); >> - 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, head= , >> lp) { >> - 7 if (p->key =3D=3D key) { 7 if (p->key =3D=3D key= ) { >> - 8 list_del(&p->list); 8 list_del_rcu(&p->list); >> - 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex)= ; >> - 10 synchronize_rcu(); >> -10 kfree(p); 11 kfree(p); >> -11 return 1; 12 return 1; >> -12 } 13 } >> -13 } 14 } >> -14 write_unlock(&listmutex); 15 spin_unlock(&listmutex); >> -15 return 0; 16 return 0; >> -16 } 17 } >> +:: >> + >> + 1 int search(long key, int *result) 1 int search(long key, int >> *result) >> + 2 { 2 { >> + 3 struct list_head *lp; 3 struct list_head *lp; >> + 4 struct el *p; 4 struct el *p; >> + 5 5 >> + 6 read_lock(&listmutex); 6 rcu_read_lock(); >> + 7 list_for_each_entry(p, head, lp) { 7 list_for_each_entry_rcu(p, >> head, lp) { >> + 8 if (p->key =3D=3D key) { 8 if (p->key =3D=3D ke= y) { >> + 9 *result =3D p->data; 9 *result =3D p->data; >> + 10 read_unlock(&listmutex); 10 rcu_read_unlock(); >> + 11 return 1; 11 return 1; >> + 12 } 12 } >> + 13 } 13 } >> + 14 read_unlock(&listmutex); 14 rcu_read_unlock(); >> + 15 return 0; 15 return 0; >> + 16 } 16 } >> + >> +:: >> + >> + 1 int delete(long key) 1 int delete(long key) >> + 2 { 2 { >> + 3 struct el *p; 3 struct el *p; >> + 4 4 >> + 5 write_lock(&listmutex); 5 spin_lock(&listmutex); >> + 6 list_for_each_entry(p, head, lp) { 6 list_for_each_entry(p, >> head, lp) { >> + 7 if (p->key =3D=3D key) { 7 if (p->key =3D=3D ke= y) { >> + 8 list_del(&p->list); 8 list_del_rcu(&p->list)= ; >> + 9 write_unlock(&listmutex); 9 spin_unlock(&listmutex= ); >> + 10 synchronize_rcu(); >> + 10 kfree(p); 11 kfree(p); >> + 11 return 1; 12 return 1; >> + 12 } 13 } >> + 13 } 14 } >> + 14 write_unlock(&listmutex); 15 spin_unlock(&listmutex); >> + 15 return 0; 16 return 0; >> + 16 } 17 } >> >> Either way, the differences are quite small. Read-side locking moves >> to rcu_read_lock() and rcu_read_unlock, update-side locking moves from >> @@ -827,13 +844,14 @@ be used in place of synchronize_rcu(). >> >> >> 7. FULL LIST OF RCU APIs >> +------------------------- >> >> The RCU APIs are documented in docbook-format header comments in the >> Linux-kernel source code, but it helps to have a full list of the >> APIs, since there does not appear to be a way to categorize them >> in docbook. Here is the list, by category. >> >> -RCU list traversal: >> +RCU list traversal:: >> >> list_entry_rcu >> list_first_entry_rcu >> @@ -854,7 +872,7 @@ RCU list traversal: >> hlist_bl_first_rcu >> hlist_bl_for_each_entry_rcu >> >> -RCU pointer/list update: >> +RCU pointer/list udate:: >> >> rcu_assign_pointer >> list_add_rcu >> @@ -876,7 +894,9 @@ RCU pointer/list update: >> hlist_bl_del_rcu >> hlist_bl_set_first_rcu >> >> -RCU: Critical sections Grace period Barrier >> +RCU:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock synchronize_net rcu_barrier >> rcu_read_unlock synchronize_rcu >> @@ -885,7 +905,9 @@ RCU: Critical sections Grace period >> Barrier >> rcu_dereference_check kfree_rcu >> rcu_dereference_protected >> >> -bh: Critical sections Grace period Barrier >> +bh:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock_bh call_rcu rcu_barrier >> rcu_read_unlock_bh synchronize_rcu >> @@ -896,7 +918,9 @@ bh: Critical sections Grace period >> Barrier >> rcu_dereference_bh_protected >> rcu_read_lock_bh_held >> >> -sched: Critical sections Grace period Barrier >> +sched:: >> + >> + Critical sections Grace period Barrier >> >> rcu_read_lock_sched call_rcu rcu_barrier >> rcu_read_unlock_sched synchronize_rcu >> @@ -910,7 +934,9 @@ sched: Critical sections Grace period >> Barrier >> rcu_read_lock_sched_held >> >> >> -SRCU: Critical sections Grace period Barrier >> +SRCU:: >> + >> + Critical sections Grace period Barrier >> >> srcu_read_lock call_srcu srcu_barrier >> srcu_read_unlock synchronize_srcu >> @@ -918,13 +944,14 @@ SRCU: Critical sections Grace period >> Barrier >> srcu_dereference_check >> srcu_read_lock_held >> >> -SRCU: Initialization/cleanup >> +SRCU: Initialization/cleanup:: >> + >> DEFINE_SRCU >> DEFINE_STATIC_SRCU >> init_srcu_struct >> cleanup_srcu_struct >> >> -All: lockdep-checked RCU-protected pointer access >> +All: lockdep-checked RCU-protected pointer access:: >> >> rcu_access_pointer >> rcu_dereference_raw >> @@ -976,6 +1003,7 @@ the right tool for your job. >> >> >> 8. ANSWERS TO QUICK QUIZZES >> +---------------------------- >> >> Quick Quiz #1: Why is this argument naive? How could a deadlock >> occur when using this algorithm in a real-world Linux >> > > Here, the formatting is not proper. In the rst file, the question should > be added in the next line after Quick Quiz #1. Currently, half of the > question appears in bold and the rest half does not. > Also, as followed in all the documents there should be a cross-reference > to the answer to this question. As this document is quite big having > references would be helpful. > The same applies to all other quick quiz questions in this document and i= n > the Answers section as well the questions do not appear properly, half in > bold text and half not bold. > > Apart from this, the other added changes look good! > > Thank you > Madhuparna > > -- >> 2.20.1 >> >> _______________________________________________ >> Linux-kernel-mentees mailing list >> Linux-kernel-mentees@lists.linuxfoundation.org >> https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees >> > =E1=90=A7 > --0000000000000be2e305965bd6bd Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Sat, Nov 2, 2019 at 3:31 PM Madhuparna= Bhowmik <madhuparnabho= wmik04@gmail.com> wrote:
I reviewed= this patch, and I have the following suggestions:

Thank for feedback. I did some change adding the cross-ref. patch = sent
also apply in rcu-dev branch.


Regards= ,
Phong.=C2=A0
On Thu, Oct 31, 2019 at 5:04 AM Phong Tran <tranmanphong@gmail.com> wrote:
Syn= c the format with current state of kernel documentation.
This change base on rcu-dev branch
what changed:
- Format bullet lists
- Add literal blocks

Signed-off-by: Phong Tran <
tranmanphong@gmail.com>
---
=C2=A0Documentation/RCU/index.rst=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A01 +
=C2=A0.../RCU/{whatisRCU.txt =3D> whatisRCU.rst}=C2=A0 =C2=A0 =C2=A0 | 1= 50 +++++++++++-------
=C2=A02 files changed, 90 insertions(+), 61 deletions(-)
=C2=A0rename Documentation/RCU/{whatisRCU.txt =3D> whatisRCU.rst} (91%)<= br>
diff --git a/Documentation/RCU/index.rst b/Documentation/RCU/index.rst
index 627128c230dc..b9b11481c727 100644
--- a/Documentation/RCU/index.rst
+++ b/Documentation/RCU/index.rst
@@ -8,6 +8,7 @@ RCU concepts
=C2=A0 =C2=A0 :maxdepth: 3

=C2=A0 =C2=A0 arrayRCU
+=C2=A0 =C2=A0whatisRCU
=C2=A0 =C2=A0 rcu
=C2=A0 =C2=A0 listRCU
=C2=A0 =C2=A0 NMI-RCU
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.= rst
similarity index 91%
rename from Documentation/RCU/whatisRCU.txt
rename to Documentation/RCU/whatisRCU.rst
index 58ba05c4d97f..70d0e4c21917 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.rst
@@ -1,15 +1,18 @@
+.. _rcu_doc:
+
=C2=A0What is RCU?=C2=A0 --=C2=A0 "Read, Copy, Update"
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

=C2=A0Please note that the "What is RCU?" LWN series is an excell= ent place
=C2=A0to start learning about RCU:

-1.=C2=A0 =C2=A0 =C2=A0What is RCU, Fundamentally?=C2=A0 http://lwn.n= et/Articles/262464/
-2.=C2=A0 =C2=A0 =C2=A0What is RCU? Part 2: Usage=C2=A0 =C2=A0http://= lwn.net/Articles/263130/
-3.=C2=A0 =C2=A0 =C2=A0RCU part 3: the RCU API=C2=A0 =C2=A0 =C2=A0 h= ttp://lwn.net/Articles/264090/
-4.=C2=A0 =C2=A0 =C2=A0The RCU API, 2010 Edition=C2=A0 =C2=A0 http://= lwn.net/Articles/418853/
-=C2=A0 =C2=A0 =C2=A0 =C2=A02010 Big API Table=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0http://lwn.net/Articles/419086/
-5.=C2=A0 =C2=A0 =C2=A0The RCU API, 2014 Edition=C2=A0 =C2=A0 http://= lwn.net/Articles/609904/
-=C2=A0 =C2=A0 =C2=A0 =C2=A02014 Big API Table=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0http://lwn.net/Articles/609973/
+| 1.=C2=A0 =C2=A0What is RCU, Fundamentally?=C2=A0 http://lwn.net/Ar= ticles/262464/
+| 2.=C2=A0 =C2=A0What is RCU? Part 2: Usage=C2=A0 =C2=A0http://lwn.n= et/Articles/263130/
+| 3.=C2=A0 =C2=A0RCU part 3: the RCU API=C2=A0 =C2=A0 =C2=A0 http://= lwn.net/Articles/264090/
+| 4.=C2=A0 =C2=A0The RCU API, 2010 Edition=C2=A0 =C2=A0 http://lwn.n= et/Articles/418853/
+|=C2=A0 =C2=A0 =C2=A0 2010 Big API Table=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0http://lwn.net/Articles/419086/
+| 5.=C2=A0 =C2=A0The RCU API, 2014 Edition=C2=A0 =C2=A0 http://lwn.n= et/Articles/609904/
+|=C2=A0 =C2=A0 =C2=A0 2014 Big API Table=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0http://lwn.net/Articles/609973/

<= br>
Adding an external link here would be better.
like = this :=C2=A0=C2=A0`text=C2=A0<link URL>`_=C2=A0

=C2=A0What is RCU?
@@ -51,6 +54,7 @@ never need this document anyway.=C2=A0 ;-)



There is a list of topics that are cov= ered in this documentation.
Like this:

1= . RCU OVERVIEW
2. WHAT IS RCU=E2=80=99S CORE API?
3. WHAT ARE SOME EX= AMPLE USES OF CORE RCU API?
4. WHAT IF MY UPDATING THREAD CANNOT BLOCK?<= br>
...

=C2=A0since this document is qui= te big adding cross-references to the above would be helpful.
=C2= =A0
=C2=A01.=C2=A0 RCU OVERVIEW
+----------------

=C2=A0The basic idea behind RCU is to split updates into "removal"= ; and
=C2=A0"reclamation" phases.=C2=A0 The removal phase removes refer= ences to data items
@@ -118,6 +122,7 @@ Read on to learn about how RCU's API makes this eas= y.


=C2=A02.=C2=A0 WHAT IS RCU'S CORE API?
+---------------------------

=C2=A0The core RCU API is quite small:

@@ -166,7 +171,7 @@ synchronize_rcu()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 read-side critical sections on all CPUs have co= mpleted.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Note that synchronize_rcu() will -not- necessar= ily wait for
=C2=A0 =C2=A0 =C2=A0 =C2=A0 any subsequent RCU read-side critical sections = to complete.
-=C2=A0 =C2=A0 =C2=A0 =C2=A0For example, consider the following sequence of= events:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0For example, consider the following sequence of= events::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0CPU 0=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 CPU 1=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0CPU 2
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0----------------- ---------= ---------------- ---------------
@@ -248,13 +253,13 @@ rcu_dereference()

=C2=A0 =C2=A0 =C2=A0 =C2=A0 Common coding practice uses rcu_dereference() t= o copy an
=C2=A0 =C2=A0 =C2=A0 =C2=A0 RCU-protected pointer to a local variable, then= dereferences
-=C2=A0 =C2=A0 =C2=A0 =C2=A0this local variable, for example as follows: +=C2=A0 =C2=A0 =C2=A0 =C2=A0this local variable, for example as follows::
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 p =3D rcu_dereferen= ce(head.next);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return p->data;<= br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 However, in this case, one could just as easily= combine these
-=C2=A0 =C2=A0 =C2=A0 =C2=A0into one statement:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0into one statement::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return rcu_derefere= nce(head.next)->data;

@@ -267,7 +272,7 @@ rcu_dereference()

=C2=A0 =C2=A0 =C2=A0 =C2=A0 Note that the value returned by rcu_dereference= () is valid
=C2=A0 =C2=A0 =C2=A0 =C2=A0 only within the enclosing RCU read-side critica= l section [1].
-=C2=A0 =C2=A0 =C2=A0 =C2=A0For example, the following is -not- legal:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0For example, the following is -not- legal::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_lock(); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 p =3D rcu_dereferen= ce(head.next);
@@ -315,6 +320,7 @@ rcu_dereference()

=C2=A0The following diagram shows how each API communicates among the
=C2=A0reader, updater, and reclaimer.
+::


=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_assign_pointer()
@@ -377,10 +383,12 @@ for specialized uses, but are relatively uncommon.

=C2=A03.=C2=A0 WHAT ARE SOME EXAMPLE USES OF CORE RCU API?
+-----------------------------------------------

=C2=A0This section shows a simple use of the core RCU API to protect a
=C2=A0global pointer to a dynamically allocated structure.=C2=A0 More-typic= al
=C2=A0uses of RCU may be found in listRCU.txt, arrayRCU.txt, and NMI-RCU.tx= t.
+::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct foo {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int a;
@@ -467,13 +475,14 @@ arrayRCU.txt, and NMI-RCU.txt.


=C2=A04.=C2=A0 WHAT IF MY UPDATING THREAD CANNOT BLOCK?
+--------------------------------------------

=C2=A0In the example above, foo_update_a() blocks until a grace period elap= ses.
=C2=A0This is quite simple, but in some cases one cannot afford to wait so<= br> =C2=A0long -- there might be other high-priority work to be done.

=C2=A0In such cases, one uses call_rcu() rather than synchronize_rcu().
-The call_rcu() API is as follows:
+The call_rcu() API is as follows::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 void call_rcu(struct rcu_head * head,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 void (*func)(struct rcu_head *head));
@@ -481,7 +490,7 @@ The call_rcu() API is as follows:
=C2=A0This function invokes func(head) after a grace period has elapsed. =C2=A0This invocation might happen from either softirq or process context,<= br> =C2=A0so the function is not permitted to block.=C2=A0 The foo struct needs= to
-have an rcu_head structure added, perhaps as follows:
+have an rcu_head structure added, perhaps as follows::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 struct foo {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int a;
@@ -490,7 +499,7 @@ have an rcu_head structure added, perhaps as follows: =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct rcu_head rcu= ;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 };

-The foo_update_a() function might then be written as follows:
+The foo_update_a() function might then be written as follows::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Create a new struct foo that is the sam= e as the one currently
@@ -520,7 +529,7 @@ The foo_update_a() function might then be written as fo= llows:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 call_rcu(&old_f= p->rcu, foo_reclaim);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

-The foo_reclaim() function might appear as follows:
+The foo_reclaim() function might appear as follows::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 void foo_reclaim(struct rcu_head *rp)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
@@ -552,7 +561,7 @@ o=C2=A0 =C2=A0Use call_rcu() -after- removing a data el= ement from an

=C2=A0If the callback for call_rcu() is not doing anything more than callin= g
=C2=A0kfree() on the structure, you can use kfree_rcu() instead of call_rcu= ()
-to avoid having to write your own callback:
+to avoid having to write your own callback::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 kfree_rcu(old_fp, rcu);

@@ -560,6 +569,7 @@ Again, see checklist.txt for additional rules governing= the use of RCU.


=C2=A05.=C2=A0 WHAT ARE SOME SIMPLE IMPLEMENTATIONS OF RCU?
+------------------------------------------------

=C2=A0One of the nice things about RCU is that it has extremely simple &quo= t;toy"
=C2=A0implementations that are a good first step towards understanding the<= br> @@ -591,7 +601,7 @@ you allow nested rcu_read_lock() calls, you can deadloc= k.
=C2=A0However, it is probably the easiest implementation to relate to, so i= s
=C2=A0a good starting point.

-It is extremely simple:
+It is extremely simple::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 static DEFINE_RWLOCK(rcu_gp_mutex);

@@ -614,7 +624,7 @@ It is extremely simple:

=C2=A0[You can ignore rcu_assign_pointer() and rcu_dereference() without mi= ssing
=C2=A0much.=C2=A0 But here are simplified versions anyway.=C2=A0 And whatev= er you do,
-don't forget about them when submitting patches making use of RCU!] +don't forget about them when submitting patches making use of RCU!]::<= br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 #define rcu_assign_pointer(p, v) \
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ({ \
@@ -659,6 +669,7 @@ This section presents a "toy" RCU implementat= ion that is based on
=C2=A0on features such as hotplug CPU and the ability to run in CONFIG_PREE= MPT
=C2=A0kernels.=C2=A0 The definitions of rcu_dereference() and rcu_assign_po= inter()
=C2=A0are the same as those shown in the preceding section, so they are omi= tted.
+::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 void rcu_read_lock(void) { }

@@ -707,10 +718,12 @@ Quick Quiz #3:=C2=A0 If it is illegal to block in an = RCU read-side


=C2=A06.=C2=A0 ANALOGY WITH READER-WRITER LOCKING
+--------------------------------------

=C2=A0Although RCU can be used in many different ways, a very common use of=
=C2=A0RCU is analogous to reader-writer locking.=C2=A0 The following unifie= d
=C2=A0diff shows how closely related RCU and reader-writer locking can be.<= br> +::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 @@ -5,5 +5,5 @@ struct el {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int data;
@@ -762,7 +775,7 @@ diff shows how closely related RCU and reader-writer lo= cking can be.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}

-Or, for those who prefer a side-by-side listing:
+Or, for those who prefer a side-by-side listing::

=C2=A0 1 struct el {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 1 struct el {
=C2=A0 2=C2=A0 =C2=A0struct list_head list;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A02=C2=A0 =C2=A0struct list_head list;
@@ -774,40 +787,44 @@ Or, for those who prefer a side-by-side listing:
=C2=A0 8 rwlock_t listmutex;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 8 spinlock_t listmutex;
=C2=A0 9 struct el head;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 9 struct el head;

- 1 int search(long key, int *result)=C2=A0 =C2=A0 1 int search(long key, i= nt *result)
- 2 {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2 {
- 3=C2=A0 =C2=A0struct list_head *lp;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 3=C2=A0 =C2=A0struct list_head *lp;
- 4=C2=A0 =C2=A0struct el *p;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4=C2=A0 =C2=A0struct el *p;
- 5=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 5
- 6=C2=A0 =C2=A0read_lock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A06=C2=A0 =C2=A0rcu_read_lock();
- 7=C2=A0 =C2=A0list_for_each_entry(p, head, lp) { 7=C2=A0 =C2=A0list_for_e= ach_entry_rcu(p, head, lp) {
- 8=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D key) {=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D key) { - 9=C2=A0 =C2=A0 =C2=A0 =C2=A0*result =3D p->data;=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A0*result =3D p->da= ta;
-10=C2=A0 =C2=A0 =C2=A0 =C2=A0read_unlock(&listmutex);=C2=A0 =C2=A0 =C2= =A0 10=C2=A0 =C2=A0 =C2=A0 =C2=A0rcu_read_unlock();
-11=C2=A0 =C2=A0 =C2=A0 =C2=A0return 1;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A011=C2=A0 =C2=A0 =C2=A0 =C2=A0retur= n 1;
-12=C2=A0 =C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A012=C2=A0 =C2= =A0 =C2=A0}
-13=C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A013=C2=A0 =C2= =A0}
-14=C2=A0 =C2=A0read_unlock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 14=C2=A0 =C2=A0rcu_read_unlock();
-15=C2=A0 =C2=A0return 0;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A015=C2=A0 =C2=A0return 0;
-16 }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A016 }
-
- 1 int delete(long key)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A01 int delete(long key)
- 2 {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2 {
- 3=C2=A0 =C2=A0struct el *p;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 3=C2=A0 =C2=A0struct el *p;
- 4=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4
- 5=C2=A0 =C2=A0write_lock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 5=C2=A0 =C2=A0spin_lock(&listmutex);
- 6=C2=A0 =C2=A0list_for_each_entry(p, head, lp) { 6=C2=A0 =C2=A0list_for_e= ach_entry(p, head, lp) {
- 7=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D key) {=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A07=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D key) { - 8=C2=A0 =C2=A0 =C2=A0 =C2=A0list_del(&p->list);=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 8=C2=A0 =C2=A0 =C2=A0 =C2=A0list_del_rcu(&p-&g= t;list);
- 9=C2=A0 =C2=A0 =C2=A0 =C2=A0write_unlock(&listmutex);=C2=A0 =C2=A0 = =C2=A0 9=C2=A0 =C2=A0 =C2=A0 =C2=A0spin_unlock(&listmutex);
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A010=C2=A0 = =C2=A0 =C2=A0 =C2=A0synchronize_rcu();
-10=C2=A0 =C2=A0 =C2=A0 =C2=A0kfree(p);=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A011=C2=A0 =C2=A0 =C2=A0 =C2=A0kfree= (p);
-11=C2=A0 =C2=A0 =C2=A0 =C2=A0return 1;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A012=C2=A0 =C2=A0 =C2=A0 =C2=A0retur= n 1;
-12=C2=A0 =C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A013=C2=A0 =C2= =A0 =C2=A0}
-13=C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A014=C2=A0 =C2= =A0}
-14=C2=A0 =C2=A0write_unlock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A015=C2=A0 =C2=A0spin_unlock(&listmutex);
-15=C2=A0 =C2=A0return 0;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A016=C2=A0 =C2=A0return 0;
-16 }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A017 }
+::
+
+=C2=A0 1 int search(long key, int *result)=C2=A0 =C2=A0 1 int search(long = key, int *result)
+=C2=A0 2 {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2 {
+=C2=A0 3=C2=A0 =C2=A0struct list_head *lp;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 3=C2=A0 =C2=A0struct list_head *lp;
+=C2=A0 4=C2=A0 =C2=A0struct el *p;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4=C2=A0 =C2=A0struct el *p;
+=C2=A0 5=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 5
+=C2=A0 6=C2=A0 =C2=A0read_lock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A06=C2=A0 =C2=A0rcu_read_lock();
+=C2=A0 7=C2=A0 =C2=A0list_for_each_entry(p, head, lp) { 7=C2=A0 =C2=A0list= _for_each_entry_rcu(p, head, lp) {
+=C2=A0 8=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D key) {=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D ke= y) {
+=C2=A0 9=C2=A0 =C2=A0 =C2=A0 =C2=A0*result =3D p->data;=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A0*result =3D p= ->data;
+ 10=C2=A0 =C2=A0 =C2=A0 =C2=A0read_unlock(&listmutex);=C2=A0 =C2=A0 = =C2=A0 10=C2=A0 =C2=A0 =C2=A0 =C2=A0rcu_read_unlock();
+ 11=C2=A0 =C2=A0 =C2=A0 =C2=A0return 1;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A011=C2=A0 =C2=A0 =C2=A0 =C2=A0retur= n 1;
+ 12=C2=A0 =C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A012=C2=A0 =C2= =A0 =C2=A0}
+ 13=C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A013=C2=A0 =C2= =A0}
+ 14=C2=A0 =C2=A0read_unlock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 14=C2=A0 =C2=A0rcu_read_unlock();
+ 15=C2=A0 =C2=A0return 0;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A015=C2=A0 =C2=A0return 0;
+ 16 }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A016 }
+
+::
+
+=C2=A0 1 int delete(long key)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A01 int delete(long key)
+=C2=A0 2 {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 2 {
+=C2=A0 3=C2=A0 =C2=A0struct el *p;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 3=C2=A0 =C2=A0struct el *p;
+=C2=A0 4=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4
+=C2=A0 5=C2=A0 =C2=A0write_lock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 5=C2=A0 =C2=A0spin_lock(&listmutex);
+=C2=A0 6=C2=A0 =C2=A0list_for_each_entry(p, head, lp) { 6=C2=A0 =C2=A0list= _for_each_entry(p, head, lp) {
+=C2=A0 7=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D key) {=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A07=C2=A0 =C2=A0 =C2=A0if (p->key =3D=3D ke= y) {
+=C2=A0 8=C2=A0 =C2=A0 =C2=A0 =C2=A0list_del(&p->list);=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 8=C2=A0 =C2=A0 =C2=A0 =C2=A0list_del_rcu(&= p->list);
+=C2=A0 9=C2=A0 =C2=A0 =C2=A0 =C2=A0write_unlock(&listmutex);=C2=A0 =C2= =A0 =C2=A0 9=C2=A0 =C2=A0 =C2=A0 =C2=A0spin_unlock(&listmutex);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 10=C2=A0= =C2=A0 =C2=A0 =C2=A0synchronize_rcu();
+ 10=C2=A0 =C2=A0 =C2=A0 =C2=A0kfree(p);=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A011=C2=A0 =C2=A0 =C2=A0 =C2=A0kfree= (p);
+ 11=C2=A0 =C2=A0 =C2=A0 =C2=A0return 1;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A012=C2=A0 =C2=A0 =C2=A0 =C2=A0retur= n 1;
+ 12=C2=A0 =C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A013=C2=A0 =C2= =A0 =C2=A0}
+ 13=C2=A0 =C2=A0}=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A014=C2=A0 =C2= =A0}
+ 14=C2=A0 =C2=A0write_unlock(&listmutex);=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A015=C2=A0 =C2=A0spin_unlock(&listmutex);
+ 15=C2=A0 =C2=A0return 0;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A016=C2=A0 =C2=A0return 0;
+ 16 }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A017 }

=C2=A0Either way, the differences are quite small.=C2=A0 Read-side locking = moves
=C2=A0to rcu_read_lock() and rcu_read_unlock, update-side locking moves fro= m
@@ -827,13 +844,14 @@ be used in place of synchronize_rcu().


=C2=A07.=C2=A0 FULL LIST OF RCU APIs
+-------------------------

=C2=A0The RCU APIs are documented in docbook-format header comments in the<= br> =C2=A0Linux-kernel source code, but it helps to have a full list of the
=C2=A0APIs, since there does not appear to be a way to categorize them
=C2=A0in docbook.=C2=A0 Here is the list, by category.

-RCU list traversal:
+RCU list traversal::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 list_entry_rcu
=C2=A0 =C2=A0 =C2=A0 =C2=A0 list_first_entry_rcu
@@ -854,7 +872,7 @@ RCU list traversal:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 hlist_bl_first_rcu
=C2=A0 =C2=A0 =C2=A0 =C2=A0 hlist_bl_for_each_entry_rcu

-RCU pointer/list update:
+RCU pointer/list udate::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_assign_pointer
=C2=A0 =C2=A0 =C2=A0 =C2=A0 list_add_rcu
@@ -876,7 +894,9 @@ RCU pointer/list update:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 hlist_bl_del_rcu
=C2=A0 =C2=A0 =C2=A0 =C2=A0 hlist_bl_set_first_rcu

-RCU:=C2=A0 =C2=A0Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Grace period= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier
+RCU::
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Gra= ce period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier

=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_lock=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0synchronize_net=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rcu_barrier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_unlock=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0synchronize_rcu
@@ -885,7 +905,9 @@ RCU:=C2=A0 =C2=A0 =C2=A0 =C2=A0 Critical sections=C2=A0= =C2=A0 =C2=A0 =C2=A0Grace period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = Barrier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_dereference_check=C2=A0 =C2=A0kfree_rcu
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_dereference_protected

-bh:=C2=A0 =C2=A0 Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Grace period= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier
+bh::
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Gra= ce period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier

=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_lock_bh=C2=A0 =C2=A0 =C2=A0 =C2=A0 cal= l_rcu=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_barrier =C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_unlock_bh=C2=A0 =C2=A0 =C2=A0 synchron= ize_rcu
@@ -896,7 +918,9 @@ bh: Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Grace p= eriod=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_dereference_bh_protected
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_lock_bh_held

-sched: Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Grace period=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier
+sched::
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Gra= ce period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier

=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_lock_sched=C2=A0 =C2=A0 =C2=A0call_rcu= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_barrier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_unlock_sched=C2=A0 =C2=A0synchronize_r= cu
@@ -910,7 +934,9 @@ sched:=C2=A0 =C2=A0 =C2=A0 Critical sections=C2=A0 =C2= =A0 =C2=A0 =C2=A0Grace period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barr= ier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_read_lock_sched_held


-SRCU:=C2=A0 Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Grace period=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier
+SRCU::
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0Critical sections=C2=A0 =C2=A0 =C2=A0 =C2=A0Gra= ce period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barrier

=C2=A0 =C2=A0 =C2=A0 =C2=A0 srcu_read_lock=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 call_srcu=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0srcu_ba= rrier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 srcu_read_unlock=C2=A0 =C2=A0 =C2=A0 =C2=A0 syn= chronize_srcu
@@ -918,13 +944,14 @@ SRCU:=C2=A0 =C2=A0 =C2=A0Critical sections=C2=A0 =C2= =A0 =C2=A0 =C2=A0Grace period=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Barr= ier
=C2=A0 =C2=A0 =C2=A0 =C2=A0 srcu_dereference_check
=C2=A0 =C2=A0 =C2=A0 =C2=A0 srcu_read_lock_held

-SRCU:=C2=A0 Initialization/cleanup
+SRCU: Initialization/cleanup::
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEFINE_SRCU
=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEFINE_STATIC_SRCU
=C2=A0 =C2=A0 =C2=A0 =C2=A0 init_srcu_struct
=C2=A0 =C2=A0 =C2=A0 =C2=A0 cleanup_srcu_struct

-All:=C2=A0 lockdep-checked RCU-protected pointer access
+All: lockdep-checked RCU-protected pointer access::

=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_access_pointer
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rcu_dereference_raw
@@ -976,6 +1003,7 @@ the right tool for your job.


=C2=A08.=C2=A0 ANSWERS TO QUICK QUIZZES
+----------------------------

=C2=A0Quick Quiz #1: Why is this argument naive?=C2=A0 How could a deadlock=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 occur when using th= is algorithm in a real-world Linux

Here= , the formatting is not proper. In the rst file, the question should be add= ed in the next line after Quick Quiz #1. Currently, half of the question ap= pears in bold and the rest half does not.
Also, as followed in al= l the documents there should be a cross-reference to the answer to this que= stion. As this document is quite big having references would be helpful.
The same applies to all other quick quiz questions in this document= and in the Answers section as well the questions do not appear properly, h= alf in bold text and half not bold.

Apart from thi= s, the other added changes look good!

Thank you
Madhuparna

--
2.20.1

_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation= .org/mailman/listinfo/linux-kernel-mentees
3D""=E1=90=A7
--0000000000000be2e305965bd6bd-- --===============8788838115013394139== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Linux-kernel-mentees mailing list Linux-kernel-mentees@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees --===============8788838115013394139==--