Synchronization mechanism of the Linux kernel---spin lock

Source: Internet
Author: User
Tags semaphore

Spin Lock thinking: http://bbs.chinaunix.net/thread-2333160-1-1.html

recently in See Song Baohua "device driver development Specific explanation" second edition. See the spin lock part, some doubts. So come and ask the people.
Here are some of the ideas I've got from some of the online information that I've come up with, and I don't know right or wrong. Let's write it down and discuss it:
(1) There are three implementations of spin locks on Linux:
1. On a single CPU. Cannot preempt the kernel, the spin lock is an empty operation.
2. In a single CPU that can preempt the kernel, the spin lock is implemented as "Prohibit kernel preemption". "Spin" is not implemented.
3. In multi-CPU, the kernel can be preempted. The spin lock is implemented as "Prohibit kernel preemption" + "spin".
(2) about preemptive kernel and non-preemptive kernel:
in a non-preemptive kernel, if a process executes in the kernel state, it will be switched only in the following two cases:
1. The execution is complete (return to user space)
2. Proactively make up the CPU (that is, the active call to schedule or a task blockage in the kernel-this will also cause the call to schedule)

In the preemptive kernel, assume that a process executes in the kernel state. It will be switched only in the following four situations:
1. The execution is complete (return to user space)
2. Proactively make up the CPU (that is, the active call to schedule or a task blockage in the kernel-this will also cause the call to schedule)
3. When the interrupt handler is running and before the kernel space is returned (at this point the preemption flag Premptcount must be 0).
4. When the kernel code once again has the preemption. such as unlocking and enabling soft interrupts.

In Song Baohua's book, it is mentioned when using a spin lock. Avoid using to protect "including code that causes clogging." The blockage means that the process will be switched. This is confusing to me. Since the use of spin locks in a preemptive kernel is a "no kernel preemption", since the "forbidden kernel preemption", how does the process switch?
This is what I think: the prohibition of kernel preemption is simply to turn off the "preemption flag." Instead of banning process switching. Process scheduling occurs when an explicit use of schedule or a process jam (which also results in a call to schedule).

Here are some ideas to add: Song Baohua's book says that when using a spin lock to protect critical areas. If there is a blockage caused by "including the blockage Code" in the critical section, which causes the process to switch, if there is another process attempting to obtain this spin lock. Deadlocks can occur.
personal feelings. Only in multi-CPU. Deadlocks can occur when the kernel is preempted. And in a single CPU. If the kernel can be preempted or not preempted, there will be no deadlock, but the spin lock fails at this point (that is, the ability to protect the critical section cannot be achieved). This is due to the "spin" of the multi-CPU preemption kernel, which results in deadlocks. A single CPU can preempt or not preempt the kernel, and no "spin" is implemented. However, no kernel preemption is allowed, so no deadlock occurs. However, there will be unprotected repeated entry to the critical zone (i.e., the function of the critical zone cannot be achieved).

The above view is only a personal idea, the wrong place, please also point out, thank you.



Five, Spin lock (Spinlock)

Spin locks are somewhat similar to mutually exclusive locks, and only spin locks do not cause the caller to sleep. Assuming that the spin lock has been maintained by another operating unit, the caller has been circulating there to see if the spin lock's hold has released the lock, and the word "spin" is named.

Since spin-lock users generally keep the lock time short, it is necessary to choose a spin instead of sleep, and the spin lock is much more efficient than a mutually exclusive lock.

Semaphores and read and write semaphores are suitable for long periods of time, and they cause the caller to sleep. So it can be used only in the context of the process (the variant of _trylock can be used in the interrupt context), and the spin lock is suitable for situations where the hold time is short, and it can be used in whatever context.

Assuming that the shared resource being protected is only available in the context of the process, it is appropriate to use semaphores to protect the shared resource, assuming that the access to the common roadway resource is short and the spin lock can. However, assume that the protected shared resource needs to be interviewed in the interrupt context (including the bottom half of the interrupt handling handle and the top half of the soft interrupt). You must use a spin lock.

The spin lock retention period is a preemption failure, while the semaphore and read/write semaphore retention period can be preempted. A spin lock is only really necessary in the case of a kernel preemption or SMP, and in a single CPU and non-preemptive kernel, all operations of the spin lock are empty operations.

as with mutually exclusive locks, a running unit that wants to access a shared resource protected by a spin lock must first get a lock and must release the lock after visiting the shared resource. Assuming that a spin lock is acquired, no matter what unit of operation is holding the lock, the lock is immediately obtained. Assuming that the lock already has a hold when the spin lock is acquired, the acquire lock operation will spin there until the lock is released by the hold of the spin lock .

