2010-03-30 63 views
10

Tôi đã đọc về những gì xảy ra sau khi các gói được chụp bởi NIC, và càng đọc nhiều, tôi càng bối rối. Trước tiên, tôi đã đọc theo truyền thống, sau khi một gói được chụp bởi NIC, nó được sao chép vào một khối bộ nhớ trong không gian hạt nhân, sau đó đến không gian người dùng cho bất kỳ ứng dụng nào sau đó hoạt động trên dữ liệu gói . Sau đó, tôi đọc về DMA, nơi NIC trực tiếp sao chép gói vào bộ nhớ, bỏ qua CPU. Vì vậy, là NIC -> bộ nhớ hạt nhân -> Luồng bộ nhớ không gian người dùng vẫn còn hợp lệ? Ngoài ra, hầu hết NIC (ví dụ: Myricom) đều sử dụng DMA để cải thiện tốc độ chụp gói?Điều gì sẽ xảy ra sau khi gói bị bắt?

Thứ hai, không RSS (Nhận tỷ lệ phụ) hoạt động tương tự trong cả hệ thống Windows và Linux? Tôi chỉ có thể tìm thấy giải thích chi tiết về cách RSS hoạt động trong các bài MSDN, nơi chúng nói về RSS (và MSI-X) hoạt động trên Windows Server 2008. Nhưng khái niệm tương tự về RSS và MSI-X vẫn nên áp dụng cho các hệ thống Linux, ?

Cảm ơn bạn.

Kính trọng, Rayne

+1

Google cho mạng không sao chép ... rất ít thiết bị tốc độ cao có thể chịu đựng được bản sao đôi cho hạt nhân, sau đó người dùng trong những ngày này. IANANG (Tôi không phải là một Guru mạng) nhưng tôi tin rằng DMA được sử dụng tích cực –

+0

Vì vậy, ngày nay, một khi một NIC chụp một gói, nó sẽ được sao chép trực tiếp vào bộ nhớ (người dùng)? – Rayne

+3

@Rayne yes; NIC sẽ sử dụng DMA để chuyển dữ liệu trực tiếp vào bộ nhớ vật lý được ánh xạ vào không gian địa chỉ '(userland) của quá trình của bạn. – vladr

Trả lời

12

Làm thế nào quá trình này diễn ra chủ yếu là lên đến tác giả tài xế và phần cứng , nhưng đối với các trình điều khiển tôi đã xem xét hoặc viết và phần cứng tôi đã làm việc, đây thường là cách hoạt động của nó:

  1. Lúc khởi động trình điều khiển, nó sẽ phân bổ một số bộ đệm và cung cấp cho các NIC.
  2. Khi một gói được nhận bởi NIC, nó sẽ kéo địa chỉ tiếp theo ra khỏi danh sách bộ đệm, DMA dữ liệu trực tiếp vào nó, và thông báo cho trình điều khiển thông qua ngắt.
  3. Trình điều khiển bị gián đoạn và có thể chuyển bộ đệm sang nhân hoặc nó sẽ cấp phát bộ đệm hạt nhân mới và sao chép dữ liệu. "Zero sao chép mạng" là trước đây và rõ ràng đòi hỏi sự hỗ trợ từ hệ điều hành. (chi tiết bên dưới về điều này)
  4. Trình điều khiển cần phân bổ bộ đệm mới (trong trường hợp không sao chép) hoặc nó sẽ tái sử dụng bộ đệm. Trong cả hai trường hợp, bộ đệm được trả lại cho NIC cho các gói trong tương lai.

Mạng không sao chép trong hạt nhân không quá tệ. Không sao chép tất cả các con đường xuống vùng đất người dùng là nhiều hơn khó hơn. Userland nhận dữ liệu, nhưng các gói mạng được tạo thành từ cả đầu trang và dữ liệu. Ít nhất, bản sao không chính xác tất cả các cách để userland đòi hỏi sự hỗ trợ từ NIC của bạn để nó có thể DMA gói vào bộ đệm tiêu đề/dữ liệu riêng biệt. Các tiêu đề được tái chế khi hạt nhân định tuyến gói đến đích và kiểm tra tổng kiểm tra (đối với TCP, hoặc trong phần cứng nếu NIC hỗ trợ nó hoặc trong phần mềm nếu không; lưu ý rằng nếu hạt nhân phải tính toán tổng kiểm tra, nó sẽ cũng có thể sao chép các dữ liệu, quá: nhìn vào dữ liệu incurs cache nhớ và sao chép nó ở nơi khác có thể được miễn phí với mã điều chỉnh).

Thậm chí giả sử tất cả các ngôi sao căn chỉnh, dữ liệu không thực sự nằm trong bộ đệm người dùng của bạn khi hệ thống nhận được. Cho đến khi một ứng dụng yêu cầu dữ liệu, hạt nhân không biết nó sẽ kết thúc ở đâu. Hãy xem xét trường hợp của một daemon đa tiến trình như Apache. Có rất nhiều tiến trình con, tất cả đều lắng nghe trên cùng một socket. Bạn cũng có thể thiết lập kết nối, fork() và cả hai quá trình có thể recv() dữ liệu đến.

Gói TCP trên Internet thường là 1460 byte trọng tải (MTU của 1500 = 20 byte tiêu đề IP + 20 byte TCP header + 1460 byte dữ liệu). 1460 không phải là sức mạnh của 2 và sẽ không khớp với kích thước trang trên bất kỳ hệ thống nào bạn sẽ tìm thấy. Điều này trình bày các vấn đề cho việc lắp ráp lại luồng dữ liệu. Hãy nhớ rằng TCP là định hướng luồng. Không có sự phân biệt giữa người gửi viết, và hai 1000 byte ghi chờ đợi tại nhận được sẽ được tiêu thụ hoàn toàn trong một đọc 2000 byte.

Thực hiện việc này thêm, hãy xem xét bộ đệm người dùng. Chúng được phân bổ bởi ứng dụng. Để được sử dụng cho không sao chép tất cả các con đường xuống, bộ đệm cần phải được liên kết trang và không chia sẻ trang bộ nhớ đó với bất kỳ thứ gì khác. Tại thời điểm recv(), hạt nhân về mặt lý thuyết có thể remap trang cũ có chứa dữ liệu và "lật" nó vào vị trí, nhưng điều này phức tạp bởi vấn đề lắp ráp ở trên vì các gói kế tiếp sẽ nằm trên các trang riêng biệt. Hạt nhân có thể giới hạn dữ liệu mà nó quay trở lại với tải trọng của mỗi gói, nhưng điều này sẽ có nghĩa là có rất nhiều cuộc gọi hệ thống bổ sung, việc sắp xếp lại trang và thông lượng tổng thể thấp hơn.

Tôi thực sự chỉ làm xước bề mặt về chủ đề này. Tôi đã làm việc tại một vài công ty vào đầu những năm 2000 để cố gắng mở rộng các khái niệm không sao chép vào trong vùng đất của người dùng. Chúng tôi thậm chí còn thực hiện một ngăn xếp TCP trong vùng đất người dùng và phá vỡ hoàn toàn hạt nhân cho các ứng dụng bằng cách sử dụng ngăn xếp, nhưng điều đó mang lại bộ vấn đề riêng của nó và không bao giờ là chất lượng sản xuất. Đó là một vấn đề rất khó giải quyết.

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