The spin lock mutex and the spin lock mutex

Source: Internet
Author: User

The spin lock mutex and the spin lock mutex
In Linux, there are four main operations related to spin locks.
1. Define the spin lock
Spinlock_t lock;
2. initialize the spin lock
Spin_lock_init (lock)
This macro is used to dynamically initialize the spin lock.
3. Get the spin lock
Spin_lock (lock)
This macro is used to obtain the spin lock. If the lock can be obtained immediately, it returns immediately. Otherwise, it will spin there until the self
The lock holder is released.
Spin_trylock (lock)
This macro tries to get the spin lock. If it can get the lock immediately, it gets the lock and returns true. Otherwise, false is returned immediately.
Then, "repeat in the same place ".
4. Release the spin lock
Spin_unlock (lock)
This macro releases the spin lock, which is used in pairs with the spin lock or the spin lock.
The spin lock is generally used as follows:
/* Define a spin lock */
Spinlock_t lock;
Spin_lock_init (& lock );
Spin_lock (& lock);/* Get the spin lock to protect the critical section */
.../* Critical section */
Spin_unlock (& lock);/* unlock */
The spin lock is mainly used for SMP or single-CPU but kernel preemption. For systems that do not support preemption of a single CPU or kernel, the spin lock is deprecated.
Empty operation. In systems with a single CPU and kernel that can be preemptible, kernel preemption during the spin lock hold will be disabled. Because the kernel can be preemptible
In fact, the behavior of a single CPU system is very similar to that of an SMP system. Therefore, it is necessary to use a spin lock in such a single CPU system. Another
In addition, in the case of multi-core SMP, if any core gets a spin lock, the preemption Scheduling on the core is also temporarily disabled, but no other
Preemptible scheduling of the other core.
Although the spin lock can be used to ensure that the critical zone is not disturbed by the preemptible processes of other CPUs and the CPU, the code path to the lock is
When executing the critical section, it may also be affected by the interruption and the bottom half (BH, which will be described later. To prevent such impact,
The derivative of the spin lock is required. Spin_lock ()/spin_unlock () is the basis of the spin lock mechanism.
Local_irq_disable ()/enable local_irq_enable (), bottom half local_bh_disable ()/bottom half
Local_bh_enable (), Guanzhong disconnection, and save the state word local_irq_save ()/enable the interruption and restore the State. The local_irq_restore () is closed.
A complete spin lock mechanism is formed. The relationship is as follows:
Spin_lock_irq () = spin_lock () + local_irq_disable ()
Spin_unlock_irq () = spin_unlock () + local_irq_enable ()
Spin_lock_irqsave () = spin_lock () + local_irq_save ()
Spin_unlock_irqrestore () = spin_unlock () + local_irq_restore ()
Spin_lock_bh () = spin_lock () + local_bh_disable ()
Spin_unlock_bh () = spin_unlock () + local_bh_enable ()
Functions similar to spin_lock_irq (), spin_lock_irqsave (), and spin_lock_bh () Will fasten "security" for the use of spin locks.
To avoid system damage caused by sudden interruptions.
During multi-core programming, if the process and interrupt may access the same critical resource, we generally need to call
Spin_lock_irqsave ()/spin_unlock_irqrestore (), which calls spin_lock ()/spin_unlock () in the interrupt context, such
Figure 7.8. In this way, on CPU0, both the process context and the interrupt context obtain the spin lock. After that, if CPU1 does not
In terms of process context or interrupt context, to obtain the same spin lock, you must be busy waiting, which avoids the possibility of concurrency between all kernels.
At the same time, because the process context of each core holds the lock, it uses the spin_lock_irqsave (), so the interruption on the core is impossible.
This avoids the possibility of concurrency in the kernel.
Drive engineers should be cautious about using spin locks, and pay special attention to the following issues during use.
1) The spin lock is actually a waiting lock. When the lock is unavailable, the CPU continuously executes "test and set" the lock until it is available to obtain the lock.
Lock, the CPU does not do any useful work while waiting for the spin lock, just waiting. Therefore, only when the lock occupation time is extremely short,
It is reasonable to use the spin lock. When the critical section is large or there is a shared device, it takes a long time to occupy the lock. Using the spin lock will decrease
System performance.
2) spin locks may cause system deadlocks. The most common cause of this problem is to recursively use a spin lock, that is, if
If a CPU with a spin lock wants to obtain the spin lock for the second time, the CPU will be deadlocked.
Figure 7.8 instance used for spin lock
3) functions that may cause process scheduling cannot be called during spin lock. If the process gets the spin lock and then blocks it, such as calling
Functions such as copy_from_user (), copy_to_user (), kmalloc (), and msleep () may cause kernel crash.
4) when programming in a single core, you should also think that your CPU is multi-core, and the driver emphasizes the concept of cross-platform. Ratio
For example, in the case of a single CPU, if the interrupt and the process may access the same critical section, it is safe to call spin_lock_irqsave () in the process.
In fact, it is okay not to call the spin_lock () in the interrupt, because the spin_lock_irqsave () can ensure that the CPU is interrupted.
The service program cannot be executed. However, if the CPU becomes multi-core, the interruption of the other core cannot be blocked.
Another core may cause concurrency problems. Therefore, in any case, we should also call spin_lock () in the interrupted service program ().
Code List 7.3 provides an example of how to use a spin lock. It is used to enable a device to be opened by a maximum of one process.
The configuration is similar to 7.2.
Code List 7.3 use a spin lock to enable a device only by one process
1 int xxx_count = 0;/* defines the number of times a file is opened */
23
Static int xxx_open (struct inode * inode, struct file * filp)
4 {
5...
6 spinlock (& xxx_lock );
7 if (xxx_count) {/* enabled */
8 spin_unlock (& xxx_lock );
9 return-EBUSY;
10}
11 xxx_count ++;/* increase the usage count */
12 spin_unlock (& xxx_lock );
13...
14 return 0;/* succeeded */
15}
16
17 static int xxx_release (struct inode * inode, struct file * filp)
18 {
19...
20 spinlock (& xxx_lock );
21 xxx_count --;/* reduce the use count */
22 spin_unlock (& xxx_lock );
23
24 return 0;

25}