Whether it is mutually exclusive lock. Or a spin lock, at any time, at most only one of the holders, also said, at any time at most only one operating unit to obtain the lock.

The spin lock APIs are:

Spin_lock_init (x)

This macro is used to initialize the spin lock x. Spin locks must be initialized before they are actually used. The macro is used for dynamic initialization.

Define_spinlock (x)

The macro declares a spin lock x and initializes it. The macro is defined for the first time in 2.6.11 and does not have the macro in the previous kernel.

Spin_lock_unlocked

This macro is used to statically initialize a spin lock.

Define_spinlock (x) is equivalent to spinlock_t x = spin_lock_unlockedspin_is_locked (x)

The macro is used to infer whether the spin lock x has been persisted by a running unit (that is, locked), assuming that it returns true, otherwise false.

Spin_unlock_wait (x)

The macro is used to wait for the spin lock X to become not maintained by any running unit, assuming that no matter what the running unit is holding the spin lock, the macro returns immediately. Otherwise it will loop over there. Until the spin lock is released by the holding person.

Spin_trylock (Lock)

The macro tries to get the spin lock lock, assuming that it can get the lock immediately, it gets the lock and returns to true, otherwise it can't get the lock immediately. Return to false immediately. It does not spin to wait for lock to be released.

Spin_lock (Lock)

the macro is used to obtain the spin lock lock, assuming that the lock can be obtained immediately, it returns immediately, otherwise it will spin out there until the spin lock is released by the hold. at this point, it gets the lock and returns. Anyway. It only returns if it gets a lock.

Spin_lock_irqsave (lock, flags)

The macro obtains the spin lock at the same time that the value of the flag register is saved to the variable flags and fails the local interrupt.

SPIN_LOCK_IRQ (Lock)

the macro is similar to Spin_lock_irqsave, only the value of which the macro does not save the flag register .

SPIN_LOCK_BH (Lock)

The macro fails the local soft interrupt at the same time that the spin lock is obtained.

Spin_unlock (Lock)

The macro releases the spin lock lock, which is paired with Spin_trylock or Spin_lock. Suppose Spin_trylock returns false, indicating that no spin lock is obtained, so it is not necessary to use Spin_unlock release.

Spin_unlock_irqrestore (lock, flags)

The macro releases the same time as the spin lock lock. Also restores the value of the flag register to the value that the variable flags holds.

It is paired with the Spin_lock_irqsave.

SPIN_UNLOCK_IRQ (Lock)

the macro releases the same time as the spin lock lock and also enables local interrupts. It is suitable for use with SPIN_LOCK_IRQ .

SPIN_UNLOCK_BH (Lock)

The macro releases the same time as the spin lock lock and also enables local soft interrupts.

It is paired with the SPIN_LOCK_BH.

Spin_trylock_irqsave (lock, flags)
the macro assumes that the spin lock lock is obtained. It will also save the value of the flag register to the variable flags, and fail the local interrupt, assuming that no lock is obtained and that it does nothing.

So suppose you can get the lock right away. It is equivalent to Spin_lock_irqsave, assuming that the lock cannot be obtained. It is equivalent to Spin_trylock.

Assuming that the macro obtains the spin lock lock, it needs to be released using Spin_unlock_irqrestore.

SPIN_TRYLOCK_IRQ (Lock)

The macro is similar to Spin_trylock_irqsave, only that the macro does not save the flag register.

Assuming that the macro obtains a spin lock lock, it needs to be released using SPIN_UNLOCK_IRQ.

SPIN_TRYLOCK_BH (Lock)

the macro assumes that a spin lock is obtained. It will also fail local soft interrupts. Suppose you don't get a lock. It doesn't do anything . So, assuming a lock is obtained, it is equivalent to SPIN_LOCK_BH, assuming that there is no lock, it is equivalent to Spin_trylock. Assume that the macro has a spin lock. Need to use SPIN_UNLOCK_BH to release.

Spin_can_lock (Lock)

the macro is used to infer whether the spin lock lock can be locked, and it is actually spin_is_locked reversed. Assuming lock is not locked, it returns true, otherwise, returns false. The macro is defined for the first time in 2.6.11 and does not have the macro in the previous kernel.

There are several version numbers for spin lock and release spin locks, so it is necessary to let the reader know what version numbers are used to obtain and release the lock macros.

