CHAPTER 07
7. MSI/MSI-X를 Memory Write TLP부터 irqdomain까지 추적한다
MSI는 별도 물리 interrupt wire가 아니라 device가 특정 address와 data로 보내는 Memory Write입니다. DWC 내부 MSI controller를 쓰는 구성과 GIC ITS 같은 외부 MSI parent를 쓰는 구성을 먼저 구분해야 합니다.
DWC 내부 MSI register group
| Register | Offset | 역할 | Linux 자료구조 | 검증 |
|---|---|---|---|---|
| PCIE_MSI_ADDR_LO | 0x820 | MSI target address low | pp->msi_data | device capability에 program된 address와 일치 |
| PCIE_MSI_ADDR_HI | 0x824 | MSI target address high | pp->msi_data upper | 64-bit address 지원 확인 |
| MSI_INTR0_ENABLE | 0x828 + block offset | 32-vector block enable | irqdomain allocation | 할당 vector bit set |
| MSI_INTR0_MASK | 0x82c + block offset | mask 상태 | pp->irq_mask[ctrl] | software shadow와 hardware 일치 |
| MSI_INTR0_STATUS | 0x830 + block offset | pending/W1C status | dw_handle_msi_irq | pending bit와 virq mapping |
| block stride | 12 bytes | 다음 32 vector group | MAX_MSI_CTRLS | vector/32와 bit%32 계산 |
| MAX_MSI_IRQS | 256 | 공통 driver 상한 | bitmap/irq arrays | IP 실제 vector 수와 min 적용 |
MSI write가 Linux handler까지 가는 경로
| 단계 | 값 | 관찰 지점 | 실패 시 |
|---|---|---|---|
| Vector allocation | hwirq/virq | irqdomain, driver return | vector 부족/domain 오류 |
| Message compose | address_lo/hi + data | MSI capability/MSI-X table | 잘못된 target/data |
| Device Memory Write | Requester ID, address, data | protocol analyzer/AER | TLP 미발생/UR |
| Internal DWC match | MSI address/status bit | MSI status register | status 0이면 route/address 문제 |
| Parent IRQ | DWC MSI summary IRQ | GIC/PLIC/APIC counter | status는 1인데 parent IRQ 없음 |
| irqdomain dispatch | hwirq→virq | generic_handle_domain_irq | mapping/affinity 문제 |
| Device ISR | queue/vector | /proc/interrupts/trace | IRQ는 오나 wrong queue |
| Ack/clear/unmask | W1C status/mask | register readback | interrupt storm 또는 1회 후 정지 |
내부 DWC MSI와 외부 MSI parent 비교
| 항목 | DWC 내부 MSI | 외부 GIC ITS/플랫폼 MSI | 판정 근거 |
|---|---|---|---|
| DT 표시 | msi-parent/msi-map가 없을 수 있음 | msi-parent 또는 msi-map | live DT |
| target address | DWC가 할당한 msi_data | ITS/doorbell address | compose_msi_msg |
| pending status | DWC 0x830 계열 | ITS/외부 controller | 어느 bank가 증가하는가 |
| parent IRQ | DWC summary IRQ | LPI/MSI domain | /proc/interrupts와 irqdomain |
| mask | DWC mask shadow/register | MSI core/remapper | irq_chip ops |
| 대표 설정 오류 | 내부 block enable 누락 | RID/DeviceID/MSI map 오류 | fault/status 위치 |
MSI-X에서 추가로 볼 항목
| 항목 | 위치 | 의미 | 검증 |
|---|---|---|---|
| Table BIR | MSI-X capability | table이 들어 있는 BAR | BAR resource와 mapping |
| Table offset | MSI-X capability | BAR 내 table 시작 | entry stride/범위 |
| Message address | entry +0/+4 | vector별 target | irq core가 쓴 값 |
| Message data | entry +8 | vector data | hwirq/remapper data |
| Vector control | entry +12 | per-vector mask | unmask 후 bit0=0 |
| PBA | BIR+offset | masked pending bit | mask 중 event 후 bit set |
| Function Mask | MSI-X Message Control | 전체 vector mask | probe/runtime 전환 |
실제 검증 절차
| 순서 | 실행 | 남길 증거 | 판정 목적 |
|---|---|---|---|
| 1 | 할당된 virq, hwirq, message address/data와 queue index를 표로 저장합니다. | vector 하나가 한 queue/handler에 일관되게 연결 | 번호 공간 혼동 제거 |
| 2 | device table/capability와 irqdomain이 compose한 message를 비교합니다. | address/data exact match | device programming 누락 확인 |
| 3 | DMA completion memory write와 MSI TLP를 timestamp로 비교합니다. | completion data가 먼저, MSI가 뒤 | device ordering 또는 driver visibility 문제 |
| 4 | DWC status, parent controller count, `/proc/interrupts`를 같은 event에서 봅니다. | 처음 증가하지 않는 stage | routing 경계 확정 |
| 5 | mask/unmask와 affinity 변경을 반복합니다. | pending/재전달/target CPU 동작 | vector control과 remapper 검증 |
주의DWC 내부 MSI status가 0이라고 해서 device가 MSI를 보내지 않았다고 단정하지 않습니다. 외부 MSI parent 구성이면 해당 TLP는 DWC 내부 block을 거치지 않을 수 있습니다.
공개적으로 다시 확인할 수 있는 자료
공개되지 않은 vendor register나 integration별 offset을 추측해서 채우지 않았습니다. 아래 제조사 자료, architecture 문서와 Linux v6.18.37 원본에서 다시 확인할 수 있는 범위만 사용했습니다.
Linux v6.18.37 DWC common source
iATU programming, version/capability와 eDMA detection
Linux v6.18.37 DWC host source
ECAM/CFG access, Root Port setup, MSI irqdomain와 host lifecycle
Linux v6.18.37 PCI probe
Vendor ID read, pci_dev 생성, BAR sizing와 bridge scan
Linux v6.18.37 PCI resource assignment
bridge window와 endpoint BAR resource 배치
Linux DWC Devicetree binding
reg/ranges, iATU window 수, lane/speed와 MSI/IOMMU 연결