[bootlin/training-materials updates] master: slides/kernel-driver-development-concurrency: Change RCU example (83f20734)

Miquel Raynal miquel.raynal at bootlin.com
Mon Apr 17 12:40:18 CEST 2023


Repository : https://github.com/bootlin/training-materials
On branch  : master
Link       : https://github.com/bootlin/training-materials/commit/83f207342b9588dcef119b072ad1b122ddae3262

>---------------------------------------------------------------

commit 83f207342b9588dcef119b072ad1b122ddae3262
Author: Miquel Raynal <miquel.raynal at bootlin.com>
Date:   Mon Apr 17 12:40:18 2023 +0200

    slides/kernel-driver-development-concurrency: Change RCU example
    
    Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>


>---------------------------------------------------------------

83f207342b9588dcef119b072ad1b122ddae3262
 .../kernel-driver-development-concurrency.tex      | 60 +++++++++-------------
 1 file changed, 24 insertions(+), 36 deletions(-)

diff --git a/slides/kernel-driver-development-concurrency/kernel-driver-development-concurrency.tex b/slides/kernel-driver-development-concurrency/kernel-driver-development-concurrency.tex
index dafa5f82..3dec95d2 100644
--- a/slides/kernel-driver-development-concurrency/kernel-driver-development-concurrency.tex
+++ b/slides/kernel-driver-development-concurrency/kernel-driver-development-concurrency.tex
@@ -266,65 +266,53 @@ static unsigned int ulite_tx_empty(struct uart_port *port) {
 \end{frame}
 
 \begin{frame}[fragile]
-  \frametitle{RCU protected reads: accessing structure members in a consistent way}
-    \begin{block}{Unsafe read}<1:>
+  \frametitle{RCU example: ensuring consistent accesses (1/2)}
+    \begin{block}{Unsafe read/write}
       \begin{minted}[fontsize=\tiny]{c}
-struct myconf { int a, b; } *current_conf; /* initialized */
+struct myconf { int a, b; } *shared_conf; /* initialized */
 
 unsafe_get(int *cur_a, int *cur_b)
 {
-        *cur_a = current_conf->a;
+        *cur_a = shared_conf->a;
         /* What if *current_conf gets updated now? The assignement is inconsistent! */
-        *cur_b = current_conf->b;
+        *cur_b = shared_conf->b;
 };
-      \end{minted}
-    \end{block}
-  \begin{block}{Safe read}<2>
-    \begin{minted}[fontsize=\tiny]{c}
-struct myconf { int a, b; } *current_conf; /* initialized */
 
-safe_get(int *cur_a, int *cur_b)
+unsafe_set(int new_a, int new_b)
 {
-        struct myconf *conf;
-
-        rcu_read_lock();
-        conf = rcu_dereference(current_conf);
-        *cur_a = conf->a;
-        /* If *current_conf is updated, conf->a and conf->b will remain consistent! */
-        *cur_b = conf->b;
-        rcu_read_unlock();
+        shared_conf->a = new_a;
+        shared_conf->b = new_b;
 };
     \end{minted}
   \end{block}
 \end{frame}
 
 \begin{frame}[fragile]
-  \frametitle{RCU protected writes: updating a pointer in a consistent way}
-  \begin{block}{Unsafe write}<1:>
+  \frametitle{RCU example: ensuring consistent accesses (2/2)}
+  \begin{block}{Safe read/write with RCU}
     \begin{minted}[fontsize=\tiny]{c}
-struct myconf { int a, b; } *current_conf; /* initialized */
+struct myconf { int a, b; } *shared_conf; /* initialized */
 
-unsafe_set(int cur_a, int cur_b)
+safe_get(int *cur_a, int *cur_b)
 {
-        struct myconf *newconf = kmalloc(...), *oldconf;
-        newconf->a = cur_a, newconf->b = cur_b;
+        struct myconf *temp;
 
-        oldconf = current_conf;
-        current_conf = newconf;
-        kfree(oldconf); /* Readers might still have a reference over the freed struct! */
+        rcu_read_lock();
+        temp = rcu_dereference(shared_conf);
+        *cur_a = temp->a;
+        /* If *shared_conf is updated, temp->a and temp->b will remain consistent! */
+        *cur_b = temp->b;
+        rcu_read_unlock();
 };
-    \end{minted}
-  \end{block}
-  \begin{block}{Safe write}<2>
-    \begin{minted}[fontsize=\tiny]{c}
-struct myconf { int a, b; } *current_conf; /* initialized */
 
-safe_set(int cur_a, int cur_b)
+safe_set(int new_a, int new_b)
 {
-        struct myconf *newconf = kmalloc(...), *oldconf;
-        newconf->a = cur_a, newconf->b = cur_b;
+        struct myconf *newconf = kmalloc(...);
+        struct myconf *oldconf;
 
         oldconf = rcu_dereference(current_conf);
+        newconf->a = new_a;
+        newconf->b = new_b;
         rcu_assign_pointer(current_conf, newconf);
         /* Readers might still have a reference over the old struct here... */
         synchronize_rcu();




More information about the training-materials-updates mailing list