Mutex
Although semaphores can achieve mutex, the "authentic" mutex still exists in the Linux kernel.
The following code defines the mutex named my_mutex and initializes it:
Struct mutex my_mutex;
Mutex_init (& my_mutex );
The following two functions are used to obtain the mutex:
Void mutex_lock (struct mutex * lock );
Int mutex_lock_interruptible (struct mutex * lock );
Int mutex_trylock (struct mutex * lock );
The difference between mutex_lock () and mutex_lock_interruptible () is exactly the same as that between down () and down_trylock ().
Therefore, the former causes sleep and cannot be interrupted by signals, while the latter does. Mutex_trylock () is used to obtain the mutex.
Mutex does not cause process sleep.
The following functions are used to release mutex:
Void mutex_unlock (struct mutex * lock );
The usage of mutex is the same as that of semaphores for mutual exclusion:
Struct mutex my_mutex;/* define mutex */
Mutex_init (& my_mutex);/* initialize mutex */
Mutex_lock (& my_mutex);/* Get mutex */
.../* Critical resource */
Mutex_unlock (& my_mutex);/* release mutex */
Spin locks and mutex are the basic methods to solve the mutex problem. In the face of specific situations, how should we choose these two methods? Select
The basis is the nature of the critical section and the characteristics of the system.
Strictly speaking, the mutex and spin lock belong to different levels of mutex. The implementation of the former depends on the latter. In the mutex itself
To ensure the atomicity of the access to the mutex structure, the spin lock is required for mutual exclusion. So spin locks belong to the more underlying means.
The mutex is a process-level resource mutex between multiple processes. Although it is also in the kernel, the kernel execution path is
Process Identity, representing the process to compete for resources. If the competition fails, process context switches will occur, and the current process enters sleep state,
The CPU runs other processes. In view of the large overhead of process context switching, only when the process occupies resources for a long time
It is a good choice.
When the access time of the critical section to be protected is relatively short, It is very convenient to use the spin lock because it can save the context switching time. However, if the CPU does not get the spin lock, it will be idling there until other execution units are unlocked. Therefore, the lock cannot be stopped for a long time in the critical section.
Otherwise, the system efficiency will be reduced.
As a result, we can summarize the Three Principles selected by the self-spin lock and mutex.
1) when the lock cannot be obtained, the overhead of the mutex is the context switching time of the process, and the overhead of the spin lock is waiting for retrieval.
Spin lock (determined by the execution time in the critical section ). If the critical section is small, the spin lock should be used. If the critical section is large, the mutex should be used.
2) The critical section protected by the mutex can contain code that may cause blocking, while the spin lock must be avoided to protect against containing such a generation
The critical section of the Code. Because blocking means that the process is to be switched. if the process is switched out, another process attempts to get the current spin
Lock, the deadlock will occur.
3) The mutex exists in the process context. Therefore, if the protected shared resource needs to be used in case of interruption or soft interruption
Only the spin lock can be selected between the mutex and the spin lock. Of course, if you must use mutex, you can only use the mutex_trylock () method
To avoid blocking.

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.