2012-11-07 17 views
7

Các mã gốc trong kernel linux là:Nhân Linux: Spinlock SMP: Tại sao có một preempt_disable() trong phiên bản SMP spin_lock_irq?

static inline void __raw_spin_lock_irq(raw_spinlock_t *lock) 
{ 
    local_irq_disable(); 
    preempt_disable(); 
    spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); 
    LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); 
} 

Tôi nghĩ rằng không có con đường thực hiện có thể chặn trước đường dẫn hiện tại sau khi IRQ địa phương bị vô hiệu hóa.

Vì tất cả các IRQ cứng thường gặp đều bị vô hiệu hóa, nên không có softirq nào xảy ra và cũng không có dấu chọn để chạy bánh xe theo lịch trình. Tôi nghĩ con đường hiện tại là an toàn. Vậy tại sao có một preempt_disable()?

Cảm ơn bạn.

+0

@ cnicutar.Bạn có chắc không? Tôi không nghĩ vậy. Mỗi lõi CPU sử dụng lịch biểu() để chọn một công việc để chạy. Trong một hệ thống SMP với nhiều lõi, mỗi lõi có một đường dẫn thực hiện chuyên dụng giống như hệ thống UP. Trong trường hợp này, IRQ cục bộ bị vô hiệu hóa, vì vậy lịch trình bánh xe trên lõi này bị chặn. Việc sử dụng trước sẽ xảy ra ở một CPU khác, nhưng điều đó sẽ không ảnh hưởng đến đường dẫn thực hiện trên nó, tôi nghĩ chúng được dành riêng ở mức thực thi. –

Trả lời

6

Theo như tôi có thể biết, các cuộc gọi preempt_disable() được thêm vào một số nguyên thủy khóa, bao gồm spin_lock_irq, bởi Dave Miller vào ngày 4 tháng 12 năm 2002 và được phát hành ở 2.5.51. Thông báo cam kết không hữu ích; nó chỉ nói "[SPINLOCK]: Sửa các macro quay/rwlock không có SMP."

Tôi tin rằng tài liệu Proper Locking Under a Preemptible Kernel giải thích điều này đủ tốt. Phần cuối cùng mang tên "PHÒNG đòn phủ đầu SỬ DỤNG gián đoạn vô hiệu hóa" bắt đầu,

It is possible to prevent a preemption event using local_irq_disable and 
local_irq_save. Note, when doing so, you must be very careful ... 
+0

, Nhận xét của bạn rất hữu ích.Cảm ơn bạn rất nhiều. :) –

1

tôi lướt các patch đề cập bởi Sharp và thấy rằng việc vô hiệu hóa irq thể vô hiệu hóa đòn phủ đầu ngầm nhưng là nguy hiểm.

Tuy nhiên, xin lưu ý rằng việc dựa vào các IRQ bị vô hiệu hóa là một rủi ro kinh doanh . Bất kỳ spin_unlock() nào làm giảm số tiền được gửi đến 0 có thể kích hoạt lịch lại. Ngay cả một printk đơn giản() có thể kích hoạt một lịch lại. Do đó, hãy dựa vào việc vô hiệu hóa việc vô hiệu hóa việc vô hiệu hóa chỉ khi bạn biết rằng loại điều này không thể xảy ra trong đường dẫn mã của bạn. Chính sách tốt nhất chỉ dựa vào việc vô hiệu hóa việc vô hiệu hóa việc sử dụng tạm thời cho thời gian ngắn và chỉ miễn là bạn vẫn còn trong mã của riêng bạn.

Các vấn đề liên quan