2012-07-04 30 views
12

Một trong các trình điều khiển nhân Linux mà tôi đang phát triển đang sử dụng giao tiếp mạng trong hạt nhân (sock_create(), sock->ops->bind(), v.v.).Mô phỏng hiệu ứng của select() và poll() trong lập trình socket kernel

Vấn đề là sẽ có nhiều ổ cắm để nhận dữ liệu từ đó. Vì vậy, tôi cần một cái gì đó mà sẽ mô phỏng một select() hoặc poll() trong không gian hạt nhân. Vì các chức năng này sử dụng các bộ mô tả tập tin, tôi không thể sử dụng các cuộc gọi hệ thống trừ khi tôi sử dụng các cuộc gọi hệ thống để tạo các ổ cắm, nhưng điều đó có vẻ không cần thiết vì tôi đang làm việc trong hạt nhân.

Vì vậy, tôi đã nghĩ đến việc gói trình xử lý mặc định sock->sk_data_ready trong trình xử lý của riêng mình (custom_sk_data_ready()), sẽ mở khóa một semaphore. Sau đó, tôi có thể viết chức năng kernel_select() của riêng mình để cố gắng khóa semaphore và thực hiện chờ đợi cho đến khi nó được mở. Bằng cách đó, chức năng hạt nhân đi ngủ cho đến khi semaphore được mở khóa bởi custom_sk_data_ready(). Khi kernel_select() nhận khóa, thiết bị sẽ mở khóa và gọi custom_sk_data_ready() để khóa lại. Vì vậy, việc khởi tạo bổ sung duy nhất là chạy custom_sk_data_ready() trước khi ràng buộc một ổ cắm để cuộc gọi đầu tiên đến custom_select() không kích hoạt sai.

Tôi thấy một vấn đề có thể xảy ra. Nếu nhiều lần nhận xảy ra, thì nhiều cuộc gọi đến custom_sk_data_ready() sẽ thử mở khóa semaphore. Vì vậy, để không mất nhiều cuộc gọi và để theo dõi sock đang được sử dụng, sẽ có một bảng hoặc danh sách các con trỏ đến các ổ cắm đang được sử dụng. Và custom_sk_data_ready() sẽ phải gắn cờ trong bảng/danh sách mà ổ cắm đã được truyền.

Phương pháp này có âm thanh không? Hoặc tôi chỉ nên đấu tranh với vấn đề người dùng/không gian hạt nhân khi sử dụng các cuộc gọi hệ thống tiêu chuẩn?

Finding ban đầu:

Tất cả các chức năng gọi lại trong cơ cấu sock được gọi là trong bối cảnh ngắt. Điều này có nghĩa là họ không thể ngủ được. Để cho phép chuỗi hạt nhân chính ngủ trên danh sách các ổ cắm sẵn sàng, các mutex được sử dụng, nhưng custom_sk_data_ready() phải hoạt động giống như một spinlock trên các mutex (liên tục gọi số mutex_trylock()). Điều này cũng có nghĩa là mọi phân bổ động phải sử dụng cờ GFP_ATOMIC.


khả năng bổ sung:

Đối với mỗi ổ cắm mở, thay thế mỗi sk_data_ready() với một tuỳ chỉnh một (custom_sk_data_ready()) ổ cắm và tạo ra một công nhân (struct work_struct) và hàng đợi công việc (struct workqueue_struct). Chức năng process_msg() phổ biến sẽ được sử dụng cho mỗi nhân viên. Tạo một danh sách toàn cầu cấp mô-đun hạt nhân trong đó mỗi phần tử danh sách có một con trỏ tới socket và chứa cấu trúc công nhân. Khi dữ liệu đã sẵn sàng trên một socket, custom_sk_data_ready() sẽ thực thi và tìm phần tử danh sách khớp với cùng một socket, và sau đó gọi queue_work() với hàng đợi công việc của phần tử danh sách và nhân viên. Sau đó, chức năng process_msg() sẽ được gọi và có thể tìm phần tử danh sách khớp thông qua nội dung của thông số struct work_struct * (địa chỉ) hoặc sử dụng macro container_of() để lấy địa chỉ của cấu trúc danh sách chứa cấu trúc công nhân.

Kỹ thuật nào là âm thanh nhiều nhất?

+0

Bạn không thể có chương trình trợ giúp không gian người dùng đang thực hiện 'poll'? Đầu vào ghép kênh với 'poll' hoặc' select' có liên quan đến bộ lập lịch (vì quá trình tạm dừng không hoạt động nên các quá trình khác có thể chạy) vì vậy tôi sẽ không làm điều đó bên trong hạt nhân! –

+1

@BasileStarynkevitch: Đó là lý do tại sao tôi chỉ cố gắng mô phỏng chặn giấc ngủ của 'poll()' và 'select()'. Sử dụng hai cuộc gọi hệ thống từ hạt nhân là phương sách cuối cùng. Tôi nghi ngờ rằng có vấn đề với chạy 'poll()' và 'select()' trong một trình trợ giúp không gian người dùng. Người trợ giúp phải có quyền truy cập vào một bộ mô tả tệp (mà không được thực hiện trong 'sock_create()') và có thể cho phép truy cập vào một ổ cắm nằm trong không gian hạt nhân. Vì vậy, bây giờ tạo ổ cắm phải xảy ra trong trình trợ giúp không gian người dùng và mô-đun phải tìm ổ cắm dựa trên bộ mô tả tệp không gian người dùng. Bây giờ nó trở nên phức tạp hơn. – Joshua

+0

Bạn không nên thực hiện bất kỳ thao tác nào trong hạt nhân. – mpe

Trả lời

3

Ý tưởng thứ hai của bạn nghe có vẻ giống như nó sẽ hoạt động.

Mã CEPH có vẻ như tương tự, xem net/ceph/messenger.c.

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