Vietnamese (machine translation)

Lưu ý

Mục đích của file này là để độc giả tiếng Việt có thể đọc và hiểu tài liệu nhân kernel dễ dàng hơn, không phải để tạo ra một nhánh tài liệu riêng. Nếu bạn có bất kỳ nhận xét hoặc cập nhật nào cho file này, vui lòng thử cập nhật file tiếng Anh gốc trước. Nếu bạn thấy có sự khác biệt giữa bản dịch và bản gốc, hoặc có vấn đề về bản dịch, vui lòng gửi góp ý hoặc patch cho người dịch của file này, hoặc nhờ người bảo trì và người review tài liệu tiếng Việt giúp đỡ.

Bản gốc:

When do you need to notify inside page table lock ?

Người dịch:

Google Translate (machine translation)

Phiên bản gốc:

8541d8f725c6

Cảnh báo

Tài liệu này được dịch tự động bằng máy và chưa được review bởi người dịch. Nội dung có thể không chính xác hoặc khó hiểu ở một số chỗ. Khi có sự khác biệt với bản gốc, bản gốc luôn là chuẩn. Bản dịch chất lượng cao (được review) được đặt trong thư mục vi_VN/.

Khi nào bạn cần thông báo khóa bảng trang bên trong?

Khi xóa pte/pmd, chúng tôi được lựa chọn thông báo sự kiện thông qua (thông báo phiên bản của *_clear_flush gọi mmu_notifier_invalidate_range) trong khóa bảng trang. Nhưng thông báo đó không cần thiết trong mọi trường hợp.

Đối với TLB thứ cấp (không phải CPU TLB) như IOMMU TLB hoặc thiết bị TLB (khi sử dụng thiết bị những thứ như ATS/PASID để đưa IOMMU đi qua bảng trang CPU để truy cập một xử lý không gian địa chỉ ảo). Chỉ có 2 trường hợp cần thông báo những TLB phụ đó trong khi giữ khóa bảng trang khi xóa pte/pmd:

  1. địa chỉ sao lưu trang miễn phí trước mmu_notifier_invalidate_range_end()

  1. một mục trong bảng trang được cập nhật để trỏ đến một trang mới (COW, lỗi ghi trên trang 0, __replace_page(), ...)

Trường hợp A hiển nhiên là bạn không muốn mạo hiểm để thiết bị ghi vào một trang hiện có thể được sử dụng cho một số nhiệm vụ hoàn toàn khác.

Trường hợp B tinh tế hơn. Để chính xác, nó đòi hỏi trình tự sau đây để xảy ra:

  • lấy khóa bảng trang - xóa mục nhập bảng trang và thông báo ([pmd/pte]p_huge_clear_flush_notify()) - đặt mục nhập bảng trang để trỏ đến trang mới

Nếu việc xóa mục nhập bảng trang không kèm theo thông báo trước khi cài đặt giá trị pte/pmd mới thì bạn có thể phá vỡ mô hình bộ nhớ như C11 hoặc C++11 cho thiết bị.

Hãy xem xét tình huống sau (thiết bị sử dụng tính năng tương tự ATS/PASID):

Hai địa chỉ addrA và addrB sao cho ZZ0000ZZ >= PAGE_SIZE chúng ta giả sử chúng được bảo vệ chống ghi cho COW (trường hợp B khác cũng được áp dụng).

[Thời điểm N] ----------------------------------------------------------------------

CPU-thread-0 {cố gắng ghi vào addrA} CPU-thread-1 {cố gắng ghi vào addrB} CPU-thread-2 {} CPU-luồng-3 {} DEV-thread-0 {đọc addrA và điền vào thiết bị TLB} DEV-thread-2 {đọc addrB và điền vào thiết bị TLB} [Thời điểm N+1] ------------------------------------------------------------------ CPU-thread-0 {COW_step0: {mmu_notifier_invalidate_range_start(addrA)}} CPU-thread-1 {COW_step0: {mmu_notifier_invalidate_range_start(addrB)}} CPU-thread-2 {} CPU-luồng-3 {} DEV-thread-0 {} DEV-luồng-2 {} [Thời gian N+2] ------------------------------------------------------------------ CPU-thread-0 {COW_step1: {cập nhật bảng trang để trỏ tới trang mới cho addrA}} CPU-thread-1 {COW_step1: {cập nhật bảng trang để trỏ tới trang mới cho addrB}} CPU-luồng-2 {} CPU-luồng-3 {} DEV-thread-0 {} DEV-thread-2 {} [Thời gian N+3] ------------------------------------------------------------------ CPU-thread-0 {được ưu tiên} CPU-thread-1 {được ưu tiên} CPU-thread-2 {ghi vào addrA là ghi vào trang mới} CPU-luồng-3 {} DEV-thread-0 {} DEV-thread-2 {} [Thời gian N+3] ------------------------------------------------------------------ CPU-thread-0 {được ưu tiên} CPU-thread-1 {được ưu tiên} CPU-thread-2 {} CPU-thread-3 {ghi vào addrB là ghi vào trang mới} DEV-thread-0 {} DEV-thread-2 {} [Thời gian N+4] ------------------------------------------------------------------ CPU-thread-0 {được ưu tiên} CPU-thread-1 {COW_step3: {mmu_notifier_invalidate_range_end(addrB)}} CPU-thread-2 {} CPU-luồng-3 {} DEV-thread-0 {} DEV-thread-2 {} [Thời gian N+5] ------------------------------------------------------------------ CPU-thread-0 {được ưu tiên} CPU-luồng-1 {} CPU-thread-2 {} CPU-luồng-3 {} DEV-thread-0 {đọc addrA từ trang cũ} DEV-thread-2 {đọc addrB từ trang mới}

Vì vậy, ở đây vì tại thời điểm N+2 mục trong bảng trang rõ ràng không được ghép nối với một thông báo vô hiệu hóa TLB thứ cấp, thiết bị sẽ thấy giá trị mới cho addrB trước khi nhìn thấy giá trị mới của addrA. Điều này phá vỡ tổng thứ tự bộ nhớ cho thiết bị.

Khi thay đổi một pte thành bảo vệ chống ghi hoặc trỏ đến một trang được bảo vệ chống ghi mới có cùng nội dung (KSM), bạn có thể trì hoãn mmu_notifier_invalidate_range gọi mmu_notifier_invalidate_range_end() bên ngoài khóa bảng trang. Cái này đúng ngay cả khi luồng thực hiện cập nhật bảng trang được ưu tiên ngay sau đó giải phóng khóa bảng trang nhưng trước khi gọi mmu_notifier_invalidate_range_end().