Tại sao các khóa spin lại là lựa chọn tốt trong Thiết kế hạt nhân Linux thay vì một thứ phổ biến hơn trong mã người dùng, chẳng hạn như semaphore hoặc mutex?


6

Tôi hiểu rằng Spinlocks là chất thải thực sự trong Linux Kernel Design.

Tôi muốn biết tại sao nó giống như khóa spin là lựa chọn tốt trong Linux Kernel Design thay vì một cái gì đó phổ biến hơn trong mã người dùng, chẳng hạn như semaphore hoặc mutex?


1
Spinlocks không phải luôn luôn lãng phí trong mã hạt nhân. Điều này đã được giải thích rất tốt bởi @HandyGandy trong câu hỏi trước của bạn.
Shawn J. Goff

@Shawn: Nhưng tôi muốn làm cho nó một câu hỏi riêng biệt, nơi tôi có thể nhận được câu trả lời rõ ràng hơn.
Sen

2
Mặc dù câu hỏi bạn đang hỏi ở đây không giống với câu hỏi trước đó của bạn, nhưng nó đã được trả lời bởi một số người trong chuỗi trước đó. Và một lần nữa, bạn nên đọc chương 5 của Trình điều khiển thiết bị Linux , giải thích điều này.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: Chắc chắn .. Tôi sẽ làm điều đó .. Nhưng tôi thích hiểu các khái niệm thông qua thảo luận hơn là đọc và tiếp thu các cuốn sách .. :-)
Sen

Câu trả lời:


8

Sự lựa chọn giữa một spinlock và một cấu trúc khác làm cho người gọi chặn và từ bỏ quyền kiểm soát cpu là ở mức độ lớn được điều chỉnh bởi thời gian cần thiết để thực hiện chuyển đổi ngữ cảnh (lưu thanh ghi / trạng thái trong luồng khóa và khôi phục thanh ghi / trạng thái trong một chủ đề khác). Thời gian và chi phí bộ nhớ cache để làm việc này có thể là đáng kể.

Nếu một spinlock đang được sử dụng để bảo vệ quyền truy cập vào các thanh ghi phần cứng hoặc tương tự trong đó bất kỳ luồng nào khác đang truy cập sẽ chỉ mất một phần nghìn giây hoặc ít hơn trước khi nó giải phóng khóa thì việc sử dụng thời gian cpu tốt hơn nhiều để chờ đợi thay vì chuyển đổi ngữ cảnh và tiếp tục.


1
Nếu người gọi bị chặn không chuyển đổi ngữ cảnh, làm thế nào để chủ đề khác có thể giải phóng khóa?
David Cary

1
Trong kernel, spinlock chỉ có thể được giữ bởi CPU khác, không phải luồng khác. Do đó bạn có thể đợi cho đến khi CPU khác nhả khóa.
Tino

11

Như câu hỏi ngụ ý khi nói rằng spinlocks là một "sự lãng phí", spinlocks chỉ nên được tổ chức trong thời gian ngắn.

Spinlocks không phải là cách duy nhất để đồng bộ hóa nhiều luồng. Mutexes / semaphores cũng được sử dụng trong nhân Linux, cũng như các nguyên hàm đồng bộ hóa khác (ví dụ như Waitqueues, event).

Tuy nhiên, kernel phải xử lý các trường hợp mà không gian người dùng không bao giờ nhìn thấy, một trường hợp phổ biến là các trình xử lý ngắt. Trình xử lý ngắt không thể được lên lịch lại trên Linux, nhưng thường phải sử dụng một số nguyên thủy đồng bộ hóa (ví dụ: để thêm một mục công việc vào danh sách được liên kết mà một số luồng khác sẽ xử lý thêm). Vì những người xử lý ngắt không thể ngủ, nên họ không thể sử dụng mutexes, Waitqueues, v.v ... Điều đó khá nhiều lá spinlocks. Nếu một luồng cần đồng bộ hóa truy cập với một trình xử lý ngắt, thì nó cũng phải sử dụng cùng một spinlock.

Spinlocks không nhất thiết là một sự lãng phí. Chúng được tối ưu hóa cho trường hợp không tranh chấp / không chờ đợi và có thể được thực hiện và phát hành rất nhanh. Trong trường hợp đó, chúng nhanh hơn và liên quan đến ít chi phí hơn so với các nguyên thủy đồng bộ hóa khác.


2

Những người khác đã trả lời. Tôi sẽ tóm tắt các trường hợp bạn sẽ sử dụng spinlock và các quy tắc để sử dụng spinlock.

1. Khi spinlock được sử dụng?

Trả lời: Trong các tình huống sau.

  1. Các chủ đề giữ khóa không được phép ngủ.
  2. Sợi chỉ chờ khóa không ngủ, nhưng quay tròn trong một vòng lặp chặt chẽ.

Khi được sử dụng đúng cách, spinlock có thể cho hiệu suất cao hơn semaphore. Vd: Xử lý xâm nhập.

