/proc/irq//smp_affinityの書き換えでPCIコンフィグレーション空間はどのように書き換わるか

※追記:実際にはカーネルにprintkを突っ込みまくるという、ずっと泥臭い方法で調査をしてました。多分役にたたないと思うけど、一応その時のdiffも併せて公開しておきます。Linux 3.2.0+用なので、他のバージョンだと当たらないかもしれません。
Debug print for trace MSI Interrupt routing settings, Linux-3.2.0+ · GitHub


例えば僕のThinkpad x200にはこんなデバイスがあります。
(dmesgから抜粋)

e1000e: Intel(R) PRO/1000 Network Driver - 1.5.1-k
e1000e: Copyright(c) 1999 - 2011 Intel Corporation.
e1000e 0000:00:19.0: PCI INT A -> GSI 20 (level, low) -> IRQ 20
e1000e 0000:00:19.0: setting latency timer to 64
e1000e 0000:00:19.0: irq 44 for MSI/MSI-X
e1000e 0000:00:19.0: eth0: (PCI Express:2.5GT/s:Width x1) 00:1f:16:2a:a4:59
e1000e 0000:00:19.0: eth0: Intel(R) PRO/1000 Network Connection
e1000e 0000:00:19.0: eth0: MAC: 7, PHY: 8, PBA No: 1008FF-0FF
udev[16200]: renamed network interface eth0 to eth4

IRQ44のMSI割り込みを一つ持つe1000eで、PCIのアドレスは00:19.0ですね。

※同時にIRQ20のLegacy割り込みを一つ持ってるのはなんででしょうね?分かる人居たら教えて下さい。

# cat /proc/irq/44/smp_affinity
3

CPUはcpu0とcpu1なので、全てのCPUのビットを立ててるから3。

# grep eth4 /proc/interrupts 
 44:      50037      49330   PCI-MSI-edge      eth4

設定通り、両側のCPUに割り込んでますね。

この時、MSI Address RegisterとMSI Data Registerにはどのような値が設定されているか確認してみます。

# lspci -vvvv -s 00:19.0
00:19.0 Ethernet controller: Intel Corporation 82567LM Gigabit Network Connection (rev 03)
	Subsystem: Lenovo Device 20ee
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0
	Interrupt: pin A routed to IRQ 44
	Region 0: Memory at f2600000 (32-bit, non-prefetchable) [size=128K]
	Region 1: Memory at f2625000 (32-bit, non-prefetchable) [size=4K]
	Region 2: I/O ports at 1840 [size=32]
	Capabilities: [c8] Power Management version 2
		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1 PME-
	Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
		Address: 00000000fee0300c  Data: 41b9
	Capabilities: [e0] PCI Advanced Features
		AFCap: TP+ FLR+
		AFCtrl: FLR-
		AFStatus: TP-
	Kernel driver in use: e1000e
	Kernel modules: e1000e

「Capabilities: [d0] MSI」の「Address」と「Data」の所ですが、これを前回説明したビットフィールドと突き合わせて読まないといけません
分かりにくいですね。
なので、lspciを改造してわかり易く表示出来るようにしてみます。

こちらが改造後のコードになります。
早速実行してみます。

# gcc -lpci msireg.c
# ./a.out 00:19.0
Message Signalled Interrupts: 64bit+ Queue=0/0 Enable+
address_hi=0
address_lo=fee0300c dest_mode=logical redirection=lowpri dest_id=3
data=41b9 trigger=edge level=assert delivery_mode=lowpri vector=185

Logical modeでLowpri、destid=3、vector=185になってるのが分かります。
ここでsmp_affinityを変えてみましょう。

# echo 1 > /proc/irq/44/smp_affinity
# ./a.out 00:19.0
Message Signalled Interrupts: 64bit+ Queue=0/0 Enable+
address_hi=0
address_lo=fee0100c dest_mode=logical redirection=lowpri dest_id=1
data=41b9 trigger=edge level=assert delivery_mode=lowpri vector=185

dest_idが1に書き換わったのが見て取れます。