Concurrency Control for Linux kernel development (III)

Source: Internet
Author: User

Now that you have so many tips, you don't care about the remaining two or three tips:

Outbound table 5: sequential lock)

When sequential locks are used, read execution units are never blocked by write execution units. At the same time, write execution units do not need to wait for all read execution units to complete the read operation. However, write execution units are mutually exclusive. If the write Execution Unit has been operated during the read operation, the read execution unit must re-read the data to ensure that the obtained data is complete.

Fatal weakness: there is a limit on the sequential lock, that is, it must require that the protected shared resources do not contain pointers. The write execution unit may invalidate the pointer, but if the read execution unit is about to access the pointer, it will cause oops.

In the Linux kernel. The read execution unit is designed as follows.

1) read start

Unsigned read_seqbegin (const seqlock_t * S1 );

Read_seqbegin_irqsave (lock, flag); [read_seqbegin_irqsave (lock, flag) = local_irq_save () + read_seqbegin ();]

2) rereading

Int read_seqretry (const seqlock_t * S1, unsigned IV );

Read_seqretry_irqrestore (lock, IV, flag); [read_seqretry_irqrestore (lock, IV, flag) = read_seqretry () + local_irq_restore ();]

The read Execution Unit uses the sequence lock mode as follows:

Do {

Seqnum = read_seqbegin (& seqlock_a );

// Read operationCodeBlock

...

} While (read_seqretry (& seqlock_a, seqnum ));

In the Linux kernel. The write execution unit is designed as follows.

1) obtain the sequence lock

Void write_seqlock (seqlock_t * S1 );

Int write _ tryseqlock (seqlock_t * S1 );

Write_seqlock_irqsave (lock, flags); [= local_irq_save () + write_seqlock ()]

Write_seqlock_irq (Lock); [= local_irq_disable () + write_seqlock ()]

Write_seqlock_bh (Lock); [= local_bh_disable () + write_seqlock ()]

2) release the sequence lock

Void write_sequnlock (seqlock_t * S1 );

Write_sequnlock_irqrestore (lock, flag); [= write_sequnlock () + local_irq_restore ()]

Write_sequnlock_irq (Lock); [= write_sequnlock () + local_irq_enable ()]

Write_sequnlock_bh (Lock); [write_sequnlock () + local_bh_enable ()]

The write Execution Unit uses the sequence lock mode as follows:

Write_seqlock (& seqlock_a );

... // Write operation code

Write_sequnlock (& seqlock_a );

 

Output Table 6: RCU (read-copy-Update)

For the shared data structure protected by RCU, you do not need to obtain any locks to access it. However, when accessing it, the writer first backs up a copy and then modifies the copy, modify the copy, and use a callback mechanism to re-point the original data pointer to the new data at the right time. This is when all CPUs that reference the data exit the operation on the shared data.

1) read lock. 2) unlock the read. The read mode using RCU is as follows:

Rcu_read_lock (); rcu_read_unlock (); rcu_read_lock ()

Rcu_read_lock_bh (); rcu_read_unlock_bh ();... // Read the critical section

Rcu_read_unlock ()

3) RCU-related writer functions include:

Struct rcu_head {

Struct rcu_head * Next; // The next RCU

Void (* func) (struct rcu_head * head); // processing function after obtaining the Competition Condition

};

Synchronize_rcu (void); // blocks the reader until all the readers have completed the read-end critical section. The writer can continue the next step.

Synchronize_sched (); // wait until all CPUs are in the preemption status to ensure that all interrupts (not including soft interrupts) are processed.

Void call_rcu (struct rcu_head * head, void (* func) (void * Arg), void Arg); // The writer is not blocked and can be used in the interrupt context or Soft Interrupt,

The write process using synchronize_rcu is as follows:

Define_spinlock (foo_spinlock );

Int a_new;

Spin_lock (& foo_spinlock );

// A_new =;

// Write a_new;

Synchronize_rcu ();

// A = a_new;

Spin_unlock (& foo_spinlock );

// The write process using call_rcu is as follows:

Struct protectrcu

{

Int protect;

Struct rcu_head RCU;

};

Struct protectrcu * global_pr;

// Usually used to release old data

Void callback_function (struct rcu_head * r)

{

Struct protectrcu * t;

T = container_of (R, struct protectrcu, RCU );

Kfree (t );

}

Void write_process ()

{

Struct protectrcu * t, * old;

T = kmalloc (sizeof (* t), gfp_kernel); // create a copy

Spin_lock (& foo_spinlock );

T-> protect = xx;

Old = global_pr;

Global_pr = T; // replace with a copy

Spin_unlock (& foo_spinlock );

Call_rcu (old-> RCU, callback_function );

}

 

 

 

 

 

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.