2. Các quy tắc để sử dụng spinlocks là gì?

Trả lời:

Quy tắc - 1: Bất kỳ mã nào chứa spinlock, không thể từ bỏ bộ xử lý vì bất kỳ lý do nào ngoại trừ các ngắt dịch vụ (đôi khi thậm chí không phải sau đó). Vì vậy, mã giữ spinlock không thể ngủ.

Lý do: giả sử tài xế của bạn cầm spinlock đi ngủ. Ví dụ: chức năng gọi copy_from_user()hoặc copy_to_user(), hoặc quyền ưu tiên kernel khởi động trong quá trình ưu tiên cao hơn để đẩy mã của bạn sang một bên. Hiệu quả quá trình từ bỏ CPU giữ spinlock.

Bây giờ chúng tôi không biết khi nào mã sẽ phát hành khóa. Nếu một số luồng khác cố gắng để có được cùng một khóa, nó sẽ quay trong thời gian rất dài. Trong trường hợp xấu nhất, nó sẽ dẫn đến deedlock.

Trường hợp ưu tiên hạt nhân được xử lý bởi chính mã spinlock. Bất cứ lúc nào mã hạt nhân giữ một spinlock, quyền ưu tiên bị vô hiệu hóa trên bộ xử lý có liên quan. Ngay cả hệ thống bộ xử lý đơn cũng phải vô hiệu hóa quyền ưu tiên theo cách này.

Quy tắc - 2: Vô hiệu hóa các ngắt trên CPU cục bộ, trong khi spinlock được giữ.

Lý do: Hỗ trợ trình điều khiển của bạn thực hiện một spinlock kiểm soát truy cập vào thiết bị và sau đó phát ra một ngắt. Điều này làm cho trình xử lý ngắt chạy. Bây giờ trình xử lý ngắt cũng cần khóa để truy cập thiết bị. Nếu trình xử lý ngắt chạy trên cùng một bộ xử lý, nó sẽ bắt đầu quay. Mã trình điều khiển cũng không thể chạy để giải phóng khóa. Vì vậy, bộ xử lý sẽ quay mãi mãi.

Quy tắc - 3: Spinlocks phải được tổ chức trong thời gian tối thiểu có thể.

Lý do: Thời gian giữ khóa dài cũng giữ cho bộ xử lý hiện tại không lên lịch, nghĩa là quá trình ưu tiên cao hơn có thể phải chờ để lấy CPU.

Vì vậy, nó ảnh hưởng đến độ trễ của hạt nhân (thời gian một quá trình có thể phải chờ để được lên lịch). Thông thường các spinlocks nên được giữ trong khoảng thời gian, ít hơn CPU đó để thực hiện chuyển đổi bối cảnh giữa các luồng.

Quy tắc -4: nếu bạn có cả semaphores và spinlocks đều được thực hiện. Sau đó lấy semaphore trước và sau đó spinlock.


-3

Spinlocks & mutexes được sử dụng do thiếu tài nguyên trên CPU .. Chúng đang trở thành một di sản thừa của thiết kế Von Neumann đăng ký 8 bit, đây là kiến ​​trúc tồi tệ nhất, hoàn toàn phi logic trong thời đại ngày nay.

Thật không may, các tính năng của trình biên dịch C / C ++ đã phát triển không tương xứng với phần cứng trong các tính năng mà đơn giản là không thể bị mắc kẹt trong phần cứng với tài nguyên trên chip cổ xưa vẫn còn tồn tại với chúng ta cho đến ngày nay .. Bộ nhớ cache đơn giản không được phát hành lại ở cấp độ 2 trong Uniprocessor, do đó bối cảnh tốn thời gian tiết kiệm và tải lại SMP tiếp tục .. Tương lai là trong các thiết bị FPGA, có các công cụ xây dựng được tối ưu hóa .. Xilinix có quy trình 14nm mới với 3000 kết nối giữa lõi tứ A9 và mảng cổng lập trình được, có thể giữ được lên đến hàng trăm bit SRAM lớn trong các bảng để tận dụng thiết kế máy trạng thái tiên tiến, có khả năng giảm số học / vectơ đa chiều / bảng eigen phức tạp .. rất nhiều so với trình biên dịch buộc xe lăn cũ.

Thiết kế phần cứng của tôi 25 năm trước, đã tích hợp phần cứng tăng cường vào giao diện DSP AD 21020 / CPU i960 .. thiết kế tăng cường rõ ràng đã giải quyết nhiều vấn đề đau đầu về phần mềm trong máy in vòi phun 160 độ rộng 1 mét này.

Những người có kỹ năng phát triển Kernel, được mời thành lập một nhóm nhỏ để đánh giá / sửa đổi kiến ​​trúc mới có tiềm năng thay thế spinlocks / bộ nhớ cache bị mất / tái cấp điều kiện SMP.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.