Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 353 Vote(s) - 3.66 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What does rcu_read_lock() actually do (Linux Kernel)

#1
I'm trying to understand rcu_read_lock() synchronization mechanism. From what I understand, rcu_read_lock() is used, where there are several read threads and one write thread, that read/writes the same data, and reading is performed under rcu_read_lock(), and the data are copied for each thread. I wrote a simple driver to test this (read() and write() functions are core):

#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/rcupdate.h>
#include <linux/preempt.h>
#include <linux/fs.h>
#include <linux/cdev.h>

#define MY_MAJOR 42
#define MY_MAX_MINORS 5

char buf[] = "0";

struct dev_data
{
struct cdev cdev;
};

struct dev_data devs[MY_MAX_MINORS];

static ssize_t read(struct file *file, char __user *buffer, size_t size, loff_t *offset)
{
rcu_read_lock();
while (1)
{
printk(KERN_INFO "%s", buf);
}
rcu_read_unlock();

return 0;
}

static ssize_t write(struct file *file, const char __user *buffer, size_t size, loff_t *offset)
{
buf[0] = '1';

return size;
}

const struct file_operations fops = {
.read = &read,
.write = &write,
};

static int __init foo_start(void)
{
int i, err_code;

err_code = register_chrdev_region(MKDEV(MY_MAJOR, 0), MY_MAX_MINORS, "Test char driver");
if (err_code != 0)
return err_code;

for(i=0; i<MY_MAX_MINORS; ++i)
{
cdev_init(&devs[i].cdev, &fops);
cdev_add(&devs[i].cdev, MKDEV(MY_MAJOR, i), 1);
}

return 0;
}

static void __exit foo_end(void)
{
int i;

for(i=0; i<MY_MAX_MINORS; ++i)
{
cdev_del(&devs[i].cdev);
}

unregister_chrdev_region(MKDEV(MY_MAJOR, 0), MY_MAX_MINORS);
}

module_init(foo_start);
module_exit(foo_end);

but when I call the write function during reading, the data is changing under rcu_read_lock() too. Where is my mistake?
P.S. The driver itself is crippy, but my goal was just to test rcu_read_lock().
Reply

#2
You can find [the RCU documentation on kernel.org](

[To see links please register here]

) which describe it.

Its introduction is really interesting:

> Although RCU is actually quite simple once you understand it,
getting there can sometimes be a challenge. Part of the problem is that
most of the past descriptions of RCU have been written with the mistaken
assumption that there is "one true way" to describe RCU. Instead,
the experience has been that different people must take different paths
to arrive at an understanding of RCU.

As you can see, anyone who wants to really understand it must take the time to read the documentation.

To get a basic idea of it:

> The basic idea behind RCU is to split updates into "removal" and
> "reclamation" phases. The removal phase removes references to data
> items within a data structure (possibly by replacing them with
> references to new versions of these data items), and can run
> concurrently with readers.

Read more from the documentation.

Coming now to your question, here is the description of the `rcu_read_lock()` and `rcu_read_unlock()` API functions:

> rcu_read_lock()
>
> void rcu_read_lock(void);
>
> Used by a reader to inform the reclaimer that the reader is entering
> an RCU read-side critical section. It is illegal to block while in
> an RCU read-side critical section, though kernels built with
> CONFIG_PREEMPT_RCU can preempt RCU read-side critical sections. Any
> RCU-protected data structure accessed during an RCU read-side
> critical section is guaranteed to remain unreclaimed for the full
> duration of that critical section. Reference counts may be used in
> conjunction with RCU to maintain longer-term references to data
> structures.
>
> rcu_read_unlock()
>
> void rcu_read_unlock(void);
>
> Used by a reader to inform the reclaimer that the reader is exiting
> an RCU read-side critical section. Note that RCU read-side critical
> sections may be nested and/or overlapping.

Have a look at the "WHAT ARE SOME EXAMPLE USES OF CORE RCU API?" section in order to have an example of code using them.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through