1. PCIe fan-out switch là gì?
PCIe fan-out switch là một con chip switch PCIe dùng để lấy một link PCIe upstream (thường từ CPU root complex) rồi “trải” (fan-out) ra thành nhiều downstream port để kết nối đồng thời tới nhiều thiết bị endpoint.
Bản chất nằm ở chỗ PCIe là kiến trúc point-to-point – mỗi link chỉ nối trực tiếp hai thiết bị, và root complex của CPU chỉ có số lane giới hạn (vd Gen4/Gen5 x16). Khi cần kết nối nhiều thiết bị hơn số lane native cho phép, ta đặt một con switch vào giữa: nó có 1 upstream port và N downstream port, định tuyến TLP (Transaction Layer Packets) giữa upstream và các downstream dựa trên address/ID routing.

Hình 1. Một upstream link x16 được fan-out thành nhiều downstream x4 tới các endpoint.
Ví dụ điển hình ngay trong domain của bạn: một storage server có cả chục ổ U.2 NVMe nhưng CPU không đủ lane để cấp x4 native cho từng ổ. Backplane NVMe nhiều khe vì vậy luôn có một (hoặc nhiều) con switch lấy x16 upstream rồi fan-out thành nhiều downstream x4. HBA/retimer/NIC cũng thường treo dưới switch theo kiểu này.
Một số điểm kỹ thuật đáng lưu ý khi debug:
- Oversubscription – tổng bandwidth downstream thường lớn hơn upstream (vd 24 ổ × x4 = 96 lane downstream nhưng chỉ x16 upstream). Bình thường không sao, nhưng khi nhiều ổ I/O nặng đồng thời thì bottleneck nằm ở upstream link, không phải ở ổ.
- Link training từng port độc lập – mỗi downstream port của switch train riêng. Đây chính là chỗ hay sinh ra các lỗi kiểu bạn vẫn gặp: port train xuống 4×1 thay vì 4×2/4×4, hoặc degrade speed (Gen4 → Gen1) do contact pin, signal integrity, hoặc seating của card/ổ. Khi đọc log, cần phân biệt rõ lỗi nằm ở link upstream switch ↔ CPU hay ở downstream switch ↔ endpoint – vì hướng xử lý (RMA chassis vs RMA drive/card) khác hẳn nhau.
- Lspci topology – khi debug, switch hiện ra dưới dạng bridge: một upstream bridge + nhiều downstream bridge, endpoint nằm sau các downstream bridge đó. Đọc cây lspci -tv sẽ thấy rõ ổ nào treo dưới switch nào, hữu ích để khoanh vùng xem một loạt ổ cùng fail có phải do chung một con switch không.
- NTB (Non-Transparent Bridging) – một số switch hỗ trợ multi-host / dual-controller, cho phép hai host cùng “nhìn” vào một miền PCIe qua bridge không trong suốt. Liên quan tới các bài dual-controller storage.
Vendor phổ biến: Broadcom/PLX (dòng PEX), Microchip (Switchtec PFX/PSX), Astera Labs.
2. Non-Transparent Bridging (NTB)
NTB là tính năng thú vị nhất của PCIe switch, và đúng là phần cốt lõi đằng sau kiến trúc dual-controller mà các unit bạn đang test sử dụng. Để hiểu NTB, trước hết cần đối chiếu với bridge thường:
Một transparent bridge (TB) – chính là downstream port bình thường của switch – thì “trong suốt”: root complex nhìn xuyên qua nó và enumerate được mọi thiết bị phía sau. Cả cây PCIe chỉ có một root complex, một address domain, một chủ sở hữu duy nhất. Đây là lý do bạn không thể cắm hai CPU/host vào cùng một cây PCIe – cả hai sẽ cùng đòi làm root complex, cùng enumerate, cùng đòi sở hữu config space và address space → xung đột ngay.
Non-transparent bridge (NTB) giải quyết đúng vấn đề đó. Thay vì hiện ra như một bridge để nhìn xuyên qua, NTB trình diện với mỗi bên như một endpoint (một thiết bị có BAR). Quá trình enumerate của Host A dừng lại ngay tại NTB – nó chỉ thấy “một endpoint”, không cố enumerate cây phía bên kia. Host B cũng vậy. Nhờ đó hai domain PCIe độc lập (hai root complex) có thể nối với nhau mà không bên nào giẫm chân bên nào.

