System space SMP Programming

Source: Internet
Author: User

Abstract: multi-processor systems are becoming more and more common. Although most of the user space code will still run perfectly, and in some cases, the advantages of SMP can be exploited without additional code, however, the kernel space code must be written to be "SMP aware" and "SMP secure ". The following sections explain how to do this.

Multi-processor systems are becoming more and more common. Although most of the user space code will still run perfectly, and in some cases, the advantages of SMP can be exploited without additional code, however, the kernel space code must be written to be "SMP aware" and "SMP secure ". The following sections explain how to do this.

Problem

 

When multiple CPUs exist, the same code may be executed on two or more CPUs at the same time. This may cause problems in the following routine for initializing an image device.

Void init_hardware (void)

{

Outb (0x1, hardware_base + 0x30 );

Outb (0x2, hardware_base + 0x30 );

Outb (0x3, hardware_base + 0x30 );

Outb (0x4, hardware_base + 0x30 );

}

Assume that the hardware depends on the register 0x30 and is set to 0, 1, 2, and 3 in order for initialization. If there is another CPU parameter, the problem will get worse. Imagine two CPUs, both of which are executing this routine, but the CPU entry on the 2nd is a little slow:

CPU 1 CPU 2

0x30 = 1

0x30 = 2 0x30 = 1

0x30 = 3 0x30 = 2

0x30 = 4 0x30 = 3

0x30 = 4

What will happen? From the perspective of the hardware device we imagine, the bytes it receives on the register 0x30 are in the order of 1, 2, 1, 3, 2, 4, 3, and 4.

Ah! The second CPU was a mess. Fortunately, we have a way to prevent such incidents.

History of spin locks

In version 2.0.x, the Linux kernel introduces a global variable to the entire kernel to prevent problems caused by more than one CPU. This means that only one CPU can execute code from the kernel space at any time. In this way, although it can work, but when the system starts to appear with more than two CPUs, the expansion performance is not very good.

Kernel series of version 2.1.x have added more granular SMP support. This means that it is no longer dependent on the "big lock" that previously appeared as a global variable, but every smp-conscious routine now needs its own spin lock. The ASM/spinlock. h file defines several types of spin locks.

With the localized spin lock, more than one CPU can execute the kernel space code at the same time.

Simple spin lock

The simplest way to understand a spin lock is to treat it as a variable that marks a routine or as "I am currently running on another CPU. Please wait ", or mark it as "I am not running now ". If CPU 1 first enters this routine, it obtains the spin lock. When the number 2 CPU attempts to enter the same routine, the spin lock tells it that it is already held by the number 1 CPU. It can only enter after the number 1 CPU is released.

Spinlock_t my_spinlock = spin_lock_unlocked;

Unsigned long flags;

Spin_lock (& my_spinlock );

 

...

Critical Section

...

Spin_unlock (& my_spinlock );

Interrupted

Imagine that our hardware driver has another interrupt handler. This handler needs to modify some global variables defined by our driver. This can cause confusion. How can we solve this problem?

The first way to protect a Data Structure from interruption is to globally prohibit interruption. This is very inefficient when it is known that only your own interrupt will modify your driver variables. Fortunately, we have a better solution now. We only disable interruption during use of shared variables, and then re-enable.

There are three functions to implement this method:

Disable_irq ()

Enable_irq ()

Disable_irq_nosync ()

All three functions use an interrupt number as the parameter. Note: disabling an interruption for too long will make it difficult to track program defects, lose data, or even worse.

The non-synchronous version of The disable_irq function allows the specified IRQ handler to continue running, provided that it is already running. For general disable_irq, the specified IRQ handler is not running on the CPU.

If you need to modify the spin lock in the interrupt handler, you cannot use the common spin_lock () and spin_unlock (), but should save the interrupt status. This can be easily done by adding the _ irqsave suffix to the two functions:

Spinlock_t my_spinlock = spin_lock_unlocked;

Unsigned long flags;

Spin_lock_irqsave (& my_spinlock, flags );

...

Critical Section

...

Spin_unlock_irqrestore (& my_spinlock, flags );

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.