From: madhuparnabhowmik04 at gmail.com (Madhuparna Bhowmik)
Subject: [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst
Date: Fri, 1 Nov 2019 09:03:57 +0530 [thread overview]
Message-ID: <CAF65HP2yZkxjrqY+Jk9GYobo4NA3ePkrNcu3bZRCVZ8sxSUVrA@mail.gmail.com> (raw)
In-Reply-To: <20191031225439.GD20975@paulmck-ThinkPad-P72>
On Fri, 1 Nov, 2019, 4:24 AM Paul E. McKenney, <paulmck at kernel.org> wrote:
> On Thu, Oct 31, 2019 at 06:31:28AM +0700, 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 <tranmanphong at gmail.com>
>
> Queued and pushed with updated subject line and commit log, thank you!
>
> Could you and Madhuparna please review and test each other's
> .rst-conversion patches?
>
Sure, I will do it.
Regards
Madhuparna
> Thanx, Paul
>
> > ---
> > 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/
> >
> >
> > What is RCU?
> > @@ -51,6 +54,7 @@ never need this document anyway. ;-)
> >
> >
> > 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
> > --
> > 2.20.1
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/linux-kernel-mentees/attachments/20191101/678e3afc/attachment-0001.html>
WARNING: multiple messages have this Message-ID (diff)
From: madhuparnabhowmik04@gmail.com (Madhuparna Bhowmik)
Subject: [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst
Date: Fri, 1 Nov 2019 09:03:57 +0530 [thread overview]
Message-ID: <CAF65HP2yZkxjrqY+Jk9GYobo4NA3ePkrNcu3bZRCVZ8sxSUVrA@mail.gmail.com> (raw)
Message-ID: <20191101033357.8DCZI6-_TcjKWxUBLj4ao8vZfBADVzmGV3o9eUnWmJE@z> (raw)
In-Reply-To: <20191031225439.GD20975@paulmck-ThinkPad-P72>
On Fri, 1 Nov, 2019, 4:24 AM Paul E. McKenney, <paulmck at kernel.org> wrote:
> On Thu, Oct 31, 2019 at 06:31:28AM +0700, 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 <tranmanphong at gmail.com>
>
> Queued and pushed with updated subject line and commit log, thank you!
>
> Could you and Madhuparna please review and test each other's
> .rst-conversion patches?
>
Sure, I will do it.
Regards
Madhuparna
> Thanx, Paul
>
> > ---
> > 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/
> >
> >
> > What is RCU?
> > @@ -51,6 +54,7 @@ never need this document anyway. ;-)
> >
> >
> > 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
> > --
> > 2.20.1
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/linux-kernel-mentees/attachments/20191101/678e3afc/attachment-0001.html>
WARNING: multiple messages have this Message-ID (diff)
From: Madhuparna Bhowmik <madhuparnabhowmik04@gmail.com>
To: paulmck@kernel.org
Cc: corbet@lwn.net, 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@joelfernandes.org,
linux-kernel-mentees@lists.linuxfoundation.org
Subject: Re: [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst
Date: Fri, 1 Nov 2019 09:03:57 +0530 [thread overview]
Message-ID: <CAF65HP2yZkxjrqY+Jk9GYobo4NA3ePkrNcu3bZRCVZ8sxSUVrA@mail.gmail.com> (raw)
Message-ID: <20191101033357.uDqDYeQl1bKHGHXxa8Rd1WLVYkeNeuvjPfgBxybkvP4@z> (raw)
In-Reply-To: <20191031225439.GD20975@paulmck-ThinkPad-P72>
[-- Attachment #1.1: Type: text/plain, Size: 17989 bytes --]
On Fri, 1 Nov, 2019, 4:24 AM Paul E. McKenney, <paulmck@kernel.org> wrote:
> On Thu, Oct 31, 2019 at 06:31:28AM +0700, 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 <tranmanphong@gmail.com>
>
> Queued and pushed with updated subject line and commit log, thank you!
>
> Could you and Madhuparna please review and test each other's
> .rst-conversion patches?
>
Sure, I will do it.
Regards
Madhuparna
> Thanx, Paul
>
> > ---
> > 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/
> >
> >
> > What is RCU?
> > @@ -51,6 +54,7 @@ never need this document anyway. ;-)
> >
> >
> > 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
> > --
> > 2.20.1
> >
>
[-- Attachment #1.2: Type: text/html, Size: 24707 bytes --]
[-- Attachment #2: Type: text/plain, Size: 201 bytes --]
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees
next prev parent reply other threads:[~2019-11-01 3:33 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-30 23:31 [Linux-kernel-mentees] [PATCH] Doc: convert whatisRCU.txt to rst tranmanphong
2019-10-30 23:31 ` Phong Tran
2019-10-31 22:54 ` paulmck
2019-10-31 22:54 ` Paul E. McKenney
2019-10-31 22:54 ` Paul E. McKenney
2019-11-01 1:17 ` tranmanphong
2019-11-01 1:17 ` Phong Tran
2019-11-01 1:17 ` Phong Tran
2019-11-01 7:53 ` paulmck
2019-11-01 7:53 ` Paul E. McKenney
2019-11-01 7:53 ` Paul E. McKenney
2019-11-01 3:33 ` madhuparnabhowmik04 [this message]
2019-11-01 3:33 ` Madhuparna Bhowmik
2019-11-01 3:33 ` Madhuparna Bhowmik
2019-11-01 7:53 ` paulmck
2019-11-01 7:53 ` Paul E. McKenney
2019-11-01 7:53 ` Paul E. McKenney
2019-11-02 8:31 ` madhuparnabhowmik04
2019-11-02 8:31 ` Madhuparna Bhowmik
2019-11-02 8:31 ` Madhuparna Bhowmik
2019-11-02 12:00 ` tranmanphong
2019-11-02 12:00 ` Phong Tran
2019-11-02 12:00 ` Phong Tran
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAF65HP2yZkxjrqY+Jk9GYobo4NA3ePkrNcu3bZRCVZ8sxSUVrA@mail.gmail.com \
--to=linux-kernel-mentees@lists.linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).