Linux RCU Mechanism detailed

Source: Internet
Author: User

A few statements about RCU:

1:rcu use a lot of readers and write less. RCU is similar to a read-write lock. But RCU's reader-lock does not have any overhead. The writer must be in sync with the writer, and the writer must wait until all of its readers have exited before releasing the resources.
2:RCU is a pointer. This is especially important. Because the pointer assignment is a single instruction. That is, an atomic operation. Because it changes the pointer, it doesn't have to be considered for synchronization. Just consider the impact of the cache.
3: readers can be nested. That is, Rcu_read_lock () can nest calls.
4: When the reader is holding Rcu_read_lock (), the process context switch cannot occur. Otherwise, the writer process will always be blocked because the writer needs to wait for the reader to complete.

Core API:

The operations for READER,RCU include:

(1) Rcu_read_lock, used to identify the beginning of the critical section of RCU read side.

(2) Rcu_dereference, this interface is used to obtain RCU protected pointer. Reader to access RCU protected shared data, of course, to get RCU protected pointer, and then through the pointer for dereference operations.

(3) Rcu_read_unlock, used to identify reader leaving RCU read side critical section

The operations for WRITER,RCU include:

(1) Rcu_assign_pointer. This interface is used by writer for removal operation, after witer complete new version of the data allocation and update, call this interface can let RCU protected pointer point to RCU protected data.

(2) Synchronize_rcu. The operation of the writer side can be synchronous, that is, after the update operation is completed, the interface function can be called to wait for all reader threads on the old version data to leave the critical section, and once returned from the function, there is no reference to the old shared data. The reclaimation can be operated directly.

(3) Call_rcu. Of course, in some cases (for example, in SOFTIRQ context), writer cannot block, this time can call the Call_rcu interface function, the function is only registered callback directly returned, at the appropriate moment will call the callback function, Complete the reclaimation operation. Such scenes are actually separate removal and reclaimation operations in two different threads: Updater and Reclaimer.

Simple example:

struct Foo {
int A;
Char b;
Long C;
};
Define_spinlock (Foo_mutex);

struct Foo *gbl_foo;
void foo_update_a (int new_a)
{
struct Foo *NEW_FP;
struct Foo *OLD_FP;

NEW_FP = Kmalloc (sizeof (*NEW_FP), Gfp_kernel);
Spin_lock (&foo_mutex);
OLD_FP = Gbl_foo;
*NEW_FP = *OLD_FP;
New_fp->a = new_a;
Rcu_assign_pointer (Gbl_foo, NEW_FP);
Spin_unlock (&foo_mutex);
Synchronize_rcu ();
Kfree (OLD_FP);
}

int foo_get_a (void)
{
int retval;

Rcu_read_lock ();
retval = Rcu_dereference (Gbl_foo)->a;
Rcu_read_unlock ();
return retval;
}
As shown in the code above, RCU is used to protect the global pointer struct foo *gbl_foo. Foo_get_a () is used to obtain the Gbl_foo value from the RCU protected structure. and Foo_update_a () is used to update the value of RCU protected by Gbl_foo.
In addition, let's think about why we should use spin lock Foo_mutex in Foo_update_a ().
It is assumed that no spin lock is used in the middle. The code for the Foo_update_a () is as follows:

void foo_update_a (int new_a)
{
struct Foo *NEW_FP;
struct Foo *OLD_FP;

NEW_FP = Kmalloc (sizeof (*NEW_FP), Gfp_kernel);

OLD_FP = Gbl_foo;
1:-------------------------
*NEW_FP = *OLD_FP;
New_fp->a = new_a;
Rcu_assign_pointer (Gbl_foo, NEW_FP);

Synchronize_rcu ();
Kfree (OLD_FP);
}
Suppose a process is some cards by the B process at the----identifier. b process also performed goo_ipdate_a (). When B is finished, it switches back to the a process. At this point, the a process of the OLD_FD has actually been released by the B process. Thereafter, the a process is illegal for the operation of the OLD_FD.

In addition, we have seen several core APIs on RCU. They are:
Rcu_read_lock ()
Rcu_read_unlock ()
Synchronize_rcu ()
Rcu_assign_pointer ()
Rcu_dereference ()
Among them, Rcu_read_lock () and Rcu_read_unlock () are used to maintain a reader's RCU critical section. Context switching is not allowed within this critical area.
Rcu_dereference (): The reader invokes it to obtain a pointer that is RCU protected.
Rcu_assign_pointer (): The writer uses this function to assign a new value to the RCU-protected pointer. This is for security to change its value from the writer to the reader. This function returns a new value

Linux RCU Mechanism detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.