Hình 2. NTB nối hai domain PCIe độc lập; mỗi bên chỉ thấy NTB như một endpoint.
Vậy hai bên trao đổi dữ liệu với nhau bằng cách nào? NTB cung cấp một cơ chế address translation giữa hai domain. Mỗi bên có các BAR window map vào không gian địa chỉ của mình; khi một bên ghi vào window đó, NTB dịch địa chỉ sang địa chỉ tương ứng trong domain bên kia rồi forward transaction qua. Ngoài ra còn ba thành phần phụ trợ quan trọng:
- Doorbell registers: một bên ghi vào doorbell để phát interrupt/tín hiệu sang bên kia (“dữ liệu đã ghi xong, xử lý đi”).
- Scratchpad registers: thanh ghi dùng chung cả hai bên đọc/ghi được, dùng để handshake, trao đổi trạng thái.
- Requester ID translation: vì hai domain đánh số Bus/Device/Function riêng, NTB phải dịch cả requester ID để completion route ngược về đúng chỗ.

Ví dụ cụ thể — write-cache mirroring trong dual-controller array (đúng kiến trúc Pure):
Một array có Controller A và Controller B, mỗi controller có CPU/root complex riêng, nối với nhau qua switch có NTB. Khi Controller A nhận một write từ host, trước khi ACK về cho host, nó bắt buộc phải mirror dữ liệu sang NVRAM của Controller B — để nếu A chết đột ngột thì B vẫn còn dữ liệu, không mất write (đảm bảo durability). Luồng diễn ra đúng như hình trên: A DMA dữ liệu qua NTB window → NTB dịch địa chỉ → dữ liệu hạ cánh vào NVRAM của B → A rung doorbell báo B. Độ trễ chỉ cỡ micro-giây vì đi thẳng qua PCIe, không phải đóng gói qua TCP/IP hay thậm chí RDMA. Khi failover, B đã có sẵn dữ liệu và tiếp quản các ổ.
Khi debug, đây cũng là lý do trên một số unit bạn thấy trong lspci có một “endpoint” lạ với vài BAR lớn nằm giữa hai miền — đó chính là NTB, không phải card hỏng.
Giờ phân tích điểm mạnh / điểm yếu:
Điểm mạnh
- Độ trễ cực thấp & băng thông cao: giao tiếp PCIe native, không có overhead protocol stack. Lý tưởng cho mirroring cache, heartbeat, coordination giữa hai controller.
- Cách ly lỗi (fault isolation) — đây chính là lý do tồn tại của NTB: hai domain độc lập, nên một bên crash/reset/re-enumerate hay reboot không kéo bên kia sập theo. Mỗi controller boot độc lập được. Với HA storage đây là yêu cầu sống còn.
- Offload bằng phần cứng: DMA engine + doorbell + scratchpad cho phép trao đổi không tốn nhiều CPU.
- Rẻ và đơn giản hơn so với gắn thêm cặp RDMA NIC chỉ để nối hai host ở cự ly gần trong cùng chassis.
Điểm yếu
- Phức tạp về phần mềm: phải cấu hình BAR window, LUT (lookup table) cho address translation, quản lý mapping — driver không hề tầm thường.
- Window/LUT có giới hạn: cửa sổ dịch địa chỉ có kích thước và số entry hữu hạn, nên không “phơi” tùy ý toàn bộ RAM bên kia được; map vùng nhớ lớn/động khá vướng.
- Phụ thuộc vendor nặng: NTB của Broadcom/PLX, Microchip (Switchtec), Intel… khác nhau về thanh ghi và cấu hình. Linux có lớp
ntbchung nhưng phần cứng bên dưới vẫn không portable. - Cự ly ngắn: PCIe là short-reach, chỉ trong chassis hoặc cáp ngoài ngắn — không dùng cho khoảng cách xa.
- Xử lý lỗi & hot-plug xuyên bridge phức tạp: phải chặn không cho fatal error của một bên lan sang bên kia; error containment cần thiết kế cẩn thận.
- Bề mặt tin cậy/bảo mật: NTB cho một host một “cửa sổ” ghi thẳng vào bộ nhớ host kia — hai bên buộc phải tin nhau hoàn toàn.
- Khó mở rộng: về cơ bản là point-to-point giữa 2 domain; multi-host NTB có tồn tại nhưng độ phức tạp tăng nhanh.
Một lưu ý cho bức tranh hiện tại: với nhu cầu chia sẻ/gộp bộ nhớ giữa nhiều host, CXL đang dần thay thế NTB ở các thiết kế mới (cache-coherent, mô hình lập trình sạch hơn). Nhưng cho bài toán mirroring low-latency giữa hai controller trong cùng array thì NTB vẫn rất phổ biến và đáng tin trên các nền tảng đang sản xuất.