assume that the shared resources that are protected are only in the context of the process context access and soft interrupt contexts, so when visiting the shared resource in the context of the process. May be interrupted by a soft interrupt, which may enter the soft interrupt context to access the protected shared resource. For this reason, access to shared resources must be protected by using SPIN_LOCK_BH and Spin_unlock_bh .

of course the use of SPIN_LOCK_IRQ and SPIN_UNLOCK_IRQ as well as Spin_lock_irqsave and Spin_unlock_irqrestore are also possible. They fail the local hard interrupt, and the failed hard interrupt implicitly also fails the soft interrupt. But using SPIN_LOCK_BH and SPIN_UNLOCK_BH is the most appropriate. It's two faster than the other one .

Assume that the protected shared resource is only visited in the context of the process and tasklet or timer contexts. Then you should use the same macro that gets and releases the lock as in the case above, because Tasklet and timer are implemented with soft interrupts.

Assuming that a protected shared resource is only visited in a Tasklet or timer context, there is no need for spin lock protection, because the same tasklet or timer can only be executed on a single CPU, even in an SMP environment. The Tasklet actually binds the Tasklet to the current CPU when the tasklet_schedule tag is called, so it is never possible for the same tasklet to execute on other CPUs at the same time.

The timer is also add_timer to the current CPU when it is added to the timer queue, so the same timer can never be executed on other CPUs.

Of course, there are two instances of the same tasklet. It is even more impossible to execute the same CPU at the same time.

Assuming that a protected shared resource is only visited in two or more tasklet or timer contexts, access to shared resources needs to be protected only with Spin_lock and Spin_unlock, without the _BH version number, because when Tasklet or a timer executes, There can be no other tasklet or timer executing on the current CPU.

Assuming that the shared resource being protected is only in context of a soft interrupt (except Tasklet and timer), the shared resource needs to be protected by Spin_lock and Spin_unlock, since the same soft interrupt can be performed on different CPUs at the same time.

Assuming that a protected shared resource is interviewed in two or more soft interrupt contexts, the shared resource will of course need to be protected with spin_lock and spin_unlock, and different soft interrupts can be performed on different CPUs at the same time.

Assume that a protected shared resource is visited during soft interrupts (including Tasklet and timers) or process contexts and hard interrupt contexts, then during a soft interrupt or process context visit. May be interrupted by a hard interrupt, thus accessing the shared resource in a hard interrupt context. So. SPIN_LOCK_IRQ and SPIN_UNLOCK_IRQ are required in the context of a process or soft interrupt to protect access to shared resources.

And what version number is used in the interrupt handling handle. Depending on the situation, assuming that there is only one interrupt handling handle to access the shared resource, only Spin_lock and Spin_unlock are required in the interrupt handling handle to secure access to the shared resource.

It is not possible to be interrupted by a soft interrupt or a process on the same CPU during the run of the interrupt handling handle. However, assume that there are different interrupt handling handles to access the shared resource. Then you need to use SPIN_LOCK_IRQ and SPIN_UNLOCK_IRQ in the interrupt handling handle to protect access to shared resources.

In the case of using SPIN_LOCK_IRQ and SPIN_UNLOCK_IRQ, it is entirely possible to replace it with Spin_lock_irqsave and Spin_unlock_irqrestore, and that which should be used in detail depends on the circumstances. Assuming you can be confident that the interrupt is enabled before you access the shared resources, use SPIN_LOCK_IRQ better.

Because it is faster than Spin_lock_irqsave. However, assuming that you are not sure whether the interrupt is enabled, then using Spin_lock_irqsave and Spin_unlock_irqrestore is better, because it will revert to the interrupt flag before the shared resource is resumed instead of directly enabling the interrupt.

Of course. In some cases, there is a need to break down when visiting shared resources. And after the interview must be interrupted to enable, this situation using SPIN_LOCK_IRQ and SPIN_UNLOCK_IRQ best.

It is necessary to remind readers that Spin_lock is used to prevent non-synchronized access to shared resources by running units on different CPUs to access the shared resources at the same time and to preempt different process contexts. Interrupt failure and soft interrupt invalidation are intended to prevent soft interrupts on the same CPU or to interrupt non-synchronized access to shared resources.

References

Kernel Locking techniques,http://www.linuxjournal.com/article/5833

Redhat 9.0 Kernel source tree

kernel.org 2.6.12 Source Tree

The new lock mechanism in the Linux 2.6 kernel--rcu (read-copy Update),

http://www.ibm.com/developerworks/cn/linux/l-rcu/

Unreliable guide to Locking.

Synchronization mechanism of the Linux kernel---spin lock

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.